Skip to content

Commit a35ed6b

Browse files
ljqxariya
authored andcommitted
Support for ES2020 import.meta
1 parent 145bd1c commit a35ed6b

15 files changed

+1267
-10
lines changed

src/messages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const Messages = {
44
BadGetterArity: 'Getter must not have any formal parameters',
55
BadSetterArity: 'Setter must have exactly one formal parameter',
66
BadSetterRestParameter: 'Setter function argument must not be a rest parameter',
7+
CannotUseImportMetaOutsideAModule: 'Cannot use \'import.meta\' outside a module',
78
ConstructorIsAsync: 'Class constructor may not be an async method',
89
ConstructorSpecialMethod: 'Class constructor may not be an accessor',
910
DeclarationMissingInitializer: 'Missing initializer in %0 declaration',

src/parser.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,11 @@ export class Parser {
694694
expr = this.parseClassExpression();
695695
} else if (this.matchImportCall()) {
696696
expr = this.parseImportCall();
697+
} else if (this.matchImportMeta()) {
698+
if (!this.context.isModule) {
699+
this.tolerateUnexpectedToken(this.lookahead, Messages.CannotUseImportMetaOutsideAModule);
700+
}
701+
expr = this.parseImportMeta();
697702
} else {
698703
expr = this.throwUnexpectedToken(this.nextToken());
699704
}
@@ -1285,6 +1290,39 @@ export class Parser {
12851290
return this.finalize(node, new Node.Import());
12861291
}
12871292

1293+
matchImportMeta(): boolean {
1294+
let match = this.matchKeyword('import');
1295+
if (match) {
1296+
const state = this.scanner.saveState();
1297+
this.scanner.scanComments();
1298+
const dot = this.scanner.lex();
1299+
if ((dot.type === Token.Punctuator) && (dot.value === '.')) {
1300+
this.scanner.scanComments();
1301+
const meta = this.scanner.lex();
1302+
match = (meta.type === Token.Identifier) && (meta.value === 'meta');
1303+
if (match) {
1304+
if (meta.end - meta.start !== 'meta'.length) {
1305+
this.tolerateUnexpectedToken(meta, Messages.InvalidEscapedReservedWord);
1306+
}
1307+
}
1308+
} else {
1309+
match = false;
1310+
}
1311+
this.scanner.restoreState(state);
1312+
}
1313+
1314+
return match;
1315+
}
1316+
1317+
parseImportMeta(): Node.MetaProperty {
1318+
const node = this.createNode();
1319+
const id = this.parseIdentifierName(); // 'import', already ensured by matchImportMeta
1320+
this.expect('.');
1321+
const property = this.parseIdentifierName(); // 'meta', already ensured by matchImportMeta
1322+
this.context.isAssignmentTarget = false;
1323+
return this.finalize(node, new Node.MetaProperty(id, property));
1324+
}
1325+
12881326
parseLeftHandSideExpressionAllowCall(): Node.Expression {
12891327
const startToken = this.lookahead;
12901328
const maybeAsync = this.matchContextualKeyword('async');
@@ -1897,6 +1935,8 @@ export class Parser {
18971935
case 'import':
18981936
if (this.matchImportCall()) {
18991937
statement = this.parseExpressionStatement();
1938+
} else if (this.matchImportMeta()) {
1939+
statement = this.parseStatement();
19001940
} else {
19011941
if (!this.context.isModule) {
19021942
this.tolerateUnexpectedToken(this.lookahead, Messages.IllegalImportDeclaration);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import.meta.foo = 'bar';
Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
{
2+
"type": "Program",
3+
"body": [
4+
{
5+
"type": "ExpressionStatement",
6+
"expression": {
7+
"type": "AssignmentExpression",
8+
"operator": "=",
9+
"left": {
10+
"type": "MemberExpression",
11+
"computed": false,
12+
"object": {
13+
"type": "MetaProperty",
14+
"meta": {
15+
"type": "Identifier",
16+
"name": "import",
17+
"range": [
18+
0,
19+
6
20+
],
21+
"loc": {
22+
"start": {
23+
"line": 1,
24+
"column": 0
25+
},
26+
"end": {
27+
"line": 1,
28+
"column": 6
29+
}
30+
}
31+
},
32+
"property": {
33+
"type": "Identifier",
34+
"name": "meta",
35+
"range": [
36+
7,
37+
11
38+
],
39+
"loc": {
40+
"start": {
41+
"line": 1,
42+
"column": 7
43+
},
44+
"end": {
45+
"line": 1,
46+
"column": 11
47+
}
48+
}
49+
},
50+
"range": [
51+
0,
52+
11
53+
],
54+
"loc": {
55+
"start": {
56+
"line": 1,
57+
"column": 0
58+
},
59+
"end": {
60+
"line": 1,
61+
"column": 11
62+
}
63+
}
64+
},
65+
"property": {
66+
"type": "Identifier",
67+
"name": "foo",
68+
"range": [
69+
12,
70+
15
71+
],
72+
"loc": {
73+
"start": {
74+
"line": 1,
75+
"column": 12
76+
},
77+
"end": {
78+
"line": 1,
79+
"column": 15
80+
}
81+
}
82+
},
83+
"range": [
84+
0,
85+
15
86+
],
87+
"loc": {
88+
"start": {
89+
"line": 1,
90+
"column": 0
91+
},
92+
"end": {
93+
"line": 1,
94+
"column": 15
95+
}
96+
}
97+
},
98+
"right": {
99+
"type": "Literal",
100+
"value": "bar",
101+
"raw": "'bar'",
102+
"range": [
103+
18,
104+
23
105+
],
106+
"loc": {
107+
"start": {
108+
"line": 1,
109+
"column": 18
110+
},
111+
"end": {
112+
"line": 1,
113+
"column": 23
114+
}
115+
}
116+
},
117+
"range": [
118+
0,
119+
23
120+
],
121+
"loc": {
122+
"start": {
123+
"line": 1,
124+
"column": 0
125+
},
126+
"end": {
127+
"line": 1,
128+
"column": 23
129+
}
130+
}
131+
},
132+
"range": [
133+
0,
134+
24
135+
],
136+
"loc": {
137+
"start": {
138+
"line": 1,
139+
"column": 0
140+
},
141+
"end": {
142+
"line": 1,
143+
"column": 24
144+
}
145+
}
146+
}
147+
],
148+
"sourceType": "module",
149+
"range": [
150+
0,
151+
24
152+
],
153+
"loc": {
154+
"start": {
155+
"line": 1,
156+
"column": 0
157+
},
158+
"end": {
159+
"line": 1,
160+
"column": 24
161+
}
162+
},
163+
"tokens": [
164+
{
165+
"type": "Keyword",
166+
"value": "import",
167+
"range": [
168+
0,
169+
6
170+
],
171+
"loc": {
172+
"start": {
173+
"line": 1,
174+
"column": 0
175+
},
176+
"end": {
177+
"line": 1,
178+
"column": 6
179+
}
180+
}
181+
},
182+
{
183+
"type": "Punctuator",
184+
"value": ".",
185+
"range": [
186+
6,
187+
7
188+
],
189+
"loc": {
190+
"start": {
191+
"line": 1,
192+
"column": 6
193+
},
194+
"end": {
195+
"line": 1,
196+
"column": 7
197+
}
198+
}
199+
},
200+
{
201+
"type": "Identifier",
202+
"value": "meta",
203+
"range": [
204+
7,
205+
11
206+
],
207+
"loc": {
208+
"start": {
209+
"line": 1,
210+
"column": 7
211+
},
212+
"end": {
213+
"line": 1,
214+
"column": 11
215+
}
216+
}
217+
},
218+
{
219+
"type": "Punctuator",
220+
"value": ".",
221+
"range": [
222+
11,
223+
12
224+
],
225+
"loc": {
226+
"start": {
227+
"line": 1,
228+
"column": 11
229+
},
230+
"end": {
231+
"line": 1,
232+
"column": 12
233+
}
234+
}
235+
},
236+
{
237+
"type": "Identifier",
238+
"value": "foo",
239+
"range": [
240+
12,
241+
15
242+
],
243+
"loc": {
244+
"start": {
245+
"line": 1,
246+
"column": 12
247+
},
248+
"end": {
249+
"line": 1,
250+
"column": 15
251+
}
252+
}
253+
},
254+
{
255+
"type": "Punctuator",
256+
"value": "=",
257+
"range": [
258+
16,
259+
17
260+
],
261+
"loc": {
262+
"start": {
263+
"line": 1,
264+
"column": 16
265+
},
266+
"end": {
267+
"line": 1,
268+
"column": 17
269+
}
270+
}
271+
},
272+
{
273+
"type": "String",
274+
"value": "'bar'",
275+
"range": [
276+
18,
277+
23
278+
],
279+
"loc": {
280+
"start": {
281+
"line": 1,
282+
"column": 18
283+
},
284+
"end": {
285+
"line": 1,
286+
"column": 23
287+
}
288+
}
289+
},
290+
{
291+
"type": "Punctuator",
292+
"value": ";",
293+
"range": [
294+
23,
295+
24
296+
],
297+
"loc": {
298+
"start": {
299+
"line": 1,
300+
"column": 23
301+
},
302+
"end": {
303+
"line": 1,
304+
"column": 24
305+
}
306+
}
307+
}
308+
]
309+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"index":12,"lineNumber":1,"column":13,"message":"Error: Line 1: Cannot use 'import.meta' outside a module","description":"Cannot use 'import.meta' outside a module"}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log(import.meta);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log(import.meta);

0 commit comments

Comments
 (0)