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_FullParseHandler_h
8 #define frontend_FullParseHandler_h
10 #include "mozilla/Maybe.h" // mozilla::Maybe
11 #include "mozilla/Result.h" // mozilla::Result, mozilla::UnusedZero
12 #include "mozilla/Try.h" // MOZ_TRY*
14 #include <cstddef> // std::nullptr_t
19 #include "frontend/CompilationStencil.h" // CompilationState
20 #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
21 #include "frontend/NameAnalysisTypes.h" // PrivateNameKind
22 #include "frontend/ParseNode.h"
23 #include "frontend/Parser-macros.h" // MOZ_TRY_VAR_OR_RETURN
24 #include "frontend/ParserAtom.h" // TaggedParserAtomIndex
25 #include "frontend/SharedContext.h"
26 #include "frontend/Stencil.h"
29 struct mozilla::detail::UnusedZero
<js::frontend::ParseNode
*> {
30 static const bool value
= true;
33 #define DEFINE_UNUSED_ZERO(typeName) \
35 struct mozilla::detail::UnusedZero<js::frontend::typeName*> { \
36 static const bool value = true; \
38 FOR_EACH_PARSENODE_SUBCLASS(DEFINE_UNUSED_ZERO
)
39 #undef DEFINE_UNUSED_ZERO
44 class TokenStreamAnyChars
;
46 // Parse handler used when generating a full parse tree for all code which the
48 class FullParseHandler
{
49 ParseNodeAllocator allocator
;
51 ParseNode
* allocParseNode(size_t size
) {
52 return static_cast<ParseNode
*>(allocator
.allocNode(size
));
55 // If this is a full parse to construct the bytecode for a function that
56 // was previously lazily parsed, we still don't want to full parse the
57 // inner functions. These members are used for this functionality:
59 // - reuseGCThings if ture it means that the following fields are valid.
60 // - gcThingsData holds an incomplete stencil-like copy of inner functions as
62 // - scriptData and scriptExtra_ hold information necessary to locate inner
63 // functions to skip over each.
64 // - lazyInnerFunctionIndex is used as we skip over inner functions
65 // (see skipLazyInnerFunction),
66 // - lazyClosedOverBindingIndex is used to synchronize binding computation
67 // with the scope traversal.
68 // (see propagateFreeNamesAndMarkClosedOverBindings),
69 const CompilationSyntaxParseCache
& previousParseCache_
;
71 size_t lazyInnerFunctionIndex
;
72 size_t lazyClosedOverBindingIndex
;
76 /* new_ methods for creating parse nodes. These report OOM on context. */
77 JS_DECLARE_NEW_METHODS(new_
, allocParseNode
, inline)
80 using NodeError
= ParseNodeError
;
82 using Node
= ParseNode
*;
83 using NodeResult
= ParseNodeResult
;
84 using NodeErrorResult
= mozilla::GenericErrorResult
<NodeError
>;
86 #define DECLARE_TYPE(typeName) \
87 using typeName##Type = typeName*; \
88 using typeName##Result = mozilla::Result<typeName*, NodeError>;
89 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE
)
92 template <class T
, typename
... Args
>
93 inline mozilla::Result
<T
*, NodeError
> newResult(Args
&&... args
) {
94 auto* node
= new_
<T
>(std::forward
<Args
>(args
)...);
96 return mozilla::Result
<T
*, NodeError
>(NodeError());
101 using NullNode
= std::nullptr_t
;
103 bool isPropertyOrPrivateMemberAccess(Node node
) {
104 return node
->isKind(ParseNodeKind::DotExpr
) ||
105 node
->isKind(ParseNodeKind::ElemExpr
) ||
106 node
->isKind(ParseNodeKind::PrivateMemberExpr
);
109 bool isOptionalPropertyOrPrivateMemberAccess(Node node
) {
110 return node
->isKind(ParseNodeKind::OptionalDotExpr
) ||
111 node
->isKind(ParseNodeKind::OptionalElemExpr
) ||
112 node
->isKind(ParseNodeKind::PrivateMemberExpr
);
115 bool isFunctionCall(Node node
) {
116 // Note: super() is a special form, *not* a function call.
117 return node
->isKind(ParseNodeKind::CallExpr
);
120 static bool isUnparenthesizedDestructuringPattern(Node node
) {
121 return !node
->isInParens() && (node
->isKind(ParseNodeKind::ObjectExpr
) ||
122 node
->isKind(ParseNodeKind::ArrayExpr
));
125 static bool isParenthesizedDestructuringPattern(Node node
) {
126 // Technically this isn't a destructuring pattern at all -- the grammar
127 // doesn't treat it as such. But we need to know when this happens to
128 // consider it a SyntaxError rather than an invalid-left-hand-side
130 return node
->isInParens() && (node
->isKind(ParseNodeKind::ObjectExpr
) ||
131 node
->isKind(ParseNodeKind::ArrayExpr
));
134 FullParseHandler(FrontendContext
* fc
, CompilationState
& compilationState
)
135 : allocator(fc
, compilationState
.parserAllocScope
.alloc()),
136 previousParseCache_(compilationState
.previousParseCache
),
137 lazyInnerFunctionIndex(0),
138 lazyClosedOverBindingIndex(0),
139 reuseGCThings(compilationState
.input
.isDelazifying()) {}
141 static NullNode
null() { return NullNode(); }
142 static constexpr NodeErrorResult
errorResult() {
143 return NodeErrorResult(NodeError());
146 #define DECLARE_AS(typeName) \
147 static typeName##Type as##typeName(Node node) { \
148 return &node->as<typeName>(); \
150 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS
)
153 NameNodeResult
newName(TaggedParserAtomIndex name
, const TokenPos
& pos
) {
154 return newResult
<NameNode
>(ParseNodeKind::Name
, name
, pos
);
157 UnaryNodeResult
newComputedName(Node expr
, uint32_t begin
, uint32_t end
) {
158 TokenPos
pos(begin
, end
);
159 return newResult
<UnaryNode
>(ParseNodeKind::ComputedName
, pos
, expr
);
162 UnaryNodeResult
newSyntheticComputedName(Node expr
, uint32_t begin
,
164 TokenPos
pos(begin
, end
);
167 newResult
<UnaryNode
>(ParseNodeKind::ComputedName
, pos
, expr
));
168 node
->setSyntheticComputedName();
172 NameNodeResult
newObjectLiteralPropertyName(TaggedParserAtomIndex atom
,
173 const TokenPos
& pos
) {
174 return newResult
<NameNode
>(ParseNodeKind::ObjectPropertyName
, atom
, pos
);
177 NameNodeResult
newPrivateName(TaggedParserAtomIndex atom
,
178 const TokenPos
& pos
) {
179 return newResult
<NameNode
>(ParseNodeKind::PrivateName
, atom
, pos
);
182 NumericLiteralResult
newNumber(double value
, DecimalPoint decimalPoint
,
183 const TokenPos
& pos
) {
184 return newResult
<NumericLiteral
>(value
, decimalPoint
, pos
);
187 BigIntLiteralResult
newBigInt(BigIntIndex index
, bool isZero
,
188 const TokenPos
& pos
) {
189 return newResult
<BigIntLiteral
>(index
, isZero
, pos
);
192 BooleanLiteralResult
newBooleanLiteral(bool cond
, const TokenPos
& pos
) {
193 return newResult
<BooleanLiteral
>(cond
, pos
);
196 NameNodeResult
newStringLiteral(TaggedParserAtomIndex atom
,
197 const TokenPos
& pos
) {
198 return newResult
<NameNode
>(ParseNodeKind::StringExpr
, atom
, pos
);
201 NameNodeResult
newTemplateStringLiteral(TaggedParserAtomIndex atom
,
202 const TokenPos
& pos
) {
203 return newResult
<NameNode
>(ParseNodeKind::TemplateStringExpr
, atom
, pos
);
206 CallSiteNodeResult
newCallSiteObject(uint32_t begin
) {
207 CallSiteNode
* callSiteObj
;
208 MOZ_TRY_VAR(callSiteObj
, newResult
<CallSiteNode
>(begin
));
211 MOZ_TRY_VAR(rawNodes
, newArrayLiteral(callSiteObj
->pn_pos
.begin
));
213 addArrayElement(callSiteObj
, rawNodes
);
218 void addToCallSiteObject(CallSiteNodeType callSiteObj
, Node rawNode
,
220 MOZ_ASSERT(callSiteObj
->isKind(ParseNodeKind::CallSiteObj
));
221 MOZ_ASSERT(rawNode
->isKind(ParseNodeKind::TemplateStringExpr
));
222 MOZ_ASSERT(cookedNode
->isKind(ParseNodeKind::TemplateStringExpr
) ||
223 cookedNode
->isKind(ParseNodeKind::RawUndefinedExpr
));
225 addArrayElement(callSiteObj
, cookedNode
);
226 addArrayElement(callSiteObj
->rawNodes(), rawNode
);
229 * We don't know when the last noSubstTemplate will come in, and we
230 * don't want to deal with this outside this method
232 setEndPosition(callSiteObj
, callSiteObj
->rawNodes());
235 ThisLiteralResult
newThisLiteral(const TokenPos
& pos
, Node thisName
) {
236 return newResult
<ThisLiteral
>(pos
, thisName
);
239 NullLiteralResult
newNullLiteral(const TokenPos
& pos
) {
240 return newResult
<NullLiteral
>(pos
);
243 RawUndefinedLiteralResult
newRawUndefinedLiteral(const TokenPos
& pos
) {
244 return newResult
<RawUndefinedLiteral
>(pos
);
247 RegExpLiteralResult
newRegExp(RegExpIndex index
, const TokenPos
& pos
) {
248 return newResult
<RegExpLiteral
>(index
, pos
);
251 ConditionalExpressionResult
newConditional(Node cond
, Node thenExpr
,
253 return newResult
<ConditionalExpression
>(cond
, thenExpr
, elseExpr
);
256 UnaryNodeResult
newDelete(uint32_t begin
, Node expr
) {
257 if (expr
->isKind(ParseNodeKind::Name
)) {
258 return newUnary(ParseNodeKind::DeleteNameExpr
, begin
, expr
);
261 if (expr
->isKind(ParseNodeKind::DotExpr
)) {
262 return newUnary(ParseNodeKind::DeletePropExpr
, begin
, expr
);
265 if (expr
->isKind(ParseNodeKind::ElemExpr
)) {
266 return newUnary(ParseNodeKind::DeleteElemExpr
, begin
, expr
);
269 if (expr
->isKind(ParseNodeKind::OptionalChain
)) {
270 Node kid
= expr
->as
<UnaryNode
>().kid();
271 // Handle property deletion explicitly. OptionalCall is handled
273 if (kid
->isKind(ParseNodeKind::DotExpr
) ||
274 kid
->isKind(ParseNodeKind::OptionalDotExpr
) ||
275 kid
->isKind(ParseNodeKind::ElemExpr
) ||
276 kid
->isKind(ParseNodeKind::OptionalElemExpr
)) {
277 return newUnary(ParseNodeKind::DeleteOptionalChainExpr
, begin
, kid
);
281 return newUnary(ParseNodeKind::DeleteExpr
, begin
, expr
);
284 UnaryNodeResult
newTypeof(uint32_t begin
, Node kid
) {
285 ParseNodeKind pnk
= kid
->isKind(ParseNodeKind::Name
)
286 ? ParseNodeKind::TypeOfNameExpr
287 : ParseNodeKind::TypeOfExpr
;
288 return newUnary(pnk
, begin
, kid
);
291 UnaryNodeResult
newUnary(ParseNodeKind kind
, uint32_t begin
, Node kid
) {
292 TokenPos
pos(begin
, kid
->pn_pos
.end
);
293 return newResult
<UnaryNode
>(kind
, pos
, kid
);
296 UnaryNodeResult
newUpdate(ParseNodeKind kind
, uint32_t begin
, Node kid
) {
297 TokenPos
pos(begin
, kid
->pn_pos
.end
);
298 return newResult
<UnaryNode
>(kind
, pos
, kid
);
301 UnaryNodeResult
newSpread(uint32_t begin
, Node kid
) {
302 TokenPos
pos(begin
, kid
->pn_pos
.end
);
303 return newResult
<UnaryNode
>(ParseNodeKind::Spread
, pos
, kid
);
307 BinaryNodeResult
newBinary(ParseNodeKind kind
, Node left
, Node right
) {
308 TokenPos
pos(left
->pn_pos
.begin
, right
->pn_pos
.end
);
309 return newResult
<BinaryNode
>(kind
, pos
, left
, right
);
313 NodeResult
appendOrCreateList(ParseNodeKind kind
, Node left
, Node right
,
315 return ParseNode::appendOrCreateList(kind
, left
, right
, this, pc
);
320 ListNodeResult
newArrayLiteral(uint32_t begin
) {
321 return newResult
<ListNode
>(ParseNodeKind::ArrayExpr
,
322 TokenPos(begin
, begin
+ 1));
325 [[nodiscard
]] bool addElision(ListNodeType literal
, const TokenPos
& pos
) {
326 MOZ_ASSERT(literal
->isKind(ParseNodeKind::ArrayExpr
));
328 NullaryNode
* elision
;
329 MOZ_TRY_VAR_OR_RETURN(
330 elision
, newResult
<NullaryNode
>(ParseNodeKind::Elision
, pos
), false);
331 addList(/* list = */ literal
, /* kid = */ elision
);
332 literal
->setHasNonConstInitializer();
336 [[nodiscard
]] bool addSpreadElement(ListNodeType literal
, uint32_t begin
,
339 literal
->isKind(ParseNodeKind::ArrayExpr
) ||
340 IF_RECORD_TUPLE(literal
->isKind(ParseNodeKind::TupleExpr
), false));
342 UnaryNodeType spread
;
343 MOZ_TRY_VAR_OR_RETURN(spread
, newSpread(begin
, inner
), false);
344 addList(/* list = */ literal
, /* kid = */ spread
);
345 literal
->setHasNonConstInitializer();
349 void addArrayElement(ListNodeType literal
, Node element
) {
351 literal
->isKind(ParseNodeKind::ArrayExpr
) ||
352 literal
->isKind(ParseNodeKind::CallSiteObj
) ||
353 IF_RECORD_TUPLE(literal
->isKind(ParseNodeKind::TupleExpr
), false));
354 if (!element
->isConstant()) {
355 literal
->setHasNonConstInitializer();
357 addList(/* list = */ literal
, /* kid = */ element
);
360 CallNodeResult
newCall(Node callee
, ListNodeType args
, JSOp callOp
) {
361 return newResult
<CallNode
>(ParseNodeKind::CallExpr
, callOp
, callee
, args
);
364 CallNodeResult
newOptionalCall(Node callee
, ListNodeType args
, JSOp callOp
) {
365 return newResult
<CallNode
>(ParseNodeKind::OptionalCallExpr
, callOp
, callee
,
369 ListNodeResult
newArguments(const TokenPos
& pos
) {
370 return newResult
<ListNode
>(ParseNodeKind::Arguments
, pos
);
373 CallNodeResult
newSuperCall(Node callee
, ListNodeType args
, bool isSpread
) {
374 return newResult
<CallNode
>(
375 ParseNodeKind::SuperCallExpr
,
376 isSpread
? JSOp::SpreadSuperCall
: JSOp::SuperCall
, callee
, args
);
379 CallNodeResult
newTaggedTemplate(Node tag
, ListNodeType args
, JSOp callOp
) {
380 return newResult
<CallNode
>(ParseNodeKind::TaggedTemplateExpr
, callOp
, tag
,
384 ListNodeResult
newObjectLiteral(uint32_t begin
) {
385 return newResult
<ListNode
>(ParseNodeKind::ObjectExpr
,
386 TokenPos(begin
, begin
+ 1));
389 #ifdef ENABLE_RECORD_TUPLE
390 ListNodeResult
newRecordLiteral(uint32_t begin
) {
391 return newResult
<ListNode
>(ParseNodeKind::RecordExpr
,
392 TokenPos(begin
, begin
+ 1));
395 ListNodeResult
newTupleLiteral(uint32_t begin
) {
396 return newResult
<ListNode
>(ParseNodeKind::TupleExpr
,
397 TokenPos(begin
, begin
+ 1));
401 ClassNodeResult
newClass(Node name
, Node heritage
,
402 LexicalScopeNodeType memberBlock
,
403 #ifdef ENABLE_DECORATORS
404 ListNodeType decorators
,
406 const TokenPos
& pos
) {
407 return newResult
<ClassNode
>(name
, heritage
, memberBlock
,
408 #ifdef ENABLE_DECORATORS
413 ListNodeResult
newClassMemberList(uint32_t begin
) {
414 return newResult
<ListNode
>(ParseNodeKind::ClassMemberList
,
415 TokenPos(begin
, begin
+ 1));
417 ClassNamesResult
newClassNames(Node outer
, Node inner
, const TokenPos
& pos
) {
418 return newResult
<ClassNames
>(outer
, inner
, pos
);
420 NewTargetNodeResult
newNewTarget(NullaryNodeType newHolder
,
421 NullaryNodeType targetHolder
,
422 NameNodeType newTargetName
) {
423 return newResult
<NewTargetNode
>(newHolder
, targetHolder
, newTargetName
);
425 NullaryNodeResult
newPosHolder(const TokenPos
& pos
) {
426 return newResult
<NullaryNode
>(ParseNodeKind::PosHolder
, pos
);
428 UnaryNodeResult
newSuperBase(Node thisName
, const TokenPos
& pos
) {
429 return newResult
<UnaryNode
>(ParseNodeKind::SuperBase
, pos
, thisName
);
431 [[nodiscard
]] bool addPrototypeMutation(ListNodeType literal
, uint32_t begin
,
433 MOZ_ASSERT(literal
->isKind(ParseNodeKind::ObjectExpr
));
435 // Object literals with mutated [[Prototype]] are non-constant so that
436 // singleton objects will have Object.prototype as their [[Prototype]].
437 literal
->setHasNonConstInitializer();
440 MOZ_TRY_VAR_OR_RETURN(
441 mutation
, newUnary(ParseNodeKind::MutateProto
, begin
, expr
), false);
442 addList(/* list = */ literal
, /* kid = */ mutation
);
446 BinaryNodeResult
newPropertyDefinition(Node key
, Node val
) {
447 MOZ_ASSERT(isUsableAsObjectPropertyName(key
));
448 checkAndSetIsDirectRHSAnonFunction(val
);
449 return newResult
<PropertyDefinition
>(key
, val
, AccessorType::None
);
452 void addPropertyDefinition(ListNodeType literal
, BinaryNodeType propdef
) {
454 literal
->isKind(ParseNodeKind::ObjectExpr
) ||
455 IF_RECORD_TUPLE(literal
->isKind(ParseNodeKind::RecordExpr
), false));
456 MOZ_ASSERT(propdef
->isKind(ParseNodeKind::PropertyDefinition
));
458 if (!propdef
->right()->isConstant()) {
459 literal
->setHasNonConstInitializer();
462 addList(/* list = */ literal
, /* kid = */ propdef
);
465 [[nodiscard
]] bool addPropertyDefinition(ListNodeType literal
, Node key
,
468 MOZ_TRY_VAR_OR_RETURN(propdef
, newPropertyDefinition(key
, val
), false);
469 addPropertyDefinition(literal
, propdef
);
473 [[nodiscard
]] bool addShorthand(ListNodeType literal
, NameNodeType name
,
476 literal
->isKind(ParseNodeKind::ObjectExpr
) ||
477 IF_RECORD_TUPLE(literal
->isKind(ParseNodeKind::RecordExpr
), false));
478 MOZ_ASSERT(name
->isKind(ParseNodeKind::ObjectPropertyName
));
479 MOZ_ASSERT(expr
->isKind(ParseNodeKind::Name
));
480 MOZ_ASSERT(name
->atom() == expr
->atom());
482 literal
->setHasNonConstInitializer();
484 MOZ_TRY_VAR_OR_RETURN(
485 propdef
, newBinary(ParseNodeKind::Shorthand
, name
, expr
), false);
486 addList(/* list = */ literal
, /* kid = */ propdef
);
490 [[nodiscard
]] bool addSpreadProperty(ListNodeType literal
, uint32_t begin
,
493 literal
->isKind(ParseNodeKind::ObjectExpr
) ||
494 IF_RECORD_TUPLE(literal
->isKind(ParseNodeKind::RecordExpr
), false));
496 literal
->setHasNonConstInitializer();
498 MOZ_TRY_VAR_OR_RETURN(spread
, newSpread(begin
, inner
), false);
499 addList(/* list = */ literal
, /* kid = */ spread
);
503 [[nodiscard
]] bool addObjectMethodDefinition(ListNodeType literal
, Node key
,
504 FunctionNodeType funNode
,
505 AccessorType atype
) {
506 literal
->setHasNonConstInitializer();
508 checkAndSetIsDirectRHSAnonFunction(funNode
);
511 MOZ_TRY_VAR_OR_RETURN(
512 propdef
, newObjectMethodOrPropertyDefinition(key
, funNode
, atype
),
514 addList(/* list = */ literal
, /* kid = */ propdef
);
518 [[nodiscard
]] ClassMethodResult
newDefaultClassConstructor(
519 Node key
, FunctionNodeType funNode
) {
520 MOZ_ASSERT(isUsableAsObjectPropertyName(key
));
522 checkAndSetIsDirectRHSAnonFunction(funNode
);
524 return newResult
<ClassMethod
>(
525 ParseNodeKind::DefaultConstructor
, key
, funNode
, AccessorType::None
,
526 /* isStatic = */ false, /* initializeIfPrivate = */ nullptr
527 #ifdef ENABLE_DECORATORS
529 /* decorators = */ nullptr
534 [[nodiscard
]] ClassMethodResult
newClassMethodDefinition(
535 Node key
, FunctionNodeType funNode
, AccessorType atype
, bool isStatic
,
536 mozilla::Maybe
<FunctionNodeType
> initializerIfPrivate
537 #ifdef ENABLE_DECORATORS
539 ListNodeType decorators
542 MOZ_ASSERT(isUsableAsObjectPropertyName(key
));
544 checkAndSetIsDirectRHSAnonFunction(funNode
);
546 if (initializerIfPrivate
.isSome()) {
547 return newResult
<ClassMethod
>(ParseNodeKind::ClassMethod
, key
, funNode
,
549 initializerIfPrivate
.value()
550 #ifdef ENABLE_DECORATORS
556 return newResult
<ClassMethod
>(ParseNodeKind::ClassMethod
, key
, funNode
,
558 /* initializeIfPrivate = */ nullptr
559 #ifdef ENABLE_DECORATORS
566 [[nodiscard
]] ClassFieldResult
newClassFieldDefinition(
567 Node name
, FunctionNodeType initializer
, bool isStatic
568 #ifdef ENABLE_DECORATORS
570 ListNodeType decorators
, ClassMethodType accessorGetterNode
,
571 ClassMethodType accessorSetterNode
574 MOZ_ASSERT(isUsableAsObjectPropertyName(name
));
576 return newResult
<ClassField
>(name
, initializer
, isStatic
577 #if ENABLE_DECORATORS
579 decorators
, accessorGetterNode
,
585 [[nodiscard
]] StaticClassBlockResult
newStaticClassBlock(
586 FunctionNodeType block
) {
587 return newResult
<StaticClassBlock
>(block
);
590 [[nodiscard
]] bool addClassMemberDefinition(ListNodeType memberList
,
592 MOZ_ASSERT(memberList
->isKind(ParseNodeKind::ClassMemberList
));
593 // Constructors can be surrounded by LexicalScopes.
594 MOZ_ASSERT(member
->isKind(ParseNodeKind::DefaultConstructor
) ||
595 member
->isKind(ParseNodeKind::ClassMethod
) ||
596 member
->isKind(ParseNodeKind::ClassField
) ||
597 member
->isKind(ParseNodeKind::StaticClassBlock
) ||
598 (member
->isKind(ParseNodeKind::LexicalScope
) &&
599 member
->as
<LexicalScopeNode
>().scopeBody()->is
<ClassMethod
>()));
601 addList(/* list = */ memberList
, /* kid = */ member
);
605 UnaryNodeResult
newInitialYieldExpression(uint32_t begin
, Node gen
) {
606 TokenPos
pos(begin
, begin
+ 1);
607 return newResult
<UnaryNode
>(ParseNodeKind::InitialYield
, pos
, gen
);
610 UnaryNodeResult
newYieldExpression(uint32_t begin
, Node value
) {
611 TokenPos
pos(begin
, value
? value
->pn_pos
.end
: begin
+ 1);
612 return newResult
<UnaryNode
>(ParseNodeKind::YieldExpr
, pos
, value
);
615 UnaryNodeResult
newYieldStarExpression(uint32_t begin
, Node value
) {
616 TokenPos
pos(begin
, value
->pn_pos
.end
);
617 return newResult
<UnaryNode
>(ParseNodeKind::YieldStarExpr
, pos
, value
);
620 UnaryNodeResult
newAwaitExpression(uint32_t begin
, Node value
) {
621 TokenPos
pos(begin
, value
? value
->pn_pos
.end
: begin
+ 1);
622 return newResult
<UnaryNode
>(ParseNodeKind::AwaitExpr
, pos
, value
);
625 UnaryNodeResult
newOptionalChain(uint32_t begin
, Node value
) {
626 TokenPos
pos(begin
, value
->pn_pos
.end
);
627 return newResult
<UnaryNode
>(ParseNodeKind::OptionalChain
, pos
, value
);
632 ListNodeResult
newStatementList(const TokenPos
& pos
) {
633 return newResult
<ListNode
>(ParseNodeKind::StatementList
, pos
);
636 [[nodiscard
]] bool isFunctionStmt(Node stmt
) {
637 while (stmt
->isKind(ParseNodeKind::LabelStmt
)) {
638 stmt
= stmt
->as
<LabeledStatement
>().statement();
640 return stmt
->is
<FunctionNode
>();
643 void addStatementToList(ListNodeType list
, Node stmt
) {
644 MOZ_ASSERT(list
->isKind(ParseNodeKind::StatementList
));
646 addList(/* list = */ list
, /* kid = */ stmt
);
648 if (isFunctionStmt(stmt
)) {
649 // Notify the emitter that the block contains body-level function
650 // definitions that should be processed before the rest of nodes.
651 list
->setHasTopLevelFunctionDeclarations();
655 void setListEndPosition(ListNodeType list
, const TokenPos
& pos
) {
656 MOZ_ASSERT(list
->isKind(ParseNodeKind::StatementList
));
657 list
->pn_pos
.end
= pos
.end
;
660 void addCaseStatementToList(ListNodeType list
, CaseClauseType caseClause
) {
661 MOZ_ASSERT(list
->isKind(ParseNodeKind::StatementList
));
663 addList(/* list = */ list
, /* kid = */ caseClause
);
665 if (caseClause
->statementList()->hasTopLevelFunctionDeclarations()) {
666 list
->setHasTopLevelFunctionDeclarations();
670 [[nodiscard
]] bool prependInitialYield(ListNodeType stmtList
, Node genName
) {
671 MOZ_ASSERT(stmtList
->isKind(ParseNodeKind::StatementList
));
673 TokenPos
yieldPos(stmtList
->pn_pos
.begin
, stmtList
->pn_pos
.begin
+ 1);
674 NullaryNode
* makeGen
;
675 MOZ_TRY_VAR_OR_RETURN(
676 makeGen
, newResult
<NullaryNode
>(ParseNodeKind::Generator
, yieldPos
),
680 MOZ_TRY_VAR_OR_RETURN(
682 newAssignment(ParseNodeKind::AssignExpr
, /* lhs = */ genName
,
683 /* rhs = */ makeGen
),
686 UnaryNode
* initialYield
;
687 MOZ_TRY_VAR_OR_RETURN(initialYield
,
688 newInitialYieldExpression(yieldPos
.begin
, genInit
),
691 stmtList
->prepend(initialYield
);
695 BinaryNodeResult
newSetThis(Node thisName
, Node value
) {
696 return newBinary(ParseNodeKind::SetThis
, thisName
, value
);
699 NullaryNodeResult
newEmptyStatement(const TokenPos
& pos
) {
700 return newResult
<NullaryNode
>(ParseNodeKind::EmptyStmt
, pos
);
703 BinaryNodeResult
newImportAssertion(Node keyNode
, Node valueNode
) {
704 return newBinary(ParseNodeKind::ImportAssertion
, keyNode
, valueNode
);
707 BinaryNodeResult
newModuleRequest(Node moduleSpec
, Node importAssertionList
,
708 const TokenPos
& pos
) {
709 return newResult
<BinaryNode
>(ParseNodeKind::ImportModuleRequest
, pos
,
710 moduleSpec
, importAssertionList
);
713 BinaryNodeResult
newImportDeclaration(Node importSpecSet
, Node moduleRequest
,
714 const TokenPos
& pos
) {
715 return newResult
<BinaryNode
>(ParseNodeKind::ImportDecl
, pos
, importSpecSet
,
719 BinaryNodeResult
newImportSpec(Node importNameNode
, Node bindingName
) {
720 return newBinary(ParseNodeKind::ImportSpec
, importNameNode
, bindingName
);
723 UnaryNodeResult
newImportNamespaceSpec(uint32_t begin
, Node bindingName
) {
724 return newUnary(ParseNodeKind::ImportNamespaceSpec
, begin
, bindingName
);
727 UnaryNodeResult
newExportDeclaration(Node kid
, const TokenPos
& pos
) {
728 return newResult
<UnaryNode
>(ParseNodeKind::ExportStmt
, pos
, kid
);
731 BinaryNodeResult
newExportFromDeclaration(uint32_t begin
, Node exportSpecSet
,
732 Node moduleRequest
) {
734 MOZ_TRY_VAR(decl
, newResult
<BinaryNode
>(ParseNodeKind::ExportFromStmt
,
735 exportSpecSet
, moduleRequest
));
736 decl
->pn_pos
.begin
= begin
;
740 BinaryNodeResult
newExportDefaultDeclaration(Node kid
, Node maybeBinding
,
741 const TokenPos
& pos
) {
743 MOZ_ASSERT(maybeBinding
->isKind(ParseNodeKind::Name
));
744 MOZ_ASSERT(!maybeBinding
->isInParens());
746 checkAndSetIsDirectRHSAnonFunction(kid
);
749 return newResult
<BinaryNode
>(ParseNodeKind::ExportDefaultStmt
, pos
, kid
,
753 BinaryNodeResult
newExportSpec(Node bindingName
, Node exportName
) {
754 return newBinary(ParseNodeKind::ExportSpec
, bindingName
, exportName
);
757 UnaryNodeResult
newExportNamespaceSpec(uint32_t begin
, Node exportName
) {
758 return newUnary(ParseNodeKind::ExportNamespaceSpec
, begin
, exportName
);
761 NullaryNodeResult
newExportBatchSpec(const TokenPos
& pos
) {
762 return newResult
<NullaryNode
>(ParseNodeKind::ExportBatchSpecStmt
, pos
);
765 BinaryNodeResult
newImportMeta(NullaryNodeType importHolder
,
766 NullaryNodeType metaHolder
) {
767 return newResult
<BinaryNode
>(ParseNodeKind::ImportMetaExpr
, importHolder
,
771 BinaryNodeResult
newCallImport(NullaryNodeType importHolder
, Node singleArg
) {
772 return newResult
<BinaryNode
>(ParseNodeKind::CallImportExpr
, importHolder
,
776 BinaryNodeResult
newCallImportSpec(Node specifierArg
, Node optionalArg
) {
777 return newResult
<BinaryNode
>(ParseNodeKind::CallImportSpec
, specifierArg
,
781 UnaryNodeResult
newExprStatement(Node expr
, uint32_t end
) {
782 MOZ_ASSERT(expr
->pn_pos
.end
<= end
);
783 return newResult
<UnaryNode
>(ParseNodeKind::ExpressionStmt
,
784 TokenPos(expr
->pn_pos
.begin
, end
), expr
);
787 TernaryNodeResult
newIfStatement(uint32_t begin
, Node cond
, Node thenBranch
,
790 MOZ_TRY_VAR(node
, newResult
<TernaryNode
>(ParseNodeKind::IfStmt
, cond
,
791 thenBranch
, elseBranch
));
792 node
->pn_pos
.begin
= begin
;
796 BinaryNodeResult
newDoWhileStatement(Node body
, Node cond
,
797 const TokenPos
& pos
) {
798 return newResult
<BinaryNode
>(ParseNodeKind::DoWhileStmt
, pos
, body
, cond
);
801 BinaryNodeResult
newWhileStatement(uint32_t begin
, Node cond
, Node body
) {
802 TokenPos
pos(begin
, body
->pn_pos
.end
);
803 return newResult
<BinaryNode
>(ParseNodeKind::WhileStmt
, pos
, cond
, body
);
806 ForNodeResult
newForStatement(uint32_t begin
, TernaryNodeType forHead
,
807 Node body
, unsigned iflags
) {
808 return newResult
<ForNode
>(TokenPos(begin
, body
->pn_pos
.end
), forHead
, body
,
812 TernaryNodeResult
newForHead(Node init
, Node test
, Node update
,
813 const TokenPos
& pos
) {
814 return newResult
<TernaryNode
>(ParseNodeKind::ForHead
, init
, test
, update
,
818 TernaryNodeResult
newForInOrOfHead(ParseNodeKind kind
, Node target
,
819 Node iteratedExpr
, const TokenPos
& pos
) {
820 MOZ_ASSERT(kind
== ParseNodeKind::ForIn
|| kind
== ParseNodeKind::ForOf
);
821 return newResult
<TernaryNode
>(kind
, target
, nullptr, iteratedExpr
, pos
);
824 SwitchStatementResult
newSwitchStatement(
825 uint32_t begin
, Node discriminant
,
826 LexicalScopeNodeType lexicalForCaseList
, bool hasDefault
) {
827 return newResult
<SwitchStatement
>(begin
, discriminant
, lexicalForCaseList
,
831 CaseClauseResult
newCaseOrDefault(uint32_t begin
, Node expr
, Node body
) {
832 return newResult
<CaseClause
>(expr
, body
, begin
);
835 ContinueStatementResult
newContinueStatement(TaggedParserAtomIndex label
,
836 const TokenPos
& pos
) {
837 return newResult
<ContinueStatement
>(label
, pos
);
840 BreakStatementResult
newBreakStatement(TaggedParserAtomIndex label
,
841 const TokenPos
& pos
) {
842 return newResult
<BreakStatement
>(label
, pos
);
845 UnaryNodeResult
newReturnStatement(Node expr
, const TokenPos
& pos
) {
846 MOZ_ASSERT_IF(expr
, pos
.encloses(expr
->pn_pos
));
847 return newResult
<UnaryNode
>(ParseNodeKind::ReturnStmt
, pos
, expr
);
850 UnaryNodeResult
newExpressionBody(Node expr
) {
851 return newResult
<UnaryNode
>(ParseNodeKind::ReturnStmt
, expr
->pn_pos
, expr
);
854 BinaryNodeResult
newWithStatement(uint32_t begin
, Node expr
, Node body
) {
855 return newResult
<BinaryNode
>(ParseNodeKind::WithStmt
,
856 TokenPos(begin
, body
->pn_pos
.end
), expr
, body
);
859 LabeledStatementResult
newLabeledStatement(TaggedParserAtomIndex label
,
860 Node stmt
, uint32_t begin
) {
861 return newResult
<LabeledStatement
>(label
, stmt
, begin
);
864 UnaryNodeResult
newThrowStatement(Node expr
, const TokenPos
& pos
) {
865 MOZ_ASSERT(pos
.encloses(expr
->pn_pos
));
866 return newResult
<UnaryNode
>(ParseNodeKind::ThrowStmt
, pos
, expr
);
869 TernaryNodeResult
newTryStatement(uint32_t begin
, Node body
,
870 LexicalScopeNodeType catchScope
,
872 return newResult
<TryNode
>(begin
, body
, catchScope
, finallyBlock
);
875 DebuggerStatementResult
newDebuggerStatement(const TokenPos
& pos
) {
876 return newResult
<DebuggerStatement
>(pos
);
879 NameNodeResult
newPropertyName(TaggedParserAtomIndex name
,
880 const TokenPos
& pos
) {
881 return newResult
<NameNode
>(ParseNodeKind::PropertyNameExpr
, name
, pos
);
884 PropertyAccessResult
newPropertyAccess(Node expr
, NameNodeType key
) {
885 return newResult
<PropertyAccess
>(expr
, key
, expr
->pn_pos
.begin
,
889 PropertyByValueResult
newPropertyByValue(Node lhs
, Node index
, uint32_t end
) {
890 return newResult
<PropertyByValue
>(lhs
, index
, lhs
->pn_pos
.begin
, end
);
893 OptionalPropertyAccessResult
newOptionalPropertyAccess(Node expr
,
895 return newResult
<OptionalPropertyAccess
>(expr
, key
, expr
->pn_pos
.begin
,
899 OptionalPropertyByValueResult
newOptionalPropertyByValue(Node lhs
, Node index
,
901 return newResult
<OptionalPropertyByValue
>(lhs
, index
, lhs
->pn_pos
.begin
,
905 PrivateMemberAccessResult
newPrivateMemberAccess(Node lhs
,
906 NameNodeType privateName
,
908 return newResult
<PrivateMemberAccess
>(lhs
, privateName
, lhs
->pn_pos
.begin
,
912 OptionalPrivateMemberAccessResult
newOptionalPrivateMemberAccess(
913 Node lhs
, NameNodeType privateName
, uint32_t end
) {
914 return newResult
<OptionalPrivateMemberAccess
>(lhs
, privateName
,
915 lhs
->pn_pos
.begin
, end
);
918 bool setupCatchScope(LexicalScopeNodeType lexicalScope
, Node catchName
,
920 BinaryNode
* catchClause
;
922 MOZ_TRY_VAR_OR_RETURN(
924 newResult
<BinaryNode
>(ParseNodeKind::Catch
, catchName
, catchBody
),
927 MOZ_TRY_VAR_OR_RETURN(
929 newResult
<BinaryNode
>(ParseNodeKind::Catch
, catchBody
->pn_pos
,
930 catchName
, catchBody
),
933 lexicalScope
->setScopeBody(catchClause
);
937 [[nodiscard
]] inline bool setLastFunctionFormalParameterDefault(
938 FunctionNodeType funNode
, Node defaultValue
);
940 void checkAndSetIsDirectRHSAnonFunction(Node pn
) {
941 if (IsAnonymousFunctionDefinition(pn
)) {
942 pn
->setDirectRHSAnonFunction(true);
946 ParamsBodyNodeResult
newParamsBody(const TokenPos
& pos
) {
947 return newResult
<ParamsBodyNode
>(pos
);
950 FunctionNodeResult
newFunction(FunctionSyntaxKind syntaxKind
,
951 const TokenPos
& pos
) {
952 return newResult
<FunctionNode
>(syntaxKind
, pos
);
955 BinaryNodeResult
newObjectMethodOrPropertyDefinition(Node key
, Node value
,
956 AccessorType atype
) {
957 MOZ_ASSERT(isUsableAsObjectPropertyName(key
));
959 return newResult
<PropertyDefinition
>(key
, value
, atype
);
962 void setFunctionFormalParametersAndBody(FunctionNodeType funNode
,
963 ParamsBodyNodeType paramsBody
) {
964 funNode
->setBody(paramsBody
);
966 void setFunctionBox(FunctionNodeType funNode
, FunctionBox
* funbox
) {
967 funNode
->setFunbox(funbox
);
968 funbox
->functionNode
= funNode
;
970 void addFunctionFormalParameter(FunctionNodeType funNode
, Node argpn
) {
971 addList(/* list = */ funNode
->body(), /* kid = */ argpn
);
973 void setFunctionBody(FunctionNodeType funNode
, LexicalScopeNodeType body
) {
974 addList(/* list = */ funNode
->body(), /* kid = */ body
);
977 ModuleNodeResult
newModule(const TokenPos
& pos
) {
978 return newResult
<ModuleNode
>(pos
);
981 LexicalScopeNodeResult
newLexicalScope(LexicalScope::ParserData
* bindings
,
983 ScopeKind kind
= ScopeKind::Lexical
) {
984 return newResult
<LexicalScopeNode
>(bindings
, body
, kind
);
987 ClassBodyScopeNodeResult
newClassBodyScope(
988 ClassBodyScope::ParserData
* bindings
, ListNodeType body
) {
989 return newResult
<ClassBodyScopeNode
>(bindings
, body
);
992 CallNodeResult
newNewExpression(uint32_t begin
, Node ctor
, ListNodeType args
,
994 return newResult
<CallNode
>(ParseNodeKind::NewExpr
,
995 isSpread
? JSOp::SpreadNew
: JSOp::New
,
996 TokenPos(begin
, args
->pn_pos
.end
), ctor
, args
);
999 AssignmentNodeResult
newAssignment(ParseNodeKind kind
, Node lhs
, Node rhs
) {
1000 if ((kind
== ParseNodeKind::AssignExpr
||
1001 kind
== ParseNodeKind::CoalesceAssignExpr
||
1002 kind
== ParseNodeKind::OrAssignExpr
||
1003 kind
== ParseNodeKind::AndAssignExpr
) &&
1004 lhs
->isKind(ParseNodeKind::Name
) && !lhs
->isInParens()) {
1005 checkAndSetIsDirectRHSAnonFunction(rhs
);
1008 return newResult
<AssignmentNode
>(kind
, lhs
, rhs
);
1011 BinaryNodeResult
newInitExpr(Node lhs
, Node rhs
) {
1012 TokenPos
pos(lhs
->pn_pos
.begin
, rhs
->pn_pos
.end
);
1013 return newResult
<BinaryNode
>(ParseNodeKind::InitExpr
, pos
, lhs
, rhs
);
1016 bool isUnparenthesizedAssignment(Node node
) {
1017 if ((node
->isKind(ParseNodeKind::AssignExpr
)) && !node
->isInParens()) {
1024 bool isUnparenthesizedUnaryExpression(Node node
) {
1025 if (!node
->isInParens()) {
1026 ParseNodeKind kind
= node
->getKind();
1027 return kind
== ParseNodeKind::VoidExpr
||
1028 kind
== ParseNodeKind::NotExpr
||
1029 kind
== ParseNodeKind::BitNotExpr
||
1030 kind
== ParseNodeKind::PosExpr
|| kind
== ParseNodeKind::NegExpr
||
1031 kind
== ParseNodeKind::AwaitExpr
|| IsTypeofKind(kind
) ||
1037 bool isReturnStatement(Node node
) {
1038 return node
->isKind(ParseNodeKind::ReturnStmt
);
1041 bool isStatementPermittedAfterReturnStatement(Node node
) {
1042 ParseNodeKind kind
= node
->getKind();
1043 return kind
== ParseNodeKind::Function
|| kind
== ParseNodeKind::VarStmt
||
1044 kind
== ParseNodeKind::BreakStmt
||
1045 kind
== ParseNodeKind::ThrowStmt
|| kind
== ParseNodeKind::EmptyStmt
;
1048 bool isSuperBase(Node node
) { return node
->isKind(ParseNodeKind::SuperBase
); }
1050 bool isUsableAsObjectPropertyName(Node node
) {
1051 return node
->isKind(ParseNodeKind::NumberExpr
) ||
1052 node
->isKind(ParseNodeKind::BigIntExpr
) ||
1053 node
->isKind(ParseNodeKind::ObjectPropertyName
) ||
1054 node
->isKind(ParseNodeKind::StringExpr
) ||
1055 node
->isKind(ParseNodeKind::ComputedName
) ||
1056 node
->isKind(ParseNodeKind::PrivateName
);
1059 AssignmentNodeResult
finishInitializerAssignment(NameNodeType nameNode
,
1061 MOZ_ASSERT(nameNode
->isKind(ParseNodeKind::Name
));
1062 MOZ_ASSERT(!nameNode
->isInParens());
1064 checkAndSetIsDirectRHSAnonFunction(init
);
1066 return newAssignment(ParseNodeKind::AssignExpr
, nameNode
, init
);
1069 void setBeginPosition(Node pn
, Node oth
) {
1070 setBeginPosition(pn
, oth
->pn_pos
.begin
);
1072 void setBeginPosition(Node pn
, uint32_t begin
) {
1073 pn
->pn_pos
.begin
= begin
;
1074 MOZ_ASSERT(pn
->pn_pos
.begin
<= pn
->pn_pos
.end
);
1077 void setEndPosition(Node pn
, Node oth
) {
1078 setEndPosition(pn
, oth
->pn_pos
.end
);
1080 void setEndPosition(Node pn
, uint32_t end
) {
1081 pn
->pn_pos
.end
= end
;
1082 MOZ_ASSERT(pn
->pn_pos
.begin
<= pn
->pn_pos
.end
);
1085 uint32_t getFunctionNameOffset(Node func
, TokenStreamAnyChars
& ts
) {
1086 return func
->pn_pos
.begin
;
1089 ListNodeResult
newList(ParseNodeKind kind
, const TokenPos
& pos
) {
1090 auto list
= newResult
<ListNode
>(kind
, pos
);
1091 MOZ_ASSERT_IF(list
.isOk(), !list
.unwrap()->is
<DeclarationListNode
>());
1092 MOZ_ASSERT_IF(list
.isOk(), !list
.unwrap()->is
<ParamsBodyNode
>());
1096 ListNodeResult
newList(ParseNodeKind kind
, Node kid
) {
1097 auto list
= newResult
<ListNode
>(kind
, kid
);
1098 MOZ_ASSERT_IF(list
.isOk(), !list
.unwrap()->is
<DeclarationListNode
>());
1099 MOZ_ASSERT_IF(list
.isOk(), !list
.unwrap()->is
<ParamsBodyNode
>());
1103 DeclarationListNodeResult
newDeclarationList(ParseNodeKind kind
,
1104 const TokenPos
& pos
) {
1105 return newResult
<DeclarationListNode
>(kind
, pos
);
1108 ListNodeResult
newCommaExpressionList(Node kid
) {
1109 return newResult
<ListNode
>(ParseNodeKind::CommaExpr
, kid
);
1112 void addList(ListNodeType list
, Node kid
) { list
->append(kid
); }
1114 void setListHasNonConstInitializer(ListNodeType literal
) {
1115 literal
->setHasNonConstInitializer();
1118 // NOTE: This is infallible.
1119 template <typename NodeType
>
1120 [[nodiscard
]] NodeType
parenthesize(NodeType node
) {
1121 node
->setInParens(true);
1125 // NOTE: This is infallible.
1126 template <typename NodeType
>
1127 [[nodiscard
]] NodeType
setLikelyIIFE(NodeType node
) {
1128 return parenthesize(node
);
1131 bool isName(Node node
) { return node
->isKind(ParseNodeKind::Name
); }
1133 bool isArgumentsName(Node node
) {
1134 return node
->isKind(ParseNodeKind::Name
) &&
1135 node
->as
<NameNode
>().atom() ==
1136 TaggedParserAtomIndex::WellKnown::arguments();
1139 bool isEvalName(Node node
) {
1140 return node
->isKind(ParseNodeKind::Name
) &&
1141 node
->as
<NameNode
>().atom() ==
1142 TaggedParserAtomIndex::WellKnown::eval();
1145 bool isAsyncKeyword(Node node
) {
1146 return node
->isKind(ParseNodeKind::Name
) &&
1147 node
->pn_pos
.begin
+ strlen("async") == node
->pn_pos
.end
&&
1148 node
->as
<NameNode
>().atom() ==
1149 TaggedParserAtomIndex::WellKnown::async();
1152 bool isPrivateName(Node node
) {
1153 return node
->isKind(ParseNodeKind::PrivateName
);
1156 bool isPrivateMemberAccess(Node node
) {
1157 if (node
->isKind(ParseNodeKind::OptionalChain
)) {
1158 return isPrivateMemberAccess(node
->as
<UnaryNode
>().kid());
1160 return node
->is
<PrivateMemberAccessBase
>();
1163 TaggedParserAtomIndex
maybeDottedProperty(Node pn
) {
1164 return pn
->is
<PropertyAccessBase
>() ? pn
->as
<PropertyAccessBase
>().name()
1165 : TaggedParserAtomIndex::null();
1167 TaggedParserAtomIndex
isStringExprStatement(Node pn
, TokenPos
* pos
) {
1168 if (pn
->is
<UnaryNode
>()) {
1169 UnaryNode
* unary
= &pn
->as
<UnaryNode
>();
1170 if (auto atom
= unary
->isStringExprStatement()) {
1171 *pos
= unary
->kid()->pn_pos
;
1175 return TaggedParserAtomIndex::null();
1178 bool reuseLazyInnerFunctions() { return reuseGCThings
; }
1179 bool reuseClosedOverBindings() { return reuseGCThings
; }
1180 bool reuseRegexpSyntaxParse() { return reuseGCThings
; }
1181 void nextLazyInnerFunction() { lazyInnerFunctionIndex
++; }
1182 TaggedParserAtomIndex
nextLazyClosedOverBinding() {
1183 // Trailing nullptrs were elided in PerHandlerParser::finishFunction().
1184 auto closedOverBindings
= previousParseCache_
.closedOverBindings();
1185 if (lazyClosedOverBindingIndex
>= closedOverBindings
.Length()) {
1186 return TaggedParserAtomIndex::null();
1189 return closedOverBindings
[lazyClosedOverBindingIndex
++];
1191 const ScriptStencil
& cachedScriptData() const {
1192 // lazyInnerFunctionIndex is incremented with nextLazyInnferFunction before
1193 // reading the content, thus we need -1 to access the element that we just
1195 return previousParseCache_
.scriptData(lazyInnerFunctionIndex
- 1);
1197 const ScriptStencilExtra
& cachedScriptExtra() const {
1198 // lazyInnerFunctionIndex is incremented with nextLazyInnferFunction before
1199 // reading the content, thus we need -1 to access the element that we just
1201 return previousParseCache_
.scriptExtra(lazyInnerFunctionIndex
- 1);
1204 void setPrivateNameKind(Node node
, PrivateNameKind kind
) {
1205 MOZ_ASSERT(node
->is
<NameNode
>());
1206 node
->as
<NameNode
>().setPrivateNameKind(kind
);
1210 inline bool FullParseHandler::setLastFunctionFormalParameterDefault(
1211 FunctionNodeType funNode
, Node defaultValue
) {
1212 ParamsBodyNode
* body
= funNode
->body();
1213 ParseNode
* arg
= body
->last();
1215 MOZ_TRY_VAR_OR_RETURN(
1216 pn
, newAssignment(ParseNodeKind::AssignExpr
, arg
, defaultValue
), false);
1218 body
->replaceLast(pn
);
1222 } // namespace frontend
1225 #endif /* frontend_FullParseHandler_h */