source: frontend/node_modules/sucrase/dist/parser/traverser/statement.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 2 weeks ago

Fix frontend appearance

  • Property mode set to 100644
File size: 42.4 KB
Line 
1"use strict";Object.defineProperty(exports, "__esModule", {value: true});/* eslint max-len: 0 */
2
3var _index = require('../index');
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20var _flow = require('../plugins/flow');
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39var _typescript = require('../plugins/typescript');
40
41
42
43
44
45
46
47
48
49
50
51
52var _tokenizer = require('../tokenizer');
53var _keywords = require('../tokenizer/keywords');
54var _state = require('../tokenizer/state');
55var _types = require('../tokenizer/types');
56var _charcodes = require('../util/charcodes');
57var _base = require('./base');
58
59
60
61
62
63
64
65
66
67
68
69
70var _expression = require('./expression');
71
72
73
74
75
76var _lval = require('./lval');
77
78
79
80
81
82
83
84
85
86
87
88
89var _util = require('./util');
90
91 function parseTopLevel() {
92 parseBlockBody(_types.TokenType.eof);
93 _base.state.scopes.push(new (0, _state.Scope)(0, _base.state.tokens.length, true));
94 if (_base.state.scopeDepth !== 0) {
95 throw new Error(`Invalid scope depth at end of file: ${_base.state.scopeDepth}`);
96 }
97 return new (0, _index.File)(_base.state.tokens, _base.state.scopes);
98} exports.parseTopLevel = parseTopLevel;
99
100// Parse a single statement.
101//
102// If expecting a statement and finding a slash operator, parse a
103// regular expression literal. This is to handle cases like
104// `if (foo) /blah/.exec(foo)`, where looking at the previous token
105// does not help.
106
107 function parseStatement(declaration) {
108 if (_base.isFlowEnabled) {
109 if (_flow.flowTryParseStatement.call(void 0, )) {
110 return;
111 }
112 }
113 if (_tokenizer.match.call(void 0, _types.TokenType.at)) {
114 parseDecorators();
115 }
116 parseStatementContent(declaration);
117} exports.parseStatement = parseStatement;
118
119function parseStatementContent(declaration) {
120 if (_base.isTypeScriptEnabled) {
121 if (_typescript.tsTryParseStatementContent.call(void 0, )) {
122 return;
123 }
124 }
125
126 const starttype = _base.state.type;
127
128 // Most types of statements are recognized by the keyword they
129 // start with. Many are trivial to parse, some require a bit of
130 // complexity.
131
132 switch (starttype) {
133 case _types.TokenType._break:
134 case _types.TokenType._continue:
135 parseBreakContinueStatement();
136 return;
137 case _types.TokenType._debugger:
138 parseDebuggerStatement();
139 return;
140 case _types.TokenType._do:
141 parseDoStatement();
142 return;
143 case _types.TokenType._for:
144 parseForStatement();
145 return;
146 case _types.TokenType._function:
147 if (_tokenizer.lookaheadType.call(void 0, ) === _types.TokenType.dot) break;
148 if (!declaration) _util.unexpected.call(void 0, );
149 parseFunctionStatement();
150 return;
151
152 case _types.TokenType._class:
153 if (!declaration) _util.unexpected.call(void 0, );
154 parseClass(true);
155 return;
156
157 case _types.TokenType._if:
158 parseIfStatement();
159 return;
160 case _types.TokenType._return:
161 parseReturnStatement();
162 return;
163 case _types.TokenType._switch:
164 parseSwitchStatement();
165 return;
166 case _types.TokenType._throw:
167 parseThrowStatement();
168 return;
169 case _types.TokenType._try:
170 parseTryStatement();
171 return;
172
173 case _types.TokenType._let:
174 case _types.TokenType._const:
175 if (!declaration) _util.unexpected.call(void 0, ); // NOTE: falls through to _var
176
177 case _types.TokenType._var:
178 parseVarStatement(starttype !== _types.TokenType._var);
179 return;
180
181 case _types.TokenType._while:
182 parseWhileStatement();
183 return;
184 case _types.TokenType.braceL:
185 parseBlock();
186 return;
187 case _types.TokenType.semi:
188 parseEmptyStatement();
189 return;
190 case _types.TokenType._export:
191 case _types.TokenType._import: {
192 const nextType = _tokenizer.lookaheadType.call(void 0, );
193 if (nextType === _types.TokenType.parenL || nextType === _types.TokenType.dot) {
194 break;
195 }
196 _tokenizer.next.call(void 0, );
197 if (starttype === _types.TokenType._import) {
198 parseImport();
199 } else {
200 parseExport();
201 }
202 return;
203 }
204 case _types.TokenType.name:
205 if (_base.state.contextualKeyword === _keywords.ContextualKeyword._async) {
206 const functionStart = _base.state.start;
207 // peek ahead and see if next token is a function
208 const snapshot = _base.state.snapshot();
209 _tokenizer.next.call(void 0, );
210 if (_tokenizer.match.call(void 0, _types.TokenType._function) && !_util.canInsertSemicolon.call(void 0, )) {
211 _util.expect.call(void 0, _types.TokenType._function);
212 parseFunction(functionStart, true);
213 return;
214 } else {
215 _base.state.restoreFromSnapshot(snapshot);
216 }
217 } else if (
218 _base.state.contextualKeyword === _keywords.ContextualKeyword._using &&
219 !_util.hasFollowingLineBreak.call(void 0, ) &&
220 // Statements like `using[0]` and `using in foo` aren't actual using
221 // declarations.
222 _tokenizer.lookaheadType.call(void 0, ) === _types.TokenType.name
223 ) {
224 parseVarStatement(true);
225 return;
226 } else if (startsAwaitUsing()) {
227 _util.expectContextual.call(void 0, _keywords.ContextualKeyword._await);
228 parseVarStatement(true);
229 return;
230 }
231 default:
232 // Do nothing.
233 break;
234 }
235
236 // If the statement does not start with a statement keyword or a
237 // brace, it's an ExpressionStatement or LabeledStatement. We
238 // simply start parsing an expression, and afterwards, if the
239 // next token is a colon and the expression was a simple
240 // Identifier node, we switch to interpreting it as a label.
241 const initialTokensLength = _base.state.tokens.length;
242 _expression.parseExpression.call(void 0, );
243 let simpleName = null;
244 if (_base.state.tokens.length === initialTokensLength + 1) {
245 const token = _base.state.tokens[_base.state.tokens.length - 1];
246 if (token.type === _types.TokenType.name) {
247 simpleName = token.contextualKeyword;
248 }
249 }
250 if (simpleName == null) {
251 _util.semicolon.call(void 0, );
252 return;
253 }
254 if (_tokenizer.eat.call(void 0, _types.TokenType.colon)) {
255 parseLabeledStatement();
256 } else {
257 // This was an identifier, so we might want to handle flow/typescript-specific cases.
258 parseIdentifierStatement(simpleName);
259 }
260}
261
262/**
263 * Determine if we're positioned at an `await using` declaration.
264 *
265 * Note that this can happen either in place of a regular variable declaration
266 * or in a loop body, and in both places, there are similar-looking cases where
267 * we need to return false.
268 *
269 * Examples returning true:
270 * await using foo = bar();
271 * for (await using a of b) {}
272 *
273 * Examples returning false:
274 * await using
275 * await using + 1
276 * await using instanceof T
277 * for (await using;;) {}
278 *
279 * For now, we early return if we don't see `await`, then do a simple
280 * backtracking-based lookahead for the `using` and identifier tokens. In the
281 * future, this could be optimized with a character-based approach.
282 */
283function startsAwaitUsing() {
284 if (!_util.isContextual.call(void 0, _keywords.ContextualKeyword._await)) {
285 return false;
286 }
287 const snapshot = _base.state.snapshot();
288 // await
289 _tokenizer.next.call(void 0, );
290 if (!_util.isContextual.call(void 0, _keywords.ContextualKeyword._using) || _util.hasPrecedingLineBreak.call(void 0, )) {
291 _base.state.restoreFromSnapshot(snapshot);
292 return false;
293 }
294 // using
295 _tokenizer.next.call(void 0, );
296 if (!_tokenizer.match.call(void 0, _types.TokenType.name) || _util.hasPrecedingLineBreak.call(void 0, )) {
297 _base.state.restoreFromSnapshot(snapshot);
298 return false;
299 }
300 _base.state.restoreFromSnapshot(snapshot);
301 return true;
302}
303
304 function parseDecorators() {
305 while (_tokenizer.match.call(void 0, _types.TokenType.at)) {
306 parseDecorator();
307 }
308} exports.parseDecorators = parseDecorators;
309
310function parseDecorator() {
311 _tokenizer.next.call(void 0, );
312 if (_tokenizer.eat.call(void 0, _types.TokenType.parenL)) {
313 _expression.parseExpression.call(void 0, );
314 _util.expect.call(void 0, _types.TokenType.parenR);
315 } else {
316 _expression.parseIdentifier.call(void 0, );
317 while (_tokenizer.eat.call(void 0, _types.TokenType.dot)) {
318 _expression.parseIdentifier.call(void 0, );
319 }
320 parseMaybeDecoratorArguments();
321 }
322}
323
324function parseMaybeDecoratorArguments() {
325 if (_base.isTypeScriptEnabled) {
326 _typescript.tsParseMaybeDecoratorArguments.call(void 0, );
327 } else {
328 baseParseMaybeDecoratorArguments();
329 }
330}
331
332 function baseParseMaybeDecoratorArguments() {
333 if (_tokenizer.eat.call(void 0, _types.TokenType.parenL)) {
334 _expression.parseCallExpressionArguments.call(void 0, );
335 }
336} exports.baseParseMaybeDecoratorArguments = baseParseMaybeDecoratorArguments;
337
338function parseBreakContinueStatement() {
339 _tokenizer.next.call(void 0, );
340 if (!_util.isLineTerminator.call(void 0, )) {
341 _expression.parseIdentifier.call(void 0, );
342 _util.semicolon.call(void 0, );
343 }
344}
345
346function parseDebuggerStatement() {
347 _tokenizer.next.call(void 0, );
348 _util.semicolon.call(void 0, );
349}
350
351function parseDoStatement() {
352 _tokenizer.next.call(void 0, );
353 parseStatement(false);
354 _util.expect.call(void 0, _types.TokenType._while);
355 _expression.parseParenExpression.call(void 0, );
356 _tokenizer.eat.call(void 0, _types.TokenType.semi);
357}
358
359function parseForStatement() {
360 _base.state.scopeDepth++;
361 const startTokenIndex = _base.state.tokens.length;
362 parseAmbiguousForStatement();
363 const endTokenIndex = _base.state.tokens.length;
364 _base.state.scopes.push(new (0, _state.Scope)(startTokenIndex, endTokenIndex, false));
365 _base.state.scopeDepth--;
366}
367
368/**
369 * Determine if this token is a `using` declaration (explicit resource
370 * management) as part of a loop.
371 * https://github.com/tc39/proposal-explicit-resource-management
372 */
373function isUsingInLoop() {
374 if (!_util.isContextual.call(void 0, _keywords.ContextualKeyword._using)) {
375 return false;
376 }
377 // This must be `for (using of`, where `using` is the name of the loop
378 // variable.
379 if (_util.isLookaheadContextual.call(void 0, _keywords.ContextualKeyword._of)) {
380 return false;
381 }
382 return true;
383}
384
385// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
386// loop is non-trivial. Basically, we have to parse the init `var`
387// statement or expression, disallowing the `in` operator (see
388// the second parameter to `parseExpression`), and then check
389// whether the next token is `in` or `of`. When there is no init
390// part (semicolon immediately after the opening parenthesis), it
391// is a regular `for` loop.
392function parseAmbiguousForStatement() {
393 _tokenizer.next.call(void 0, );
394
395 let forAwait = false;
396 if (_util.isContextual.call(void 0, _keywords.ContextualKeyword._await)) {
397 forAwait = true;
398 _tokenizer.next.call(void 0, );
399 }
400 _util.expect.call(void 0, _types.TokenType.parenL);
401
402 if (_tokenizer.match.call(void 0, _types.TokenType.semi)) {
403 if (forAwait) {
404 _util.unexpected.call(void 0, );
405 }
406 parseFor();
407 return;
408 }
409
410 const isAwaitUsing = startsAwaitUsing();
411 if (isAwaitUsing || _tokenizer.match.call(void 0, _types.TokenType._var) || _tokenizer.match.call(void 0, _types.TokenType._let) || _tokenizer.match.call(void 0, _types.TokenType._const) || isUsingInLoop()) {
412 if (isAwaitUsing) {
413 _util.expectContextual.call(void 0, _keywords.ContextualKeyword._await);
414 }
415 _tokenizer.next.call(void 0, );
416 parseVar(true, _base.state.type !== _types.TokenType._var);
417 if (_tokenizer.match.call(void 0, _types.TokenType._in) || _util.isContextual.call(void 0, _keywords.ContextualKeyword._of)) {
418 parseForIn(forAwait);
419 return;
420 }
421 parseFor();
422 return;
423 }
424
425 _expression.parseExpression.call(void 0, true);
426 if (_tokenizer.match.call(void 0, _types.TokenType._in) || _util.isContextual.call(void 0, _keywords.ContextualKeyword._of)) {
427 parseForIn(forAwait);
428 return;
429 }
430 if (forAwait) {
431 _util.unexpected.call(void 0, );
432 }
433 parseFor();
434}
435
436function parseFunctionStatement() {
437 const functionStart = _base.state.start;
438 _tokenizer.next.call(void 0, );
439 parseFunction(functionStart, true);
440}
441
442function parseIfStatement() {
443 _tokenizer.next.call(void 0, );
444 _expression.parseParenExpression.call(void 0, );
445 parseStatement(false);
446 if (_tokenizer.eat.call(void 0, _types.TokenType._else)) {
447 parseStatement(false);
448 }
449}
450
451function parseReturnStatement() {
452 _tokenizer.next.call(void 0, );
453
454 // In `return` (and `break`/`continue`), the keywords with
455 // optional arguments, we eagerly look for a semicolon or the
456 // possibility to insert one.
457
458 if (!_util.isLineTerminator.call(void 0, )) {
459 _expression.parseExpression.call(void 0, );
460 _util.semicolon.call(void 0, );
461 }
462}
463
464function parseSwitchStatement() {
465 _tokenizer.next.call(void 0, );
466 _expression.parseParenExpression.call(void 0, );
467 _base.state.scopeDepth++;
468 const startTokenIndex = _base.state.tokens.length;
469 _util.expect.call(void 0, _types.TokenType.braceL);
470
471 // Don't bother validation; just go through any sequence of cases, defaults, and statements.
472 while (!_tokenizer.match.call(void 0, _types.TokenType.braceR) && !_base.state.error) {
473 if (_tokenizer.match.call(void 0, _types.TokenType._case) || _tokenizer.match.call(void 0, _types.TokenType._default)) {
474 const isCase = _tokenizer.match.call(void 0, _types.TokenType._case);
475 _tokenizer.next.call(void 0, );
476 if (isCase) {
477 _expression.parseExpression.call(void 0, );
478 }
479 _util.expect.call(void 0, _types.TokenType.colon);
480 } else {
481 parseStatement(true);
482 }
483 }
484 _tokenizer.next.call(void 0, ); // Closing brace
485 const endTokenIndex = _base.state.tokens.length;
486 _base.state.scopes.push(new (0, _state.Scope)(startTokenIndex, endTokenIndex, false));
487 _base.state.scopeDepth--;
488}
489
490function parseThrowStatement() {
491 _tokenizer.next.call(void 0, );
492 _expression.parseExpression.call(void 0, );
493 _util.semicolon.call(void 0, );
494}
495
496function parseCatchClauseParam() {
497 _lval.parseBindingAtom.call(void 0, true /* isBlockScope */);
498
499 if (_base.isTypeScriptEnabled) {
500 _typescript.tsTryParseTypeAnnotation.call(void 0, );
501 }
502}
503
504function parseTryStatement() {
505 _tokenizer.next.call(void 0, );
506
507 parseBlock();
508
509 if (_tokenizer.match.call(void 0, _types.TokenType._catch)) {
510 _tokenizer.next.call(void 0, );
511 let catchBindingStartTokenIndex = null;
512 if (_tokenizer.match.call(void 0, _types.TokenType.parenL)) {
513 _base.state.scopeDepth++;
514 catchBindingStartTokenIndex = _base.state.tokens.length;
515 _util.expect.call(void 0, _types.TokenType.parenL);
516 parseCatchClauseParam();
517 _util.expect.call(void 0, _types.TokenType.parenR);
518 }
519 parseBlock();
520 if (catchBindingStartTokenIndex != null) {
521 // We need a special scope for the catch binding which includes the binding itself and the
522 // catch block.
523 const endTokenIndex = _base.state.tokens.length;
524 _base.state.scopes.push(new (0, _state.Scope)(catchBindingStartTokenIndex, endTokenIndex, false));
525 _base.state.scopeDepth--;
526 }
527 }
528 if (_tokenizer.eat.call(void 0, _types.TokenType._finally)) {
529 parseBlock();
530 }
531}
532
533 function parseVarStatement(isBlockScope) {
534 _tokenizer.next.call(void 0, );
535 parseVar(false, isBlockScope);
536 _util.semicolon.call(void 0, );
537} exports.parseVarStatement = parseVarStatement;
538
539function parseWhileStatement() {
540 _tokenizer.next.call(void 0, );
541 _expression.parseParenExpression.call(void 0, );
542 parseStatement(false);
543}
544
545function parseEmptyStatement() {
546 _tokenizer.next.call(void 0, );
547}
548
549function parseLabeledStatement() {
550 parseStatement(true);
551}
552
553/**
554 * Parse a statement starting with an identifier of the given name. Subclasses match on the name
555 * to handle statements like "declare".
556 */
557function parseIdentifierStatement(contextualKeyword) {
558 if (_base.isTypeScriptEnabled) {
559 _typescript.tsParseIdentifierStatement.call(void 0, contextualKeyword);
560 } else if (_base.isFlowEnabled) {
561 _flow.flowParseIdentifierStatement.call(void 0, contextualKeyword);
562 } else {
563 _util.semicolon.call(void 0, );
564 }
565}
566
567// Parse a semicolon-enclosed block of statements.
568 function parseBlock(isFunctionScope = false, contextId = 0) {
569 const startTokenIndex = _base.state.tokens.length;
570 _base.state.scopeDepth++;
571 _util.expect.call(void 0, _types.TokenType.braceL);
572 if (contextId) {
573 _base.state.tokens[_base.state.tokens.length - 1].contextId = contextId;
574 }
575 parseBlockBody(_types.TokenType.braceR);
576 if (contextId) {
577 _base.state.tokens[_base.state.tokens.length - 1].contextId = contextId;
578 }
579 const endTokenIndex = _base.state.tokens.length;
580 _base.state.scopes.push(new (0, _state.Scope)(startTokenIndex, endTokenIndex, isFunctionScope));
581 _base.state.scopeDepth--;
582} exports.parseBlock = parseBlock;
583
584 function parseBlockBody(end) {
585 while (!_tokenizer.eat.call(void 0, end) && !_base.state.error) {
586 parseStatement(true);
587 }
588} exports.parseBlockBody = parseBlockBody;
589
590// Parse a regular `for` loop. The disambiguation code in
591// `parseStatement` will already have parsed the init statement or
592// expression.
593
594function parseFor() {
595 _util.expect.call(void 0, _types.TokenType.semi);
596 if (!_tokenizer.match.call(void 0, _types.TokenType.semi)) {
597 _expression.parseExpression.call(void 0, );
598 }
599 _util.expect.call(void 0, _types.TokenType.semi);
600 if (!_tokenizer.match.call(void 0, _types.TokenType.parenR)) {
601 _expression.parseExpression.call(void 0, );
602 }
603 _util.expect.call(void 0, _types.TokenType.parenR);
604 parseStatement(false);
605}
606
607// Parse a `for`/`in` and `for`/`of` loop, which are almost
608// same from parser's perspective.
609
610function parseForIn(forAwait) {
611 if (forAwait) {
612 _util.eatContextual.call(void 0, _keywords.ContextualKeyword._of);
613 } else {
614 _tokenizer.next.call(void 0, );
615 }
616 _expression.parseExpression.call(void 0, );
617 _util.expect.call(void 0, _types.TokenType.parenR);
618 parseStatement(false);
619}
620
621// Parse a list of variable declarations.
622
623function parseVar(isFor, isBlockScope) {
624 while (true) {
625 parseVarHead(isBlockScope);
626 if (_tokenizer.eat.call(void 0, _types.TokenType.eq)) {
627 const eqIndex = _base.state.tokens.length - 1;
628 _expression.parseMaybeAssign.call(void 0, isFor);
629 _base.state.tokens[eqIndex].rhsEndIndex = _base.state.tokens.length;
630 }
631 if (!_tokenizer.eat.call(void 0, _types.TokenType.comma)) {
632 break;
633 }
634 }
635}
636
637function parseVarHead(isBlockScope) {
638 _lval.parseBindingAtom.call(void 0, isBlockScope);
639 if (_base.isTypeScriptEnabled) {
640 _typescript.tsAfterParseVarHead.call(void 0, );
641 } else if (_base.isFlowEnabled) {
642 _flow.flowAfterParseVarHead.call(void 0, );
643 }
644}
645
646// Parse a function declaration or literal (depending on the
647// `isStatement` parameter).
648
649 function parseFunction(
650 functionStart,
651 isStatement,
652 optionalId = false,
653) {
654 if (_tokenizer.match.call(void 0, _types.TokenType.star)) {
655 _tokenizer.next.call(void 0, );
656 }
657
658 if (isStatement && !optionalId && !_tokenizer.match.call(void 0, _types.TokenType.name) && !_tokenizer.match.call(void 0, _types.TokenType._yield)) {
659 _util.unexpected.call(void 0, );
660 }
661
662 let nameScopeStartTokenIndex = null;
663
664 if (_tokenizer.match.call(void 0, _types.TokenType.name)) {
665 // Expression-style functions should limit their name's scope to the function body, so we make
666 // a new function scope to enforce that.
667 if (!isStatement) {
668 nameScopeStartTokenIndex = _base.state.tokens.length;
669 _base.state.scopeDepth++;
670 }
671 _lval.parseBindingIdentifier.call(void 0, false);
672 }
673
674 const startTokenIndex = _base.state.tokens.length;
675 _base.state.scopeDepth++;
676 parseFunctionParams();
677 _expression.parseFunctionBodyAndFinish.call(void 0, functionStart);
678 const endTokenIndex = _base.state.tokens.length;
679 // In addition to the block scope of the function body, we need a separate function-style scope
680 // that includes the params.
681 _base.state.scopes.push(new (0, _state.Scope)(startTokenIndex, endTokenIndex, true));
682 _base.state.scopeDepth--;
683 if (nameScopeStartTokenIndex !== null) {
684 _base.state.scopes.push(new (0, _state.Scope)(nameScopeStartTokenIndex, endTokenIndex, true));
685 _base.state.scopeDepth--;
686 }
687} exports.parseFunction = parseFunction;
688
689 function parseFunctionParams(
690 allowModifiers = false,
691 funcContextId = 0,
692) {
693 if (_base.isTypeScriptEnabled) {
694 _typescript.tsStartParseFunctionParams.call(void 0, );
695 } else if (_base.isFlowEnabled) {
696 _flow.flowStartParseFunctionParams.call(void 0, );
697 }
698
699 _util.expect.call(void 0, _types.TokenType.parenL);
700 if (funcContextId) {
701 _base.state.tokens[_base.state.tokens.length - 1].contextId = funcContextId;
702 }
703 _lval.parseBindingList.call(void 0,
704 _types.TokenType.parenR,
705 false /* isBlockScope */,
706 false /* allowEmpty */,
707 allowModifiers,
708 funcContextId,
709 );
710 if (funcContextId) {
711 _base.state.tokens[_base.state.tokens.length - 1].contextId = funcContextId;
712 }
713} exports.parseFunctionParams = parseFunctionParams;
714
715// Parse a class declaration or literal (depending on the
716// `isStatement` parameter).
717
718 function parseClass(isStatement, optionalId = false) {
719 // Put a context ID on the class keyword, the open-brace, and the close-brace, so that later
720 // code can easily navigate to meaningful points on the class.
721 const contextId = _base.getNextContextId.call(void 0, );
722
723 _tokenizer.next.call(void 0, );
724 _base.state.tokens[_base.state.tokens.length - 1].contextId = contextId;
725 _base.state.tokens[_base.state.tokens.length - 1].isExpression = !isStatement;
726 // Like with functions, we declare a special "name scope" from the start of the name to the end
727 // of the class, but only with expression-style classes, to represent the fact that the name is
728 // available to the body of the class but not an outer declaration.
729 let nameScopeStartTokenIndex = null;
730 if (!isStatement) {
731 nameScopeStartTokenIndex = _base.state.tokens.length;
732 _base.state.scopeDepth++;
733 }
734 parseClassId(isStatement, optionalId);
735 parseClassSuper();
736 const openBraceIndex = _base.state.tokens.length;
737 parseClassBody(contextId);
738 if (_base.state.error) {
739 return;
740 }
741 _base.state.tokens[openBraceIndex].contextId = contextId;
742 _base.state.tokens[_base.state.tokens.length - 1].contextId = contextId;
743 if (nameScopeStartTokenIndex !== null) {
744 const endTokenIndex = _base.state.tokens.length;
745 _base.state.scopes.push(new (0, _state.Scope)(nameScopeStartTokenIndex, endTokenIndex, false));
746 _base.state.scopeDepth--;
747 }
748} exports.parseClass = parseClass;
749
750function isClassProperty() {
751 return _tokenizer.match.call(void 0, _types.TokenType.eq) || _tokenizer.match.call(void 0, _types.TokenType.semi) || _tokenizer.match.call(void 0, _types.TokenType.braceR) || _tokenizer.match.call(void 0, _types.TokenType.bang) || _tokenizer.match.call(void 0, _types.TokenType.colon);
752}
753
754function isClassMethod() {
755 return _tokenizer.match.call(void 0, _types.TokenType.parenL) || _tokenizer.match.call(void 0, _types.TokenType.lessThan);
756}
757
758function parseClassBody(classContextId) {
759 _util.expect.call(void 0, _types.TokenType.braceL);
760
761 while (!_tokenizer.eat.call(void 0, _types.TokenType.braceR) && !_base.state.error) {
762 if (_tokenizer.eat.call(void 0, _types.TokenType.semi)) {
763 continue;
764 }
765
766 if (_tokenizer.match.call(void 0, _types.TokenType.at)) {
767 parseDecorator();
768 continue;
769 }
770 const memberStart = _base.state.start;
771 parseClassMember(memberStart, classContextId);
772 }
773}
774
775function parseClassMember(memberStart, classContextId) {
776 if (_base.isTypeScriptEnabled) {
777 _typescript.tsParseModifiers.call(void 0, [
778 _keywords.ContextualKeyword._declare,
779 _keywords.ContextualKeyword._public,
780 _keywords.ContextualKeyword._protected,
781 _keywords.ContextualKeyword._private,
782 _keywords.ContextualKeyword._override,
783 ]);
784 }
785 let isStatic = false;
786 if (_tokenizer.match.call(void 0, _types.TokenType.name) && _base.state.contextualKeyword === _keywords.ContextualKeyword._static) {
787 _expression.parseIdentifier.call(void 0, ); // eats 'static'
788 if (isClassMethod()) {
789 parseClassMethod(memberStart, /* isConstructor */ false);
790 return;
791 } else if (isClassProperty()) {
792 parseClassProperty();
793 return;
794 }
795 // otherwise something static
796 _base.state.tokens[_base.state.tokens.length - 1].type = _types.TokenType._static;
797 isStatic = true;
798
799 if (_tokenizer.match.call(void 0, _types.TokenType.braceL)) {
800 // This is a static block. Mark the word "static" with the class context ID for class element
801 // detection and parse as a regular block.
802 _base.state.tokens[_base.state.tokens.length - 1].contextId = classContextId;
803 parseBlock();
804 return;
805 }
806 }
807
808 parseClassMemberWithIsStatic(memberStart, isStatic, classContextId);
809}
810
811function parseClassMemberWithIsStatic(
812 memberStart,
813 isStatic,
814 classContextId,
815) {
816 if (_base.isTypeScriptEnabled) {
817 if (_typescript.tsTryParseClassMemberWithIsStatic.call(void 0, isStatic)) {
818 return;
819 }
820 }
821 if (_tokenizer.eat.call(void 0, _types.TokenType.star)) {
822 // a generator
823 parseClassPropertyName(classContextId);
824 parseClassMethod(memberStart, /* isConstructor */ false);
825 return;
826 }
827
828 // Get the identifier name so we can tell if it's actually a keyword like "async", "get", or
829 // "set".
830 parseClassPropertyName(classContextId);
831 let isConstructor = false;
832 const token = _base.state.tokens[_base.state.tokens.length - 1];
833 // We allow "constructor" as either an identifier or a string.
834 if (token.contextualKeyword === _keywords.ContextualKeyword._constructor) {
835 isConstructor = true;
836 }
837 parsePostMemberNameModifiers();
838
839 if (isClassMethod()) {
840 parseClassMethod(memberStart, isConstructor);
841 } else if (isClassProperty()) {
842 parseClassProperty();
843 } else if (token.contextualKeyword === _keywords.ContextualKeyword._async && !_util.isLineTerminator.call(void 0, )) {
844 _base.state.tokens[_base.state.tokens.length - 1].type = _types.TokenType._async;
845 // an async method
846 const isGenerator = _tokenizer.match.call(void 0, _types.TokenType.star);
847 if (isGenerator) {
848 _tokenizer.next.call(void 0, );
849 }
850
851 // The so-called parsed name would have been "async": get the real name.
852 parseClassPropertyName(classContextId);
853 parsePostMemberNameModifiers();
854 parseClassMethod(memberStart, false /* isConstructor */);
855 } else if (
856 (token.contextualKeyword === _keywords.ContextualKeyword._get ||
857 token.contextualKeyword === _keywords.ContextualKeyword._set) &&
858 !(_util.isLineTerminator.call(void 0, ) && _tokenizer.match.call(void 0, _types.TokenType.star))
859 ) {
860 if (token.contextualKeyword === _keywords.ContextualKeyword._get) {
861 _base.state.tokens[_base.state.tokens.length - 1].type = _types.TokenType._get;
862 } else {
863 _base.state.tokens[_base.state.tokens.length - 1].type = _types.TokenType._set;
864 }
865 // `get\n*` is an uninitialized property named 'get' followed by a generator.
866 // a getter or setter
867 // The so-called parsed name would have been "get/set": get the real name.
868 parseClassPropertyName(classContextId);
869 parseClassMethod(memberStart, /* isConstructor */ false);
870 } else if (token.contextualKeyword === _keywords.ContextualKeyword._accessor && !_util.isLineTerminator.call(void 0, )) {
871 parseClassPropertyName(classContextId);
872 parseClassProperty();
873 } else if (_util.isLineTerminator.call(void 0, )) {
874 // an uninitialized class property (due to ASI, since we don't otherwise recognize the next token)
875 parseClassProperty();
876 } else {
877 _util.unexpected.call(void 0, );
878 }
879}
880
881function parseClassMethod(functionStart, isConstructor) {
882 if (_base.isTypeScriptEnabled) {
883 _typescript.tsTryParseTypeParameters.call(void 0, );
884 } else if (_base.isFlowEnabled) {
885 if (_tokenizer.match.call(void 0, _types.TokenType.lessThan)) {
886 _flow.flowParseTypeParameterDeclaration.call(void 0, );
887 }
888 }
889 _expression.parseMethod.call(void 0, functionStart, isConstructor);
890}
891
892// Return the name of the class property, if it is a simple identifier.
893 function parseClassPropertyName(classContextId) {
894 _expression.parsePropertyName.call(void 0, classContextId);
895} exports.parseClassPropertyName = parseClassPropertyName;
896
897 function parsePostMemberNameModifiers() {
898 if (_base.isTypeScriptEnabled) {
899 const oldIsType = _tokenizer.pushTypeContext.call(void 0, 0);
900 _tokenizer.eat.call(void 0, _types.TokenType.question);
901 _tokenizer.popTypeContext.call(void 0, oldIsType);
902 }
903} exports.parsePostMemberNameModifiers = parsePostMemberNameModifiers;
904
905 function parseClassProperty() {
906 if (_base.isTypeScriptEnabled) {
907 _tokenizer.eatTypeToken.call(void 0, _types.TokenType.bang);
908 _typescript.tsTryParseTypeAnnotation.call(void 0, );
909 } else if (_base.isFlowEnabled) {
910 if (_tokenizer.match.call(void 0, _types.TokenType.colon)) {
911 _flow.flowParseTypeAnnotation.call(void 0, );
912 }
913 }
914
915 if (_tokenizer.match.call(void 0, _types.TokenType.eq)) {
916 const equalsTokenIndex = _base.state.tokens.length;
917 _tokenizer.next.call(void 0, );
918 _expression.parseMaybeAssign.call(void 0, );
919 _base.state.tokens[equalsTokenIndex].rhsEndIndex = _base.state.tokens.length;
920 }
921 _util.semicolon.call(void 0, );
922} exports.parseClassProperty = parseClassProperty;
923
924function parseClassId(isStatement, optionalId = false) {
925 if (
926 _base.isTypeScriptEnabled &&
927 (!isStatement || optionalId) &&
928 _util.isContextual.call(void 0, _keywords.ContextualKeyword._implements)
929 ) {
930 return;
931 }
932
933 if (_tokenizer.match.call(void 0, _types.TokenType.name)) {
934 _lval.parseBindingIdentifier.call(void 0, true);
935 }
936
937 if (_base.isTypeScriptEnabled) {
938 _typescript.tsTryParseTypeParameters.call(void 0, );
939 } else if (_base.isFlowEnabled) {
940 if (_tokenizer.match.call(void 0, _types.TokenType.lessThan)) {
941 _flow.flowParseTypeParameterDeclaration.call(void 0, );
942 }
943 }
944}
945
946// Returns true if there was a superclass.
947function parseClassSuper() {
948 let hasSuper = false;
949 if (_tokenizer.eat.call(void 0, _types.TokenType._extends)) {
950 _expression.parseExprSubscripts.call(void 0, );
951 hasSuper = true;
952 } else {
953 hasSuper = false;
954 }
955 if (_base.isTypeScriptEnabled) {
956 _typescript.tsAfterParseClassSuper.call(void 0, hasSuper);
957 } else if (_base.isFlowEnabled) {
958 _flow.flowAfterParseClassSuper.call(void 0, hasSuper);
959 }
960}
961
962// Parses module export declaration.
963
964 function parseExport() {
965 const exportIndex = _base.state.tokens.length - 1;
966 if (_base.isTypeScriptEnabled) {
967 if (_typescript.tsTryParseExport.call(void 0, )) {
968 return;
969 }
970 }
971 // export * from '...'
972 if (shouldParseExportStar()) {
973 parseExportStar();
974 } else if (isExportDefaultSpecifier()) {
975 // export default from
976 _expression.parseIdentifier.call(void 0, );
977 if (_tokenizer.match.call(void 0, _types.TokenType.comma) && _tokenizer.lookaheadType.call(void 0, ) === _types.TokenType.star) {
978 _util.expect.call(void 0, _types.TokenType.comma);
979 _util.expect.call(void 0, _types.TokenType.star);
980 _util.expectContextual.call(void 0, _keywords.ContextualKeyword._as);
981 _expression.parseIdentifier.call(void 0, );
982 } else {
983 parseExportSpecifiersMaybe();
984 }
985 parseExportFrom();
986 } else if (_tokenizer.eat.call(void 0, _types.TokenType._default)) {
987 // export default ...
988 parseExportDefaultExpression();
989 } else if (shouldParseExportDeclaration()) {
990 parseExportDeclaration();
991 } else {
992 // export { x, y as z } [from '...']
993 parseExportSpecifiers();
994 parseExportFrom();
995 }
996 _base.state.tokens[exportIndex].rhsEndIndex = _base.state.tokens.length;
997} exports.parseExport = parseExport;
998
999function parseExportDefaultExpression() {
1000 if (_base.isTypeScriptEnabled) {
1001 if (_typescript.tsTryParseExportDefaultExpression.call(void 0, )) {
1002 return;
1003 }
1004 }
1005 if (_base.isFlowEnabled) {
1006 if (_flow.flowTryParseExportDefaultExpression.call(void 0, )) {
1007 return;
1008 }
1009 }
1010 const functionStart = _base.state.start;
1011 if (_tokenizer.eat.call(void 0, _types.TokenType._function)) {
1012 parseFunction(functionStart, true, true);
1013 } else if (_util.isContextual.call(void 0, _keywords.ContextualKeyword._async) && _tokenizer.lookaheadType.call(void 0, ) === _types.TokenType._function) {
1014 // async function declaration
1015 _util.eatContextual.call(void 0, _keywords.ContextualKeyword._async);
1016 _tokenizer.eat.call(void 0, _types.TokenType._function);
1017 parseFunction(functionStart, true, true);
1018 } else if (_tokenizer.match.call(void 0, _types.TokenType._class)) {
1019 parseClass(true, true);
1020 } else if (_tokenizer.match.call(void 0, _types.TokenType.at)) {
1021 parseDecorators();
1022 parseClass(true, true);
1023 } else {
1024 _expression.parseMaybeAssign.call(void 0, );
1025 _util.semicolon.call(void 0, );
1026 }
1027}
1028
1029function parseExportDeclaration() {
1030 if (_base.isTypeScriptEnabled) {
1031 _typescript.tsParseExportDeclaration.call(void 0, );
1032 } else if (_base.isFlowEnabled) {
1033 _flow.flowParseExportDeclaration.call(void 0, );
1034 } else {
1035 parseStatement(true);
1036 }
1037}
1038
1039function isExportDefaultSpecifier() {
1040 if (_base.isTypeScriptEnabled && _typescript.tsIsDeclarationStart.call(void 0, )) {
1041 return false;
1042 } else if (_base.isFlowEnabled && _flow.flowShouldDisallowExportDefaultSpecifier.call(void 0, )) {
1043 return false;
1044 }
1045 if (_tokenizer.match.call(void 0, _types.TokenType.name)) {
1046 return _base.state.contextualKeyword !== _keywords.ContextualKeyword._async;
1047 }
1048
1049 if (!_tokenizer.match.call(void 0, _types.TokenType._default)) {
1050 return false;
1051 }
1052
1053 const _next = _tokenizer.nextTokenStart.call(void 0, );
1054 const lookahead = _tokenizer.lookaheadTypeAndKeyword.call(void 0, );
1055 const hasFrom =
1056 lookahead.type === _types.TokenType.name && lookahead.contextualKeyword === _keywords.ContextualKeyword._from;
1057 if (lookahead.type === _types.TokenType.comma) {
1058 return true;
1059 }
1060 // lookahead again when `export default from` is seen
1061 if (hasFrom) {
1062 const nextAfterFrom = _base.input.charCodeAt(_tokenizer.nextTokenStartSince.call(void 0, _next + 4));
1063 return nextAfterFrom === _charcodes.charCodes.quotationMark || nextAfterFrom === _charcodes.charCodes.apostrophe;
1064 }
1065 return false;
1066}
1067
1068function parseExportSpecifiersMaybe() {
1069 if (_tokenizer.eat.call(void 0, _types.TokenType.comma)) {
1070 parseExportSpecifiers();
1071 }
1072}
1073
1074 function parseExportFrom() {
1075 if (_util.eatContextual.call(void 0, _keywords.ContextualKeyword._from)) {
1076 _expression.parseExprAtom.call(void 0, );
1077 maybeParseImportAttributes();
1078 }
1079 _util.semicolon.call(void 0, );
1080} exports.parseExportFrom = parseExportFrom;
1081
1082function shouldParseExportStar() {
1083 if (_base.isFlowEnabled) {
1084 return _flow.flowShouldParseExportStar.call(void 0, );
1085 } else {
1086 return _tokenizer.match.call(void 0, _types.TokenType.star);
1087 }
1088}
1089
1090function parseExportStar() {
1091 if (_base.isFlowEnabled) {
1092 _flow.flowParseExportStar.call(void 0, );
1093 } else {
1094 baseParseExportStar();
1095 }
1096}
1097
1098 function baseParseExportStar() {
1099 _util.expect.call(void 0, _types.TokenType.star);
1100
1101 if (_util.isContextual.call(void 0, _keywords.ContextualKeyword._as)) {
1102 parseExportNamespace();
1103 } else {
1104 parseExportFrom();
1105 }
1106} exports.baseParseExportStar = baseParseExportStar;
1107
1108function parseExportNamespace() {
1109 _tokenizer.next.call(void 0, );
1110 _base.state.tokens[_base.state.tokens.length - 1].type = _types.TokenType._as;
1111 _expression.parseIdentifier.call(void 0, );
1112 parseExportSpecifiersMaybe();
1113 parseExportFrom();
1114}
1115
1116function shouldParseExportDeclaration() {
1117 return (
1118 (_base.isTypeScriptEnabled && _typescript.tsIsDeclarationStart.call(void 0, )) ||
1119 (_base.isFlowEnabled && _flow.flowShouldParseExportDeclaration.call(void 0, )) ||
1120 _base.state.type === _types.TokenType._var ||
1121 _base.state.type === _types.TokenType._const ||
1122 _base.state.type === _types.TokenType._let ||
1123 _base.state.type === _types.TokenType._function ||
1124 _base.state.type === _types.TokenType._class ||
1125 _util.isContextual.call(void 0, _keywords.ContextualKeyword._async) ||
1126 _tokenizer.match.call(void 0, _types.TokenType.at)
1127 );
1128}
1129
1130// Parses a comma-separated list of module exports.
1131 function parseExportSpecifiers() {
1132 let first = true;
1133
1134 // export { x, y as z } [from '...']
1135 _util.expect.call(void 0, _types.TokenType.braceL);
1136
1137 while (!_tokenizer.eat.call(void 0, _types.TokenType.braceR) && !_base.state.error) {
1138 if (first) {
1139 first = false;
1140 } else {
1141 _util.expect.call(void 0, _types.TokenType.comma);
1142 if (_tokenizer.eat.call(void 0, _types.TokenType.braceR)) {
1143 break;
1144 }
1145 }
1146 parseExportSpecifier();
1147 }
1148} exports.parseExportSpecifiers = parseExportSpecifiers;
1149
1150function parseExportSpecifier() {
1151 if (_base.isTypeScriptEnabled) {
1152 _typescript.tsParseExportSpecifier.call(void 0, );
1153 return;
1154 }
1155 _expression.parseIdentifier.call(void 0, );
1156 _base.state.tokens[_base.state.tokens.length - 1].identifierRole = _tokenizer.IdentifierRole.ExportAccess;
1157 if (_util.eatContextual.call(void 0, _keywords.ContextualKeyword._as)) {
1158 _expression.parseIdentifier.call(void 0, );
1159 }
1160}
1161
1162/**
1163 * Starting at the `module` token in an import, determine if it was truly an
1164 * import reflection token or just looks like one.
1165 *
1166 * Returns true for:
1167 * import module foo from "foo";
1168 * import module from from "foo";
1169 *
1170 * Returns false for:
1171 * import module from "foo";
1172 * import module, {bar} from "foo";
1173 */
1174function isImportReflection() {
1175 const snapshot = _base.state.snapshot();
1176 _util.expectContextual.call(void 0, _keywords.ContextualKeyword._module);
1177 if (_util.eatContextual.call(void 0, _keywords.ContextualKeyword._from)) {
1178 if (_util.isContextual.call(void 0, _keywords.ContextualKeyword._from)) {
1179 _base.state.restoreFromSnapshot(snapshot);
1180 return true;
1181 } else {
1182 _base.state.restoreFromSnapshot(snapshot);
1183 return false;
1184 }
1185 } else if (_tokenizer.match.call(void 0, _types.TokenType.comma)) {
1186 _base.state.restoreFromSnapshot(snapshot);
1187 return false;
1188 } else {
1189 _base.state.restoreFromSnapshot(snapshot);
1190 return true;
1191 }
1192}
1193
1194/**
1195 * Eat the "module" token from the import reflection proposal.
1196 * https://github.com/tc39/proposal-import-reflection
1197 */
1198function parseMaybeImportReflection() {
1199 // isImportReflection does snapshot/restore, so only run it if we see the word
1200 // "module".
1201 if (_util.isContextual.call(void 0, _keywords.ContextualKeyword._module) && isImportReflection()) {
1202 _tokenizer.next.call(void 0, );
1203 }
1204}
1205
1206// Parses import declaration.
1207
1208 function parseImport() {
1209 if (_base.isTypeScriptEnabled && _tokenizer.match.call(void 0, _types.TokenType.name) && _tokenizer.lookaheadType.call(void 0, ) === _types.TokenType.eq) {
1210 _typescript.tsParseImportEqualsDeclaration.call(void 0, );
1211 return;
1212 }
1213 if (_base.isTypeScriptEnabled && _util.isContextual.call(void 0, _keywords.ContextualKeyword._type)) {
1214 const lookahead = _tokenizer.lookaheadTypeAndKeyword.call(void 0, );
1215 if (lookahead.type === _types.TokenType.name && lookahead.contextualKeyword !== _keywords.ContextualKeyword._from) {
1216 // One of these `import type` cases:
1217 // import type T = require('T');
1218 // import type A from 'A';
1219 _util.expectContextual.call(void 0, _keywords.ContextualKeyword._type);
1220 if (_tokenizer.lookaheadType.call(void 0, ) === _types.TokenType.eq) {
1221 _typescript.tsParseImportEqualsDeclaration.call(void 0, );
1222 return;
1223 }
1224 // If this is an `import type...from` statement, then we already ate the
1225 // type token, so proceed to the regular import parser.
1226 } else if (lookahead.type === _types.TokenType.star || lookahead.type === _types.TokenType.braceL) {
1227 // One of these `import type` cases, in which case we can eat the type token
1228 // and proceed as normal:
1229 // import type * as A from 'A';
1230 // import type {a} from 'A';
1231 _util.expectContextual.call(void 0, _keywords.ContextualKeyword._type);
1232 }
1233 // Otherwise, we are importing the name "type".
1234 }
1235
1236 // import '...'
1237 if (_tokenizer.match.call(void 0, _types.TokenType.string)) {
1238 _expression.parseExprAtom.call(void 0, );
1239 } else {
1240 parseMaybeImportReflection();
1241 parseImportSpecifiers();
1242 _util.expectContextual.call(void 0, _keywords.ContextualKeyword._from);
1243 _expression.parseExprAtom.call(void 0, );
1244 }
1245 maybeParseImportAttributes();
1246 _util.semicolon.call(void 0, );
1247} exports.parseImport = parseImport;
1248
1249// eslint-disable-next-line no-unused-vars
1250function shouldParseDefaultImport() {
1251 return _tokenizer.match.call(void 0, _types.TokenType.name);
1252}
1253
1254function parseImportSpecifierLocal() {
1255 _lval.parseImportedIdentifier.call(void 0, );
1256}
1257
1258// Parses a comma-separated list of module imports.
1259function parseImportSpecifiers() {
1260 if (_base.isFlowEnabled) {
1261 _flow.flowStartParseImportSpecifiers.call(void 0, );
1262 }
1263
1264 let first = true;
1265 if (shouldParseDefaultImport()) {
1266 // import defaultObj, { x, y as z } from '...'
1267 parseImportSpecifierLocal();
1268
1269 if (!_tokenizer.eat.call(void 0, _types.TokenType.comma)) return;
1270 }
1271
1272 if (_tokenizer.match.call(void 0, _types.TokenType.star)) {
1273 _tokenizer.next.call(void 0, );
1274 _util.expectContextual.call(void 0, _keywords.ContextualKeyword._as);
1275
1276 parseImportSpecifierLocal();
1277
1278 return;
1279 }
1280
1281 _util.expect.call(void 0, _types.TokenType.braceL);
1282 while (!_tokenizer.eat.call(void 0, _types.TokenType.braceR) && !_base.state.error) {
1283 if (first) {
1284 first = false;
1285 } else {
1286 // Detect an attempt to deep destructure
1287 if (_tokenizer.eat.call(void 0, _types.TokenType.colon)) {
1288 _util.unexpected.call(void 0,
1289 "ES2015 named imports do not destructure. Use another statement for destructuring after the import.",
1290 );
1291 }
1292
1293 _util.expect.call(void 0, _types.TokenType.comma);
1294 if (_tokenizer.eat.call(void 0, _types.TokenType.braceR)) {
1295 break;
1296 }
1297 }
1298
1299 parseImportSpecifier();
1300 }
1301}
1302
1303function parseImportSpecifier() {
1304 if (_base.isTypeScriptEnabled) {
1305 _typescript.tsParseImportSpecifier.call(void 0, );
1306 return;
1307 }
1308 if (_base.isFlowEnabled) {
1309 _flow.flowParseImportSpecifier.call(void 0, );
1310 return;
1311 }
1312 _lval.parseImportedIdentifier.call(void 0, );
1313 if (_util.isContextual.call(void 0, _keywords.ContextualKeyword._as)) {
1314 _base.state.tokens[_base.state.tokens.length - 1].identifierRole = _tokenizer.IdentifierRole.ImportAccess;
1315 _tokenizer.next.call(void 0, );
1316 _lval.parseImportedIdentifier.call(void 0, );
1317 }
1318}
1319
1320/**
1321 * Parse import attributes like `with {type: "json"}`, or the legacy form
1322 * `assert {type: "json"}`.
1323 *
1324 * Import attributes technically have their own syntax, but are always parseable
1325 * as a plain JS object, so just do that for simplicity.
1326 */
1327function maybeParseImportAttributes() {
1328 if (_tokenizer.match.call(void 0, _types.TokenType._with) || (_util.isContextual.call(void 0, _keywords.ContextualKeyword._assert) && !_util.hasPrecedingLineBreak.call(void 0, ))) {
1329 _tokenizer.next.call(void 0, );
1330 _expression.parseObj.call(void 0, false, false);
1331 }
1332}
Note: See TracBrowser for help on using the repository browser.