1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef frontend_SyntaxParseHandler_h
8 #define frontend_SyntaxParseHandler_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Maybe.h" // mozilla::Maybe
17 #include "frontend/CompilationStencil.h" // CompilationState
18 #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
19 #include "frontend/NameAnalysisTypes.h" // PrivateNameKind
20 #include "frontend/ParseNode.h"
21 #include "frontend/ParserAtom.h" // TaggedParserAtomIndex
22 #include "frontend/TokenStream.h"
28 // Parse handler used when processing the syntax in a block of code, to generate
29 // the minimal information which is required to detect syntax errors and allow
30 // bytecode to be emitted for outer functions.
32 // When parsing, we start at the top level with a full parse, and when possible
33 // only check the syntax for inner functions, so that they can be lazily parsed
34 // into bytecode when/if they first run. Checking the syntax of a function is
35 // several times faster than doing a full parse/emit, and lazy parsing improves
36 // both performance and memory usage significantly when pages contain large
37 // amounts of code that never executes (which happens often).
38 class SyntaxParseHandler
{
39 // Remember the last encountered name or string literal during syntax parses.
40 TaggedParserAtomIndex lastAtom
;
41 TokenPos lastStringPos
;
48 NodeStringExprStatement
,
55 NodeLexicalDeclaration
,
57 // A non-arrow function expression with block body, from bog-standard
59 NodeFunctionExpression
,
62 NodeFunctionStatement
,
64 // This is needed for proper assignment-target handling. ES6 formally
65 // requires function calls *not* pass IsValidSimpleAssignmentTarget,
66 // but at last check there were still sites with |f() = 5| and similar
67 // in code not actually executed (or at least not executed enough to be
71 NodeOptionalFunctionCall
,
73 // Node representing normal names which don't require any special
77 // Nodes representing the names "arguments" and "eval".
81 // Node representing the "async" name, which may actually be a
82 // contextual keyword.
83 NodePotentialAsyncKeyword
,
85 // Node representing private names.
89 NodeOptionalDottedProperty
,
92 // A distinct node for [PrivateName], to make detecting delete this.#x
93 // detectable in syntax parse
94 NodePrivateMemberAccess
,
95 NodeOptionalPrivateMemberAccess
,
97 // Destructuring target patterns can't be parenthesized: |([a]) = [3];|
98 // must be a syntax error. (We can't use NodeGeneric instead of these
99 // because that would trigger invalid-left-hand-side ReferenceError
100 // semantics when SyntaxError semantics are desired.)
101 NodeParenthesizedArray
,
102 NodeParenthesizedObject
,
104 // In rare cases a parenthesized |node| doesn't have the same semantics
105 // as |node|. Each such node has a special Node value, and we use a
106 // different Node value to represent the parenthesized form. See also
107 // is{Unp,P}arenthesized*(Node), parenthesize(Node), and the various
108 // functions that deal in NodeUnparenthesized* below.
110 // Valuable for recognizing potential destructuring patterns.
111 NodeUnparenthesizedArray
,
112 NodeUnparenthesizedObject
,
114 // The directive prologue at the start of a FunctionBody or ScriptBody
115 // is the longest sequence (possibly empty) of string literal
116 // expression statements at the start of a function. Thus we need this
117 // to treat |"use strict";| as a possible Use Strict Directive and
118 // |("use strict");| as a useless statement.
119 NodeUnparenthesizedString
,
121 // For destructuring patterns an assignment element with
122 // an initializer expression is not allowed be parenthesized.
123 // i.e. |{x = 1} = obj|
124 NodeUnparenthesizedAssignment
,
126 // This node is necessary to determine if the base operand in an
127 // exponentiation operation is an unparenthesized unary expression.
128 // We want to reject |-2 ** 3|, but still need to allow |(-2) ** 3|.
129 NodeUnparenthesizedUnary
,
131 // This node is necessary to determine if the LHS of a property access is
136 #define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
137 using longTypeName = Node;
138 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE
)
141 using NullNode
= Node
;
143 bool isNonArrowFunctionExpression(Node node
) const {
144 return node
== NodeFunctionExpression
;
147 bool isPropertyOrPrivateMemberAccess(Node node
) {
148 return node
== NodeDottedProperty
|| node
== NodeElement
||
149 node
== NodePrivateMemberAccess
;
152 bool isOptionalPropertyOrPrivateMemberAccess(Node node
) {
153 return node
== NodeOptionalDottedProperty
|| node
== NodeOptionalElement
||
154 node
== NodeOptionalPrivateMemberAccess
;
157 bool isFunctionCall(Node node
) {
158 // Note: super() is a special form, *not* a function call.
159 return node
== NodeFunctionCall
;
162 static bool isUnparenthesizedDestructuringPattern(Node node
) {
163 return node
== NodeUnparenthesizedArray
||
164 node
== NodeUnparenthesizedObject
;
167 static bool isParenthesizedDestructuringPattern(Node node
) {
168 // Technically this isn't a destructuring target at all -- the grammar
169 // doesn't treat it as such. But we need to know when this happens to
170 // consider it a SyntaxError rather than an invalid-left-hand-side
172 return node
== NodeParenthesizedArray
|| node
== NodeParenthesizedObject
;
176 SyntaxParseHandler(FrontendContext
* fc
, CompilationState
& compilationState
) {
177 MOZ_ASSERT(!compilationState
.input
.isDelazifying());
180 static NullNode
null() { return NodeFailure
; }
182 #define DECLARE_AS(typeName, longTypeName, asMethodName) \
183 static longTypeName asMethodName(Node node) { return node; }
184 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS
)
187 NameNodeType
newName(TaggedParserAtomIndex name
, const TokenPos
& pos
) {
189 if (name
== TaggedParserAtomIndex::WellKnown::arguments()) {
190 return NodeArgumentsName
;
192 if (pos
.begin
+ strlen("async") == pos
.end
&&
193 name
== TaggedParserAtomIndex::WellKnown::async()) {
194 return NodePotentialAsyncKeyword
;
196 if (name
== TaggedParserAtomIndex::WellKnown::eval()) {
202 UnaryNodeType
newComputedName(Node expr
, uint32_t start
, uint32_t end
) {
206 UnaryNodeType
newSyntheticComputedName(Node expr
, uint32_t start
,
211 NameNodeType
newObjectLiteralPropertyName(TaggedParserAtomIndex atom
,
212 const TokenPos
& pos
) {
216 NameNodeType
newPrivateName(TaggedParserAtomIndex atom
, const TokenPos
& pos
) {
217 return NodePrivateName
;
220 NumericLiteralType
newNumber(double value
, DecimalPoint decimalPoint
,
221 const TokenPos
& pos
) {
225 BigIntLiteralType
newBigInt() { return NodeGeneric
; }
227 BooleanLiteralType
newBooleanLiteral(bool cond
, const TokenPos
& pos
) {
231 NameNodeType
newStringLiteral(TaggedParserAtomIndex atom
,
232 const TokenPos
& pos
) {
235 return NodeUnparenthesizedString
;
238 NameNodeType
newTemplateStringLiteral(TaggedParserAtomIndex atom
,
239 const TokenPos
& pos
) {
243 CallSiteNodeType
newCallSiteObject(uint32_t begin
) { return NodeGeneric
; }
245 void addToCallSiteObject(CallSiteNodeType callSiteObj
, Node rawNode
,
248 ThisLiteralType
newThisLiteral(const TokenPos
& pos
, Node thisName
) {
251 NullLiteralType
newNullLiteral(const TokenPos
& pos
) { return NodeGeneric
; }
252 RawUndefinedLiteralType
newRawUndefinedLiteral(const TokenPos
& pos
) {
256 RegExpLiteralType
newRegExp(Node reobj
, const TokenPos
& pos
) {
260 ConditionalExpressionType
newConditional(Node cond
, Node thenExpr
,
265 UnaryNodeType
newDelete(uint32_t begin
, Node expr
) {
266 return NodeUnparenthesizedUnary
;
269 UnaryNodeType
newTypeof(uint32_t begin
, Node kid
) {
270 return NodeUnparenthesizedUnary
;
273 UnaryNodeType
newUnary(ParseNodeKind kind
, uint32_t begin
, Node kid
) {
274 return NodeUnparenthesizedUnary
;
277 UnaryNodeType
newUpdate(ParseNodeKind kind
, uint32_t begin
, Node kid
) {
281 UnaryNodeType
newSpread(uint32_t begin
, Node kid
) { return NodeGeneric
; }
283 Node
appendOrCreateList(ParseNodeKind kind
, Node left
, Node right
,
290 ListNodeType
newArrayLiteral(uint32_t begin
) {
291 return NodeUnparenthesizedArray
;
293 [[nodiscard
]] bool addElision(ListNodeType literal
, const TokenPos
& pos
) {
296 [[nodiscard
]] bool addSpreadElement(ListNodeType literal
, uint32_t begin
,
300 void addArrayElement(ListNodeType literal
, Node element
) {}
302 ListNodeType
newArguments(const TokenPos
& pos
) { return NodeGeneric
; }
303 CallNodeType
newCall(Node callee
, ListNodeType args
, JSOp callOp
) {
304 return NodeFunctionCall
;
307 CallNodeType
newOptionalCall(Node callee
, ListNodeType args
, JSOp callOp
) {
308 return NodeOptionalFunctionCall
;
311 CallNodeType
newSuperCall(Node callee
, ListNodeType args
, bool isSpread
) {
314 CallNodeType
newTaggedTemplate(Node tag
, ListNodeType args
, JSOp callOp
) {
318 ListNodeType
newObjectLiteral(uint32_t begin
) {
319 return NodeUnparenthesizedObject
;
322 #ifdef ENABLE_RECORD_TUPLE
323 ListNodeType
newRecordLiteral(uint32_t begin
) { return NodeGeneric
; }
325 ListNodeType
newTupleLiteral(uint32_t begin
) { return NodeGeneric
; }
328 ListNodeType
newClassMemberList(uint32_t begin
) { return NodeGeneric
; }
329 ClassNamesType
newClassNames(Node outer
, Node inner
, const TokenPos
& pos
) {
332 ClassNodeType
newClass(Node name
, Node heritage
, Node methodBlock
,
333 #ifdef ENABLE_DECORATORS
334 ListNodeType decorators
,
336 const TokenPos
& pos
) {
340 LexicalScopeNodeType
newLexicalScope(Node body
) {
341 return NodeLexicalDeclaration
;
344 ClassBodyScopeNodeType
newClassBodyScope(Node body
) {
345 return NodeLexicalDeclaration
;
348 NewTargetNodeType
newNewTarget(NullaryNodeType newHolder
,
349 NullaryNodeType targetHolder
,
350 NameNodeType newTargetName
) {
353 NullaryNodeType
newPosHolder(const TokenPos
& pos
) { return NodeGeneric
; }
354 UnaryNodeType
newSuperBase(Node thisName
, const TokenPos
& pos
) {
355 return NodeSuperBase
;
358 [[nodiscard
]] bool addPrototypeMutation(ListNodeType literal
, uint32_t begin
,
362 BinaryNodeType
newPropertyDefinition(Node key
, Node val
) {
365 void addPropertyDefinition(ListNodeType literal
, BinaryNodeType propdef
) {}
366 [[nodiscard
]] bool addPropertyDefinition(ListNodeType literal
, Node key
,
370 [[nodiscard
]] bool addShorthand(ListNodeType literal
, NameNodeType name
,
374 [[nodiscard
]] bool addSpreadProperty(ListNodeType literal
, uint32_t begin
,
378 [[nodiscard
]] bool addObjectMethodDefinition(ListNodeType literal
, Node key
,
379 FunctionNodeType funNode
,
380 AccessorType atype
) {
383 [[nodiscard
]] Node
newDefaultClassConstructor(Node key
,
384 FunctionNodeType funNode
) {
387 [[nodiscard
]] Node
newClassMethodDefinition(
388 Node key
, FunctionNodeType funNode
, AccessorType atype
, bool isStatic
,
389 mozilla::Maybe
<FunctionNodeType
> initializerIfPrivate
390 #ifdef ENABLE_DECORATORS
392 ListNodeType decorators
397 [[nodiscard
]] Node
newClassFieldDefinition(Node name
,
398 FunctionNodeType initializer
,
400 #ifdef ENABLE_DECORATORS
402 ListNodeType decorators
,
403 ClassMethodType accessorGetterNode
,
404 ClassMethodType accessorSetterNode
410 [[nodiscard
]] Node
newStaticClassBlock(FunctionNodeType block
) {
414 [[nodiscard
]] bool addClassMemberDefinition(ListNodeType memberList
,
418 UnaryNodeType
newYieldExpression(uint32_t begin
, Node value
) {
421 UnaryNodeType
newYieldStarExpression(uint32_t begin
, Node value
) {
424 UnaryNodeType
newAwaitExpression(uint32_t begin
, Node value
) {
425 return NodeUnparenthesizedUnary
;
427 UnaryNodeType
newOptionalChain(uint32_t begin
, Node value
) {
433 ListNodeType
newStatementList(const TokenPos
& pos
) { return NodeGeneric
; }
434 void addStatementToList(ListNodeType list
, Node stmt
) {}
435 void setListEndPosition(ListNodeType list
, const TokenPos
& pos
) {}
436 void addCaseStatementToList(ListNodeType list
, CaseClauseType caseClause
) {}
437 [[nodiscard
]] bool prependInitialYield(ListNodeType stmtList
, Node genName
) {
440 NullaryNodeType
newEmptyStatement(const TokenPos
& pos
) {
441 return NodeEmptyStatement
;
444 BinaryNodeType
newImportAssertion(Node keyNode
, Node valueNode
) {
447 BinaryNodeType
newModuleRequest(Node moduleSpec
, Node importAssertionList
,
448 const TokenPos
& pos
) {
451 BinaryNodeType
newImportDeclaration(Node importSpecSet
, Node moduleRequest
,
452 const TokenPos
& pos
) {
455 BinaryNodeType
newImportSpec(Node importNameNode
, Node bindingName
) {
458 UnaryNodeType
newImportNamespaceSpec(uint32_t begin
, Node bindingName
) {
461 UnaryNodeType
newExportDeclaration(Node kid
, const TokenPos
& pos
) {
464 BinaryNodeType
newExportFromDeclaration(uint32_t begin
, Node exportSpecSet
,
465 Node moduleRequest
) {
468 BinaryNodeType
newExportDefaultDeclaration(Node kid
, Node maybeBinding
,
469 const TokenPos
& pos
) {
472 BinaryNodeType
newExportSpec(Node bindingName
, Node exportName
) {
475 UnaryNodeType
newExportNamespaceSpec(uint32_t begin
, Node exportName
) {
478 NullaryNodeType
newExportBatchSpec(const TokenPos
& pos
) {
481 BinaryNodeType
newImportMeta(NullaryNodeType importHolder
,
482 NullaryNodeType metaHolder
) {
485 BinaryNodeType
newCallImport(NullaryNodeType importHolder
, Node singleArg
) {
488 BinaryNodeType
newCallImportSpec(Node specifierArg
, Node optionalArg
) {
492 BinaryNodeType
newSetThis(Node thisName
, Node value
) { return value
; }
494 UnaryNodeType
newExprStatement(Node expr
, uint32_t end
) {
495 return expr
== NodeUnparenthesizedString
? NodeStringExprStatement
499 TernaryNodeType
newIfStatement(uint32_t begin
, Node cond
, Node thenBranch
,
503 BinaryNodeType
newDoWhileStatement(Node body
, Node cond
,
504 const TokenPos
& pos
) {
507 BinaryNodeType
newWhileStatement(uint32_t begin
, Node cond
, Node body
) {
510 SwitchStatementType
newSwitchStatement(
511 uint32_t begin
, Node discriminant
,
512 LexicalScopeNodeType lexicalForCaseList
, bool hasDefault
) {
515 CaseClauseType
newCaseOrDefault(uint32_t begin
, Node expr
, Node body
) {
518 ContinueStatementType
newContinueStatement(TaggedParserAtomIndex label
,
519 const TokenPos
& pos
) {
522 BreakStatementType
newBreakStatement(TaggedParserAtomIndex label
,
523 const TokenPos
& pos
) {
526 UnaryNodeType
newReturnStatement(Node expr
, const TokenPos
& pos
) {
529 UnaryNodeType
newExpressionBody(Node expr
) { return NodeReturn
; }
530 BinaryNodeType
newWithStatement(uint32_t begin
, Node expr
, Node body
) {
534 LabeledStatementType
newLabeledStatement(TaggedParserAtomIndex label
,
535 Node stmt
, uint32_t begin
) {
539 UnaryNodeType
newThrowStatement(Node expr
, const TokenPos
& pos
) {
542 TernaryNodeType
newTryStatement(uint32_t begin
, Node body
,
543 LexicalScopeNodeType catchScope
,
547 DebuggerStatementType
newDebuggerStatement(const TokenPos
& pos
) {
551 NameNodeType
newPropertyName(TaggedParserAtomIndex name
,
552 const TokenPos
& pos
) {
557 PropertyAccessType
newPropertyAccess(Node expr
, NameNodeType key
) {
558 return NodeDottedProperty
;
561 PropertyAccessType
newOptionalPropertyAccess(Node expr
, NameNodeType key
) {
562 return NodeOptionalDottedProperty
;
565 PropertyByValueType
newPropertyByValue(Node lhs
, Node index
, uint32_t end
) {
566 MOZ_ASSERT(!isPrivateName(index
));
570 PropertyByValueType
newOptionalPropertyByValue(Node lhs
, Node index
,
572 return NodeOptionalElement
;
575 PrivateMemberAccessType
newPrivateMemberAccess(Node lhs
, Node privateName
,
577 return NodePrivateMemberAccess
;
580 PrivateMemberAccessType
newOptionalPrivateMemberAccess(Node lhs
,
583 return NodeOptionalPrivateMemberAccess
;
586 [[nodiscard
]] bool setupCatchScope(LexicalScopeNodeType lexicalScope
,
587 Node catchName
, Node catchBody
) {
591 [[nodiscard
]] bool setLastFunctionFormalParameterDefault(
592 FunctionNodeType funNode
, Node defaultValue
) {
596 void checkAndSetIsDirectRHSAnonFunction(Node pn
) {}
598 ParamsBodyNodeType
newParamsBody(const TokenPos
& pos
) { return NodeGeneric
; }
600 FunctionNodeType
newFunction(FunctionSyntaxKind syntaxKind
,
601 const TokenPos
& pos
) {
602 switch (syntaxKind
) {
603 case FunctionSyntaxKind::Statement
:
604 return NodeFunctionStatement
;
605 case FunctionSyntaxKind::Arrow
:
606 return NodeFunctionArrow
;
608 // All non-arrow function expressions are initially presumed to have
609 // block body. This will be overridden later *if* the function
610 // expression permissibly has an AssignmentExpression body.
611 return NodeFunctionExpression
;
615 void setFunctionFormalParametersAndBody(FunctionNodeType funNode
,
616 ParamsBodyNodeType paramsBody
) {}
617 void setFunctionBody(FunctionNodeType funNode
, LexicalScopeNodeType body
) {}
618 void setFunctionBox(FunctionNodeType funNode
, FunctionBox
* funbox
) {}
619 void addFunctionFormalParameter(FunctionNodeType funNode
, Node argpn
) {}
621 ForNodeType
newForStatement(uint32_t begin
, TernaryNodeType forHead
,
622 Node body
, unsigned iflags
) {
626 TernaryNodeType
newForHead(Node init
, Node test
, Node update
,
627 const TokenPos
& pos
) {
631 TernaryNodeType
newForInOrOfHead(ParseNodeKind kind
, Node target
,
632 Node iteratedExpr
, const TokenPos
& pos
) {
636 AssignmentNodeType
finishInitializerAssignment(NameNodeType nameNode
,
638 return NodeUnparenthesizedAssignment
;
641 void setBeginPosition(Node pn
, Node oth
) {}
642 void setBeginPosition(Node pn
, uint32_t begin
) {}
644 void setEndPosition(Node pn
, Node oth
) {}
645 void setEndPosition(Node pn
, uint32_t end
) {}
647 uint32_t getFunctionNameOffset(Node func
, TokenStreamAnyChars
& ts
) {
648 // XXX This offset isn't relevant to the offending function name. But
649 // we may not *have* that function name around, because of how lazy
650 // parsing works -- the actual name could be outside
651 // |tokenStream.userbuf|'s observed region. So the current offset
652 // is the best we can do.
653 return ts
.currentToken().pos
.begin
;
656 ListNodeType
newList(ParseNodeKind kind
, const TokenPos
& pos
) {
657 MOZ_ASSERT(kind
!= ParseNodeKind::VarStmt
);
658 MOZ_ASSERT(kind
!= ParseNodeKind::LetDecl
);
659 MOZ_ASSERT(kind
!= ParseNodeKind::ConstDecl
);
660 MOZ_ASSERT(kind
!= ParseNodeKind::ParamsBody
);
664 ListNodeType
newList(ParseNodeKind kind
, Node kid
) {
665 return newList(kind
, TokenPos());
668 DeclarationListNodeType
newDeclarationList(ParseNodeKind kind
,
669 const TokenPos
& pos
) {
670 if (kind
== ParseNodeKind::VarStmt
) {
671 return NodeVarDeclaration
;
673 MOZ_ASSERT(kind
== ParseNodeKind::LetDecl
||
674 kind
== ParseNodeKind::ConstDecl
);
675 return NodeLexicalDeclaration
;
678 ListNodeType
newCommaExpressionList(Node kid
) { return NodeGeneric
; }
680 void addList(ListNodeType list
, Node kid
) {
681 MOZ_ASSERT(list
== NodeGeneric
|| list
== NodeUnparenthesizedArray
||
682 list
== NodeUnparenthesizedObject
||
683 list
== NodeVarDeclaration
|| list
== NodeLexicalDeclaration
||
684 list
== NodeFunctionCall
);
687 CallNodeType
newNewExpression(uint32_t begin
, Node ctor
, ListNodeType args
,
692 AssignmentNodeType
newAssignment(ParseNodeKind kind
, Node lhs
, Node rhs
) {
693 return kind
== ParseNodeKind::AssignExpr
? NodeUnparenthesizedAssignment
697 AssignmentNodeType
newInitExpr(Node lhs
, Node rhs
) { return NodeGeneric
; }
699 bool isUnparenthesizedAssignment(Node node
) {
700 return node
== NodeUnparenthesizedAssignment
;
703 bool isUnparenthesizedUnaryExpression(Node node
) {
704 return node
== NodeUnparenthesizedUnary
;
707 bool isReturnStatement(Node node
) { return node
== NodeReturn
; }
709 bool isStatementPermittedAfterReturnStatement(Node pn
) {
710 return pn
== NodeFunctionStatement
|| isNonArrowFunctionExpression(pn
) ||
711 pn
== NodeVarDeclaration
|| pn
== NodeBreak
|| pn
== NodeThrow
||
712 pn
== NodeEmptyStatement
;
715 bool isSuperBase(Node pn
) { return pn
== NodeSuperBase
; }
717 void setListHasNonConstInitializer(ListNodeType literal
) {}
718 [[nodiscard
]] Node
parenthesize(Node node
) {
719 // A number of nodes have different behavior upon parenthesization, but
720 // only in some circumstances. Convert these nodes to special
721 // parenthesized forms.
722 if (node
== NodeUnparenthesizedArray
) {
723 return NodeParenthesizedArray
;
725 if (node
== NodeUnparenthesizedObject
) {
726 return NodeParenthesizedObject
;
729 // Other nodes need not be recognizable after parenthesization; convert
730 // them to a generic node.
731 if (node
== NodeUnparenthesizedString
||
732 node
== NodeUnparenthesizedAssignment
||
733 node
== NodeUnparenthesizedUnary
) {
737 // Convert parenthesized |async| to a normal name node.
738 if (node
== NodePotentialAsyncKeyword
) {
742 // In all other cases, the parenthesized form of |node| is equivalent
743 // to the unparenthesized form: return |node| unchanged.
746 template <typename NodeType
>
747 [[nodiscard
]] NodeType
setLikelyIIFE(NodeType node
) {
748 return node
; // Remain in syntax-parse mode.
751 bool isName(Node node
) {
752 return node
== NodeName
|| node
== NodeArgumentsName
||
753 node
== NodeEvalName
|| node
== NodePotentialAsyncKeyword
;
756 bool isArgumentsName(Node node
) { return node
== NodeArgumentsName
; }
757 bool isEvalName(Node node
) { return node
== NodeEvalName
; }
758 bool isAsyncKeyword(Node node
) { return node
== NodePotentialAsyncKeyword
; }
760 bool isPrivateName(Node node
) { return node
== NodePrivateName
; }
761 bool isPrivateMemberAccess(Node node
) {
762 return node
== NodePrivateMemberAccess
;
765 TaggedParserAtomIndex
maybeDottedProperty(Node node
) {
766 // Note: |super.apply(...)| is a special form that calls an "apply"
767 // method retrieved from one value, but using a *different* value as
768 // |this|. It's not really eligible for the funapply/funcall
769 // optimizations as they're currently implemented (assuming a single
770 // value is used for both retrieval and |this|).
771 if (node
!= NodeDottedProperty
&& node
!= NodeOptionalDottedProperty
) {
772 return TaggedParserAtomIndex::null();
777 TaggedParserAtomIndex
isStringExprStatement(Node pn
, TokenPos
* pos
) {
778 if (pn
== NodeStringExprStatement
) {
779 *pos
= lastStringPos
;
782 return TaggedParserAtomIndex::null();
785 bool reuseLazyInnerFunctions() { return false; }
786 bool reuseClosedOverBindings() { return false; }
787 TaggedParserAtomIndex
nextLazyClosedOverBinding() {
789 "SyntaxParseHandler::canSkipLazyClosedOverBindings must return false");
792 void setPrivateNameKind(Node node
, PrivateNameKind kind
) {}
795 } // namespace frontend
798 #endif /* frontend_SyntaxParseHandler_h */