fix(es): Fix for the type checker (#1528)

swc_ecma_codegen:
 - Fix codegen of type assertions.


swc_ecma_transforms_base:
 - `resolver`: Handle getter properties.
 - •resolver`: Handle setter properties.
This commit is contained in:
강동윤 2021-04-01 03:01:44 +09:00 committed by GitHub
parent 0fabc2cfc9
commit 4ab7a91fe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 211 additions and 9 deletions

View File

@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"]
license = "Apache-2.0/MIT"
name = "swc_ecma_codegen"
repository = "https://github.com/swc-project/swc.git"
version = "0.50.1"
version = "0.50.2"
[dependencies]
bitflags = "1"

View File

@ -845,13 +845,10 @@ impl<'a> Emitter<'a> {
fn emit_ts_type_assertion(&mut self, n: &TsTypeAssertion) -> Result {
self.emit_leading_comments_of_pos(n.span().lo())?;
keyword!("asserts");
space!();
emit!(n.expr);
space!();
keyword!("is");
space!();
punct!("<");
emit!(n.type_ann);
punct!(">");
emit!(n.expr);
}
#[emitter]

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_base"
repository = "https://github.com/swc-project/swc.git"
version = "0.10.0"
version = "0.10.1"
[dependencies]
fxhash = "0.2.1"

View File

@ -498,7 +498,23 @@ macro_rules! track_ident_mut {
self.ident_type = old;
}
fn visit_mut_getter_prop(&mut self, f: &mut GetterProp) {
let old = self.ident_type;
self.ident_type = IdentType::Ref;
f.key.visit_mut_with(self);
self.ident_type = old;
f.type_ann.visit_mut_with(self);
f.body.visit_mut_with(self);
}
fn visit_mut_setter_prop(&mut self, f: &mut SetterProp) {
let old = self.ident_type;
self.ident_type = IdentType::Ref;
f.key.visit_mut_with(self);
self.ident_type = old;
let old = self.ident_type;
self.ident_type = IdentType::Binding;
f.param.visit_mut_with(self);

View File

@ -28,7 +28,14 @@ impl VisitMut for TsHygiene {
}
}
fn visit_mut_prop_name(&mut self, _: &mut PropName) {}
fn visit_mut_prop_name(&mut self, n: &mut PropName) {
match n {
PropName::Computed(n) => {
n.visit_mut_with(self);
}
_ => {}
}
}
fn visit_mut_ts_qualified_name(&mut self, q: &mut TsQualifiedName) {
q.left.visit_mut_with(self);
@ -2377,3 +2384,43 @@ to_ts!(
}
"
);
to_ts!(
tsc_computed_property_name_11,
"
var s: string;
var n: number;
var a: any;
var v = {
get [s]() { return 0; },
set [n](v) { },
get [s + s]() { return 0; },
set [s + n](v) { },
get [+s]() { return 0; },
set [\"\"](v) { },
get [0]() { return 0; },
set [a](v) { },
get [<any>true]() { return 0; },
set [`hello bye`](v) { },
get [`hello ${a} bye`]() { return 0; }
}
",
"
var s: string;
var n: number;
var a: any;
var v = {
get [s]() { return 0; },
set [n](v__2) { },
get [s + s]() { return 0; },
set [s + n](v__2) { },
get [+s]() { return 0; },
set [\"\"](v__2) { },
get [0]() { return 0; },
set [a](v__2) { },
get [<any>true]() { return 0; },
set [`hello bye`](v__2) { },
get [`hello ${a} bye`]() { return 0; }
}
"
);

View File

@ -0,0 +1,142 @@
use std::path::PathBuf;
use swc_common::input::SourceFileInput;
use swc_common::Mark;
use swc_common::SyntaxContext;
use swc_common::DUMMY_SP;
use swc_ecma_ast::*;
use swc_ecma_parser::lexer::Lexer;
use swc_ecma_parser::Parser;
use swc_ecma_parser::Syntax;
use swc_ecma_parser::TsConfig;
use swc_ecma_transforms_base::resolver::ts_resolver;
use swc_ecma_visit::FoldWith;
use swc_ecma_visit::Node;
use swc_ecma_visit::Visit;
use swc_ecma_visit::VisitWith;
use testing::fixture;
#[fixture("../../../parser/tests/typescript/**/*.ts")]
#[fixture("../../../parser/tests/typescript/**/*.tsx")]
fn no_empty(input: PathBuf) {
eprintln!("{}", input.display());
testing::run_test2(false, |cm, _handler| {
let fm = cm.load_file(&input).expect("failed to load file");
let lexer = Lexer::new(
Syntax::Typescript(TsConfig {
tsx: input.ends_with("tsx"),
decorators: true,
dynamic_import: true,
no_early_errors: true,
import_assertions: true,
..Default::default()
}),
EsVersion::latest(),
SourceFileInput::from(&*fm),
None,
);
let mut parser = Parser::new_from(lexer);
let module = match parser.parse_module() {
Ok(v) => v,
// We are not testing parser
Err(..) => return Ok(()),
};
let module = module.fold_with(&mut ts_resolver(Mark::fresh(Mark::root())));
module.visit_with(&Invalid { span: DUMMY_SP }, &mut AssertNoEmptyCtxt);
Ok(())
})
.unwrap();
}
struct AssertNoEmptyCtxt;
impl Visit for AssertNoEmptyCtxt {
fn visit_class_prop(&mut self, n: &ClassProp, _: &dyn Node) {
if n.computed {
n.key.visit_with(n, self);
}
n.value.visit_with(n, self);
n.type_ann.visit_with(n, self);
n.decorators.visit_with(n, self);
}
fn visit_expr(&mut self, n: &Expr, _: &dyn Node) {
n.visit_children_with(self);
match n {
Expr::Ident(i) => {
if i.span.ctxt == SyntaxContext::empty() {
unreachable!("ts_resolver has a bug")
}
}
_ => {}
}
}
fn visit_member_expr(&mut self, n: &MemberExpr, _: &dyn Node) {
n.obj.visit_with(n, self);
if n.computed {
n.prop.visit_with(n, self);
}
}
fn visit_pat(&mut self, n: &Pat, _: &dyn Node) {
n.visit_children_with(self);
match n {
Pat::Ident(i) => {
if i.id.span.ctxt == SyntaxContext::empty() {
unreachable!("ts_resolver has a bug")
}
}
_ => {}
}
}
fn visit_ts_getter_signature(&mut self, n: &TsGetterSignature, _: &dyn Node) {
if n.computed {
n.key.visit_with(n, self);
}
n.type_ann.visit_with(n, self);
}
fn visit_ts_method_signature(&mut self, n: &TsMethodSignature, _: &dyn Node) {
if n.computed {
n.key.visit_with(n, self);
}
n.params.visit_with(n, self);
n.type_ann.visit_with(n, self);
n.type_params.visit_with(n, self);
}
fn visit_ts_property_signature(&mut self, n: &TsPropertySignature, _: &dyn Node) {
if n.computed {
n.key.visit_with(n, self);
}
n.init.visit_with(n, self);
n.params.visit_with(n, self);
n.type_ann.visit_with(n, self);
n.type_params.visit_with(n, self);
}
fn visit_ts_setter_signature(&mut self, n: &TsSetterSignature, _: &dyn Node) {
if n.computed {
n.key.visit_with(n, self);
}
n.param.visit_with(n, self);
}
fn visit_ts_tuple_element(&mut self, n: &TsTupleElement, _: &dyn Node) {
n.ty.visit_with(n, self);
}
}