mirror of
https://github.com/swc-project/swc.git
synced 2024-11-28 11:13:43 +03:00
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:
parent
0fabc2cfc9
commit
4ab7a91fe3
@ -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"
|
||||
|
@ -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]
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
}
|
||||
"
|
||||
);
|
||||
|
142
ecmascript/transforms/base/tests/ts_resolver.rs
Normal file
142
ecmascript/transforms/base/tests/ts_resolver.rs
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user