Skip to content

Commit d79d904

Browse files
committed
fix(semantic): flag super in function inside ObjectExpression
1 parent d976a11 commit d79d904

File tree

9 files changed

+165
-21
lines changed

9 files changed

+165
-21
lines changed

crates/oxc_semantic/src/checker/javascript.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::ptr;
33
use phf::{Set, phf_set};
44
use rustc_hash::FxHashMap;
55

6+
use oxc_allocator::GetAddress;
67
use oxc_ast::{AstKind, ModuleDeclarationKind, ast::*};
78
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
89
use oxc_ecmascript::{BoundNames, IsSimpleParameterList, PropName};
@@ -900,16 +901,24 @@ pub fn check_super(sup: &Super, ctx: &SemanticBuilder<'_>) {
900901
// Not in a class. `super` only valid in an object method.
901902
for scope_id in ctx.scoping.scope_ancestors(ctx.current_scope_id) {
902903
let flags = ctx.scoping.scope_flags(scope_id);
903-
if flags.is_function()
904-
&& matches!(
905-
ctx.nodes.parent_kind(ctx.scoping.get_node_id(scope_id)),
906-
AstKind::ObjectProperty(_)
907-
)
908-
{
909-
if let Some(super_call_span) = super_call_span {
910-
ctx.error(unexpected_super_call(super_call_span));
904+
if flags.is_function() && !flags.is_arrow() {
905+
let func_node_id = ctx.scoping.get_node_id(scope_id);
906+
if let AstKind::ObjectProperty(prop) = ctx.nodes.parent_kind(func_node_id) {
907+
if prop.method || prop.kind != PropertyKind::Init {
908+
// Function's parent is an `ObjectProperty` representing a method/getter/setter.
909+
// Check the function is the value of the property, not computed key.
910+
// Valid: `obj = { method() { super.foo } }`
911+
// Invalid: `obj = { [ function() { super.foo } ]() {} }`
912+
let func_kind = ctx.nodes.kind(func_node_id);
913+
if func_kind.address() == prop.value.address() {
914+
if let Some(super_call_span) = super_call_span {
915+
ctx.error(unexpected_super_call(super_call_span));
916+
}
917+
return;
918+
}
919+
}
911920
}
912-
return;
921+
break;
913922
}
914923
}
915924

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
o = {
2+
foo: function() {
3+
super.foo;
4+
},
5+
6+
bar() {
7+
return function() {
8+
super.bar;
9+
};
10+
},
11+
12+
[ function() { super.qux; } ]() {},
13+
14+
get [ function() { super.bing; } ]() {},
15+
16+
set [ function() { super.bong; } ](v) {},
17+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
o = {
2+
foo() {
3+
super.foo();
4+
return () => super.foo();
5+
},
6+
7+
get bar() {
8+
const f = () => super.bar;
9+
return super.bar;
10+
},
11+
12+
set bar(v) {
13+
const f = () => super.bar;
14+
super.bar = v;
15+
},
16+
};
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
codegen_misc Summary:
2-
AST Parsed : 47/47 (100.00%)
3-
Positive Passed: 47/47 (100.00%)
2+
AST Parsed : 48/48 (100.00%)
3+
Positive Passed: 48/48 (100.00%)

tasks/coverage/snapshots/parser_babel.snap

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ commit: 41d96516
33
parser_babel Summary:
44
AST Parsed : 2407/2423 (99.34%)
55
Positive Passed: 2385/2423 (98.43%)
6-
Negative Passed: 1642/1755 (93.56%)
6+
Negative Passed: 1643/1755 (93.62%)
77
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/categorized/invalid-startindex-and-startline-specified-without-startcolumn/input.js
88

99
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/categorized/startline-and-startcolumn-specified/input.js
@@ -20,8 +20,6 @@ Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/co
2020

2121
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/sourcetype-commonjs/invalid-allowReturnOutsideFunction-true/input.js
2222

23-
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2015/class-methods/direct-super-in-object-method/input.js
24-
2523
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2015/destructuring/error-operator-for-default/input.js
2624

2725
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2015/for-of/invalid-let-as-identifier/input.js
@@ -2969,6 +2967,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
29692967
· ───────────
29702968
╰────
29712969

2970+
× 'super' can only be referenced in members of derived classes or object literal expressions.
2971+
╭─[babel/packages/babel-parser/test/fixtures/es2015/class-methods/direct-super-in-object-method/input.js:4:14]
2972+
3 │ get: function(){
2973+
4 │ return super.foo;
2974+
· ─────
2975+
5 │ }
2976+
╰────
2977+
29722978
× Super calls are not permitted outside constructors or in nested functions inside constructors.
29732979
╭─[babel/packages/babel-parser/test/fixtures/es2015/class-methods/direct-super-outside-constructor/input.js:2:9]
29742980
1 │ class A {

tasks/coverage/snapshots/parser_misc.snap

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
parser_misc Summary:
2-
AST Parsed : 47/47 (100.00%)
3-
Positive Passed: 47/47 (100.00%)
4-
Negative Passed: 55/55 (100.00%)
2+
AST Parsed : 48/48 (100.00%)
3+
Positive Passed: 48/48 (100.00%)
4+
Negative Passed: 56/56 (100.00%)
55

66
× Cannot assign to 'arguments' in strict mode
77
╭─[misc/fail/arguments-eval.ts:1:10]
@@ -235,6 +235,46 @@ Negative Passed: 55/55 (100.00%)
235235
6 │ },
236236
╰────
237237
238+
× 'super' can only be referenced in members of derived classes or object literal expressions.
239+
╭─[misc/fail/oxc-13323.js:3:5]
240+
2 │ foo: function() {
241+
3super.foo;
242+
· ─────
243+
4 │ },
244+
╰────
245+
246+
× 'super' can only be referenced in members of derived classes or object literal expressions.
247+
╭─[misc/fail/oxc-13323.js:8:7]
248+
7return function() {
249+
8super.bar;
250+
· ─────
251+
9 │ };
252+
╰────
253+
254+
× 'super' can only be referenced in members of derived classes or object literal expressions.
255+
╭─[misc/fail/oxc-13323.js:12:18]
256+
11
257+
12 │ [ function() { super.qux; } ]() {},
258+
· ─────
259+
13 │
260+
╰────
261+
262+
× 'super' can only be referenced in members of derived classes or object literal expressions.
263+
╭─[misc/fail/oxc-13323.js:14:22]
264+
13
265+
14get [ function() { super.bing; } ]() {},
266+
· ─────
267+
15 │
268+
╰────
269+
270+
× 'super' can only be referenced in members of derived classes or object literal expressions.
271+
╭─[misc/fail/oxc-13323.js:16:22]
272+
15
273+
16set [ function() { super.bong; } ](v) {},
274+
· ─────
275+
17 │ };
276+
╰────
277+
238278
× Unexpected token
239279
╭─[misc/fail/oxc-169.js:2:1]
240280
11<(V=82<<t-j0<(V=$<LBI<(V=ut<I<(V=$<LBI<(V=uIV=82<<t-j0<(V=$<LBI<(V=ut<I<(V=$<LBI<(V<II>

tasks/coverage/snapshots/parser_typescript.snap

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12963,6 +12963,30 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
1296312963
╰────
1296412964
help: replace with `super()` or `super.prop` or `super[prop]`
1296512965

12966+
× 'super' can only be referenced in members of derived classes or object literal expressions.
12967+
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:17:9]
12968+
16 │ p1: function () {
12969+
17 │ super.method();
12970+
· ─────
12971+
18 │ },
12972+
╰────
12973+
12974+
× 'super' can only be referenced in members of derived classes or object literal expressions.
12975+
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:20:9]
12976+
19 │ p2: function f() {
12977+
20 │ super.method();
12978+
· ─────
12979+
21 │ },
12980+
╰────
12981+
12982+
× 'super' can only be referenced in members of derived classes or object literal expressions.
12983+
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:23:9]
12984+
22 │ p3: () => {
12985+
23 │ super.method();
12986+
· ─────
12987+
24 │ }
12988+
╰────
12989+
1296612990
× 'super' can only be referenced in members of derived classes or object literal expressions.
1296712991
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES5.ts:39:17]
1296812992
38 │ method() {
@@ -13003,6 +13027,30 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
1300313027
53 │ },
1300413028
╰────
1300513029

13030+
× 'super' can only be referenced in members of derived classes or object literal expressions.
13031+
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:17:9]
13032+
16 │ p1: function () {
13033+
17 │ super.method();
13034+
· ─────
13035+
18 │ },
13036+
╰────
13037+
13038+
× 'super' can only be referenced in members of derived classes or object literal expressions.
13039+
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:20:9]
13040+
19 │ p2: function f() {
13041+
20 │ super.method();
13042+
· ─────
13043+
21 │ },
13044+
╰────
13045+
13046+
× 'super' can only be referenced in members of derived classes or object literal expressions.
13047+
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:23:9]
13048+
22 │ p3: () => {
13049+
23 │ super.method();
13050+
· ─────
13051+
24 │ }
13052+
╰────
13053+
1300613054
× 'super' can only be referenced in members of derived classes or object literal expressions.
1300713055
╭─[typescript/tests/cases/compiler/superInObjectLiterals_ES6.ts:39:17]
1300813056
38 │ method() {
@@ -13070,6 +13118,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
1307013118
╰────
1307113119
help: replace with `super()` or `super.prop` or `super[prop]`
1307213120

13121+
× 'super' can only be referenced in members of derived classes or object literal expressions.
13122+
╭─[typescript/tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts:11:20]
13123+
10 │ test: function () {
13124+
11 │ return super._foo;
13125+
· ─────
13126+
12 │ }
13127+
╰────
13128+
1307313129
× 'super' can only be referenced in members of derived classes or object literal expressions.
1307413130
╭─[typescript/tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts:21:24]
1307513131
20 │ get F() {

tasks/coverage/snapshots/semantic_misc.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
semantic_misc Summary:
2-
AST Parsed : 47/47 (100.00%)
3-
Positive Passed: 31/47 (65.96%)
2+
AST Parsed : 48/48 (100.00%)
3+
Positive Passed: 32/48 (66.67%)
44
semantic Error: tasks/coverage/misc/pass/oxc-11593.ts
55
Scope children mismatch:
66
after transform: ScopeId(0): [ScopeId(1)]
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
transformer_misc Summary:
2-
AST Parsed : 47/47 (100.00%)
3-
Positive Passed: 47/47 (100.00%)
2+
AST Parsed : 48/48 (100.00%)
3+
Positive Passed: 48/48 (100.00%)

0 commit comments

Comments
 (0)