From b42bbf4926b29bf4646a9495734658e70c3c177a Mon Sep 17 00:00:00 2001 From: magic-akari Date: Mon, 11 Apr 2022 15:31:29 +0800 Subject: [PATCH] feat(es/parser): typeof on #private Fields --- crates/swc_ecma_ast/src/lib.rs | 2 +- crates/swc_ecma_ast/src/typescript.rs | 16 +- crates/swc_ecma_codegen/src/typescript.rs | 10 + .../swc_ecma_parser/src/parser/typescript.rs | 31 +- .../private-name-in-type-query/1/input.ts | 8 + .../1/input.ts.json | 290 +++++++++++++ .../private-name-in-type-query/2/input.ts | 11 + .../2/input.ts.json | 394 ++++++++++++++++++ .../src/decorators/legacy/metadata.rs | 5 +- .../src/strip.rs | 5 +- .../tests/fixture/issue-4287/1/input.ts | 8 + .../tests/fixture/issue-4287/1/output.js | 11 + .../tests/fixture/issue-4287/2/input.ts | 11 + .../tests/fixture/issue-4287/2/output.js | 15 + crates/swc_ecma_visit/src/lib.rs | 9 +- 15 files changed, 810 insertions(+), 16 deletions(-) create mode 100644 crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/1/input.ts create mode 100644 crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/1/input.ts.json create mode 100644 crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/2/input.ts create mode 100644 crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/2/input.ts.json create mode 100644 crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/1/input.ts create mode 100644 crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/1/output.js create mode 100644 crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/2/input.ts create mode 100644 crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/2/output.js diff --git a/crates/swc_ecma_ast/src/lib.rs b/crates/swc_ecma_ast/src/lib.rs index ba952a2844dbf..199f6eecc9192 100644 --- a/crates/swc_ecma_ast/src/lib.rs +++ b/crates/swc_ecma_ast/src/lib.rs @@ -58,7 +58,7 @@ pub use self::{ typescript::{ Accessibility, TruePlusMinus, TsArrayType, TsAsExpr, TsCallSignatureDecl, TsConditionalType, TsConstAssertion, TsConstructSignatureDecl, TsConstructorType, - TsEntityName, TsEnumDecl, TsEnumMember, TsEnumMemberId, TsExportAssignment, + TsEntityMember, TsEntityName, TsEnumDecl, TsEnumMember, TsEnumMemberId, TsExportAssignment, TsExprWithTypeArgs, TsExternalModuleRef, TsFnOrConstructorType, TsFnParam, TsFnType, TsGetterSignature, TsImportEqualsDecl, TsImportType, TsIndexSignature, TsIndexedAccessType, TsInferType, TsInstantiation, TsInterfaceBody, TsInterfaceDecl, TsIntersectionType, diff --git a/crates/swc_ecma_ast/src/typescript.rs b/crates/swc_ecma_ast/src/typescript.rs index a5693f95b6f68..baac3e4d9ed74 100644 --- a/crates/swc_ecma_ast/src/typescript.rs +++ b/crates/swc_ecma_ast/src/typescript.rs @@ -18,7 +18,7 @@ use crate::{ lit::{Bool, Number, Str}, module::ModuleItem, pat::{ArrayPat, AssignPat, ObjectPat, Pat, RestPat}, - BigInt, BindingIdent, TplElement, + BigInt, BindingIdent, PrivateName, TplElement, }; #[ast_node("TsTypeAnnotation")] @@ -101,7 +101,7 @@ pub struct TsQualifiedName { #[span(lo)] pub left: TsEntityName, #[span(hi)] - pub right: Ident, + pub right: TsEntityMember, } #[ast_node] @@ -116,6 +116,18 @@ pub enum TsEntityName { Ident(Ident), } +#[ast_node] +#[derive(Eq, Hash, Is, EqIgnoreSpan)] +#[allow(variant_size_differences)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub enum TsEntityMember { + #[tag("Identifier")] + Ident(Ident), + + #[tag("PrivateName")] + PrivateName(PrivateName), +} + // ================ // TypeScript type members (for type literal / interface / class) // ================ diff --git a/crates/swc_ecma_codegen/src/typescript.rs b/crates/swc_ecma_codegen/src/typescript.rs index 51cc20af39316..5481f862963a5 100644 --- a/crates/swc_ecma_codegen/src/typescript.rs +++ b/crates/swc_ecma_codegen/src/typescript.rs @@ -137,6 +137,16 @@ where } } + #[emitter] + fn emit_ts_entity_member(&mut self, n: &TsEntityMember) -> Result { + self.emit_leading_comments_of_span(n.span(), false)?; + + match n { + TsEntityMember::Ident(n) => emit!(n), + TsEntityMember::PrivateName(n) => emit!(n), + } + } + #[emitter] fn emit_ts_enum_decl(&mut self, n: &TsEnumDecl) -> Result { self.emit_leading_comments_of_span(n.span(), false)?; diff --git a/crates/swc_ecma_parser/src/parser/typescript.rs b/crates/swc_ecma_parser/src/parser/typescript.rs index b2fba6108e599..3f482d4df74d3 100644 --- a/crates/swc_ecma_parser/src/parser/typescript.rs +++ b/crates/swc_ecma_parser/src/parser/typescript.rs @@ -178,7 +178,11 @@ impl Parser { } /// `tsParseEntityName` - fn parse_ts_entity_name(&mut self, allow_reserved_words: bool) -> PResult { + fn parse_ts_entity_name( + &mut self, + allow_reserved_words: bool, + allow_private_identifiers: bool, + ) -> PResult { debug_assert!(self.input.syntax().typescript()); let init = self.parse_ident_name()?; @@ -194,7 +198,7 @@ impl Parser { let mut entity = TsEntityName::Ident(init); while eat!(self, '.') { let dot_start = cur_pos!(self); - if !is!(self, '#') && !is!(self, IdentName) { + if !allow_private_identifiers && !is!(self, '#') && !is!(self, IdentName) { self.emit_err( Span::new(dot_start, dot_start, Default::default()), SyntaxError::TS1003, @@ -203,10 +207,13 @@ impl Parser { } let left = entity; - let right = if allow_reserved_words { - self.parse_ident_name()? + let right = if allow_private_identifiers { + self.parse_maybe_private_name()? + .either(Into::into, Into::into) + } else if allow_reserved_words { + self.parse_ident_name()?.into() } else { - self.parse_ident(false, false)? + self.parse_ident(false, false)?.into() }; entity = TsEntityName::TsQualifiedName(Box::new(TsQualifiedName { left, right })); } @@ -223,7 +230,9 @@ impl Parser { let has_modifier = self.eat_any_ts_modifier()?; - let type_name = self.parse_ts_entity_name(/* allow_reserved_words */ true)?; + let type_name = self.parse_ts_entity_name( + /* allow_reserved_words */ true, /* allow_private_identifiers */ false, + )?; trace_cur!(self, parse_ts_type_ref__type_args); let type_params = if !self.input.had_line_break_before_cur() && is!(self, '<') { Some(self.parse_ts_type_args()?) @@ -315,7 +324,7 @@ impl Parser { expect!(self, ')'); let qualifier = if eat!(self, '.') { - self.parse_ts_entity_name(false).map(Some)? + self.parse_ts_entity_name(false, false).map(Some)? } else { None }; @@ -345,7 +354,7 @@ impl Parser { } else { self.parse_ts_entity_name( // allow_reserved_word - true, + true, true, ) .map(From::from)? }; @@ -1124,8 +1133,10 @@ impl Parser { if self.is_ts_external_module_ref()? { self.parse_ts_external_module_ref().map(From::from) } else { - self.parse_ts_entity_name(/* allow_reserved_words */ false) - .map(From::from) + self.parse_ts_entity_name( + /* allow_reserved_words */ false, /* allow_private_identifiers */ false, + ) + .map(From::from) } } diff --git a/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/1/input.ts b/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/1/input.ts new file mode 100644 index 0000000000000..95d8b82a0a996 --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/1/input.ts @@ -0,0 +1,8 @@ +class C { + #a = 'a'; + + constructor() { + const a: typeof this.#a = ''; // Ok + const b: typeof this.#a = 1; // Error + } +} \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/1/input.ts.json b/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/1/input.ts.json new file mode 100644 index 0000000000000..7bfc65930e1cd --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/1/input.ts.json @@ -0,0 +1,290 @@ +{ + "type": "Script", + "span": { + "start": 0, + "end": 143, + "ctxt": 0 + }, + "body": [ + { + "type": "ClassDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 6, + "end": 7, + "ctxt": 0 + }, + "value": "C", + "optional": false + }, + "declare": false, + "span": { + "start": 0, + "end": 143, + "ctxt": 0 + }, + "decorators": [], + "body": [ + { + "type": "PrivateProperty", + "span": { + "start": 14, + "end": 23, + "ctxt": 0 + }, + "key": { + "type": "PrivateName", + "span": { + "start": 14, + "end": 16, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 15, + "end": 16, + "ctxt": 0 + }, + "value": "a", + "optional": false + } + }, + "value": { + "type": "StringLiteral", + "span": { + "start": 19, + "end": 22, + "ctxt": 0 + }, + "value": "a", + "raw": "'a'" + }, + "typeAnnotation": null, + "isStatic": false, + "decorators": [], + "accessibility": null, + "isOptional": false, + "isOverride": false, + "readonly": false, + "definite": false + }, + { + "type": "Constructor", + "span": { + "start": 29, + "end": 141, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 29, + "end": 40, + "ctxt": 0 + }, + "value": "constructor", + "optional": false + }, + "params": [], + "body": { + "type": "BlockStatement", + "span": { + "start": 43, + "end": 141, + "ctxt": 0 + }, + "stmts": [ + { + "type": "VariableDeclaration", + "span": { + "start": 53, + "end": 82, + "ctxt": 0 + }, + "kind": "const", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 59, + "end": 81, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 59, + "end": 60, + "ctxt": 0 + }, + "value": "a", + "optional": false, + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 60, + "end": 76, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsTypeQuery", + "span": { + "start": 62, + "end": 76, + "ctxt": 0 + }, + "exprName": { + "type": "TsQualifiedName", + "left": { + "type": "Identifier", + "span": { + "start": 69, + "end": 73, + "ctxt": 0 + }, + "value": "this", + "optional": false + }, + "right": { + "type": "PrivateName", + "span": { + "start": 74, + "end": 76, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 75, + "end": 76, + "ctxt": 0 + }, + "value": "a", + "optional": false + } + } + }, + "typeArguments": null + } + } + }, + "init": { + "type": "StringLiteral", + "span": { + "start": 79, + "end": 81, + "ctxt": 0 + }, + "value": "", + "raw": "''" + }, + "definite": false + } + ] + }, + { + "type": "VariableDeclaration", + "span": { + "start": 97, + "end": 125, + "ctxt": 0 + }, + "kind": "const", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 103, + "end": 124, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 103, + "end": 104, + "ctxt": 0 + }, + "value": "b", + "optional": false, + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 104, + "end": 120, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsTypeQuery", + "span": { + "start": 106, + "end": 120, + "ctxt": 0 + }, + "exprName": { + "type": "TsQualifiedName", + "left": { + "type": "Identifier", + "span": { + "start": 113, + "end": 117, + "ctxt": 0 + }, + "value": "this", + "optional": false + }, + "right": { + "type": "PrivateName", + "span": { + "start": 118, + "end": 120, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 119, + "end": 120, + "ctxt": 0 + }, + "value": "a", + "optional": false + } + } + }, + "typeArguments": null + } + } + }, + "init": { + "type": "NumericLiteral", + "span": { + "start": 123, + "end": 124, + "ctxt": 0 + }, + "value": 1.0 + }, + "definite": false + } + ] + } + ] + }, + "accessibility": null, + "isOptional": false + } + ], + "superClass": null, + "isAbstract": false, + "typeParams": null, + "superTypeParams": null, + "implements": [] + } + ], + "interpreter": null +} diff --git a/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/2/input.ts b/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/2/input.ts new file mode 100644 index 0000000000000..028caeaf4b0d6 --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/2/input.ts @@ -0,0 +1,11 @@ +class Container { + #data = "hello!"; + + get data(): typeof this.#data { + return this.#data; + } + + set data(value: typeof this.#data) { + this.#data = value; + } +} \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/2/input.ts.json b/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/2/input.ts.json new file mode 100644 index 0000000000000..3b496282d01b1 --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/private-name-in-type-query/2/input.ts.json @@ -0,0 +1,394 @@ +{ + "type": "Script", + "span": { + "start": 0, + "end": 187, + "ctxt": 0 + }, + "body": [ + { + "type": "ClassDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 6, + "end": 15, + "ctxt": 0 + }, + "value": "Container", + "optional": false + }, + "declare": false, + "span": { + "start": 0, + "end": 187, + "ctxt": 0 + }, + "decorators": [], + "body": [ + { + "type": "PrivateProperty", + "span": { + "start": 22, + "end": 39, + "ctxt": 0 + }, + "key": { + "type": "PrivateName", + "span": { + "start": 22, + "end": 27, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 23, + "end": 27, + "ctxt": 0 + }, + "value": "data", + "optional": false + } + }, + "value": { + "type": "StringLiteral", + "span": { + "start": 30, + "end": 38, + "ctxt": 0 + }, + "value": "hello!", + "raw": "\"hello!\"" + }, + "typeAnnotation": null, + "isStatic": false, + "decorators": [], + "accessibility": null, + "isOptional": false, + "isOverride": false, + "readonly": false, + "definite": false + }, + { + "type": "ClassMethod", + "span": { + "start": 45, + "end": 109, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 49, + "end": 53, + "ctxt": 0 + }, + "value": "data", + "optional": false + }, + "function": { + "params": [], + "decorators": [], + "span": { + "start": 45, + "end": 109, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 75, + "end": 109, + "ctxt": 0 + }, + "stmts": [ + { + "type": "ReturnStatement", + "span": { + "start": 85, + "end": 103, + "ctxt": 0 + }, + "argument": { + "type": "MemberExpression", + "span": { + "start": 92, + "end": 102, + "ctxt": 0 + }, + "object": { + "type": "ThisExpression", + "span": { + "start": 92, + "end": 96, + "ctxt": 0 + } + }, + "property": { + "type": "PrivateName", + "span": { + "start": 97, + "end": 102, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 98, + "end": 102, + "ctxt": 0 + }, + "value": "data", + "optional": false + } + } + } + } + ] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": { + "type": "TsTypeAnnotation", + "span": { + "start": 55, + "end": 74, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsTypeQuery", + "span": { + "start": 57, + "end": 74, + "ctxt": 0 + }, + "exprName": { + "type": "TsQualifiedName", + "left": { + "type": "Identifier", + "span": { + "start": 64, + "end": 68, + "ctxt": 0 + }, + "value": "this", + "optional": false + }, + "right": { + "type": "PrivateName", + "span": { + "start": 69, + "end": 74, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 70, + "end": 74, + "ctxt": 0 + }, + "value": "data", + "optional": false + } + } + }, + "typeArguments": null + } + } + }, + "kind": "getter", + "isStatic": false, + "accessibility": null, + "isAbstract": false, + "isOptional": false, + "isOverride": false + }, + { + "type": "ClassMethod", + "span": { + "start": 115, + "end": 185, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 119, + "end": 123, + "ctxt": 0 + }, + "value": "data", + "optional": false + }, + "function": { + "params": [ + { + "type": "Parameter", + "span": { + "start": 124, + "end": 148, + "ctxt": 0 + }, + "decorators": [], + "pat": { + "type": "Identifier", + "span": { + "start": 124, + "end": 148, + "ctxt": 0 + }, + "value": "value", + "optional": false, + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 129, + "end": 148, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsTypeQuery", + "span": { + "start": 131, + "end": 148, + "ctxt": 0 + }, + "exprName": { + "type": "TsQualifiedName", + "left": { + "type": "Identifier", + "span": { + "start": 138, + "end": 142, + "ctxt": 0 + }, + "value": "this", + "optional": false + }, + "right": { + "type": "PrivateName", + "span": { + "start": 143, + "end": 148, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 144, + "end": 148, + "ctxt": 0 + }, + "value": "data", + "optional": false + } + } + }, + "typeArguments": null + } + } + } + } + ], + "decorators": [], + "span": { + "start": 115, + "end": 185, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 150, + "end": 185, + "ctxt": 0 + }, + "stmts": [ + { + "type": "ExpressionStatement", + "span": { + "start": 160, + "end": 179, + "ctxt": 0 + }, + "expression": { + "type": "AssignmentExpression", + "span": { + "start": 160, + "end": 178, + "ctxt": 0 + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "span": { + "start": 160, + "end": 170, + "ctxt": 0 + }, + "object": { + "type": "ThisExpression", + "span": { + "start": 160, + "end": 164, + "ctxt": 0 + } + }, + "property": { + "type": "PrivateName", + "span": { + "start": 165, + "end": 170, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 166, + "end": 170, + "ctxt": 0 + }, + "value": "data", + "optional": false + } + } + }, + "right": { + "type": "Identifier", + "span": { + "start": 173, + "end": 178, + "ctxt": 0 + }, + "value": "value", + "optional": false + } + } + } + ] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + }, + "kind": "setter", + "isStatic": false, + "accessibility": null, + "isAbstract": false, + "isOptional": false, + "isOverride": false + } + ], + "superClass": null, + "isAbstract": false, + "typeParams": null, + "superTypeParams": null, + "implements": [] + } + ], + "interpreter": null +} diff --git a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs index 4d39d45e6bde5..d81d209bf80ef 100644 --- a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs +++ b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs @@ -574,7 +574,10 @@ fn ts_entity_to_member_expr(type_name: &TsEntityName) -> Expr { Expr::Member(MemberExpr { span: DUMMY_SP, obj: obj.into(), - prop: MemberProp::Ident(q.right.clone()), + prop: match q.right.clone() { + TsEntityMember::Ident(i) => MemberProp::Ident(i), + TsEntityMember::PrivateName(p) => MemberProp::PrivateName(p), + }, }) } TsEntityName::Ident(i) => Expr::Ident(i.clone()), diff --git a/crates/swc_ecma_transforms_typescript/src/strip.rs b/crates/swc_ecma_transforms_typescript/src/strip.rs index 009ce0f4065ac..b5a7db4868f7e 100644 --- a/crates/swc_ecma_transforms_typescript/src/strip.rs +++ b/crates/swc_ecma_transforms_typescript/src/strip.rs @@ -2546,7 +2546,10 @@ fn ts_entity_name_to_expr(n: TsEntityName) -> Expr { MemberExpr { span: DUMMY_SP, obj: Box::new(ts_entity_name_to_expr(left)), - prop: MemberProp::Ident(right), + prop: match right { + TsEntityMember::Ident(i) => MemberProp::Ident(i), + TsEntityMember::PrivateName(p) => MemberProp::PrivateName(p), + }, } .into() } diff --git a/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/1/input.ts b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/1/input.ts new file mode 100644 index 0000000000000..95d8b82a0a996 --- /dev/null +++ b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/1/input.ts @@ -0,0 +1,8 @@ +class C { + #a = 'a'; + + constructor() { + const a: typeof this.#a = ''; // Ok + const b: typeof this.#a = 1; // Error + } +} \ No newline at end of file diff --git a/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/1/output.js b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/1/output.js new file mode 100644 index 0000000000000..c4a80136696d0 --- /dev/null +++ b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/1/output.js @@ -0,0 +1,11 @@ +var _a = /*#__PURE__*/ new WeakMap(); +class C { + constructor(){ + _classPrivateFieldInit(this, _a, { + writable: true, + value: 'a' + }); + const a = ''; // Ok + const b = 1; // Error + } +} diff --git a/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/2/input.ts b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/2/input.ts new file mode 100644 index 0000000000000..028caeaf4b0d6 --- /dev/null +++ b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/2/input.ts @@ -0,0 +1,11 @@ +class Container { + #data = "hello!"; + + get data(): typeof this.#data { + return this.#data; + } + + set data(value: typeof this.#data) { + this.#data = value; + } +} \ No newline at end of file diff --git a/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/2/output.js b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/2/output.js new file mode 100644 index 0000000000000..1919de0084dc3 --- /dev/null +++ b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-4287/2/output.js @@ -0,0 +1,15 @@ +var _data = /*#__PURE__*/ new WeakMap(); +class Container { + get data() { + return _classPrivateFieldGet(this, _data); + } + set data(value) { + _classPrivateFieldSet(this, _data, value); + } + constructor(){ + _classPrivateFieldInit(this, _data, { + writable: true, + value: "hello!" + }); + } +} diff --git a/crates/swc_ecma_visit/src/lib.rs b/crates/swc_ecma_visit/src/lib.rs index bd59bea199407..d8d66af5c9b4b 100644 --- a/crates/swc_ecma_visit/src/lib.rs +++ b/crates/swc_ecma_visit/src/lib.rs @@ -309,6 +309,7 @@ macro_rules! noop_fold_type { noop_fold_type!(fold_ts_construct_signature_decl, TsConstructSignatureDecl); noop_fold_type!(fold_ts_constructor_type, TsConstructorType); noop_fold_type!(fold_ts_entity_name, TsEntityName); + noop_fold_type!(fold_ts_entity_member, TsEntityMember); noop_fold_type!(fold_ts_enum_decl, TsEnumDecl); noop_fold_type!(fold_ts_enum_member, TsEnumMember); noop_fold_type!(fold_ts_enum_member_id, TsEnumMemberId); @@ -384,6 +385,7 @@ macro_rules! noop_visit_type { noop_visit_type!(visit_ts_construct_signature_decl, TsConstructSignatureDecl); noop_visit_type!(visit_ts_constructor_type, TsConstructorType); noop_visit_type!(visit_ts_entity_name, TsEntityName); + noop_visit_type!(visit_ts_entity_member, TsEntityMember); noop_visit_type!(visit_ts_external_module_ref, TsExternalModuleRef); noop_visit_type!(visit_ts_fn_or_constructor_type, TsFnOrConstructorType); noop_visit_type!(visit_ts_fn_param, TsFnParam); @@ -449,6 +451,7 @@ macro_rules! noop_visit_mut_type { ); noop_visit_mut_type!(visit_mut_ts_constructor_type, TsConstructorType); noop_visit_mut_type!(visit_mut_ts_entity_name, TsEntityName); + noop_visit_mut_type!(visit_mut_ts_entity_member, TsEntityMember); noop_visit_mut_type!(visit_mut_ts_external_module_ref, TsExternalModuleRef); noop_visit_mut_type!(visit_mut_ts_fn_or_constructor_type, TsFnOrConstructorType); noop_visit_mut_type!(visit_mut_ts_fn_param, TsFnParam); @@ -1424,12 +1427,16 @@ define!({ } pub struct TsQualifiedName { pub left: TsEntityName, - pub right: Ident, + pub right: TsEntityMember, } pub enum TsEntityName { TsQualifiedName(Box), Ident(Ident), } + pub enum TsEntityMember { + Ident(Ident), + PrivateName(PrivateName), + } pub enum TsTypeElement { TsCallSignatureDecl(TsCallSignatureDecl), TsConstructSignatureDecl(TsConstructSignatureDecl),