Skip to content

Commit 3e9ef62

Browse files
committed
feat: support __proto__ in object literal
1 parent 22f8fa4 commit 3e9ef62

25 files changed

+895
-373
lines changed

src/compiler/checker.ts

Lines changed: 316 additions & 277 deletions
Large diffs are not rendered by default.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
tests/cases/compiler/__proto__literal.ts(10,28): error TS2300: Duplicate identifier '__proto_\u005f'.
2+
tests/cases/compiler/__proto__literal.ts(20,13): error TS2322: Type '1' is not assignable to type 'object | null'.
3+
4+
5+
==== tests/cases/compiler/__proto__literal.ts (2 errors) ====
6+
const o = { a: 1 }
7+
const __proto__ = o
8+
// Should
9+
const x1 = { __proto__: o }
10+
const x2 = { __proto_\u005f: o }
11+
const x3 = { "__proto__": o }
12+
const x4 = { "__proto_\u005f": o }
13+
14+
// Duplicate
15+
const y1 = { __proto__: o, __proto_\u005f: o }
16+
~~~~~~~~~~~~~~
17+
!!! error TS2300: Duplicate identifier '__proto_\u005f'.
18+
19+
// Spread order
20+
const z1 = { ...({a: ''}), __proto__: o }
21+
const z2 = { __proto__: o, ...({a: ''}) }
22+
23+
// Null
24+
const w = { __proto__: null }
25+
26+
// Non-object
27+
const q = { __proto__: 1, x: 1 }
28+
~~~~~~~~~~~~
29+
!!! error TS2322: Type '1' is not assignable to type 'object | null'.
30+
31+
// Should not
32+
const x5 = { ["__proto__"]: o }
33+
const x6 = { __proto__ }
34+
const x7 = { __proto__() {} }
35+
enum e { __proto__ = 1 }
36+
{
37+
const { __proto__ } = { ['__proto__']: 1 }
38+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//// [__proto__literal.ts]
2+
const o = { a: 1 }
3+
const __proto__ = o
4+
// Should
5+
const x1 = { __proto__: o }
6+
const x2 = { __proto_\u005f: o }
7+
const x3 = { "__proto__": o }
8+
const x4 = { "__proto_\u005f": o }
9+
10+
// Duplicate
11+
const y1 = { __proto__: o, __proto_\u005f: o }
12+
13+
// Spread order
14+
const z1 = { ...({a: ''}), __proto__: o }
15+
const z2 = { __proto__: o, ...({a: ''}) }
16+
17+
// Null
18+
const w = { __proto__: null }
19+
20+
// Non-object
21+
const q = { __proto__: 1, x: 1 }
22+
23+
// Should not
24+
const x5 = { ["__proto__"]: o }
25+
const x6 = { __proto__ }
26+
const x7 = { __proto__() {} }
27+
enum e { __proto__ = 1 }
28+
{
29+
const { __proto__ } = { ['__proto__']: 1 }
30+
}
31+
32+
//// [__proto__literal.js]
33+
var __assign = (this && this.__assign) || function () {
34+
__assign = Object.assign || function(t) {
35+
for (var s, i = 1, n = arguments.length; i < n; i++) {
36+
s = arguments[i];
37+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
38+
t[p] = s[p];
39+
}
40+
return t;
41+
};
42+
return __assign.apply(this, arguments);
43+
};
44+
var _a, _b;
45+
var o = { a: 1 };
46+
var __proto__ = o;
47+
// Should
48+
var x1 = { __proto__: o };
49+
var x2 = { __proto_\u005f: o };
50+
var x3 = { "__proto__": o };
51+
var x4 = { "__proto_\u005f": o };
52+
// Duplicate
53+
var y1 = { __proto__: o, __proto_\u005f: o };
54+
// Spread order
55+
var z1 = __assign(__assign({}, ({ a: '' })), { __proto__: o });
56+
var z2 = __assign({ __proto__: o }, ({ a: '' }));
57+
// Null
58+
var w = { __proto__: null };
59+
// Non-object
60+
var q = { __proto__: 1, x: 1 };
61+
// Should not
62+
var x5 = (_a = {}, _a["__proto__"] = o, _a);
63+
var x6 = { __proto__: __proto__ };
64+
var x7 = { __proto__: function () { } };
65+
var e;
66+
(function (e) {
67+
e[e["__proto__"] = 1] = "__proto__";
68+
})(e || (e = {}));
69+
{
70+
var __proto__1 = (_b = {}, _b['__proto__'] = 1, _b).__proto__;
71+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
=== tests/cases/compiler/__proto__literal.ts ===
2+
const o = { a: 1 }
3+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
4+
>a : Symbol(a, Decl(__proto__literal.ts, 0, 11))
5+
6+
const __proto__ = o
7+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 1, 5))
8+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
9+
10+
// Should
11+
const x1 = { __proto__: o }
12+
>x1 : Symbol(x1, Decl(__proto__literal.ts, 3, 5))
13+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 3, 12))
14+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
15+
16+
const x2 = { __proto_\u005f: o }
17+
>x2 : Symbol(x2, Decl(__proto__literal.ts, 4, 5))
18+
>__proto_\u005f : Symbol(__proto_\u005f, Decl(__proto__literal.ts, 4, 12))
19+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
20+
21+
const x3 = { "__proto__": o }
22+
>x3 : Symbol(x3, Decl(__proto__literal.ts, 5, 5))
23+
>"__proto__" : Symbol("__proto__", Decl(__proto__literal.ts, 5, 12))
24+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
25+
26+
const x4 = { "__proto_\u005f": o }
27+
>x4 : Symbol(x4, Decl(__proto__literal.ts, 6, 5))
28+
>"__proto_\u005f" : Symbol("__proto_\u005f", Decl(__proto__literal.ts, 6, 12))
29+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
30+
31+
// Duplicate
32+
const y1 = { __proto__: o, __proto_\u005f: o }
33+
>y1 : Symbol(y1, Decl(__proto__literal.ts, 9, 5))
34+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 9, 12), Decl(__proto__literal.ts, 9, 26))
35+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
36+
>__proto_\u005f : Symbol(__proto__, Decl(__proto__literal.ts, 9, 12), Decl(__proto__literal.ts, 9, 26))
37+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
38+
39+
// Spread order
40+
const z1 = { ...({a: ''}), __proto__: o }
41+
>z1 : Symbol(z1, Decl(__proto__literal.ts, 12, 5))
42+
>a : Symbol(a, Decl(__proto__literal.ts, 12, 18))
43+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 12, 26))
44+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
45+
46+
const z2 = { __proto__: o, ...({a: ''}) }
47+
>z2 : Symbol(z2, Decl(__proto__literal.ts, 13, 5))
48+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 13, 12))
49+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
50+
>a : Symbol(a, Decl(__proto__literal.ts, 13, 32))
51+
52+
// Null
53+
const w = { __proto__: null }
54+
>w : Symbol(w, Decl(__proto__literal.ts, 16, 5))
55+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 16, 11))
56+
57+
// Non-object
58+
const q = { __proto__: 1, x: 1 }
59+
>q : Symbol(q, Decl(__proto__literal.ts, 19, 5))
60+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 19, 11))
61+
>x : Symbol(x, Decl(__proto__literal.ts, 19, 25))
62+
63+
// Should not
64+
const x5 = { ["__proto__"]: o }
65+
>x5 : Symbol(x5, Decl(__proto__literal.ts, 22, 5))
66+
>["__proto__"] : Symbol(["__proto__"], Decl(__proto__literal.ts, 22, 12))
67+
>"__proto__" : Symbol(["__proto__"], Decl(__proto__literal.ts, 22, 12))
68+
>o : Symbol(o, Decl(__proto__literal.ts, 0, 5))
69+
70+
const x6 = { __proto__ }
71+
>x6 : Symbol(x6, Decl(__proto__literal.ts, 23, 5))
72+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 23, 12))
73+
74+
const x7 = { __proto__() {} }
75+
>x7 : Symbol(x7, Decl(__proto__literal.ts, 24, 5))
76+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 24, 12))
77+
78+
enum e { __proto__ = 1 }
79+
>e : Symbol(e, Decl(__proto__literal.ts, 24, 29))
80+
>__proto__ : Symbol(e.__proto__, Decl(__proto__literal.ts, 25, 8))
81+
{
82+
const { __proto__ } = { ['__proto__']: 1 }
83+
>__proto__ : Symbol(__proto__, Decl(__proto__literal.ts, 27, 11))
84+
>['__proto__'] : Symbol(['__proto__'], Decl(__proto__literal.ts, 27, 27))
85+
>'__proto__' : Symbol(['__proto__'], Decl(__proto__literal.ts, 27, 27))
86+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
=== tests/cases/compiler/__proto__literal.ts ===
2+
const o = { a: 1 }
3+
>o : { a: number; }
4+
>{ a: 1 } : { a: number; }
5+
>a : number
6+
>1 : 1
7+
8+
const __proto__ = o
9+
>__proto__ : { a: number; }
10+
>o : { a: number; }
11+
12+
// Should
13+
const x1 = { __proto__: o }
14+
>x1 : { a: number; }
15+
>{ __proto__: o } : { a: number; }
16+
>__proto__ : { a: number; }
17+
>o : { a: number; }
18+
19+
const x2 = { __proto_\u005f: o }
20+
>x2 : { a: number; }
21+
>{ __proto_\u005f: o } : { a: number; }
22+
>__proto_\u005f : { a: number; }
23+
>o : { a: number; }
24+
25+
const x3 = { "__proto__": o }
26+
>x3 : { a: number; }
27+
>{ "__proto__": o } : { a: number; }
28+
>"__proto__" : { a: number; }
29+
>o : { a: number; }
30+
31+
const x4 = { "__proto_\u005f": o }
32+
>x4 : { a: number; }
33+
>{ "__proto_\u005f": o } : { a: number; }
34+
>"__proto_\u005f" : { a: number; }
35+
>o : { a: number; }
36+
37+
// Duplicate
38+
const y1 = { __proto__: o, __proto_\u005f: o }
39+
>y1 : { a: number; }
40+
>{ __proto__: o, __proto_\u005f: o } : { a: number; }
41+
>__proto__ : { a: number; }
42+
>o : { a: number; }
43+
>__proto_\u005f : { a: number; }
44+
>o : { a: number; }
45+
46+
// Spread order
47+
const z1 = { ...({a: ''}), __proto__: o }
48+
>z1 : { a: string; }
49+
>{ ...({a: ''}), __proto__: o } : { a: string; }
50+
>({a: ''}) : { a: string; }
51+
>{a: ''} : { a: string; }
52+
>a : string
53+
>'' : ""
54+
>__proto__ : { a: number; }
55+
>o : { a: number; }
56+
57+
const z2 = { __proto__: o, ...({a: ''}) }
58+
>z2 : { a: string; }
59+
>{ __proto__: o, ...({a: ''}) } : { a: string; }
60+
>__proto__ : { a: number; }
61+
>o : { a: number; }
62+
>({a: ''}) : { a: string; }
63+
>{a: ''} : { a: string; }
64+
>a : string
65+
>'' : ""
66+
67+
// Null
68+
const w = { __proto__: null }
69+
>w : {}
70+
>{ __proto__: null } : {}
71+
>__proto__ : null
72+
>null : null
73+
74+
// Non-object
75+
const q = { __proto__: 1, x: 1 }
76+
>q : { x: number; }
77+
>{ __proto__: 1, x: 1 } : { x: number; }
78+
>__proto__ : number
79+
>1 : 1
80+
>x : number
81+
>1 : 1
82+
83+
// Should not
84+
const x5 = { ["__proto__"]: o }
85+
>x5 : { __proto__: { a: number; }; }
86+
>{ ["__proto__"]: o } : { __proto__: { a: number; }; }
87+
>["__proto__"] : { a: number; }
88+
>"__proto__" : "__proto__"
89+
>o : { a: number; }
90+
91+
const x6 = { __proto__ }
92+
>x6 : { __proto__: { a: number; }; }
93+
>{ __proto__ } : { __proto__: { a: number; }; }
94+
>__proto__ : { a: number; }
95+
96+
const x7 = { __proto__() {} }
97+
>x7 : { __proto__(): void; }
98+
>{ __proto__() {} } : { __proto__(): void; }
99+
>__proto__ : () => void
100+
101+
enum e { __proto__ = 1 }
102+
>e : e
103+
>__proto__ : e.__proto__
104+
>1 : 1
105+
{
106+
const { __proto__ } = { ['__proto__']: 1 }
107+
>__proto__ : number
108+
>{ ['__proto__']: 1 } : { __proto__: number; }
109+
>['__proto__'] : number
110+
>'__proto__' : "__proto__"
111+
>1 : 1
112+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
tests/cases/compiler/escapedReservedCompilerNamedIdentifier.ts(4,5): error TS2322: Type '0' is not assignable to type 'object | null'.
2+
3+
4+
==== tests/cases/compiler/escapedReservedCompilerNamedIdentifier.ts (1 errors) ====
5+
// double underscores
6+
var __proto__ = 10;
7+
var o = {
8+
"__proto__": 0
9+
~~~~~~~~~~~~~~
10+
!!! error TS2322: Type '0' is not assignable to type 'object | null'.
11+
};
12+
var b = o["__proto__"];
13+
var o1 = {
14+
__proto__: {}
15+
};
16+
var b1 = o1["__proto__"];
17+
// Triple underscores
18+
var ___proto__ = 10;
19+
var o2 = {
20+
"___proto__": 0
21+
};
22+
var b2 = o2["___proto__"];
23+
var o3 = {
24+
___proto__: 0
25+
};
26+
var b3 = o3["___proto__"];
27+
// One underscore
28+
var _proto__ = 10;
29+
var o4 = {
30+
"_proto__": 0
31+
};
32+
var b4 = o4["_proto__"];
33+
var o5 = {
34+
_proto__: 0
35+
};
36+
var b5 = o5["_proto__"];

tests/baselines/reference/escapedReservedCompilerNamedIdentifier.js

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var o = {
66
};
77
var b = o["__proto__"];
88
var o1 = {
9-
__proto__: 0
9+
__proto__: {}
1010
};
1111
var b1 = o1["__proto__"];
1212
// Triple underscores
@@ -38,7 +38,7 @@ var o = {
3838
};
3939
var b = o["__proto__"];
4040
var o1 = {
41-
__proto__: 0
41+
__proto__: {}
4242
};
4343
var b1 = o1["__proto__"];
4444
// Triple underscores
@@ -65,14 +65,10 @@ var b5 = o5["_proto__"];
6565

6666
//// [escapedReservedCompilerNamedIdentifier.d.ts]
6767
declare var __proto__: number;
68-
declare var o: {
69-
__proto__: number;
70-
};
71-
declare var b: number;
72-
declare var o1: {
73-
__proto__: number;
74-
};
75-
declare var b1: number;
68+
declare var o: {};
69+
declare var b: any;
70+
declare var o1: {};
71+
declare var b1: any;
7672
declare var ___proto__: number;
7773
declare var o2: {
7874
___proto__: number;

0 commit comments

Comments
 (0)