mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 06:05:02 +03:00
fix(es/resolver): Fix handling of decorators (#4084)
This commit is contained in:
parent
60d820a47c
commit
f66229822c
@ -638,6 +638,10 @@ where
|
||||
|
||||
self.emit_accessibility(n.accessibility)?;
|
||||
|
||||
for dec in &n.decorators {
|
||||
emit!(dec);
|
||||
}
|
||||
|
||||
if n.is_override {
|
||||
keyword!("override");
|
||||
space!();
|
||||
|
@ -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 => {
|
||||
|
@ -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 {
|
||||
|
@ -0,0 +1,7 @@
|
||||
import { field } from "../validation/decorators";
|
||||
class C {
|
||||
constructor(
|
||||
@field("a") readonly field: string,
|
||||
@field("b") readonly b: string,
|
||||
) { }
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import { field } from "../validation/decorators";
|
||||
class C {
|
||||
constructor(@field("a")
|
||||
readonly field__2: string, @field("b")
|
||||
readonly b__2: string){}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import { field } from "../validation/decorators";
|
||||
class C {
|
||||
method(
|
||||
@field("a") readonly field: string,
|
||||
@field("b") readonly b: string,
|
||||
) { }
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
import { field } from "../validation/decorators";
|
||||
class C {
|
||||
method(
|
||||
@field("a")
|
||||
field__2: string,
|
||||
@field("b")
|
||||
b__2: string) {}
|
||||
}
|
Loading…
Reference in New Issue
Block a user