Packages
moon
2.90.1
2.90.5
retired
2.90.4
2.90.3
2.90.2
2.90.1
2.90.0
2.89.4
2.89.1
2.89.0
2.88.0
2.87.11
2.87.10
2.87.9
2.87.8
2.87.7
2.87.6
2.87.5
2.87.4
2.87.3
2.87.2
2.87.1
2.87.0
2.86.1
2.86.0
2.85.1
2.85.0
2.84.0
2.83.0
2.82.0
2.81.4
2.81.3
2.81.2
2.81.1
2.81.0
2.80.2
2.80.1
2.80.0
2.79.13
2.79.12
2.79.11
2.79.10
2.79.9
2.79.8
2.79.7
2.79.6
2.79.5
2.79.4
2.79.3
2.79.2
2.79.1
2.79.0
2.78.4
2.78.3
2.78.2
2.78.1
2.78.0
2.77.0
2.76.5
2.76.4
2.76.3
2.76.2
2.76.1
2.76.0
2.75.0
2.74.1
2.74.0
2.73.8
2.73.7
2.73.6
2.73.5
2.73.4
2.73.3
2.73.2
2.73.1
2.73.0
2.72.5
2.72.4
2.72.3
2.72.2
2.72.1
2.72.0
2.71.1
2.71.0
2.70.0
2.69.2
2.69.1
2.69.0
2.68.11
2.68.10
Components-based design system written in elixir
Current section
Files
Jump to
Current section
Files
assets/node_modules/sucrase/dist/parser/traverser/expression.js
"use strict";Object.defineProperty(exports, "__esModule", {value: true});/* eslint max-len: 0 */
// A recursive descent parser operates by defining functions for all
// syntactic elements, and recursively calling those, each function
// advancing the input stream and returning an AST node. Precedence
// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
// instead of `(!x)[1]` is handled by the fact that the parser
// function that parses unary prefix operators is called first, and
// in turn calls the function that parses `[]` subscripts — that
// way, it'll receive the node for `x[1]` already parsed, and wraps
// *that* in the unary operator node.
//
// Acorn uses an [operator precedence parser][opp] to handle binary
// operator precedence, because it is much more compact than using
// the technique outlined above, which uses different, nesting
// functions to specify precedence, for all of the ten binary
// precedence levels that JavaScript defines.
//
// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
var _flow = require('../plugins/flow');
var _index = require('../plugins/jsx/index');
var _types = require('../plugins/types');
var _typescript = require('../plugins/typescript');
var _index3 = require('../tokenizer/index');
var _keywords = require('../tokenizer/keywords');
var _state = require('../tokenizer/state');
var _types3 = require('../tokenizer/types');
var _charcodes = require('../util/charcodes');
var _identifier = require('../util/identifier');
var _base = require('./base');
var _lval = require('./lval');
var _statement = require('./statement');
var _util = require('./util');
class StopState {
constructor(stop) {
this.stop = stop;
}
} exports.StopState = StopState;
// ### Expression parsing
// These nest, from the most general expression type at the top to
// 'atomic', nondivisible expression types at the bottom. Most of
// the functions will simply let the function (s) below them parse,
// and, *if* the syntactic construct they handle is present, wrap
// the AST node that the inner parser gave them in another node.
function parseExpression(noIn = false) {
parseMaybeAssign(noIn);
if (_index3.match.call(void 0, _types3.TokenType.comma)) {
while (_index3.eat.call(void 0, _types3.TokenType.comma)) {
parseMaybeAssign(noIn);
}
}
} exports.parseExpression = parseExpression;
/**
* noIn is used when parsing a for loop so that we don't interpret a following "in" as the binary
* operatior.
* isWithinParens is used to indicate that we're parsing something that might be a comma expression
* or might be an arrow function or might be a Flow type assertion (which requires explicit parens).
* In these cases, we should allow : and ?: after the initial "left" part.
*/
function parseMaybeAssign(noIn = false, isWithinParens = false) {
if (_base.isTypeScriptEnabled) {
return _typescript.tsParseMaybeAssign.call(void 0, noIn, isWithinParens);
} else if (_base.isFlowEnabled) {
return _flow.flowParseMaybeAssign.call(void 0, noIn, isWithinParens);
} else {
return baseParseMaybeAssign(noIn, isWithinParens);
}
} exports.parseMaybeAssign = parseMaybeAssign;
// Parse an assignment expression. This includes applications of
// operators like `+=`.
// Returns true if the expression was an arrow function.
function baseParseMaybeAssign(noIn, isWithinParens) {
if (_index3.match.call(void 0, _types3.TokenType._yield)) {
parseYield();
return false;
}
if (_index3.match.call(void 0, _types3.TokenType.parenL) || _index3.match.call(void 0, _types3.TokenType.name) || _index3.match.call(void 0, _types3.TokenType._yield)) {
_base.state.potentialArrowAt = _base.state.start;
}
const wasArrow = parseMaybeConditional(noIn);
if (isWithinParens) {
parseParenItem();
}
if (_base.state.type & _types3.TokenType.IS_ASSIGN) {
_index3.next.call(void 0, );
parseMaybeAssign(noIn);
return false;
}
return wasArrow;
} exports.baseParseMaybeAssign = baseParseMaybeAssign;
// Parse a ternary conditional (`?:`) operator.
// Returns true if the expression was an arrow function.
function parseMaybeConditional(noIn) {
const wasArrow = parseExprOps(noIn);
if (wasArrow) {
return true;
}
parseConditional(noIn);
return false;
}
function parseConditional(noIn) {
if (_base.isTypeScriptEnabled || _base.isFlowEnabled) {
_types.typedParseConditional.call(void 0, noIn);
} else {
baseParseConditional(noIn);
}
}
function baseParseConditional(noIn) {
if (_index3.eat.call(void 0, _types3.TokenType.question)) {
parseMaybeAssign();
_util.expect.call(void 0, _types3.TokenType.colon);
parseMaybeAssign(noIn);
}
} exports.baseParseConditional = baseParseConditional;
// Start the precedence parser.
// Returns true if this was an arrow function
function parseExprOps(noIn) {
const startTokenIndex = _base.state.tokens.length;
const wasArrow = parseMaybeUnary();
if (wasArrow) {
return true;
}
parseExprOp(startTokenIndex, -1, noIn);
return false;
}
// Parse binary operators with the operator precedence parsing
// algorithm. `left` is the left-hand side of the operator.
// `minPrec` provides context that allows the function to stop and
// defer further parser to one of its callers when it encounters an
// operator that has a lower precedence than the set it is parsing.
function parseExprOp(startTokenIndex, minPrec, noIn) {
if (
_base.isTypeScriptEnabled &&
(_types3.TokenType._in & _types3.TokenType.PRECEDENCE_MASK) > minPrec &&
!_util.hasPrecedingLineBreak.call(void 0, ) &&
(_util.eatContextual.call(void 0, _keywords.ContextualKeyword._as) || _util.eatContextual.call(void 0, _keywords.ContextualKeyword._satisfies))
) {
const oldIsType = _index3.pushTypeContext.call(void 0, 1);
_typescript.tsParseType.call(void 0, );
_index3.popTypeContext.call(void 0, oldIsType);
_index3.rescan_gt.call(void 0, );
parseExprOp(startTokenIndex, minPrec, noIn);
return;
}
const prec = _base.state.type & _types3.TokenType.PRECEDENCE_MASK;
if (prec > 0 && (!noIn || !_index3.match.call(void 0, _types3.TokenType._in))) {
if (prec > minPrec) {
const op = _base.state.type;
_index3.next.call(void 0, );
if (op === _types3.TokenType.nullishCoalescing) {
_base.state.tokens[_base.state.tokens.length - 1].nullishStartIndex = startTokenIndex;
}
const rhsStartTokenIndex = _base.state.tokens.length;
parseMaybeUnary();
// Extend the right operand of this operator if possible.
parseExprOp(rhsStartTokenIndex, op & _types3.TokenType.IS_RIGHT_ASSOCIATIVE ? prec - 1 : prec, noIn);
if (op === _types3.TokenType.nullishCoalescing) {
_base.state.tokens[startTokenIndex].numNullishCoalesceStarts++;
_base.state.tokens[_base.state.tokens.length - 1].numNullishCoalesceEnds++;
}
// Continue with any future operator holding this expression as the left operand.
parseExprOp(startTokenIndex, minPrec, noIn);
}
}
}
// Parse unary operators, both prefix and postfix.
// Returns true if this was an arrow function.
function parseMaybeUnary() {
if (_base.isTypeScriptEnabled && !_base.isJSXEnabled && _index3.eat.call(void 0, _types3.TokenType.lessThan)) {
_typescript.tsParseTypeAssertion.call(void 0, );
return false;
}
if (
_util.isContextual.call(void 0, _keywords.ContextualKeyword._module) &&
_index3.lookaheadCharCode.call(void 0, ) === _charcodes.charCodes.leftCurlyBrace &&
!_util.hasFollowingLineBreak.call(void 0, )
) {
parseModuleExpression();
return false;
}
if (_base.state.type & _types3.TokenType.IS_PREFIX) {
_index3.next.call(void 0, );
parseMaybeUnary();
return false;
}
const wasArrow = parseExprSubscripts();
if (wasArrow) {
return true;
}
while (_base.state.type & _types3.TokenType.IS_POSTFIX && !_util.canInsertSemicolon.call(void 0, )) {
// The tokenizer calls everything a preincrement, so make it a postincrement when
// we see it in that context.
if (_base.state.type === _types3.TokenType.preIncDec) {
_base.state.type = _types3.TokenType.postIncDec;
}
_index3.next.call(void 0, );
}
return false;
} exports.parseMaybeUnary = parseMaybeUnary;
// Parse call, dot, and `[]`-subscript expressions.
// Returns true if this was an arrow function.
function parseExprSubscripts() {
const startTokenIndex = _base.state.tokens.length;
const wasArrow = parseExprAtom();
if (wasArrow) {
return true;
}
parseSubscripts(startTokenIndex);
// If there was any optional chain operation, the start token would be marked
// as such, so also mark the end now.
if (_base.state.tokens.length > startTokenIndex && _base.state.tokens[startTokenIndex].isOptionalChainStart) {
_base.state.tokens[_base.state.tokens.length - 1].isOptionalChainEnd = true;
}
return false;
} exports.parseExprSubscripts = parseExprSubscripts;
function parseSubscripts(startTokenIndex, noCalls = false) {
if (_base.isFlowEnabled) {
_flow.flowParseSubscripts.call(void 0, startTokenIndex, noCalls);
} else {
baseParseSubscripts(startTokenIndex, noCalls);
}
}
function baseParseSubscripts(startTokenIndex, noCalls = false) {
const stopState = new StopState(false);
do {
parseSubscript(startTokenIndex, noCalls, stopState);
} while (!stopState.stop && !_base.state.error);
} exports.baseParseSubscripts = baseParseSubscripts;
function parseSubscript(startTokenIndex, noCalls, stopState) {
if (_base.isTypeScriptEnabled) {
_typescript.tsParseSubscript.call(void 0, startTokenIndex, noCalls, stopState);
} else if (_base.isFlowEnabled) {
_flow.flowParseSubscript.call(void 0, startTokenIndex, noCalls, stopState);
} else {
baseParseSubscript(startTokenIndex, noCalls, stopState);
}
}
/** Set 'state.stop = true' to indicate that we should stop parsing subscripts. */
function baseParseSubscript(
startTokenIndex,
noCalls,
stopState,
) {
if (!noCalls && _index3.eat.call(void 0, _types3.TokenType.doubleColon)) {
parseNoCallExpr();
stopState.stop = true;
// Propagate startTokenIndex so that `a::b?.()` will keep `a` as the first token. We may want
// to revisit this in the future when fully supporting bind syntax.
parseSubscripts(startTokenIndex, noCalls);
} else if (_index3.match.call(void 0, _types3.TokenType.questionDot)) {
_base.state.tokens[startTokenIndex].isOptionalChainStart = true;
if (noCalls && _index3.lookaheadType.call(void 0, ) === _types3.TokenType.parenL) {
stopState.stop = true;
return;
}
_index3.next.call(void 0, );
_base.state.tokens[_base.state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
if (_index3.eat.call(void 0, _types3.TokenType.bracketL)) {
parseExpression();
_util.expect.call(void 0, _types3.TokenType.bracketR);
} else if (_index3.eat.call(void 0, _types3.TokenType.parenL)) {
parseCallExpressionArguments();
} else {
parseMaybePrivateName();
}
} else if (_index3.eat.call(void 0, _types3.TokenType.dot)) {
_base.state.tokens[_base.state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
parseMaybePrivateName();
} else if (_index3.eat.call(void 0, _types3.TokenType.bracketL)) {
_base.state.tokens[_base.state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
parseExpression();
_util.expect.call(void 0, _types3.TokenType.bracketR);
} else if (!noCalls && _index3.match.call(void 0, _types3.TokenType.parenL)) {
if (atPossibleAsync()) {
// We see "async", but it's possible it's a usage of the name "async". Parse as if it's a
// function call, and if we see an arrow later, backtrack and re-parse as a parameter list.
const snapshot = _base.state.snapshot();
const asyncStartTokenIndex = _base.state.tokens.length;
_index3.next.call(void 0, );
_base.state.tokens[_base.state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
const callContextId = _base.getNextContextId.call(void 0, );
_base.state.tokens[_base.state.tokens.length - 1].contextId = callContextId;
parseCallExpressionArguments();
_base.state.tokens[_base.state.tokens.length - 1].contextId = callContextId;
if (shouldParseAsyncArrow()) {
// We hit an arrow, so backtrack and start again parsing function parameters.
_base.state.restoreFromSnapshot(snapshot);
stopState.stop = true;
_base.state.scopeDepth++;
_statement.parseFunctionParams.call(void 0, );
parseAsyncArrowFromCallExpression(asyncStartTokenIndex);
}
} else {
_index3.next.call(void 0, );
_base.state.tokens[_base.state.tokens.length - 1].subscriptStartIndex = startTokenIndex;
const callContextId = _base.getNextContextId.call(void 0, );
_base.state.tokens[_base.state.tokens.length - 1].contextId = callContextId;
parseCallExpressionArguments();
_base.state.tokens[_base.state.tokens.length - 1].contextId = callContextId;
}
} else if (_index3.match.call(void 0, _types3.TokenType.backQuote)) {
// Tagged template expression.
parseTemplate();
} else {
stopState.stop = true;
}
} exports.baseParseSubscript = baseParseSubscript;
function atPossibleAsync() {
// This was made less strict than the original version to avoid passing around nodes, but it
// should be safe to have rare false positives here.
return (
_base.state.tokens[_base.state.tokens.length - 1].contextualKeyword === _keywords.ContextualKeyword._async &&
!_util.canInsertSemicolon.call(void 0, )
);
} exports.atPossibleAsync = atPossibleAsync;
function parseCallExpressionArguments() {
let first = true;
while (!_index3.eat.call(void 0, _types3.TokenType.parenR) && !_base.state.error) {
if (first) {
first = false;
} else {
_util.expect.call(void 0, _types3.TokenType.comma);
if (_index3.eat.call(void 0, _types3.TokenType.parenR)) {
break;
}
}
parseExprListItem(false);
}
} exports.parseCallExpressionArguments = parseCallExpressionArguments;
function shouldParseAsyncArrow() {
return _index3.match.call(void 0, _types3.TokenType.colon) || _index3.match.call(void 0, _types3.TokenType.arrow);
}
function parseAsyncArrowFromCallExpression(startTokenIndex) {
if (_base.isTypeScriptEnabled) {
_typescript.tsStartParseAsyncArrowFromCallExpression.call(void 0, );
} else if (_base.isFlowEnabled) {
_flow.flowStartParseAsyncArrowFromCallExpression.call(void 0, );
}
_util.expect.call(void 0, _types3.TokenType.arrow);
parseArrowExpression(startTokenIndex);
}
// Parse a no-call expression (like argument of `new` or `::` operators).
function parseNoCallExpr() {
const startTokenIndex = _base.state.tokens.length;
parseExprAtom();
parseSubscripts(startTokenIndex, true);
}
// Parse an atomic expression — either a single token that is an
// expression, an expression started by a keyword like `function` or
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
// or `{}`.
// Returns true if the parsed expression was an arrow function.
function parseExprAtom() {
if (_index3.eat.call(void 0, _types3.TokenType.modulo)) {
// V8 intrinsic expression. Just parse the identifier, and the function invocation is parsed
// naturally.
parseIdentifier();
return false;
}
if (_index3.match.call(void 0, _types3.TokenType.jsxText) || _index3.match.call(void 0, _types3.TokenType.jsxEmptyText)) {
parseLiteral();
return false;
} else if (_index3.match.call(void 0, _types3.TokenType.lessThan) && _base.isJSXEnabled) {
_base.state.type = _types3.TokenType.jsxTagStart;
_index.jsxParseElement.call(void 0, );
_index3.next.call(void 0, );
return false;
}
const canBeArrow = _base.state.potentialArrowAt === _base.state.start;
switch (_base.state.type) {
case _types3.TokenType.slash:
case _types3.TokenType.assign:
_index3.retokenizeSlashAsRegex.call(void 0, );
// Fall through.
case _types3.TokenType._super:
case _types3.TokenType._this:
case _types3.TokenType.regexp:
case _types3.TokenType.num:
case _types3.TokenType.bigint:
case _types3.TokenType.decimal:
case _types3.TokenType.string:
case _types3.TokenType._null:
case _types3.TokenType._true:
case _types3.TokenType._false:
_index3.next.call(void 0, );
return false;
case _types3.TokenType._import:
_index3.next.call(void 0, );
if (_index3.match.call(void 0, _types3.TokenType.dot)) {
// import.meta
_base.state.tokens[_base.state.tokens.length - 1].type = _types3.TokenType.name;
_index3.next.call(void 0, );
parseIdentifier();
}
return false;
case _types3.TokenType.name: {
const startTokenIndex = _base.state.tokens.length;
const functionStart = _base.state.start;
const contextualKeyword = _base.state.contextualKeyword;
parseIdentifier();
if (contextualKeyword === _keywords.ContextualKeyword._await) {
parseAwait();
return false;
} else if (
contextualKeyword === _keywords.ContextualKeyword._async &&
_index3.match.call(void 0, _types3.TokenType._function) &&
!_util.canInsertSemicolon.call(void 0, )
) {
_index3.next.call(void 0, );
_statement.parseFunction.call(void 0, functionStart, false);
return false;
} else if (
canBeArrow &&
contextualKeyword === _keywords.ContextualKeyword._async &&
!_util.canInsertSemicolon.call(void 0, ) &&
_index3.match.call(void 0, _types3.TokenType.name)
) {
_base.state.scopeDepth++;
_lval.parseBindingIdentifier.call(void 0, false);
_util.expect.call(void 0, _types3.TokenType.arrow);
// let foo = async bar => {};
parseArrowExpression(startTokenIndex);
return true;
} else if (_index3.match.call(void 0, _types3.TokenType._do) && !_util.canInsertSemicolon.call(void 0, )) {
_index3.next.call(void 0, );
_statement.parseBlock.call(void 0, );
return false;
}
if (canBeArrow && !_util.canInsertSemicolon.call(void 0, ) && _index3.match.call(void 0, _types3.TokenType.arrow)) {
_base.state.scopeDepth++;
_lval.markPriorBindingIdentifier.call(void 0, false);
_util.expect.call(void 0, _types3.TokenType.arrow);
parseArrowExpression(startTokenIndex);
return true;
}
_base.state.tokens[_base.state.tokens.length - 1].identifierRole = _index3.IdentifierRole.Access;
return false;
}
case _types3.TokenType._do: {
_index3.next.call(void 0, );
_statement.parseBlock.call(void 0, );
return false;
}
case _types3.TokenType.parenL: {
const wasArrow = parseParenAndDistinguishExpression(canBeArrow);
return wasArrow;
}
case _types3.TokenType.bracketL:
_index3.next.call(void 0, );
parseExprList(_types3.TokenType.bracketR, true);
return false;
case _types3.TokenType.braceL:
parseObj(false, false);
return false;
case _types3.TokenType._function:
parseFunctionExpression();
return false;
case _types3.TokenType.at:
_statement.parseDecorators.call(void 0, );
// Fall through.
case _types3.TokenType._class:
_statement.parseClass.call(void 0, false);
return false;
case _types3.TokenType._new:
parseNew();
return false;
case _types3.TokenType.backQuote:
parseTemplate();
return false;
case _types3.TokenType.doubleColon: {
_index3.next.call(void 0, );
parseNoCallExpr();
return false;
}
case _types3.TokenType.hash: {
const code = _index3.lookaheadCharCode.call(void 0, );
if (_identifier.IS_IDENTIFIER_START[code] || code === _charcodes.charCodes.backslash) {
parseMaybePrivateName();
} else {
_index3.next.call(void 0, );
}
// Smart pipeline topic reference.
return false;
}
default:
_util.unexpected.call(void 0, );
return false;
}
} exports.parseExprAtom = parseExprAtom;
function parseMaybePrivateName() {
_index3.eat.call(void 0, _types3.TokenType.hash);
parseIdentifier();
}
function parseFunctionExpression() {
const functionStart = _base.state.start;
parseIdentifier();
if (_index3.eat.call(void 0, _types3.TokenType.dot)) {
// function.sent
parseIdentifier();
}
_statement.parseFunction.call(void 0, functionStart, false);
}
function parseLiteral() {
_index3.next.call(void 0, );
} exports.parseLiteral = parseLiteral;
function parseParenExpression() {
_util.expect.call(void 0, _types3.TokenType.parenL);
parseExpression();
_util.expect.call(void 0, _types3.TokenType.parenR);
} exports.parseParenExpression = parseParenExpression;
// Returns true if this was an arrow expression.
function parseParenAndDistinguishExpression(canBeArrow) {
// Assume this is a normal parenthesized expression, but if we see an arrow, we'll bail and
// start over as a parameter list.
const snapshot = _base.state.snapshot();
const startTokenIndex = _base.state.tokens.length;
_util.expect.call(void 0, _types3.TokenType.parenL);
let first = true;
while (!_index3.match.call(void 0, _types3.TokenType.parenR) && !_base.state.error) {
if (first) {
first = false;
} else {
_util.expect.call(void 0, _types3.TokenType.comma);
if (_index3.match.call(void 0, _types3.TokenType.parenR)) {
break;
}
}
if (_index3.match.call(void 0, _types3.TokenType.ellipsis)) {
_lval.parseRest.call(void 0, false /* isBlockScope */);
parseParenItem();
break;
} else {
parseMaybeAssign(false, true);
}
}
_util.expect.call(void 0, _types3.TokenType.parenR);
if (canBeArrow && shouldParseArrow()) {
const wasArrow = parseArrow();
if (wasArrow) {
// It was an arrow function this whole time, so start over and parse it as params so that we
// get proper token annotations.
_base.state.restoreFromSnapshot(snapshot);
_base.state.scopeDepth++;
// Don't specify a context ID because arrow functions don't need a context ID.
_statement.parseFunctionParams.call(void 0, );
parseArrow();
parseArrowExpression(startTokenIndex);
if (_base.state.error) {
// Nevermind! This must have been something that looks very much like an
// arrow function but where its "parameter list" isn't actually a valid
// parameter list. Force non-arrow parsing.
// See https://github.com/alangpierce/sucrase/issues/666 for an example.
_base.state.restoreFromSnapshot(snapshot);
parseParenAndDistinguishExpression(false);
return false;
}
return true;
}
}
return false;
}
function shouldParseArrow() {
return _index3.match.call(void 0, _types3.TokenType.colon) || !_util.canInsertSemicolon.call(void 0, );
}
// Returns whether there was an arrow token.
function parseArrow() {
if (_base.isTypeScriptEnabled) {
return _typescript.tsParseArrow.call(void 0, );
} else if (_base.isFlowEnabled) {
return _flow.flowParseArrow.call(void 0, );
} else {
return _index3.eat.call(void 0, _types3.TokenType.arrow);
}
} exports.parseArrow = parseArrow;
function parseParenItem() {
if (_base.isTypeScriptEnabled || _base.isFlowEnabled) {
_types.typedParseParenItem.call(void 0, );
}
}
// New's precedence is slightly tricky. It must allow its argument to
// be a `[]` or dot subscript expression, but not a call — at least,
// not without wrapping it in parentheses. Thus, it uses the noCalls
// argument to parseSubscripts to prevent it from consuming the
// argument list.
function parseNew() {
_util.expect.call(void 0, _types3.TokenType._new);
if (_index3.eat.call(void 0, _types3.TokenType.dot)) {
// new.target
parseIdentifier();
return;
}
parseNewCallee();
if (_base.isFlowEnabled) {
_flow.flowStartParseNewArguments.call(void 0, );
}
if (_index3.eat.call(void 0, _types3.TokenType.parenL)) {
parseExprList(_types3.TokenType.parenR);
}
}
function parseNewCallee() {
parseNoCallExpr();
_index3.eat.call(void 0, _types3.TokenType.questionDot);
}
function parseTemplate() {
// Finish `, read quasi
_index3.nextTemplateToken.call(void 0, );
// Finish quasi, read ${
_index3.nextTemplateToken.call(void 0, );
while (!_index3.match.call(void 0, _types3.TokenType.backQuote) && !_base.state.error) {
_util.expect.call(void 0, _types3.TokenType.dollarBraceL);
parseExpression();
// Finish }, read quasi
_index3.nextTemplateToken.call(void 0, );
// Finish quasi, read either ${ or `
_index3.nextTemplateToken.call(void 0, );
}
_index3.next.call(void 0, );
} exports.parseTemplate = parseTemplate;
// Parse an object literal or binding pattern.
function parseObj(isPattern, isBlockScope) {
// Attach a context ID to the object open and close brace and each object key.
const contextId = _base.getNextContextId.call(void 0, );
let first = true;
_index3.next.call(void 0, );
_base.state.tokens[_base.state.tokens.length - 1].contextId = contextId;
while (!_index3.eat.call(void 0, _types3.TokenType.braceR) && !_base.state.error) {
if (first) {
first = false;
} else {
_util.expect.call(void 0, _types3.TokenType.comma);
if (_index3.eat.call(void 0, _types3.TokenType.braceR)) {
break;
}
}
let isGenerator = false;
if (_index3.match.call(void 0, _types3.TokenType.ellipsis)) {
const previousIndex = _base.state.tokens.length;
_lval.parseSpread.call(void 0, );
if (isPattern) {
// Mark role when the only thing being spread over is an identifier.
if (_base.state.tokens.length === previousIndex + 2) {
_lval.markPriorBindingIdentifier.call(void 0, isBlockScope);
}
if (_index3.eat.call(void 0, _types3.TokenType.braceR)) {
break;
}
}
continue;
}
if (!isPattern) {
isGenerator = _index3.eat.call(void 0, _types3.TokenType.star);
}
if (!isPattern && _util.isContextual.call(void 0, _keywords.ContextualKeyword._async)) {
if (isGenerator) _util.unexpected.call(void 0, );
parseIdentifier();
if (
_index3.match.call(void 0, _types3.TokenType.colon) ||
_index3.match.call(void 0, _types3.TokenType.parenL) ||
_index3.match.call(void 0, _types3.TokenType.braceR) ||
_index3.match.call(void 0, _types3.TokenType.eq) ||
_index3.match.call(void 0, _types3.TokenType.comma)
) {
// This is a key called "async" rather than an async function.
} else {
if (_index3.match.call(void 0, _types3.TokenType.star)) {
_index3.next.call(void 0, );
isGenerator = true;
}
parsePropertyName(contextId);
}
} else {
parsePropertyName(contextId);
}
parseObjPropValue(isPattern, isBlockScope, contextId);
}
_base.state.tokens[_base.state.tokens.length - 1].contextId = contextId;
} exports.parseObj = parseObj;
function isGetterOrSetterMethod(isPattern) {
// We go off of the next and don't bother checking if the node key is actually "get" or "set".
// This lets us avoid generating a node, and should only make the validation worse.
return (
!isPattern &&
(_index3.match.call(void 0, _types3.TokenType.string) || // get "string"() {}
_index3.match.call(void 0, _types3.TokenType.num) || // get 1() {}
_index3.match.call(void 0, _types3.TokenType.bracketL) || // get ["string"]() {}
_index3.match.call(void 0, _types3.TokenType.name) || // get foo() {}
!!(_base.state.type & _types3.TokenType.IS_KEYWORD)) // get debugger() {}
);
}
// Returns true if this was a method.
function parseObjectMethod(isPattern, objectContextId) {
// We don't need to worry about modifiers because object methods can't have optional bodies, so
// the start will never be used.
const functionStart = _base.state.start;
if (_index3.match.call(void 0, _types3.TokenType.parenL)) {
if (isPattern) _util.unexpected.call(void 0, );
parseMethod(functionStart, /* isConstructor */ false);
return true;
}
if (isGetterOrSetterMethod(isPattern)) {
parsePropertyName(objectContextId);
parseMethod(functionStart, /* isConstructor */ false);
return true;
}
return false;
}
function parseObjectProperty(isPattern, isBlockScope) {
if (_index3.eat.call(void 0, _types3.TokenType.colon)) {
if (isPattern) {
_lval.parseMaybeDefault.call(void 0, isBlockScope);
} else {
parseMaybeAssign(false);
}
return;
}
// Since there's no colon, we assume this is an object shorthand.
// If we're in a destructuring, we've now discovered that the key was actually an assignee, so
// we need to tag it as a declaration with the appropriate scope. Otherwise, we might need to
// transform it on access, so mark it as a normal object shorthand.
let identifierRole;
if (isPattern) {
if (_base.state.scopeDepth === 0) {
identifierRole = _index3.IdentifierRole.ObjectShorthandTopLevelDeclaration;
} else if (isBlockScope) {
identifierRole = _index3.IdentifierRole.ObjectShorthandBlockScopedDeclaration;
} else {
identifierRole = _index3.IdentifierRole.ObjectShorthandFunctionScopedDeclaration;
}
} else {
identifierRole = _index3.IdentifierRole.ObjectShorthand;
}
_base.state.tokens[_base.state.tokens.length - 1].identifierRole = identifierRole;
// Regardless of whether we know this to be a pattern or if we're in an ambiguous context, allow
// parsing as if there's a default value.
_lval.parseMaybeDefault.call(void 0, isBlockScope, true);
}
function parseObjPropValue(
isPattern,
isBlockScope,
objectContextId,
) {
if (_base.isTypeScriptEnabled) {
_typescript.tsStartParseObjPropValue.call(void 0, );
} else if (_base.isFlowEnabled) {
_flow.flowStartParseObjPropValue.call(void 0, );
}
const wasMethod = parseObjectMethod(isPattern, objectContextId);
if (!wasMethod) {
parseObjectProperty(isPattern, isBlockScope);
}
}
function parsePropertyName(objectContextId) {
if (_base.isFlowEnabled) {
_flow.flowParseVariance.call(void 0, );
}
if (_index3.eat.call(void 0, _types3.TokenType.bracketL)) {
_base.state.tokens[_base.state.tokens.length - 1].contextId = objectContextId;
parseMaybeAssign();
_util.expect.call(void 0, _types3.TokenType.bracketR);
_base.state.tokens[_base.state.tokens.length - 1].contextId = objectContextId;
} else {
if (_index3.match.call(void 0, _types3.TokenType.num) || _index3.match.call(void 0, _types3.TokenType.string) || _index3.match.call(void 0, _types3.TokenType.bigint) || _index3.match.call(void 0, _types3.TokenType.decimal)) {
parseExprAtom();
} else {
parseMaybePrivateName();
}
_base.state.tokens[_base.state.tokens.length - 1].identifierRole = _index3.IdentifierRole.ObjectKey;
_base.state.tokens[_base.state.tokens.length - 1].contextId = objectContextId;
}
} exports.parsePropertyName = parsePropertyName;
// Parse object or class method.
function parseMethod(functionStart, isConstructor) {
const funcContextId = _base.getNextContextId.call(void 0, );
_base.state.scopeDepth++;
const startTokenIndex = _base.state.tokens.length;
const allowModifiers = isConstructor; // For TypeScript parameter properties
_statement.parseFunctionParams.call(void 0, allowModifiers, funcContextId);
parseFunctionBodyAndFinish(functionStart, funcContextId);
const endTokenIndex = _base.state.tokens.length;
_base.state.scopes.push(new (0, _state.Scope)(startTokenIndex, endTokenIndex, true));
_base.state.scopeDepth--;
} exports.parseMethod = parseMethod;
// Parse arrow function expression.
// If the parameters are provided, they will be converted to an
// assignable list.
function parseArrowExpression(startTokenIndex) {
parseFunctionBody(true);
const endTokenIndex = _base.state.tokens.length;
_base.state.scopes.push(new (0, _state.Scope)(startTokenIndex, endTokenIndex, true));
_base.state.scopeDepth--;
} exports.parseArrowExpression = parseArrowExpression;
function parseFunctionBodyAndFinish(functionStart, funcContextId = 0) {
if (_base.isTypeScriptEnabled) {
_typescript.tsParseFunctionBodyAndFinish.call(void 0, functionStart, funcContextId);
} else if (_base.isFlowEnabled) {
_flow.flowParseFunctionBodyAndFinish.call(void 0, funcContextId);
} else {
parseFunctionBody(false, funcContextId);
}
} exports.parseFunctionBodyAndFinish = parseFunctionBodyAndFinish;
function parseFunctionBody(allowExpression, funcContextId = 0) {
const isExpression = allowExpression && !_index3.match.call(void 0, _types3.TokenType.braceL);
if (isExpression) {
parseMaybeAssign();
} else {
_statement.parseBlock.call(void 0, true /* isFunctionScope */, funcContextId);
}
} exports.parseFunctionBody = parseFunctionBody;
// Parses a comma-separated list of expressions, and returns them as
// an array. `close` is the token type that ends the list, and
// `allowEmpty` can be turned on to allow subsequent commas with
// nothing in between them to be parsed as `null` (which is needed
// for array literals).
function parseExprList(close, allowEmpty = false) {
let first = true;
while (!_index3.eat.call(void 0, close) && !_base.state.error) {
if (first) {
first = false;
} else {
_util.expect.call(void 0, _types3.TokenType.comma);
if (_index3.eat.call(void 0, close)) break;
}
parseExprListItem(allowEmpty);
}
}
function parseExprListItem(allowEmpty) {
if (allowEmpty && _index3.match.call(void 0, _types3.TokenType.comma)) {
// Empty item; nothing more to parse for this item.
} else if (_index3.match.call(void 0, _types3.TokenType.ellipsis)) {
_lval.parseSpread.call(void 0, );
parseParenItem();
} else if (_index3.match.call(void 0, _types3.TokenType.question)) {
// Partial function application proposal.
_index3.next.call(void 0, );
} else {
parseMaybeAssign(false, true);
}
}
// Parse the next token as an identifier.
function parseIdentifier() {
_index3.next.call(void 0, );
_base.state.tokens[_base.state.tokens.length - 1].type = _types3.TokenType.name;
} exports.parseIdentifier = parseIdentifier;
// Parses await expression inside async function.
function parseAwait() {
parseMaybeUnary();
}
// Parses yield expression inside generator.
function parseYield() {
_index3.next.call(void 0, );
if (!_index3.match.call(void 0, _types3.TokenType.semi) && !_util.canInsertSemicolon.call(void 0, )) {
_index3.eat.call(void 0, _types3.TokenType.star);
parseMaybeAssign();
}
}
// https://github.com/tc39/proposal-js-module-blocks
function parseModuleExpression() {
_util.expectContextual.call(void 0, _keywords.ContextualKeyword._module);
_util.expect.call(void 0, _types3.TokenType.braceL);
// For now, just call parseBlockBody to parse the block. In the future when we
// implement full support, we'll want to emit scopes and possibly other
// information.
_statement.parseBlockBody.call(void 0, _types3.TokenType.braceR);
}