feat(parser): support decorators in class expression (#190)

feat(parser): support decorator in class expression
This commit is contained in:
yangchenye 2023-03-16 20:33:04 -05:00 committed by GitHub
parent 164c2831e1
commit 37ad6f3a15
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 22 additions and 271 deletions

View file

@ -356,11 +356,14 @@ pub trait Visit<'a>: Sized {
}
fn visit_class(&mut self, class: &'a Class<'a>) {
let kind = AstKind::Class(class);
self.enter_node(kind);
// Class level decorators are transpiled as functions outside of the class taking the class
// itself as argument. They should be visited before class is entered. E.g., they inherit
// strict mode from the enclosing scope rather than from class.
for decorator in &class.decorators {
self.visit_decorator(decorator);
}
let kind = AstKind::Class(class);
self.enter_node(kind);
if let Some(id) = &class.id {
self.visit_binding_identifier(id);
}

View file

@ -147,6 +147,10 @@ impl<'a> Parser<'a> {
fn parse_primary_expression(&mut self) -> Result<Expression<'a>> {
let span = self.start_span();
if self.at(Kind::At) {
self.eat_decorators()?;
}
// AsyncFunctionExpression
// AsyncGeneratorExpression
if self.at_function_with_async() {

@ -1 +1 @@
Subproject commit d38f415c9f7704a201cbfb1d73e6884738931bb2
Subproject commit 6925ac555c62c67886b86e38c0c6a7dca60b3cb7

View file

@ -1,6 +1,6 @@
Babel Summary:
AST Parsed : 2050/2071 (98.99%)
Positive Passed: 2050/2071 (98.99%)
AST Parsed : 2052/2071 (99.08%)
Positive Passed: 2052/2071 (99.08%)
Negative Passed: 1335/1502 (88.88%)
Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js"
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js"
@ -349,20 +349,6 @@ Expect to Parse: "typescript/regression/nested-extends-in-arrow-type-param/input
· ───┬───
· ╰── Expect `,` here, but found `extends`
╰────
Expect to Parse: "typescript/type-arguments-bit-shift-left-like-babel-7/decorator-call-expression/input.ts"
× Unexpected token
╭─[typescript/type-arguments-bit-shift-left-like-babel-7/decorator-call-expression/input.ts:1:1]
1 │ (@f<<T>(v: T) => void>() class {});
· ─
╰────
Expect to Parse: "typescript/type-arguments-bit-shift-left-like/decorator-call-expression/input.ts"
× Unexpected token
╭─[typescript/type-arguments-bit-shift-left-like/decorator-call-expression/input.ts:1:1]
1 │ (@f<<T>(v: T) => void>() class {});
· ─
╰────
Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts"
× Unexpected token

View file

@ -1,6 +1,6 @@
Test262 Summary:
AST Parsed : 44005/44024 (99.96%)
Positive Passed: 44005/44024 (99.96%)
AST Parsed : 44015/44024 (99.98%)
Positive Passed: 44015/44024 (99.98%)
Negative Passed: 3915/3915 (100.00%)
Expect to Parse: "language/block-scope/syntax/redeclaration-global/allowed-to-redeclare-function-declaration-with-var.js"
@ -32,69 +32,9 @@ Expect to Parse: "language/expressions/class/decorator/syntax/class-valid/decora
╭─[language/expressions/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js:43:1]
43 │ static {
44 │ var C = @#$
· ─
·
45 │ @#_
╰────
Expect to Parse: "language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js"
× Unexpected token
╭─[language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js:43:1]
43 │
44 │ var C = @yield() class {};
· ─
╰────
Expect to Parse: "language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js"
× Unexpected token
╭─[language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js:50:1]
50 │
51 │ var C = @$()
· ─
52 │ @_()
╰────
Expect to Parse: "language/expressions/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js"
× Unexpected token
╭─[language/expressions/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js:42:1]
42 │
43 │ var C = @ns.$
· ─
44 │ @ns._
╰────
Expect to Parse: "language/expressions/class/decorator/syntax/valid/decorator-member-expr-identifier-reference-yield.js"
× Unexpected token
╭─[language/expressions/class/decorator/syntax/valid/decorator-member-expr-identifier-reference-yield.js:32:1]
32 │
33 │ var C = @yield class {};
· ─
╰────
Expect to Parse: "language/expressions/class/decorator/syntax/valid/decorator-member-expr-identifier-reference.js"
× Unexpected token
╭─[language/expressions/class/decorator/syntax/valid/decorator-member-expr-identifier-reference.js:39:1]
39 │
40 │ var C = @$
· ─
41 │ @_
╰────
Expect to Parse: "language/expressions/class/decorator/syntax/valid/decorator-parenthesized-expr-identifier-reference-yield.js"
× Unexpected token
╭─[language/expressions/class/decorator/syntax/valid/decorator-parenthesized-expr-identifier-reference-yield.js:50:1]
50 │
51 │ var C = @(yield) class {};
· ─
╰────
Expect to Parse: "language/expressions/class/decorator/syntax/valid/decorator-parenthesized-expr-identifier-reference.js"
× Unexpected token
╭─[language/expressions/class/decorator/syntax/valid/decorator-parenthesized-expr-identifier-reference.js:52:1]
52 │
53 │ var C = @($)
· ─
54 │ @(_)
╰────
Expect to Parse: "language/global-code/decl-func-dup.js"
× Identifier `f` has already been declared
@ -115,30 +55,6 @@ Expect to Parse: "language/statements/class/decorator/syntax/class-valid/decorat
· ──
46 │ @#_
╰────
Expect to Parse: "language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js"
× The keyword 'yield' is reserved
╭─[language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js:44:1]
44 │
45 │ @yield() class C {}
· ─────
╰────
Expect to Parse: "language/statements/class/decorator/syntax/valid/decorator-member-expr-identifier-reference-yield.js"
× The keyword 'yield' is reserved
╭─[language/statements/class/decorator/syntax/valid/decorator-member-expr-identifier-reference-yield.js:33:1]
33 │
34 │ @yield class C {}
· ─────
╰────
Expect to Parse: "language/statements/class/decorator/syntax/valid/decorator-parenthesized-expr-identifier-reference-yield.js"
× The keyword 'yield' is reserved
╭─[language/statements/class/decorator/syntax/valid/decorator-parenthesized-expr-identifier-reference-yield.js:51:1]
51 │
52 │ @(yield) class C {}
· ─────
╰────
Expect to Parse: "language/statements/function/S13_A6_T1.js"
× Identifier `__func` has already been declared

@ -1 +1 @@
Subproject commit 9ccf47fec5c1c87061956ac6e1446677654a4d4b
Subproject commit 7f292bf2a19aa14ed69a55e646111af9533d8f1c

View file

@ -1,7 +1,7 @@
TypeScript Summary:
AST Parsed : 2305/2338 (98.59%)
Positive Passed: 2305/2338 (98.59%)
Negative Passed: 683/2532 (26.97%)
AST Parsed : 2323/2340 (99.27%)
Positive Passed: 2323/2340 (99.27%)
Negative Passed: 681/2532 (26.90%)
Expect Syntax Error: "Symbols/ES5SymbolProperty2.ts"
Expect Syntax Error: "Symbols/ES5SymbolProperty6.ts"
Expect Syntax Error: "additionalChecks/noPropertyAccessFromIndexSignature1.ts"
@ -282,6 +282,7 @@ Expect Syntax Error: "decorators/class/property/decoratorOnClassProperty7.ts"
Expect Syntax Error: "decorators/decoratorCallGeneric.ts"
Expect Syntax Error: "decorators/invalid/decoratorOnEnum.ts"
Expect Syntax Error: "decorators/invalid/decoratorOnFunctionDeclaration.ts"
Expect Syntax Error: "decorators/invalid/decoratorOnFunctionExpression.ts"
Expect Syntax Error: "decorators/invalid/decoratorOnFunctionParameter.ts"
Expect Syntax Error: "decorators/invalid/decoratorOnImportEquals1.ts"
Expect Syntax Error: "decorators/invalid/decoratorOnInterface.ts"
@ -651,6 +652,7 @@ Expect Syntax Error: "esDecorators/classDeclaration/fields/esDecorators-classDec
Expect Syntax Error: "esDecorators/classDeclaration/fields/esDecorators-classDeclaration-fields-staticAmbient.ts"
Expect Syntax Error: "esDecorators/classDeclaration/methods/esDecorators-classDeclaration-methods-nonStaticAbstract.ts"
Expect Syntax Error: "esDecorators/esDecorators-arguments.ts"
Expect Syntax Error: "esDecorators/esDecorators-emitDecoratorMetadata.ts"
Expect Syntax Error: "expressions/arrayLiterals/arrayLiterals.ts"
Expect Syntax Error: "expressions/arrayLiterals/arrayLiterals3.ts"
Expect Syntax Error: "expressions/asOperator/asOperator2.ts"
@ -1918,150 +1920,6 @@ Expect to Parse: "es6/for-ofStatements/for-of53.ts"
· ╰── It can not be redeclared here
4 │ }
╰────
Expect to Parse: "esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.1.ts"
× Unexpected token
╭─[esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.1.ts:12:1]
12 │
13 │ (@dec
· ─
14 │ class C extends Base {
╰────
Expect to Parse: "esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.2.ts"
× Unexpected token
╭─[esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.2.ts:7:1]
7 │ // class expression in extends should not get an assigned name
8 │ (@dec
· ─
9 │ class C1 extends class { } {
╰────
Expect to Parse: "esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.3.ts"
× Unexpected token
╭─[esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.3.ts:12:1]
12 │
13 │ (@dec
· ─
14 │ class C extends Base {
╰────
Expect to Parse: "esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.4.ts"
× Unexpected token
╭─[esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.4.ts:12:1]
12 │
13 │ (@dec
· ─
14 │ class C extends Base {
╰────
Expect to Parse: "esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.5.ts"
× Unexpected token
╭─[esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.5.ts:12:1]
12 │
13 │ (@dec
· ─
14 │ class C1 extends Base {
╰────
Expect to Parse: "esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.6.ts"
× Unexpected token
╭─[esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.6.ts:12:1]
12 │ // none of the following should result in caching `super`
13 │ (@dec
· ─
14 │ class C extends Base {
╰────
Expect to Parse: "esDecorators/classExpression/esDecorators-classExpression-commentPreservation.ts"
× Unexpected token
╭─[esDecorators/classExpression/esDecorators-classExpression-commentPreservation.ts:10:1]
10 │ /*2*/
11 │ @dec
· ─
12 │ /*3*/
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.1.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.1.ts:10:1]
10 │
11 │ x = @dec class { };
· ─
12 │ x = class { @dec y: any; };
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.10.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.10.ts:9:1]
9 │
10 │ { class C { static x = @dec class {}; } }
· ─
11 │ { class C { static "x" = @dec class {}; } }
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.11.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.11.ts:8:1]
8 │
9 │ (@dec class {});
· ─
10 │ (class { @dec y: any });
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.2.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.2.ts:10:1]
10 │
11 │ ({ x: @dec class { } });
· ─
12 │ ({ x: class { @dec y: any; } });
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.3.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.3.ts:8:1]
8 │
9 │ { let x = @dec class { }; }
· ─
10 │ { let x = class { @dec y: any; }; }
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.4.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.4.ts:8:1]
8 │
9 │ { const [x = @dec class { }] = obj; }
· ─
10 │ { const [x = class { @dec y: any; }] = obj; }
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.5.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.5.ts:8:1]
8 │
9 │ ({ x = @dec class { } } = obj);
· ─
10 │ ({ x = class { @dec y: any; } } = obj);
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.6.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.6.ts:8:1]
8 │
9 │ ({ y: x = @dec class { } } = obj);
· ─
10 │ ({ y: x = class { @dec y: any; } } = obj);
╰────
Expect to Parse: "esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.7.ts"
× Unexpected token
╭─[esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.7.ts:8:1]
8 │
9 │ [x = @dec class { }] = obj;
· ─
10 │ [x = class { @dec y: any; }] = obj;
╰────
Expect to Parse: "expressions/typeSatisfaction/typeSatisfaction_contextualTyping1.ts"
× Automatic Semicolon Insertion
@ -4409,7 +4267,7 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
╭─[decorators/invalid/decoratorOnArrowFunction.ts:2:1]
2 │
3 │ var F = @dec () => {
· ─
·
4 │ }
╰────
@ -4421,14 +4279,6 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
5 │ }
╰────
× Unexpected token
╭─[decorators/invalid/decoratorOnFunctionExpression.ts:2:1]
2 │
3 │ var F = @dec function () {
· ─
4 │ }
╰────
× Unexpected token
╭─[dynamicImport/importCallExpressionGrammarError.ts:8:1]
8 │ var a = ["./0"];
@ -7654,14 +7504,6 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
3 │ }
╰────
× Unexpected token
╭─[esDecorators/esDecorators-emitDecoratorMetadata.ts:30:1]
30 │
31 │ (@dec class C {
· ─
32 │ constructor(x: number) {}
╰────
× Invalid assignment
╭─[expressions/assignmentOperator/assignmentLHSIsValue.ts:5:1]
5 │ class C {