mirror of
https://github.com/swc-project/swc.git
synced 2024-12-25 06:36:08 +03:00
fix(es/transforms/base): Fix resolver (#1710)
swc_ecma_transforms_base: - `ts_resolver`: Treat the type parameter of a mapped type as a binding.
This commit is contained in:
parent
dee82904f8
commit
a0241c88b2
@ -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.15.2"
|
||||
version = "0.15.3"
|
||||
|
||||
[dependencies]
|
||||
fxhash = "0.2.1"
|
||||
|
@ -388,7 +388,6 @@ impl<'a> VisitMut for Resolver<'a> {
|
||||
typed!(visit_mut_ts_fn_or_constructor_type, TsFnOrConstructorType);
|
||||
typed_ref!(visit_mut_ts_union_type, TsUnionType);
|
||||
typed_ref!(visit_mut_ts_infer_type, TsInferType);
|
||||
typed_ref!(visit_mut_ts_mapped_type, TsMappedType);
|
||||
typed_ref!(visit_mut_ts_import_type, TsImportType);
|
||||
typed_ref!(visit_mut_ts_tuple_type, TsTupleType);
|
||||
typed_ref!(visit_mut_ts_intersection_type, TsIntersectionType);
|
||||
@ -570,6 +569,33 @@ impl<'a> VisitMut for Resolver<'a> {
|
||||
decl.visit_mut_children_with(self)
|
||||
}
|
||||
|
||||
fn visit_mut_export_default_decl(&mut self, e: &mut ExportDefaultDecl) {
|
||||
// Treat default exported functions and classes as declarations
|
||||
// even though they are parsed as expressions.
|
||||
match &mut e.decl {
|
||||
DefaultDecl::Fn(f) => {
|
||||
if f.ident.is_some() {
|
||||
let child_mark = Mark::fresh(self.mark);
|
||||
|
||||
// Child folder
|
||||
let mut folder = Resolver::new(
|
||||
child_mark,
|
||||
Scope::new(ScopeKind::Fn, Some(&self.current)),
|
||||
self.handle_types,
|
||||
);
|
||||
f.function.visit_mut_with(&mut folder)
|
||||
} else {
|
||||
f.visit_mut_with(self)
|
||||
}
|
||||
}
|
||||
DefaultDecl::Class(c) => {
|
||||
// Skip class expression visitor to treat as a declaration.
|
||||
c.class.visit_mut_with(self)
|
||||
}
|
||||
_ => e.visit_mut_children_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_expr(&mut self, expr: &mut Expr) {
|
||||
self.in_type = false;
|
||||
let old = self.ident_type;
|
||||
@ -612,33 +638,6 @@ impl<'a> VisitMut for Resolver<'a> {
|
||||
e.function.visit_mut_with(&mut folder);
|
||||
}
|
||||
|
||||
fn visit_mut_export_default_decl(&mut self, e: &mut ExportDefaultDecl) {
|
||||
// Treat default exported functions and classes as declarations
|
||||
// even though they are parsed as expressions.
|
||||
match &mut e.decl {
|
||||
DefaultDecl::Fn(f) => {
|
||||
if f.ident.is_some() {
|
||||
let child_mark = Mark::fresh(self.mark);
|
||||
|
||||
// Child folder
|
||||
let mut folder = Resolver::new(
|
||||
child_mark,
|
||||
Scope::new(ScopeKind::Fn, Some(&self.current)),
|
||||
self.handle_types,
|
||||
);
|
||||
f.function.visit_mut_with(&mut folder)
|
||||
} else {
|
||||
f.visit_mut_with(self)
|
||||
}
|
||||
}
|
||||
DefaultDecl::Class(c) => {
|
||||
// Skip class expression visitor to treat as a declaration.
|
||||
c.class.visit_mut_with(self)
|
||||
}
|
||||
_ => e.visit_mut_children_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_for_in_stmt(&mut self, n: &mut ForInStmt) {
|
||||
let child_mark = Mark::fresh(self.mark);
|
||||
let mut child = Resolver::new(
|
||||
@ -777,11 +776,6 @@ impl<'a> VisitMut for Resolver<'a> {
|
||||
self.ident_type = old;
|
||||
}
|
||||
|
||||
// TODO: How should I handle this?
|
||||
typed!(visit_mut_ts_namespace_export_decl, TsNamespaceExportDecl);
|
||||
|
||||
track_ident_mut!();
|
||||
|
||||
/// Leftmost one of a member expression should be resolved.
|
||||
fn visit_mut_member_expr(&mut self, e: &mut MemberExpr) {
|
||||
e.obj.visit_mut_with(self);
|
||||
@ -791,25 +785,10 @@ impl<'a> VisitMut for Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_setter_prop(&mut self, n: &mut SetterProp) {
|
||||
n.key.visit_mut_with(self);
|
||||
// TODO: How should I handle this?
|
||||
typed!(visit_mut_ts_namespace_export_decl, TsNamespaceExportDecl);
|
||||
|
||||
{
|
||||
let child_mark = Mark::fresh(self.mark);
|
||||
|
||||
// Child folder
|
||||
let mut child = Resolver::new(
|
||||
child_mark,
|
||||
Scope::new(ScopeKind::Fn, Some(&self.current)),
|
||||
self.handle_types,
|
||||
);
|
||||
|
||||
child.in_type = false;
|
||||
child.ident_type = IdentType::Binding;
|
||||
n.param.visit_mut_with(&mut child);
|
||||
n.body.visit_mut_with(&mut child);
|
||||
};
|
||||
}
|
||||
track_ident_mut!();
|
||||
|
||||
fn visit_mut_method_prop(&mut self, m: &mut MethodProp) {
|
||||
m.key.visit_mut_with(self);
|
||||
@ -889,6 +868,26 @@ impl<'a> VisitMut for Resolver<'a> {
|
||||
|
||||
fn visit_mut_private_name(&mut self, _: &mut PrivateName) {}
|
||||
|
||||
fn visit_mut_setter_prop(&mut self, n: &mut SetterProp) {
|
||||
n.key.visit_mut_with(self);
|
||||
|
||||
{
|
||||
let child_mark = Mark::fresh(self.mark);
|
||||
|
||||
// Child folder
|
||||
let mut child = Resolver::new(
|
||||
child_mark,
|
||||
Scope::new(ScopeKind::Fn, Some(&self.current)),
|
||||
self.handle_types,
|
||||
);
|
||||
|
||||
child.in_type = false;
|
||||
child.ident_type = IdentType::Binding;
|
||||
n.param.visit_mut_with(&mut child);
|
||||
n.body.visit_mut_with(&mut child);
|
||||
};
|
||||
}
|
||||
|
||||
fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {
|
||||
// Phase 1: Handle hoisting
|
||||
{
|
||||
@ -1038,6 +1037,24 @@ impl<'a> VisitMut for Resolver<'a> {
|
||||
n.body.visit_mut_with(&mut child);
|
||||
}
|
||||
|
||||
fn visit_mut_ts_mapped_type(&mut self, n: &mut TsMappedType) {
|
||||
if !self.handle_types {
|
||||
return;
|
||||
}
|
||||
|
||||
self.in_type = true;
|
||||
self.ident_type = IdentType::Binding;
|
||||
n.type_param.visit_mut_with(self);
|
||||
|
||||
self.in_type = true;
|
||||
self.ident_type = IdentType::Ref;
|
||||
n.name_type.visit_mut_with(self);
|
||||
|
||||
self.in_type = true;
|
||||
self.ident_type = IdentType::Ref;
|
||||
n.type_ann.visit_mut_with(self);
|
||||
}
|
||||
|
||||
fn visit_mut_ts_method_signature(&mut self, n: &mut TsMethodSignature) {
|
||||
if !self.handle_types {
|
||||
return;
|
||||
|
@ -3000,3 +3000,17 @@ to_ts!(
|
||||
}
|
||||
"
|
||||
);
|
||||
|
||||
to_ts!(
|
||||
ts_mapped_type_as_clauses_01,
|
||||
"
|
||||
type Lazyify<T> = {
|
||||
[K in keyof T as `get${Capitalize<K & string>}`]: () => T[K]
|
||||
};
|
||||
",
|
||||
"
|
||||
type Lazyify<T__2> = {
|
||||
[K__2 in keyof T__2]: () => T__2[K__2];
|
||||
};
|
||||
"
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user