Bug 1865597 - Add error checking when initializing parallel marking and disable on...
[gecko.git] / js / src / frontend / SyntaxParseHandler.h
blobe1afad82e42ff0360d12820d8256c51ca08eedd8
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
12 #include "mozilla/Result.h" // mozilla::Result, mozilla::UnusedZero
14 #include <string.h>
16 #include "jstypes.h"
18 #include "frontend/CompilationStencil.h" // CompilationState
19 #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
20 #include "frontend/NameAnalysisTypes.h" // PrivateNameKind
21 #include "frontend/ParseNode.h"
22 #include "frontend/ParserAtom.h" // TaggedParserAtomIndex
23 #include "frontend/TokenStream.h"
25 namespace js {
26 namespace frontend {
27 enum SyntaxParseHandlerNode {
28 NodeFailure = 0,
29 NodeGeneric,
30 NodeGetProp,
31 NodeStringExprStatement,
32 NodeReturn,
33 NodeBreak,
34 NodeThrow,
35 NodeEmptyStatement,
37 NodeVarDeclaration,
38 NodeLexicalDeclaration,
40 // A non-arrow function expression with block body, from bog-standard
41 // ECMAScript.
42 NodeFunctionExpression,
44 NodeFunctionArrow,
45 NodeFunctionStatement,
47 // This is needed for proper assignment-target handling. ES6 formally
48 // requires function calls *not* pass IsValidSimpleAssignmentTarget,
49 // but at last check there were still sites with |f() = 5| and similar
50 // in code not actually executed (or at least not executed enough to be
51 // noticed).
52 NodeFunctionCall,
54 NodeOptionalFunctionCall,
56 // Node representing normal names which don't require any special
57 // casing.
58 NodeName,
60 // Nodes representing the names "arguments" and "eval".
61 NodeArgumentsName,
62 NodeEvalName,
64 // Node representing the "async" name, which may actually be a
65 // contextual keyword.
66 NodePotentialAsyncKeyword,
68 // Node representing private names.
69 NodePrivateName,
71 NodeDottedProperty,
72 NodeOptionalDottedProperty,
73 NodeElement,
74 NodeOptionalElement,
75 // A distinct node for [PrivateName], to make detecting delete this.#x
76 // detectable in syntax parse
77 NodePrivateMemberAccess,
78 NodeOptionalPrivateMemberAccess,
80 // Destructuring target patterns can't be parenthesized: |([a]) = [3];|
81 // must be a syntax error. (We can't use NodeGeneric instead of these
82 // because that would trigger invalid-left-hand-side ReferenceError
83 // semantics when SyntaxError semantics are desired.)
84 NodeParenthesizedArray,
85 NodeParenthesizedObject,
87 // In rare cases a parenthesized |node| doesn't have the same semantics
88 // as |node|. Each such node has a special Node value, and we use a
89 // different Node value to represent the parenthesized form. See also
90 // is{Unp,P}arenthesized*(Node), parenthesize(Node), and the various
91 // functions that deal in NodeUnparenthesized* below.
93 // Valuable for recognizing potential destructuring patterns.
94 NodeUnparenthesizedArray,
95 NodeUnparenthesizedObject,
97 // The directive prologue at the start of a FunctionBody or ScriptBody
98 // is the longest sequence (possibly empty) of string literal
99 // expression statements at the start of a function. Thus we need this
100 // to treat |"use strict";| as a possible Use Strict Directive and
101 // |("use strict");| as a useless statement.
102 NodeUnparenthesizedString,
104 // For destructuring patterns an assignment element with
105 // an initializer expression is not allowed be parenthesized.
106 // i.e. |{x = 1} = obj|
107 NodeUnparenthesizedAssignment,
109 // This node is necessary to determine if the base operand in an
110 // exponentiation operation is an unparenthesized unary expression.
111 // We want to reject |-2 ** 3|, but still need to allow |(-2) ** 3|.
112 NodeUnparenthesizedUnary,
114 // This node is necessary to determine if the LHS of a property access is
115 // super related.
116 NodeSuperBase
119 } // namespace frontend
120 } // namespace js
122 template <>
123 struct mozilla::detail::UnusedZero<js::frontend::SyntaxParseHandlerNode> {
124 static const bool value = true;
127 namespace js {
128 namespace frontend {
130 // Parse handler used when processing the syntax in a block of code, to generate
131 // the minimal information which is required to detect syntax errors and allow
132 // bytecode to be emitted for outer functions.
134 // When parsing, we start at the top level with a full parse, and when possible
135 // only check the syntax for inner functions, so that they can be lazily parsed
136 // into bytecode when/if they first run. Checking the syntax of a function is
137 // several times faster than doing a full parse/emit, and lazy parsing improves
138 // both performance and memory usage significantly when pages contain large
139 // amounts of code that never executes (which happens often).
140 class SyntaxParseHandler {
141 // Remember the last encountered name or string literal during syntax parses.
142 TaggedParserAtomIndex lastAtom;
143 TokenPos lastStringPos;
145 public:
146 struct NodeError {};
148 using Node = SyntaxParseHandlerNode;
150 using NodeResult = mozilla::Result<Node, NodeError>;
151 using NodeErrorResult = mozilla::GenericErrorResult<NodeError>;
153 #define DECLARE_TYPE(typeName) \
154 using typeName##Type = Node; \
155 using typeName##Result = mozilla::Result<Node, NodeError>;
156 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
157 #undef DECLARE_TYPE
159 using NullNode = Node;
161 bool isNonArrowFunctionExpression(Node node) const {
162 return node == NodeFunctionExpression;
165 bool isPropertyOrPrivateMemberAccess(Node node) {
166 return node == NodeDottedProperty || node == NodeElement ||
167 node == NodePrivateMemberAccess;
170 bool isOptionalPropertyOrPrivateMemberAccess(Node node) {
171 return node == NodeOptionalDottedProperty || node == NodeOptionalElement ||
172 node == NodeOptionalPrivateMemberAccess;
175 bool isFunctionCall(Node node) {
176 // Note: super() is a special form, *not* a function call.
177 return node == NodeFunctionCall;
180 static bool isUnparenthesizedDestructuringPattern(Node node) {
181 return node == NodeUnparenthesizedArray ||
182 node == NodeUnparenthesizedObject;
185 static bool isParenthesizedDestructuringPattern(Node node) {
186 // Technically this isn't a destructuring target at all -- the grammar
187 // doesn't treat it as such. But we need to know when this happens to
188 // consider it a SyntaxError rather than an invalid-left-hand-side
189 // ReferenceError.
190 return node == NodeParenthesizedArray || node == NodeParenthesizedObject;
193 public:
194 SyntaxParseHandler(FrontendContext* fc, CompilationState& compilationState) {
195 MOZ_ASSERT(!compilationState.input.isDelazifying());
198 static NullNode null() { return NodeFailure; }
199 static constexpr NodeErrorResult errorResult() {
200 return NodeErrorResult(NodeError());
203 #define DECLARE_AS(typeName) \
204 static typeName##Type as##typeName(Node node) { return node; }
205 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
206 #undef DECLARE_AS
208 NameNodeResult newName(TaggedParserAtomIndex name, const TokenPos& pos) {
209 lastAtom = name;
210 if (name == TaggedParserAtomIndex::WellKnown::arguments()) {
211 return NodeArgumentsName;
213 if (pos.begin + strlen("async") == pos.end &&
214 name == TaggedParserAtomIndex::WellKnown::async()) {
215 return NodePotentialAsyncKeyword;
217 if (name == TaggedParserAtomIndex::WellKnown::eval()) {
218 return NodeEvalName;
220 return NodeName;
223 UnaryNodeResult newComputedName(Node expr, uint32_t start, uint32_t end) {
224 return NodeGeneric;
227 UnaryNodeResult newSyntheticComputedName(Node expr, uint32_t start,
228 uint32_t end) {
229 return NodeGeneric;
232 NameNodeResult newObjectLiteralPropertyName(TaggedParserAtomIndex atom,
233 const TokenPos& pos) {
234 return NodeName;
237 NameNodeResult newPrivateName(TaggedParserAtomIndex atom,
238 const TokenPos& pos) {
239 return NodePrivateName;
242 NumericLiteralResult newNumber(double value, DecimalPoint decimalPoint,
243 const TokenPos& pos) {
244 return NodeGeneric;
247 BigIntLiteralResult newBigInt() { return NodeGeneric; }
249 BooleanLiteralResult newBooleanLiteral(bool cond, const TokenPos& pos) {
250 return NodeGeneric;
253 NameNodeResult newStringLiteral(TaggedParserAtomIndex atom,
254 const TokenPos& pos) {
255 lastAtom = atom;
256 lastStringPos = pos;
257 return NodeUnparenthesizedString;
260 NameNodeResult newTemplateStringLiteral(TaggedParserAtomIndex atom,
261 const TokenPos& pos) {
262 return NodeGeneric;
265 CallSiteNodeResult newCallSiteObject(uint32_t begin) { return NodeGeneric; }
267 void addToCallSiteObject(CallSiteNodeType callSiteObj, Node rawNode,
268 Node cookedNode) {}
270 ThisLiteralResult newThisLiteral(const TokenPos& pos, Node thisName) {
271 return NodeGeneric;
273 NullLiteralResult newNullLiteral(const TokenPos& pos) { return NodeGeneric; }
274 RawUndefinedLiteralResult newRawUndefinedLiteral(const TokenPos& pos) {
275 return NodeGeneric;
278 RegExpLiteralResult newRegExp(Node reobj, const TokenPos& pos) {
279 return NodeGeneric;
282 ConditionalExpressionResult newConditional(Node cond, Node thenExpr,
283 Node elseExpr) {
284 return NodeGeneric;
287 UnaryNodeResult newDelete(uint32_t begin, Node expr) {
288 return NodeUnparenthesizedUnary;
291 UnaryNodeResult newTypeof(uint32_t begin, Node kid) {
292 return NodeUnparenthesizedUnary;
295 UnaryNodeResult newUnary(ParseNodeKind kind, uint32_t begin, Node kid) {
296 return NodeUnparenthesizedUnary;
299 UnaryNodeResult newUpdate(ParseNodeKind kind, uint32_t begin, Node kid) {
300 return NodeGeneric;
303 UnaryNodeResult newSpread(uint32_t begin, Node kid) { return NodeGeneric; }
305 NodeResult appendOrCreateList(ParseNodeKind kind, Node left, Node right,
306 ParseContext* pc) {
307 return NodeGeneric;
310 // Expressions
312 ListNodeResult newArrayLiteral(uint32_t begin) {
313 return NodeUnparenthesizedArray;
315 [[nodiscard]] bool addElision(ListNodeType literal, const TokenPos& pos) {
316 return true;
318 [[nodiscard]] bool addSpreadElement(ListNodeType literal, uint32_t begin,
319 Node inner) {
320 return true;
322 void addArrayElement(ListNodeType literal, Node element) {}
324 ListNodeResult newArguments(const TokenPos& pos) { return NodeGeneric; }
325 CallNodeResult newCall(Node callee, ListNodeType args, JSOp callOp) {
326 return NodeFunctionCall;
329 CallNodeResult newOptionalCall(Node callee, ListNodeType args, JSOp callOp) {
330 return NodeOptionalFunctionCall;
333 CallNodeResult newSuperCall(Node callee, ListNodeType args, bool isSpread) {
334 return NodeGeneric;
336 CallNodeResult newTaggedTemplate(Node tag, ListNodeType args, JSOp callOp) {
337 return NodeGeneric;
340 ListNodeResult newObjectLiteral(uint32_t begin) {
341 return NodeUnparenthesizedObject;
344 #ifdef ENABLE_RECORD_TUPLE
345 ListNodeResult newRecordLiteral(uint32_t begin) { return NodeGeneric; }
347 ListNodeResult newTupleLiteral(uint32_t begin) { return NodeGeneric; }
348 #endif
350 ListNodeResult newClassMemberList(uint32_t begin) { return NodeGeneric; }
351 ClassNamesResult newClassNames(Node outer, Node inner, const TokenPos& pos) {
352 return NodeGeneric;
354 ClassNodeResult newClass(Node name, Node heritage, Node methodBlock,
355 #ifdef ENABLE_DECORATORS
356 ListNodeType decorators,
357 #endif
358 const TokenPos& pos) {
359 return NodeGeneric;
362 LexicalScopeNodeResult newLexicalScope(Node body) {
363 return NodeLexicalDeclaration;
366 ClassBodyScopeNodeResult newClassBodyScope(Node body) {
367 return NodeLexicalDeclaration;
370 NewTargetNodeResult newNewTarget(NullaryNodeType newHolder,
371 NullaryNodeType targetHolder,
372 NameNodeType newTargetName) {
373 return NodeGeneric;
375 NullaryNodeResult newPosHolder(const TokenPos& pos) { return NodeGeneric; }
376 UnaryNodeResult newSuperBase(Node thisName, const TokenPos& pos) {
377 return NodeSuperBase;
380 [[nodiscard]] bool addPrototypeMutation(ListNodeType literal, uint32_t begin,
381 Node expr) {
382 return true;
384 BinaryNodeResult newPropertyDefinition(Node key, Node val) {
385 return NodeGeneric;
387 void addPropertyDefinition(ListNodeType literal, BinaryNodeType propdef) {}
388 [[nodiscard]] bool addPropertyDefinition(ListNodeType literal, Node key,
389 Node expr) {
390 return true;
392 [[nodiscard]] bool addShorthand(ListNodeType literal, NameNodeType name,
393 NameNodeType expr) {
394 return true;
396 [[nodiscard]] bool addSpreadProperty(ListNodeType literal, uint32_t begin,
397 Node inner) {
398 return true;
400 [[nodiscard]] bool addObjectMethodDefinition(ListNodeType literal, Node key,
401 FunctionNodeType funNode,
402 AccessorType atype) {
403 return true;
405 [[nodiscard]] NodeResult newDefaultClassConstructor(
406 Node key, FunctionNodeType funNode) {
407 return NodeGeneric;
409 [[nodiscard]] NodeResult newClassMethodDefinition(
410 Node key, FunctionNodeType funNode, AccessorType atype, bool isStatic,
411 mozilla::Maybe<FunctionNodeType> initializerIfPrivate
412 #ifdef ENABLE_DECORATORS
414 ListNodeType decorators
415 #endif
417 return NodeGeneric;
419 [[nodiscard]] NodeResult newClassFieldDefinition(
420 Node name, FunctionNodeType initializer, bool isStatic
421 #ifdef ENABLE_DECORATORS
423 ListNodeType decorators, ClassMethodType accessorGetterNode,
424 ClassMethodType accessorSetterNode
425 #endif
427 return NodeGeneric;
430 [[nodiscard]] NodeResult newStaticClassBlock(FunctionNodeType block) {
431 return NodeGeneric;
434 [[nodiscard]] bool addClassMemberDefinition(ListNodeType memberList,
435 Node member) {
436 return true;
438 UnaryNodeResult newYieldExpression(uint32_t begin, Node value) {
439 return NodeGeneric;
441 UnaryNodeResult newYieldStarExpression(uint32_t begin, Node value) {
442 return NodeGeneric;
444 UnaryNodeResult newAwaitExpression(uint32_t begin, Node value) {
445 return NodeUnparenthesizedUnary;
447 UnaryNodeResult newOptionalChain(uint32_t begin, Node value) {
448 return NodeGeneric;
451 // Statements
453 ListNodeResult newStatementList(const TokenPos& pos) { return NodeGeneric; }
454 void addStatementToList(ListNodeType list, Node stmt) {}
455 void setListEndPosition(ListNodeType list, const TokenPos& pos) {}
456 void addCaseStatementToList(ListNodeType list, CaseClauseType caseClause) {}
457 [[nodiscard]] bool prependInitialYield(ListNodeType stmtList, Node genName) {
458 return true;
460 NullaryNodeResult newEmptyStatement(const TokenPos& pos) {
461 return NodeEmptyStatement;
464 BinaryNodeResult newImportAssertion(Node keyNode, Node valueNode) {
465 return NodeGeneric;
467 BinaryNodeResult newModuleRequest(Node moduleSpec, Node importAssertionList,
468 const TokenPos& pos) {
469 return NodeGeneric;
471 BinaryNodeResult newImportDeclaration(Node importSpecSet, Node moduleRequest,
472 const TokenPos& pos) {
473 return NodeGeneric;
475 BinaryNodeResult newImportSpec(Node importNameNode, Node bindingName) {
476 return NodeGeneric;
478 UnaryNodeResult newImportNamespaceSpec(uint32_t begin, Node bindingName) {
479 return NodeGeneric;
481 UnaryNodeResult newExportDeclaration(Node kid, const TokenPos& pos) {
482 return NodeGeneric;
484 BinaryNodeResult newExportFromDeclaration(uint32_t begin, Node exportSpecSet,
485 Node moduleRequest) {
486 return NodeGeneric;
488 BinaryNodeResult newExportDefaultDeclaration(Node kid, Node maybeBinding,
489 const TokenPos& pos) {
490 return NodeGeneric;
492 BinaryNodeResult newExportSpec(Node bindingName, Node exportName) {
493 return NodeGeneric;
495 UnaryNodeResult newExportNamespaceSpec(uint32_t begin, Node exportName) {
496 return NodeGeneric;
498 NullaryNodeResult newExportBatchSpec(const TokenPos& pos) {
499 return NodeGeneric;
501 BinaryNodeResult newImportMeta(NullaryNodeType importHolder,
502 NullaryNodeType metaHolder) {
503 return NodeGeneric;
505 BinaryNodeResult newCallImport(NullaryNodeType importHolder, Node singleArg) {
506 return NodeGeneric;
508 BinaryNodeResult newCallImportSpec(Node specifierArg, Node optionalArg) {
509 return NodeGeneric;
512 BinaryNodeResult newSetThis(Node thisName, Node value) { return value; }
514 UnaryNodeResult newExprStatement(Node expr, uint32_t end) {
515 return expr == NodeUnparenthesizedString ? NodeStringExprStatement
516 : NodeGeneric;
519 TernaryNodeResult newIfStatement(uint32_t begin, Node cond, Node thenBranch,
520 Node elseBranch) {
521 return NodeGeneric;
523 BinaryNodeResult newDoWhileStatement(Node body, Node cond,
524 const TokenPos& pos) {
525 return NodeGeneric;
527 BinaryNodeResult newWhileStatement(uint32_t begin, Node cond, Node body) {
528 return NodeGeneric;
530 SwitchStatementResult newSwitchStatement(
531 uint32_t begin, Node discriminant,
532 LexicalScopeNodeType lexicalForCaseList, bool hasDefault) {
533 return NodeGeneric;
535 CaseClauseResult newCaseOrDefault(uint32_t begin, Node expr, Node body) {
536 return NodeGeneric;
538 ContinueStatementResult newContinueStatement(TaggedParserAtomIndex label,
539 const TokenPos& pos) {
540 return NodeGeneric;
542 BreakStatementResult newBreakStatement(TaggedParserAtomIndex label,
543 const TokenPos& pos) {
544 return NodeBreak;
546 UnaryNodeResult newReturnStatement(Node expr, const TokenPos& pos) {
547 return NodeReturn;
549 UnaryNodeResult newExpressionBody(Node expr) { return NodeReturn; }
550 BinaryNodeResult newWithStatement(uint32_t begin, Node expr, Node body) {
551 return NodeGeneric;
554 LabeledStatementResult newLabeledStatement(TaggedParserAtomIndex label,
555 Node stmt, uint32_t begin) {
556 return NodeGeneric;
559 UnaryNodeResult newThrowStatement(Node expr, const TokenPos& pos) {
560 return NodeThrow;
562 TernaryNodeResult newTryStatement(uint32_t begin, Node body,
563 LexicalScopeNodeType catchScope,
564 Node finallyBlock) {
565 return NodeGeneric;
567 DebuggerStatementResult newDebuggerStatement(const TokenPos& pos) {
568 return NodeGeneric;
571 NameNodeResult newPropertyName(TaggedParserAtomIndex name,
572 const TokenPos& pos) {
573 lastAtom = name;
574 return NodeGeneric;
577 PropertyAccessResult newPropertyAccess(Node expr, NameNodeType key) {
578 return NodeDottedProperty;
581 PropertyAccessResult newOptionalPropertyAccess(Node expr, NameNodeType key) {
582 return NodeOptionalDottedProperty;
585 PropertyByValueResult newPropertyByValue(Node lhs, Node index, uint32_t end) {
586 MOZ_ASSERT(!isPrivateName(index));
587 return NodeElement;
590 PropertyByValueResult newOptionalPropertyByValue(Node lhs, Node index,
591 uint32_t end) {
592 return NodeOptionalElement;
595 PrivateMemberAccessResult newPrivateMemberAccess(Node lhs, Node privateName,
596 uint32_t end) {
597 return NodePrivateMemberAccess;
600 PrivateMemberAccessResult newOptionalPrivateMemberAccess(Node lhs,
601 Node privateName,
602 uint32_t end) {
603 return NodeOptionalPrivateMemberAccess;
606 [[nodiscard]] bool setupCatchScope(LexicalScopeNodeType lexicalScope,
607 Node catchName, Node catchBody) {
608 return true;
611 [[nodiscard]] bool setLastFunctionFormalParameterDefault(
612 FunctionNodeType funNode, Node defaultValue) {
613 return true;
616 void checkAndSetIsDirectRHSAnonFunction(Node pn) {}
618 ParamsBodyNodeResult newParamsBody(const TokenPos& pos) {
619 return NodeGeneric;
622 FunctionNodeResult newFunction(FunctionSyntaxKind syntaxKind,
623 const TokenPos& pos) {
624 switch (syntaxKind) {
625 case FunctionSyntaxKind::Statement:
626 return NodeFunctionStatement;
627 case FunctionSyntaxKind::Arrow:
628 return NodeFunctionArrow;
629 default:
630 // All non-arrow function expressions are initially presumed to have
631 // block body. This will be overridden later *if* the function
632 // expression permissibly has an AssignmentExpression body.
633 return NodeFunctionExpression;
637 void setFunctionFormalParametersAndBody(FunctionNodeType funNode,
638 ParamsBodyNodeType paramsBody) {}
639 void setFunctionBody(FunctionNodeType funNode, LexicalScopeNodeType body) {}
640 void setFunctionBox(FunctionNodeType funNode, FunctionBox* funbox) {}
641 void addFunctionFormalParameter(FunctionNodeType funNode, Node argpn) {}
643 ForNodeResult newForStatement(uint32_t begin, TernaryNodeType forHead,
644 Node body, unsigned iflags) {
645 return NodeGeneric;
648 TernaryNodeResult newForHead(Node init, Node test, Node update,
649 const TokenPos& pos) {
650 return NodeGeneric;
653 TernaryNodeResult newForInOrOfHead(ParseNodeKind kind, Node target,
654 Node iteratedExpr, const TokenPos& pos) {
655 return NodeGeneric;
658 AssignmentNodeResult finishInitializerAssignment(NameNodeType nameNode,
659 Node init) {
660 return NodeUnparenthesizedAssignment;
663 void setBeginPosition(Node pn, Node oth) {}
664 void setBeginPosition(Node pn, uint32_t begin) {}
666 void setEndPosition(Node pn, Node oth) {}
667 void setEndPosition(Node pn, uint32_t end) {}
669 uint32_t getFunctionNameOffset(Node func, TokenStreamAnyChars& ts) {
670 // XXX This offset isn't relevant to the offending function name. But
671 // we may not *have* that function name around, because of how lazy
672 // parsing works -- the actual name could be outside
673 // |tokenStream.userbuf|'s observed region. So the current offset
674 // is the best we can do.
675 return ts.currentToken().pos.begin;
678 ListNodeResult newList(ParseNodeKind kind, const TokenPos& pos) {
679 MOZ_ASSERT(kind != ParseNodeKind::VarStmt);
680 MOZ_ASSERT(kind != ParseNodeKind::LetDecl);
681 MOZ_ASSERT(kind != ParseNodeKind::ConstDecl);
682 MOZ_ASSERT(kind != ParseNodeKind::ParamsBody);
683 return NodeGeneric;
686 ListNodeResult newList(ParseNodeKind kind, Node kid) {
687 return newList(kind, TokenPos());
690 DeclarationListNodeResult newDeclarationList(ParseNodeKind kind,
691 const TokenPos& pos) {
692 if (kind == ParseNodeKind::VarStmt) {
693 return NodeVarDeclaration;
695 MOZ_ASSERT(kind == ParseNodeKind::LetDecl ||
696 kind == ParseNodeKind::ConstDecl);
697 return NodeLexicalDeclaration;
700 ListNodeResult newCommaExpressionList(Node kid) { return NodeGeneric; }
702 void addList(ListNodeType list, Node kid) {
703 MOZ_ASSERT(list == NodeGeneric || list == NodeUnparenthesizedArray ||
704 list == NodeUnparenthesizedObject ||
705 list == NodeVarDeclaration || list == NodeLexicalDeclaration ||
706 list == NodeFunctionCall);
709 CallNodeResult newNewExpression(uint32_t begin, Node ctor, ListNodeType args,
710 bool isSpread) {
711 return NodeGeneric;
714 AssignmentNodeResult newAssignment(ParseNodeKind kind, Node lhs, Node rhs) {
715 return kind == ParseNodeKind::AssignExpr ? NodeUnparenthesizedAssignment
716 : NodeGeneric;
719 AssignmentNodeResult newInitExpr(Node lhs, Node rhs) { return NodeGeneric; }
721 bool isUnparenthesizedAssignment(Node node) {
722 return node == NodeUnparenthesizedAssignment;
725 bool isUnparenthesizedUnaryExpression(Node node) {
726 return node == NodeUnparenthesizedUnary;
729 bool isReturnStatement(Node node) { return node == NodeReturn; }
731 bool isStatementPermittedAfterReturnStatement(Node pn) {
732 return pn == NodeFunctionStatement || isNonArrowFunctionExpression(pn) ||
733 pn == NodeVarDeclaration || pn == NodeBreak || pn == NodeThrow ||
734 pn == NodeEmptyStatement;
737 bool isSuperBase(Node pn) { return pn == NodeSuperBase; }
739 void setListHasNonConstInitializer(ListNodeType literal) {}
741 // NOTE: This is infallible.
742 [[nodiscard]] Node parenthesize(Node node) {
743 // A number of nodes have different behavior upon parenthesization, but
744 // only in some circumstances. Convert these nodes to special
745 // parenthesized forms.
746 if (node == NodeUnparenthesizedArray) {
747 return NodeParenthesizedArray;
749 if (node == NodeUnparenthesizedObject) {
750 return NodeParenthesizedObject;
753 // Other nodes need not be recognizable after parenthesization; convert
754 // them to a generic node.
755 if (node == NodeUnparenthesizedString ||
756 node == NodeUnparenthesizedAssignment ||
757 node == NodeUnparenthesizedUnary) {
758 return NodeGeneric;
761 // Convert parenthesized |async| to a normal name node.
762 if (node == NodePotentialAsyncKeyword) {
763 return NodeName;
766 // In all other cases, the parenthesized form of |node| is equivalent
767 // to the unparenthesized form: return |node| unchanged.
768 return node;
771 // NOTE: This is infallible.
772 template <typename NodeType>
773 [[nodiscard]] NodeType setLikelyIIFE(NodeType node) {
774 return node; // Remain in syntax-parse mode.
777 bool isName(Node node) {
778 return node == NodeName || node == NodeArgumentsName ||
779 node == NodeEvalName || node == NodePotentialAsyncKeyword;
782 bool isArgumentsName(Node node) { return node == NodeArgumentsName; }
783 bool isEvalName(Node node) { return node == NodeEvalName; }
784 bool isAsyncKeyword(Node node) { return node == NodePotentialAsyncKeyword; }
786 bool isPrivateName(Node node) { return node == NodePrivateName; }
787 bool isPrivateMemberAccess(Node node) {
788 return node == NodePrivateMemberAccess;
791 TaggedParserAtomIndex maybeDottedProperty(Node node) {
792 // Note: |super.apply(...)| is a special form that calls an "apply"
793 // method retrieved from one value, but using a *different* value as
794 // |this|. It's not really eligible for the funapply/funcall
795 // optimizations as they're currently implemented (assuming a single
796 // value is used for both retrieval and |this|).
797 if (node != NodeDottedProperty && node != NodeOptionalDottedProperty) {
798 return TaggedParserAtomIndex::null();
800 return lastAtom;
803 TaggedParserAtomIndex isStringExprStatement(Node pn, TokenPos* pos) {
804 if (pn == NodeStringExprStatement) {
805 *pos = lastStringPos;
806 return lastAtom;
808 return TaggedParserAtomIndex::null();
811 bool reuseLazyInnerFunctions() { return false; }
812 bool reuseClosedOverBindings() { return false; }
813 TaggedParserAtomIndex nextLazyClosedOverBinding() {
814 MOZ_CRASH(
815 "SyntaxParseHandler::canSkipLazyClosedOverBindings must return false");
818 void setPrivateNameKind(Node node, PrivateNameKind kind) {}
821 } // namespace frontend
822 } // namespace js
824 #endif /* frontend_SyntaxParseHandler_h */