fix(semantic): report error for super property appearing in function body (#8376)

Missing error that super property inside plain function.

```js
class C {
  constructor() {
    function g() {
      // * It is a Syntax Error if PropName of MethodDefinition is not "constructor" and HasDirectSuper of MethodDefinition is true.
      super();
    }
  }
  method() {
    function func() {
      // It is a Syntax Error if FunctionBody Contains SuperProperty is true.
      super.good();
    }
  }
}
```

I am not sure why test262 doesn't cover tests like that
This commit is contained in:
Dunqing 2025-01-09 06:38:08 +00:00
parent 5516f7fcb9
commit 79a8fc6f7d
3 changed files with 227 additions and 9 deletions

View file

@ -824,6 +824,15 @@ pub fn check_super<'a>(sup: &Super, node: &AstNode<'a>, ctx: &SemanticBuilder<'a
// super references are allowed in method
break;
}
// * It is a Syntax Error if FunctionBody Contains SuperProperty is true.
AstKind::Function(_) => {
if !matches!(ctx.nodes.parent_kind(node_id), Some(AstKind::MethodDefinition(_))) {
return super_call_span.map_or_else(
|| ctx.error(unexpected_super_reference(sup.span)),
|super_call_span| ctx.error(unexpected_super_call(super_call_span)),
);
}
}
// FieldDefinition : ClassElementName Initializer opt
// * It is a Syntax Error if Initializer is present and Initializer Contains SuperCall is true.
// PropertyDefinition : MethodDefinition

View file

@ -3,7 +3,7 @@ commit: 54a8389f
parser_babel Summary:
AST Parsed : 2205/2218 (99.41%)
Positive Passed: 2184/2218 (98.47%)
Negative Passed: 1522/1634 (93.15%)
Negative Passed: 1523/1634 (93.21%)
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/annex-b/enabled/3.1-sloppy-labeled-functions-if-body/input.js
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/categorized/invalid-fn-decl-labeled-inside-if/input.js
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/categorized/invalid-fn-decl-labeled-inside-loop/input.js
@ -25,7 +25,6 @@ Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2018/object-rest-spread/comma-after-spread-nested/input.js
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2018/object-rest-spread/no-pattern-in-rest/input.js
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2018/object-rest-spread/no-pattern-in-rest-with-ts/input.js
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/super-inside-function/input.js
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/yield-in-class-property-in-generator/input.js
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-static-block/invalid-decorators/input.js
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/private-in/invalid-private-followed-by-in-2/input.js
@ -8248,6 +8247,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
5 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/super-inside-function/input.js:3:5]
2 │ foo = function fn() {
3 │ super.x();
· ─────
4 │ }
╰────
× Cannot use `await` as an identifier in an async context
╭─[babel/packages/babel-parser/test/fixtures/es2022/class-static-block/await-binding-in-async-arrow-function-in-static-block/input.js:3:29]
2 │ // await is not allowed in async arrow

View file

@ -3,7 +3,7 @@ commit: d85767ab
parser_typescript Summary:
AST Parsed : 6494/6503 (99.86%)
Positive Passed: 6483/6503 (99.69%)
Negative Passed: 1277/5747 (22.22%)
Negative Passed: 1283/5747 (22.32%)
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration24.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ExportAssignment7.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ExportAssignment8.ts
@ -659,7 +659,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/emitCapturin
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/emitCapturingThisInTupleDestructuring2.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/emitClassExpressionInDeclarationFile2.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/emitDecoratorMetadata_isolatedModules.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/emitThisInSuperMethodCall.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/emptyGenericParamList.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/emptyModuleName.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/emptyObjectNotSubtypeOfIndexSignatureContainingObject1.ts
@ -1927,15 +1926,12 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superCallIns
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superCallInsideClassExpression.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superCallWithMissingBaseClass.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superInConstructorParam1.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superNewCall1.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superPropertyAccess.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superPropertyAccess1.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superPropertyAccess2.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superPropertyAccessInSuperCall01.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/superPropertyAccess_ES5.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/switchAssignmentCompat.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/switchCaseCircularRefeference.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/switchCases.ts
@ -2387,7 +2383,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/c
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInAmbientClass.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInConstructorParameters.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/constructorDeclarations/constructorWithAssignableReturnExpression.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassConstructorWithoutSuperCall.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsWithThisArg.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperProperties.ts
@ -2437,7 +2432,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/m
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers4.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers7.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers8.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers9.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/members/instanceAndStaticMembers/typeOfThisInstanceMemberNarrowedWithLoopAntecedent.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/members/privateNames/privateNameAccessors.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/members/privateNames/privateNameAmbientNoImplicitAny.ts
@ -7735,6 +7729,30 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
53 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/emitThisInSuperMethodCall.ts:10:17]
9 │ function inner() {
10 │ super.sayHello();
· ─────
11 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/emitThisInSuperMethodCall.ts:17:17]
16 │ () => {
17 │ super.sayHello();
· ─────
18 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/emitThisInSuperMethodCall.ts:23:13]
22 │ function inner() {
23 │ super.sayHello();
· ─────
24 │ }
╰────
× Empty parenthesized expression
╭─[typescript/tests/cases/compiler/emptyMemberAccess.ts:3:4]
2 │
@ -8371,6 +8389,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
╰────
help: Try insert a semicolon here
× Super calls are not permitted outside constructors or in nested functions inside constructors.
╭─[typescript/tests/cases/compiler/illegalSuperCallsInConstructor.ts:9:32]
8 │ var r3 = () => { super(); }
9 │ var r4 = function () { super(); }
· ───────
10 │ var r5 = {
╰────
× Super calls are not permitted outside constructors or in nested functions inside constructors.
╭─[typescript/tests/cases/compiler/illegalSuperCallsInConstructor.ts:12:17]
11 │ get foo() {
@ -12707,6 +12733,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
7 │
╰────
× Super calls are not permitted outside constructors or in nested functions inside constructors.
╭─[typescript/tests/cases/compiler/superCallOutsideConstructor.ts:16:13]
15 │ var y2 = function() {
16 │ super();
· ───────
17 │ }
╰────
× 'with' statements are not allowed
╭─[typescript/tests/cases/compiler/superCallsInConstructor.ts:12:9]
11 │ constructor() {
@ -12811,6 +12845,46 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
6 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superErrors.ts:22:13]
21 │ function inner() {
22 │ super.sayHello();
· ─────
23 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superErrors.ts:27:27]
26 │ function inner2() {
27 │ var x = () => super.sayHello();
· ─────
28 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superErrors.ts:31:36]
30 │ // super call in a lambda in a function expression in a constructor
31 │ (function() { return () => super; })();
· ─────
32 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superErrors.ts:39:27]
38 │ function inner() {
39 │ var x = () => super.sayHello();
· ─────
40 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superErrors.ts:43:36]
42 │ // super call in a lambda in a function expression in a constructor
43 │ (function() { return () => super; })();
· ─────
44 │ }
╰────
× 'super' can only be used with function calls or in property accesses
╭─[typescript/tests/cases/compiler/superInLambdas.ts:61:29]
60 │ // super in a nested lambda in a constructor
@ -12829,6 +12903,86 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
╰────
help: replace with `super()` or `super.prop` or `super[prop]`
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:39:17]
38 │ method() {
39 │ super.method();
· ─────
40 │ },
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:42:17]
41 │ get prop() {
42 │ super.method();
· ─────
43 │ return 10;
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:46:17]
45 │ set prop(value) {
46 │ super.method();
· ─────
47 │ },
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:49:17]
48 │ p1: function () {
49 │ super.method();
· ─────
50 │ },
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:52:17]
51 │ p2: function f() {
52 │ super.method();
· ─────
53 │ },
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:39:17]
38 │ method() {
39 │ super.method();
· ─────
40 │ },
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:42:17]
41 │ get prop() {
42 │ super.method();
· ─────
43 │ return 10;
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:46:17]
45 │ set prop(value) {
46 │ super.method();
· ─────
47 │ },
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:49:17]
48 │ p1: function () {
49 │ super.method();
· ─────
50 │ },
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:52:17]
51 │ p2: function f() {
52 │ super.method();
· ─────
53 │ },
╰────
× 'super' can only be used with function calls or in property accesses
╭─[typescript/tests/cases/compiler/superWithTypeArgument.ts:7:9]
6 │ constructor() {
@ -12856,6 +13010,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
╰────
help: replace with `super()` or `super.prop` or `super[prop]`
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts:21:24]
20 │ get F() {
21 │ return super.test();
· ─────
22 │ }
╰────
× Keywords cannot contain escape characters
╭─[typescript/tests/cases/compiler/switchStatementsWithMultipleDefaults.ts:25:13]
24 │ default: // Error, third 'default' clause
@ -14467,6 +14629,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
╰────
help: Remove the duplicate modifier.
× Super calls are not permitted outside constructors or in nested functions inside constructors.
╭─[typescript/tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassConstructorWithoutSuperCall.ts:24:31]
23 │ constructor() { // error
24 │ var r = function () { super() } // error
· ───────
25 │ }
╰────
× Expected a semicolon or an implicit semicolon after a statement, but found none
╭─[typescript/tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts:8:13]
7 │ class Derived extends Base {
@ -14576,6 +14746,22 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
7 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/conformance/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers9.ts:7:56]
6 │ static arrowFunctionBoundary = () => super.f + 1;
7 │ static functionExprBoundary = function () { return super.f + 2 };
· ─────
8 │ static classExprBoundary = class { a = super.f + 3 };
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/conformance/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers9.ts:11:20]
10 │ function foo () {
11 │ return super.f + 4
· ─────
12 │ }
╰────
× Private identifier '#prop' is not allowed outside class bodies
╭─[typescript/tests/cases/conformance/classes/members/privateNames/privateNameAccessorsAccess.ts:14:10]
13 │ }
@ -19239,6 +19425,22 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
72 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts:73:13]
72 │ function inner() {
73 │ super.publicFunc();
· ─────
74 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts:76:40]
75 │ var x = {
76 │ test: function () { return super.publicFunc(); }
· ─────
77 │ }
╰────
× 'super' can only be referenced in members of derived classes or object literal expressions.
╭─[typescript/tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts:127:16]
126 │ // In object literal