fix(es/resolver): Fix handling of decorators (#4084)

This commit is contained in:
Donny/강동윤 2022-03-19 14:32:53 +09:00 committed by GitHub
parent 60d820a47c
commit f66229822c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 73 additions and 9 deletions

View File

@ -638,6 +638,10 @@ where
self.emit_accessibility(n.accessibility)?;
for dec in &n.decorators {
emit!(dec);
}
if n.is_override {
keyword!("override");
space!();

View File

@ -565,6 +565,8 @@ impl<'a> VisitMut for Resolver<'a> {
fn visit_mut_class_decl(&mut self, n: &mut ClassDecl) {
self.modify(&mut n.ident, None);
n.class.decorators.visit_mut_with(self);
// Create a child scope. The class name is only accessible within the class.
let child_mark = Mark::fresh(Mark::root());
@ -597,6 +599,10 @@ impl<'a> VisitMut for Resolver<'a> {
fn visit_mut_class_method(&mut self, m: &mut ClassMethod) {
m.key.visit_mut_with(self);
for p in m.function.params.iter_mut() {
p.decorators.visit_mut_with(self);
}
{
let child_mark = Mark::fresh(Mark::root());
@ -631,6 +637,17 @@ impl<'a> VisitMut for Resolver<'a> {
fn visit_mut_constructor(&mut self, c: &mut Constructor) {
let child_mark = Mark::fresh(Mark::root());
for p in c.params.iter_mut() {
match p {
ParamOrTsParamProp::TsParamProp(p) => {
p.decorators.visit_mut_with(self);
}
ParamOrTsParamProp::Param(p) => {
p.decorators.visit_mut_with(self);
}
}
}
// Child folder
let mut folder = Resolver::new(
Scope::new(ScopeKind::Fn, child_mark, Some(&self.current)),
@ -696,6 +713,8 @@ impl<'a> VisitMut for Resolver<'a> {
fn visit_mut_fn_decl(&mut self, node: &mut FnDecl) {
// We don't fold this as Hoister handles this.
node.function.decorators.visit_mut_with(self);
{
let child_mark = Mark::fresh(Mark::root());
@ -710,6 +729,8 @@ impl<'a> VisitMut for Resolver<'a> {
}
fn visit_mut_fn_expr(&mut self, e: &mut FnExpr) {
e.function.decorators.visit_mut_with(self);
let child_mark = Mark::fresh(Mark::root());
// Child folder
@ -789,6 +810,10 @@ impl<'a> VisitMut for Resolver<'a> {
}
fn visit_mut_ident(&mut self, i: &mut Ident) {
if i.span.ctxt != SyntaxContext::empty() {
return;
}
match self.ident_type {
IdentType::Binding => self.modify(i, None),
IdentType::Ref => {

View File

@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
use swc_common::{chain, sync::Lrc, Mark, SourceMap, SyntaxContext};
use swc_ecma_ast::*;
use swc_ecma_codegen::Emitter;
use swc_ecma_parser::{lexer::Lexer, EsConfig, Parser, StringInput, Syntax};
use swc_ecma_parser::{lexer::Lexer, EsConfig, Parser, StringInput, Syntax, TsConfig};
use swc_ecma_transforms_base::{
fixer::fixer,
resolver::{resolver_with_mark, ts_resolver},
@ -90,15 +90,22 @@ fn test_resolver(input: PathBuf) {
#[fixture("tests/ts-resolver/**/input.ts")]
fn test_ts_resolver(input: PathBuf) {
run(Syntax::Typescript(Default::default()), &input, || {
let top_level_mark = Mark::fresh(Mark::root());
run(
Syntax::Typescript(TsConfig {
decorators: true,
..Default::default()
}),
&input,
|| {
let top_level_mark = Mark::fresh(Mark::root());
chain!(
ts_resolver(top_level_mark),
as_folder(TsHygiene { top_level_mark }),
fixer(None)
)
});
chain!(
ts_resolver(top_level_mark),
as_folder(TsHygiene { top_level_mark }),
fixer(None)
)
},
);
}
struct TsHygiene {

View File

@ -0,0 +1,7 @@
import { field } from "../validation/decorators";
class C {
constructor(
@field("a") readonly field: string,
@field("b") readonly b: string,
) { }
}

View File

@ -0,0 +1,6 @@
import { field } from "../validation/decorators";
class C {
constructor(@field("a")
readonly field__2: string, @field("b")
readonly b__2: string){}
}

View File

@ -0,0 +1,7 @@
import { field } from "../validation/decorators";
class C {
method(
@field("a") readonly field: string,
@field("b") readonly b: string,
) { }
}

View File

@ -0,0 +1,8 @@
import { field } from "../validation/decorators";
class C {
method(
@field("a")
field__2: string,
@field("b")
b__2: string) {}
}