1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | import {
|
22 | flowParseArrow,
|
23 | flowParseFunctionBodyAndFinish,
|
24 | flowParseMaybeAssign,
|
25 | flowParseSubscript,
|
26 | flowParseSubscripts,
|
27 | flowParseVariance,
|
28 | flowStartParseAsyncArrowFromCallExpression,
|
29 | flowStartParseNewArguments,
|
30 | flowStartParseObjPropValue,
|
31 | } from "../plugins/flow";
|
32 | import {jsxParseElement} from "../plugins/jsx/index";
|
33 | import {typedParseConditional, typedParseParenItem} from "../plugins/types";
|
34 | import {
|
35 | tsParseArrow,
|
36 | tsParseFunctionBodyAndFinish,
|
37 | tsParseMaybeAssign,
|
38 | tsParseSubscript,
|
39 | tsParseType,
|
40 | tsParseTypeAssertion,
|
41 | tsStartParseAsyncArrowFromCallExpression,
|
42 | tsStartParseNewArguments,
|
43 | tsStartParseObjPropValue,
|
44 | } from "../plugins/typescript";
|
45 | import {
|
46 | eat,
|
47 | IdentifierRole,
|
48 | lookaheadCharCode,
|
49 | lookaheadType,
|
50 | match,
|
51 | next,
|
52 | nextTemplateToken,
|
53 | popTypeContext,
|
54 | pushTypeContext,
|
55 | retokenizeSlashAsRegex,
|
56 | } from "../tokenizer/index";
|
57 | import {ContextualKeyword} from "../tokenizer/keywords";
|
58 | import {Scope} from "../tokenizer/state";
|
59 | import {TokenType, TokenType as tt} from "../tokenizer/types";
|
60 | import {charCodes} from "../util/charcodes";
|
61 | import {IS_IDENTIFIER_START} from "../util/identifier";
|
62 | import {getNextContextId, isFlowEnabled, isJSXEnabled, isTypeScriptEnabled, state} from "./base";
|
63 | import {
|
64 | markPriorBindingIdentifier,
|
65 | parseBindingIdentifier,
|
66 | parseMaybeDefault,
|
67 | parseRest,
|
68 | parseSpread,
|
69 | } from "./lval";
|
70 | import {
|
71 | parseBlock,
|
72 | parseBlockBody,
|
73 | parseClass,
|
74 | parseDecorators,
|
75 | parseFunction,
|
76 | parseFunctionParams,
|
77 | } from "./statement";
|
78 | import {
|
79 | canInsertSemicolon,
|
80 | eatContextual,
|
81 | expect,
|
82 | expectContextual,
|
83 | hasFollowingLineBreak,
|
84 | hasPrecedingLineBreak,
|
85 | isContextual,
|
86 | unexpected,
|
87 | } from "./util";
|
88 |
|
89 | export class StopState {
|
90 |
|
91 | constructor(stop) {
|
92 | this.stop = stop;
|
93 | }
|
94 | }
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 | export function parseExpression(noIn = false) {
|
104 | parseMaybeAssign(noIn);
|
105 | if (match(tt.comma)) {
|
106 | while (eat(tt.comma)) {
|
107 | parseMaybeAssign(noIn);
|
108 | }
|
109 | }
|
110 | }
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 | export function parseMaybeAssign(noIn = false, isWithinParens = false) {
|
120 | if (isTypeScriptEnabled) {
|
121 | return tsParseMaybeAssign(noIn, isWithinParens);
|
122 | } else if (isFlowEnabled) {
|
123 | return flowParseMaybeAssign(noIn, isWithinParens);
|
124 | } else {
|
125 | return baseParseMaybeAssign(noIn, isWithinParens);
|
126 | }
|
127 | }
|
128 |
|
129 |
|
130 |
|
131 |
|
132 | export function baseParseMaybeAssign(noIn, isWithinParens) {
|
133 | if (match(tt._yield)) {
|
134 | parseYield();
|
135 | return false;
|
136 | }
|
137 |
|
138 | if (match(tt.parenL) || match(tt.name) || match(tt._yield)) {
|
139 | state.potentialArrowAt = state.start;
|
140 | }
|
141 |
|
142 | const wasArrow = parseMaybeConditional(noIn);
|
143 | if (isWithinParens) {
|
144 | parseParenItem();
|
145 | }
|
146 | if (state.type & TokenType.IS_ASSIGN) {
|
147 | next();
|
148 | parseMaybeAssign(noIn);
|
149 | return false;
|
150 | }
|
151 | return wasArrow;
|
152 | }
|
153 |
|
154 |
|
155 |
|
156 | function parseMaybeConditional(noIn) {
|
157 | const wasArrow = parseExprOps(noIn);
|
158 | if (wasArrow) {
|
159 | return true;
|
160 | }
|
161 | parseConditional(noIn);
|
162 | return false;
|
163 | }
|
164 |
|
165 | function parseConditional(noIn) {
|
166 | if (isTypeScriptEnabled || isFlowEnabled) {
|
167 | typedParseConditional(noIn);
|
168 | } else {
|
169 | baseParseConditional(noIn);
|
170 | }
|
171 | }
|
172 |
|
173 | export function baseParseConditional(noIn) {
|
174 | if (eat(tt.question)) {
|
175 | parseMaybeAssign();
|
176 | expect(tt.colon);
|
177 | parseMaybeAssign(noIn);
|
178 | }
|
179 | }
|
180 |
|
181 |
|
182 |
|
183 | function parseExprOps(noIn) {
|
184 | const startTokenIndex = state.tokens.length;
|
185 | const wasArrow = parseMaybeUnary();
|
186 | if (wasArrow) {
|
187 | return true;
|
188 | }
|
189 | parseExprOp(startTokenIndex, -1, noIn);
|
190 | return false;
|
191 | }
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 | function parseExprOp(startTokenIndex, minPrec, noIn) {
|
199 | if (
|
200 | isTypeScriptEnabled &&
|
201 | (tt._in & TokenType.PRECEDENCE_MASK) > minPrec &&
|
202 | !hasPrecedingLineBreak() &&
|
203 | eatContextual(ContextualKeyword._as)
|
204 | ) {
|
205 | state.tokens[state.tokens.length - 1].type = tt._as;
|
206 | const oldIsType = pushTypeContext(1);
|
207 | tsParseType();
|
208 | popTypeContext(oldIsType);
|
209 | parseExprOp(startTokenIndex, minPrec, noIn);
|
210 | return;
|
211 | }
|
212 |
|
213 | const prec = state.type & TokenType.PRECEDENCE_MASK;
|
214 | if (prec > 0 && (!noIn || !match(tt._in))) {
|
215 | if (prec > minPrec) {
|
216 | const op = state.type;
|
217 | next();
|
218 | if (op === tt.nullishCoalescing) {
|
219 | state.tokens[state.tokens.length - 1].nullishStartIndex = startTokenIndex;
|
220 | }
|
221 |
|
222 | const rhsStartTokenIndex = state.tokens.length;
|
223 | parseMaybeUnary();
|
224 |
|
225 | parseExprOp(rhsStartTokenIndex, op & TokenType.IS_RIGHT_ASSOCIATIVE ? prec - 1 : prec, noIn);
|
226 | if (op === tt.nullishCoalescing) {
|
227 | state.tokens[startTokenIndex].numNullishCoalesceStarts++;
|
228 | state.tokens[state.tokens.length - 1].numNullishCoalesceEnds++;
|
229 | }
|
230 |
|
231 | parseExprOp(startTokenIndex, minPrec, noIn);
|
232 | }
|
233 | }
|
234 | }
|
235 |
|
236 |
|
237 |
|
238 | export function parseMaybeUnary() {
|
239 | if (isTypeScriptEnabled && !isJSXEnabled && eat(tt.lessThan)) {
|
240 | tsParseTypeAssertion();
|
241 | return false;
|
242 | }
|
243 | if (
|
244 | isContextual(ContextualKeyword._module) &&
|
245 | lookaheadCharCode() === charCodes.leftCurlyBrace &&
|
246 | !hasFollowingLineBreak()
|
247 | ) {
|
248 | parseModuleExpression();
|
249 | return false;
|
250 | }
|
251 | if (state.type & TokenType.IS_PREFIX) {
|
252 | next();
|
253 | parseMaybeUnary();
|
254 | return false;
|
255 | }
|
256 |
|
257 | const wasArrow = parseExprSubscripts();
|
258 | if (wasArrow) {
|
259 | return true;
|
260 | }
|
261 | while (state.type & TokenType.IS_POSTFIX && !canInsertSemicolon()) {
|
262 |
|
263 |
|
264 | if (state.type === tt.preIncDec) {
|
265 | state.type = tt.postIncDec;
|
266 | }
|
267 | next();
|
268 | }
|
269 | return false;
|
270 | }
|
271 |
|
272 |
|
273 |
|
274 | export function parseExprSubscripts() {
|
275 | const startTokenIndex = state.tokens.length;
|
276 | const wasArrow = parseExprAtom();
|
277 | if (wasArrow) {
|
278 | return true;
|
279 | }
|
280 | parseSubscripts(startTokenIndex);
|
281 |
|
282 |
|
283 | if (state.tokens.length > startTokenIndex && state.tokens[startTokenIndex].isOptionalChainStart) {
|
284 | state.tokens[state.tokens.length - 1].isOptionalChainEnd = true;
|
285 | }
|
286 | return false;
|
287 | }
|
288 |
|
289 | function parseSubscripts(startTokenIndex, noCalls = false) {
|
290 | if (isFlowEnabled) {
|
291 | flowParseSubscripts(startTokenIndex, noCalls);
|
292 | } else {
|
293 | baseParseSubscripts(startTokenIndex, noCalls);
|
294 | }
|
295 | }
|
296 |
|
297 | export function baseParseSubscripts(startTokenIndex, noCalls = false) {
|
298 | const stopState = new StopState(false);
|
299 | do {
|
300 | parseSubscript(startTokenIndex, noCalls, stopState);
|
301 | } while (!stopState.stop && !state.error);
|
302 | }
|
303 |
|
304 | function parseSubscript(startTokenIndex, noCalls, stopState) {
|
305 | if (isTypeScriptEnabled) {
|
306 | tsParseSubscript(startTokenIndex, noCalls, stopState);
|
307 | } else if (isFlowEnabled) {
|
308 | flowParseSubscript(startTokenIndex, noCalls, stopState);
|
309 | } else {
|
310 | baseParseSubscript(startTokenIndex, noCalls, stopState);
|
311 | }
|
312 | }
|
313 |
|
314 |
|
315 | export function baseParseSubscript(
|
316 | startTokenIndex,
|
317 | noCalls,
|
318 | stopState,
|
319 | ) {
|
320 | if (!noCalls && eat(tt.doubleColon)) {
|
321 | parseNoCallExpr();
|
322 | stopState.stop = true;
|
323 |
|
324 |
|
325 | parseSubscripts(startTokenIndex, noCalls);
|
326 | } else if (match(tt.questionDot)) {
|
327 | state.tokens[startTokenIndex].isOptionalChainStart = true;
|
328 | if (noCalls && lookaheadType() === tt.parenL) {
|
329 | stopState.stop = true;
|
330 | return;
|
331 | }
|
332 | next();
|
333 | state.tokens[state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
|
334 |
|
335 | if (eat(tt.bracketL)) {
|
336 | parseExpression();
|
337 | expect(tt.bracketR);
|
338 | } else if (eat(tt.parenL)) {
|
339 | parseCallExpressionArguments();
|
340 | } else {
|
341 | parseMaybePrivateName();
|
342 | }
|
343 | } else if (eat(tt.dot)) {
|
344 | state.tokens[state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
|
345 | parseMaybePrivateName();
|
346 | } else if (eat(tt.bracketL)) {
|
347 | state.tokens[state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
|
348 | parseExpression();
|
349 | expect(tt.bracketR);
|
350 | } else if (!noCalls && match(tt.parenL)) {
|
351 | if (atPossibleAsync()) {
|
352 |
|
353 |
|
354 | const snapshot = state.snapshot();
|
355 | const asyncStartTokenIndex = state.tokens.length;
|
356 | next();
|
357 | state.tokens[state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
|
358 |
|
359 | const callContextId = getNextContextId();
|
360 |
|
361 | state.tokens[state.tokens.length - 1].contextId = callContextId;
|
362 | parseCallExpressionArguments();
|
363 | state.tokens[state.tokens.length - 1].contextId = callContextId;
|
364 |
|
365 | if (shouldParseAsyncArrow()) {
|
366 |
|
367 | state.restoreFromSnapshot(snapshot);
|
368 | stopState.stop = true;
|
369 | state.scopeDepth++;
|
370 |
|
371 | parseFunctionParams();
|
372 | parseAsyncArrowFromCallExpression(asyncStartTokenIndex);
|
373 | }
|
374 | } else {
|
375 | next();
|
376 | state.tokens[state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
|
377 | const callContextId = getNextContextId();
|
378 | state.tokens[state.tokens.length - 1].contextId = callContextId;
|
379 | parseCallExpressionArguments();
|
380 | state.tokens[state.tokens.length - 1].contextId = callContextId;
|
381 | }
|
382 | } else if (match(tt.backQuote)) {
|
383 |
|
384 | parseTemplate();
|
385 | } else {
|
386 | stopState.stop = true;
|
387 | }
|
388 | }
|
389 |
|
390 | export function atPossibleAsync() {
|
391 |
|
392 |
|
393 | return (
|
394 | state.tokens[state.tokens.length - 1].contextualKeyword === ContextualKeyword._async &&
|
395 | !canInsertSemicolon()
|
396 | );
|
397 | }
|
398 |
|
399 | export function parseCallExpressionArguments() {
|
400 | let first = true;
|
401 | while (!eat(tt.parenR) && !state.error) {
|
402 | if (first) {
|
403 | first = false;
|
404 | } else {
|
405 | expect(tt.comma);
|
406 | if (eat(tt.parenR)) {
|
407 | break;
|
408 | }
|
409 | }
|
410 |
|
411 | parseExprListItem(false);
|
412 | }
|
413 | }
|
414 |
|
415 | function shouldParseAsyncArrow() {
|
416 | return match(tt.colon) || match(tt.arrow);
|
417 | }
|
418 |
|
419 | function parseAsyncArrowFromCallExpression(startTokenIndex) {
|
420 | if (isTypeScriptEnabled) {
|
421 | tsStartParseAsyncArrowFromCallExpression();
|
422 | } else if (isFlowEnabled) {
|
423 | flowStartParseAsyncArrowFromCallExpression();
|
424 | }
|
425 | expect(tt.arrow);
|
426 | parseArrowExpression(startTokenIndex);
|
427 | }
|
428 |
|
429 |
|
430 |
|
431 | function parseNoCallExpr() {
|
432 | const startTokenIndex = state.tokens.length;
|
433 | parseExprAtom();
|
434 | parseSubscripts(startTokenIndex, true);
|
435 | }
|
436 |
|
437 |
|
438 |
|
439 |
|
440 |
|
441 |
|
442 | export function parseExprAtom() {
|
443 | if (eat(tt.modulo)) {
|
444 |
|
445 |
|
446 | parseIdentifier();
|
447 | return false;
|
448 | }
|
449 |
|
450 | if (match(tt.jsxText)) {
|
451 | parseLiteral();
|
452 | return false;
|
453 | } else if (match(tt.lessThan) && isJSXEnabled) {
|
454 | state.type = tt.jsxTagStart;
|
455 | jsxParseElement();
|
456 | next();
|
457 | return false;
|
458 | }
|
459 |
|
460 | const canBeArrow = state.potentialArrowAt === state.start;
|
461 | switch (state.type) {
|
462 | case tt.slash:
|
463 | case tt.assign:
|
464 | retokenizeSlashAsRegex();
|
465 |
|
466 |
|
467 | case tt._super:
|
468 | case tt._this:
|
469 | case tt.regexp:
|
470 | case tt.num:
|
471 | case tt.bigint:
|
472 | case tt.decimal:
|
473 | case tt.string:
|
474 | case tt._null:
|
475 | case tt._true:
|
476 | case tt._false:
|
477 | next();
|
478 | return false;
|
479 |
|
480 | case tt._import:
|
481 | next();
|
482 | if (match(tt.dot)) {
|
483 |
|
484 | state.tokens[state.tokens.length - 1].type = tt.name;
|
485 | next();
|
486 | parseIdentifier();
|
487 | }
|
488 | return false;
|
489 |
|
490 | case tt.name: {
|
491 | const startTokenIndex = state.tokens.length;
|
492 | const functionStart = state.start;
|
493 | const contextualKeyword = state.contextualKeyword;
|
494 | parseIdentifier();
|
495 | if (contextualKeyword === ContextualKeyword._await) {
|
496 | parseAwait();
|
497 | return false;
|
498 | } else if (
|
499 | contextualKeyword === ContextualKeyword._async &&
|
500 | match(tt._function) &&
|
501 | !canInsertSemicolon()
|
502 | ) {
|
503 | next();
|
504 | parseFunction(functionStart, false);
|
505 | return false;
|
506 | } else if (
|
507 | canBeArrow &&
|
508 | contextualKeyword === ContextualKeyword._async &&
|
509 | !canInsertSemicolon() &&
|
510 | match(tt.name)
|
511 | ) {
|
512 | state.scopeDepth++;
|
513 | parseBindingIdentifier(false);
|
514 | expect(tt.arrow);
|
515 |
|
516 | parseArrowExpression(startTokenIndex);
|
517 | return true;
|
518 | } else if (match(tt._do) && !canInsertSemicolon()) {
|
519 | next();
|
520 | parseBlock();
|
521 | return false;
|
522 | }
|
523 |
|
524 | if (canBeArrow && !canInsertSemicolon() && match(tt.arrow)) {
|
525 | state.scopeDepth++;
|
526 | markPriorBindingIdentifier(false);
|
527 | expect(tt.arrow);
|
528 | parseArrowExpression(startTokenIndex);
|
529 | return true;
|
530 | }
|
531 |
|
532 | state.tokens[state.tokens.length - 1].identifierRole = IdentifierRole.Access;
|
533 | return false;
|
534 | }
|
535 |
|
536 | case tt._do: {
|
537 | next();
|
538 | parseBlock();
|
539 | return false;
|
540 | }
|
541 |
|
542 | case tt.parenL: {
|
543 | const wasArrow = parseParenAndDistinguishExpression(canBeArrow);
|
544 | return wasArrow;
|
545 | }
|
546 |
|
547 | case tt.bracketL:
|
548 | next();
|
549 | parseExprList(tt.bracketR, true);
|
550 | return false;
|
551 |
|
552 | case tt.braceL:
|
553 | parseObj(false, false);
|
554 | return false;
|
555 |
|
556 | case tt._function:
|
557 | parseFunctionExpression();
|
558 | return false;
|
559 |
|
560 | case tt.at:
|
561 | parseDecorators();
|
562 |
|
563 |
|
564 | case tt._class:
|
565 | parseClass(false);
|
566 | return false;
|
567 |
|
568 | case tt._new:
|
569 | parseNew();
|
570 | return false;
|
571 |
|
572 | case tt.backQuote:
|
573 | parseTemplate();
|
574 | return false;
|
575 |
|
576 | case tt.doubleColon: {
|
577 | next();
|
578 | parseNoCallExpr();
|
579 | return false;
|
580 | }
|
581 |
|
582 | case tt.hash: {
|
583 | const code = lookaheadCharCode();
|
584 | if (IS_IDENTIFIER_START[code] || code === charCodes.backslash) {
|
585 | parseMaybePrivateName();
|
586 | } else {
|
587 | next();
|
588 | }
|
589 |
|
590 | return false;
|
591 | }
|
592 |
|
593 | default:
|
594 | unexpected();
|
595 | return false;
|
596 | }
|
597 | }
|
598 |
|
599 | function parseMaybePrivateName() {
|
600 | eat(tt.hash);
|
601 | parseIdentifier();
|
602 | }
|
603 |
|
604 | function parseFunctionExpression() {
|
605 | const functionStart = state.start;
|
606 | parseIdentifier();
|
607 | if (eat(tt.dot)) {
|
608 |
|
609 | parseIdentifier();
|
610 | }
|
611 | parseFunction(functionStart, false);
|
612 | }
|
613 |
|
614 | export function parseLiteral() {
|
615 | next();
|
616 | }
|
617 |
|
618 | export function parseParenExpression() {
|
619 | expect(tt.parenL);
|
620 | parseExpression();
|
621 | expect(tt.parenR);
|
622 | }
|
623 |
|
624 |
|
625 | function parseParenAndDistinguishExpression(canBeArrow) {
|
626 |
|
627 |
|
628 | const snapshot = state.snapshot();
|
629 |
|
630 | const startTokenIndex = state.tokens.length;
|
631 | expect(tt.parenL);
|
632 |
|
633 | let first = true;
|
634 |
|
635 | while (!match(tt.parenR) && !state.error) {
|
636 | if (first) {
|
637 | first = false;
|
638 | } else {
|
639 | expect(tt.comma);
|
640 | if (match(tt.parenR)) {
|
641 | break;
|
642 | }
|
643 | }
|
644 |
|
645 | if (match(tt.ellipsis)) {
|
646 | parseRest(false );
|
647 | parseParenItem();
|
648 | break;
|
649 | } else {
|
650 | parseMaybeAssign(false, true);
|
651 | }
|
652 | }
|
653 |
|
654 | expect(tt.parenR);
|
655 |
|
656 | if (canBeArrow && shouldParseArrow()) {
|
657 | const wasArrow = parseArrow();
|
658 | if (wasArrow) {
|
659 |
|
660 |
|
661 | state.restoreFromSnapshot(snapshot);
|
662 | state.scopeDepth++;
|
663 |
|
664 | parseFunctionParams();
|
665 | parseArrow();
|
666 | parseArrowExpression(startTokenIndex);
|
667 | return true;
|
668 | }
|
669 | }
|
670 |
|
671 | return false;
|
672 | }
|
673 |
|
674 | function shouldParseArrow() {
|
675 | return match(tt.colon) || !canInsertSemicolon();
|
676 | }
|
677 |
|
678 |
|
679 | export function parseArrow() {
|
680 | if (isTypeScriptEnabled) {
|
681 | return tsParseArrow();
|
682 | } else if (isFlowEnabled) {
|
683 | return flowParseArrow();
|
684 | } else {
|
685 | return eat(tt.arrow);
|
686 | }
|
687 | }
|
688 |
|
689 | function parseParenItem() {
|
690 | if (isTypeScriptEnabled || isFlowEnabled) {
|
691 | typedParseParenItem();
|
692 | }
|
693 | }
|
694 |
|
695 |
|
696 |
|
697 |
|
698 |
|
699 |
|
700 | function parseNew() {
|
701 | expect(tt._new);
|
702 | if (eat(tt.dot)) {
|
703 |
|
704 | parseIdentifier();
|
705 | return;
|
706 | }
|
707 | parseNoCallExpr();
|
708 | eat(tt.questionDot);
|
709 | parseNewArguments();
|
710 | }
|
711 |
|
712 | function parseNewArguments() {
|
713 | if (isTypeScriptEnabled) {
|
714 | tsStartParseNewArguments();
|
715 | } else if (isFlowEnabled) {
|
716 | flowStartParseNewArguments();
|
717 | }
|
718 | if (eat(tt.parenL)) {
|
719 | parseExprList(tt.parenR);
|
720 | }
|
721 | }
|
722 |
|
723 | export function parseTemplate() {
|
724 |
|
725 | nextTemplateToken();
|
726 |
|
727 | nextTemplateToken();
|
728 | while (!match(tt.backQuote) && !state.error) {
|
729 | expect(tt.dollarBraceL);
|
730 | parseExpression();
|
731 |
|
732 | nextTemplateToken();
|
733 |
|
734 | nextTemplateToken();
|
735 | }
|
736 | next();
|
737 | }
|
738 |
|
739 |
|
740 | export function parseObj(isPattern, isBlockScope) {
|
741 |
|
742 | const contextId = getNextContextId();
|
743 | let first = true;
|
744 |
|
745 | next();
|
746 | state.tokens[state.tokens.length - 1].contextId = contextId;
|
747 |
|
748 | while (!eat(tt.braceR) && !state.error) {
|
749 | if (first) {
|
750 | first = false;
|
751 | } else {
|
752 | expect(tt.comma);
|
753 | if (eat(tt.braceR)) {
|
754 | break;
|
755 | }
|
756 | }
|
757 |
|
758 | let isGenerator = false;
|
759 | if (match(tt.ellipsis)) {
|
760 | const previousIndex = state.tokens.length;
|
761 | parseSpread();
|
762 | if (isPattern) {
|
763 |
|
764 | if (state.tokens.length === previousIndex + 2) {
|
765 | markPriorBindingIdentifier(isBlockScope);
|
766 | }
|
767 | if (eat(tt.braceR)) {
|
768 | break;
|
769 | }
|
770 | }
|
771 | continue;
|
772 | }
|
773 |
|
774 | if (!isPattern) {
|
775 | isGenerator = eat(tt.star);
|
776 | }
|
777 |
|
778 | if (!isPattern && isContextual(ContextualKeyword._async)) {
|
779 | if (isGenerator) unexpected();
|
780 |
|
781 | parseIdentifier();
|
782 | if (
|
783 | match(tt.colon) ||
|
784 | match(tt.parenL) ||
|
785 | match(tt.braceR) ||
|
786 | match(tt.eq) ||
|
787 | match(tt.comma)
|
788 | ) {
|
789 |
|
790 | } else {
|
791 | if (match(tt.star)) {
|
792 | next();
|
793 | isGenerator = true;
|
794 | }
|
795 | parsePropertyName(contextId);
|
796 | }
|
797 | } else {
|
798 | parsePropertyName(contextId);
|
799 | }
|
800 |
|
801 | parseObjPropValue(isPattern, isBlockScope, contextId);
|
802 | }
|
803 |
|
804 | state.tokens[state.tokens.length - 1].contextId = contextId;
|
805 | }
|
806 |
|
807 | function isGetterOrSetterMethod(isPattern) {
|
808 |
|
809 |
|
810 | return (
|
811 | !isPattern &&
|
812 | (match(tt.string) ||
|
813 | match(tt.num) ||
|
814 | match(tt.bracketL) ||
|
815 | match(tt.name) ||
|
816 | !!(state.type & TokenType.IS_KEYWORD))
|
817 | );
|
818 | }
|
819 |
|
820 |
|
821 | function parseObjectMethod(isPattern, objectContextId) {
|
822 |
|
823 |
|
824 | const functionStart = state.start;
|
825 | if (match(tt.parenL)) {
|
826 | if (isPattern) unexpected();
|
827 | parseMethod(functionStart, false);
|
828 | return true;
|
829 | }
|
830 |
|
831 | if (isGetterOrSetterMethod(isPattern)) {
|
832 | parsePropertyName(objectContextId);
|
833 | parseMethod(functionStart, false);
|
834 | return true;
|
835 | }
|
836 | return false;
|
837 | }
|
838 |
|
839 | function parseObjectProperty(isPattern, isBlockScope) {
|
840 | if (eat(tt.colon)) {
|
841 | if (isPattern) {
|
842 | parseMaybeDefault(isBlockScope);
|
843 | } else {
|
844 | parseMaybeAssign(false);
|
845 | }
|
846 | return;
|
847 | }
|
848 |
|
849 |
|
850 |
|
851 |
|
852 |
|
853 |
|
854 | let identifierRole;
|
855 | if (isPattern) {
|
856 | if (state.scopeDepth === 0) {
|
857 | identifierRole = IdentifierRole.ObjectShorthandTopLevelDeclaration;
|
858 | } else if (isBlockScope) {
|
859 | identifierRole = IdentifierRole.ObjectShorthandBlockScopedDeclaration;
|
860 | } else {
|
861 | identifierRole = IdentifierRole.ObjectShorthandFunctionScopedDeclaration;
|
862 | }
|
863 | } else {
|
864 | identifierRole = IdentifierRole.ObjectShorthand;
|
865 | }
|
866 | state.tokens[state.tokens.length - 1].identifierRole = identifierRole;
|
867 |
|
868 |
|
869 |
|
870 | parseMaybeDefault(isBlockScope, true);
|
871 | }
|
872 |
|
873 | function parseObjPropValue(
|
874 | isPattern,
|
875 | isBlockScope,
|
876 | objectContextId,
|
877 | ) {
|
878 | if (isTypeScriptEnabled) {
|
879 | tsStartParseObjPropValue();
|
880 | } else if (isFlowEnabled) {
|
881 | flowStartParseObjPropValue();
|
882 | }
|
883 | const wasMethod = parseObjectMethod(isPattern, objectContextId);
|
884 | if (!wasMethod) {
|
885 | parseObjectProperty(isPattern, isBlockScope);
|
886 | }
|
887 | }
|
888 |
|
889 | export function parsePropertyName(objectContextId) {
|
890 | if (isFlowEnabled) {
|
891 | flowParseVariance();
|
892 | }
|
893 | if (eat(tt.bracketL)) {
|
894 | state.tokens[state.tokens.length - 1].contextId = objectContextId;
|
895 | parseMaybeAssign();
|
896 | expect(tt.bracketR);
|
897 | state.tokens[state.tokens.length - 1].contextId = objectContextId;
|
898 | } else {
|
899 | if (match(tt.num) || match(tt.string) || match(tt.bigint) || match(tt.decimal)) {
|
900 | parseExprAtom();
|
901 | } else {
|
902 | parseMaybePrivateName();
|
903 | }
|
904 |
|
905 | state.tokens[state.tokens.length - 1].identifierRole = IdentifierRole.ObjectKey;
|
906 | state.tokens[state.tokens.length - 1].contextId = objectContextId;
|
907 | }
|
908 | }
|
909 |
|
910 |
|
911 | export function parseMethod(functionStart, isConstructor) {
|
912 | const funcContextId = getNextContextId();
|
913 |
|
914 | state.scopeDepth++;
|
915 | const startTokenIndex = state.tokens.length;
|
916 | const allowModifiers = isConstructor;
|
917 | parseFunctionParams(allowModifiers, funcContextId);
|
918 | parseFunctionBodyAndFinish(functionStart, funcContextId);
|
919 | const endTokenIndex = state.tokens.length;
|
920 | state.scopes.push(new Scope(startTokenIndex, endTokenIndex, true));
|
921 | state.scopeDepth--;
|
922 | }
|
923 |
|
924 |
|
925 |
|
926 |
|
927 | export function parseArrowExpression(startTokenIndex) {
|
928 | parseFunctionBody(true);
|
929 | const endTokenIndex = state.tokens.length;
|
930 | state.scopes.push(new Scope(startTokenIndex, endTokenIndex, true));
|
931 | state.scopeDepth--;
|
932 | }
|
933 |
|
934 | export function parseFunctionBodyAndFinish(functionStart, funcContextId = 0) {
|
935 | if (isTypeScriptEnabled) {
|
936 | tsParseFunctionBodyAndFinish(functionStart, funcContextId);
|
937 | } else if (isFlowEnabled) {
|
938 | flowParseFunctionBodyAndFinish(funcContextId);
|
939 | } else {
|
940 | parseFunctionBody(false, funcContextId);
|
941 | }
|
942 | }
|
943 |
|
944 | export function parseFunctionBody(allowExpression, funcContextId = 0) {
|
945 | const isExpression = allowExpression && !match(tt.braceL);
|
946 |
|
947 | if (isExpression) {
|
948 | parseMaybeAssign();
|
949 | } else {
|
950 | parseBlock(true , funcContextId);
|
951 | }
|
952 | }
|
953 |
|
954 |
|
955 |
|
956 |
|
957 |
|
958 |
|
959 |
|
960 | function parseExprList(close, allowEmpty = false) {
|
961 | let first = true;
|
962 | while (!eat(close) && !state.error) {
|
963 | if (first) {
|
964 | first = false;
|
965 | } else {
|
966 | expect(tt.comma);
|
967 | if (eat(close)) break;
|
968 | }
|
969 | parseExprListItem(allowEmpty);
|
970 | }
|
971 | }
|
972 |
|
973 | function parseExprListItem(allowEmpty) {
|
974 | if (allowEmpty && match(tt.comma)) {
|
975 |
|
976 | } else if (match(tt.ellipsis)) {
|
977 | parseSpread();
|
978 | parseParenItem();
|
979 | } else if (match(tt.question)) {
|
980 |
|
981 | next();
|
982 | } else {
|
983 | parseMaybeAssign(false, true);
|
984 | }
|
985 | }
|
986 |
|
987 |
|
988 | export function parseIdentifier() {
|
989 | next();
|
990 | state.tokens[state.tokens.length - 1].type = tt.name;
|
991 | }
|
992 |
|
993 |
|
994 | function parseAwait() {
|
995 | parseMaybeUnary();
|
996 | }
|
997 |
|
998 |
|
999 | function parseYield() {
|
1000 | next();
|
1001 | if (!match(tt.semi) && !canInsertSemicolon()) {
|
1002 | eat(tt.star);
|
1003 | parseMaybeAssign();
|
1004 | }
|
1005 | }
|
1006 |
|
1007 |
|
1008 | function parseModuleExpression() {
|
1009 | expectContextual(ContextualKeyword._module);
|
1010 | expect(tt.braceL);
|
1011 |
|
1012 |
|
1013 |
|
1014 | parseBlockBody(tt.braceR);
|
1015 | }
|