Skip to content

Commit 74ec2d3

Browse files
committed
Handle TSIndexSignature
1 parent e5df62c commit 74ec2d3

File tree

8 files changed

+174
-12
lines changed

8 files changed

+174
-12
lines changed

crates/oxc_semantic/src/checker/javascript.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,7 @@ pub fn check_super(sup: &Super, ctx: &SemanticBuilder<'_>) {
921921
// 2. Class accessor value.
922922
// 3. Computed key of a class method / property / accessor.
923923
// 4. Decorators on a class method / property / accessor.
924+
// 5. `TSIndexSignature`.
924925
// Find out which.
925926
//
926927
// Note: In terms of scopes, we could also be in a class's `super_class`,
@@ -972,13 +973,35 @@ pub fn check_super(sup: &Super, ctx: &SemanticBuilder<'_>) {
972973
// If we were in the value, we would have exited loop already,
973974
// because `value` is a function - which is handled below.
974975
}
976+
AstKind::TSIndexSignature(sig) => {
977+
// I (@overlookmotel) don't think `Super` should appear in a type annotation.
978+
// e.g. `super` is parsed as an `IdentifierReference`, not `Super` in:
979+
// `class C { [keys: typeof super.foo]: typeof super.foo }`
980+
// But I did find one weird case where `super` *is* currently parsed as `Super`:
981+
// `class C { [keys: string]: typeof import('x', { with: super.foo }).y; }`
982+
//
983+
// So probably this branch is unreachable in practice. But handle it just in case,
984+
// to avoid falling through to `unreachable!()` below.
985+
//
986+
// If it *is* possible, I'm also not sure what correct behavior should be.
987+
// As best guess, treating it like class properties:
988+
// Treat `parameters` like computed key, `type_annotation` like initializer value.
989+
if sig.type_annotation.address() == previous_node_address {
990+
// In signature's `type_annotation` - `super.foo` is legal here, `super()` is not
991+
if super_call_span.is_some() {
992+
break 'scopes;
993+
}
994+
return;
995+
}
996+
// In `parameters` - treat like computed key
997+
}
975998
_ => {
976999
previous_node_address = ancestor_kind.address();
9771000
continue;
9781001
}
9791002
}
9801003

981-
// `super` is in a computed key or decorator.
1004+
// `super` is in a computed key, decorator, or `TSIndexSignature`'s `parameters`.
9821005
//
9831006
// Whether it's legal or not depends on external context
9841007
// (whether this class is nested in another class or object method).
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Not sure this is correct, but adding this test to make sure it doesn't panic at least.
2+
// See comment in `check_super` in `oxc_semantic`.
3+
4+
// `super()`
5+
class C extends Super {
6+
[keys: string]: typeof import('x', { with: super() }).y;
7+
}
8+
9+
class D extends Super {
10+
[keys: typeof import('x', { with: super() }).y]: string;
11+
}
12+
13+
class Outer extends Super {
14+
constructor() {
15+
class Inner {
16+
[keys: string]: typeof import('x', { with: super() }).y;
17+
}
18+
}
19+
}
20+
21+
class Outer2 {
22+
constructor() {
23+
class Inner extends Super {
24+
[keys: typeof import('x', { with: super() }).y]: string;
25+
}
26+
}
27+
}
28+
29+
// `super.foo`
30+
class E {
31+
[keys: typeof super.foo]: string;
32+
}
33+
34+
class F {
35+
[keys: typeof import('x', { with: super.foo }).y]: string;
36+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Not sure this is correct, but adding this test to make sure it doesn't panic at least.
2+
// See comment in `check_super` in `oxc_semantic`.
3+
4+
class C {
5+
[keys: string]: typeof super.foo;
6+
}
7+
8+
class D {
9+
[keys: string]: typeof import('x', { with: super.foo }).y;
10+
}
11+
12+
class Outer extends Super {
13+
constructor() {
14+
class Inner {
15+
[keys: typeof super.foo]: string;
16+
}
17+
class Inner2 {
18+
[keys: typeof import('x', { with: super.foo }).y]: string;
19+
}
20+
class Inner3 {
21+
[keys: typeof import('x', { with: super() }).y]: string;
22+
}
23+
}
24+
25+
prop1 = class Inner {
26+
[keys: typeof super.foo]: string;
27+
};
28+
prop2 = class Inner {
29+
[keys: typeof import('x', { with: super.foo }).y]: string;
30+
};
31+
32+
accessor access1 = class Inner {
33+
[keys: typeof super.foo]: string;
34+
};
35+
accessor access2 = class Inner {
36+
[keys: typeof import('x', { with: super.foo }).y]: string;
37+
};
38+
39+
method() {
40+
class Inner {
41+
[keys: typeof super.foo]: string;
42+
}
43+
class Inner2 {
44+
[keys: typeof import('x', { with: super.foo }).y]: string;
45+
}
46+
}
47+
}
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 : 48/48 (100.00%)
3-
Positive Passed: 48/48 (100.00%)
2+
AST Parsed : 49/49 (100.00%)
3+
Positive Passed: 49/49 (100.00%)

tasks/coverage/snapshots/formatter_misc.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
formatter_misc Summary:
2-
AST Parsed : 48/48 (100.00%)
3-
Positive Passed: 45/48 (93.75%)
2+
AST Parsed : 49/49 (100.00%)
3+
Positive Passed: 46/49 (93.88%)
44
Expect to Parse: tasks/coverage/misc/pass/oxc-12612.ts
55

66
Expect to Parse: tasks/coverage/misc/pass/oxc-2592.ts

tasks/coverage/snapshots/parser_misc.snap

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

66
× Cannot assign to 'arguments' in strict mode
77
╭─[misc/fail/arguments-eval.ts:1:10]
@@ -2733,6 +2733,54 @@ Negative Passed: 79/79 (100.00%)
27332733
144 │ },
27342734
╰────
27352735
2736+
× Super calls are not permitted outside constructors or in nested functions inside constructors.
2737+
╭─[misc/fail/oxc-13284.ts:6:46]
2738+
5class C extends Super {
2739+
6 │ [keys: string]: typeof import('x', { with: super() }).y;
2740+
· ───────
2741+
7 │ }
2742+
╰────
2743+
2744+
× Super calls are not permitted outside constructors or in nested functions inside constructors.
2745+
╭─[misc/fail/oxc-13284.ts:10:37]
2746+
9class D extends Super {
2747+
10 │ [keys: typeof import('x', { with: super() }).y]: string;
2748+
· ───────
2749+
11 │ }
2750+
╰────
2751+
2752+
× Super calls are not permitted outside constructors or in nested functions inside constructors.
2753+
╭─[misc/fail/oxc-13284.ts:16:50]
2754+
15class Inner {
2755+
16 │ [keys: string]: typeof import('x', { with: super() }).y;
2756+
· ───────
2757+
17 │ }
2758+
╰────
2759+
2760+
× 'super' can only be referenced in a derived class.
2761+
╭─[misc/fail/oxc-13284.ts:21:1]
2762+
20 │
2763+
21 │ ╭─▶ class Outer2 {
2764+
22 │ │ constructor() {
2765+
23 │ │ class Inner extends Super {
2766+
24 │ │ [keys: typeof import('x', { with: super() }).y]: string;
2767+
· │ ─────
2768+
25 │ │ }
2769+
26 │ │ }
2770+
27 │ ├─▶ }
2771+
· ╰──── class does not have `extends`
2772+
28 │
2773+
╰────
2774+
help: either remove this super, or extend the class
2775+
2776+
× 'super' can only be referenced in members of derived classes or object literal expressions.
2777+
╭─[misc/fail/oxc-13284.ts:35:37]
2778+
34 │ class F {
2779+
35 │ [keys: typeof import('x', { with: super.foo }).y]: string;
2780+
· ─────
2781+
36}
2782+
╰────
2783+
27362784
× 'super' can only be referenced in members of derived classes or object literal expressions.
27372785
╭─[misc/fail/oxc-13323.js:3:5]
27382786
2 │ foo: function() {

tasks/coverage/snapshots/semantic_misc.snap

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
semantic_misc Summary:
2-
AST Parsed : 48/48 (100.00%)
3-
Positive Passed: 31/48 (64.58%)
2+
AST Parsed : 49/49 (100.00%)
3+
Positive Passed: 31/49 (63.27%)
44
semantic Error: tasks/coverage/misc/pass/oxc-11593.ts
55
Scope children mismatch:
66
after transform: ScopeId(0): [ScopeId(1)]
@@ -195,6 +195,14 @@ Unresolved reference IDs mismatch for "Function":
195195
after transform: [ReferenceId(75), ReferenceId(79), ReferenceId(109), ReferenceId(123), ReferenceId(137), ReferenceId(151), ReferenceId(165), ReferenceId(189), ReferenceId(203), ReferenceId(227), ReferenceId(241), ReferenceId(265), ReferenceId(279), ReferenceId(303), ReferenceId(432), ReferenceId(460), ReferenceId(464), ReferenceId(482), ReferenceId(486), ReferenceId(490), ReferenceId(496), ReferenceId(500), ReferenceId(504), ReferenceId(510), ReferenceId(514), ReferenceId(518)]
196196
rebuilt : [ReferenceId(80), ReferenceId(86), ReferenceId(130), ReferenceId(162), ReferenceId(194), ReferenceId(315), ReferenceId(394), ReferenceId(422), ReferenceId(428), ReferenceId(435), ReferenceId(441), ReferenceId(448)]
197197

198+
semantic Error: tasks/coverage/misc/pass/oxc-13284.ts
199+
Symbol reference IDs mismatch for "_super":
200+
after transform: SymbolId(13): [ReferenceId(8)]
201+
rebuilt : SymbolId(4): []
202+
Unresolved references mismatch:
203+
after transform: ["Super", "super"]
204+
rebuilt : ["Super"]
205+
198206
semantic Error: tasks/coverage/misc/pass/oxc-2087.ts
199207
Scope children mismatch:
200208
after transform: ScopeId(0): [ScopeId(1)]
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
transformer_misc Summary:
2-
AST Parsed : 48/48 (100.00%)
3-
Positive Passed: 47/48 (97.92%)
2+
AST Parsed : 49/49 (100.00%)
3+
Positive Passed: 48/49 (97.96%)
44
Mismatch: tasks/coverage/misc/pass/oxc-13284.js
55

0 commit comments

Comments
 (0)