Bug 1904979 - Update codespell to 2.3.0 r=linter-reviewers,Standard8
[gecko.git] / js / src / frontend / FullParseHandler.h
blob9209ba4d6705e834c2588dd06cf2ca3338745332
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
15 #include <string.h>
17 #include "jstypes.h"
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"
28 template <>
29 struct mozilla::detail::UnusedZero<js::frontend::ParseNode*> {
30 static const bool value = true;
33 #define DEFINE_UNUSED_ZERO(typeName) \
34 template <> \
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
41 namespace js {
42 namespace frontend {
44 class TokenStreamAnyChars;
46 // Parse handler used when generating a full parse tree for all code which the
47 // parser encounters.
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
61 // well as atoms.
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;
74 bool reuseGCThings;
76 /* new_ methods for creating parse nodes. These report OOM on context. */
77 JS_DECLARE_NEW_METHODS(new_, allocParseNode, inline)
79 public:
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)
90 #undef 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)...);
95 if (!node) {
96 return mozilla::Result<T*, NodeError>(NodeError());
98 return node;
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) ||
107 node->isKind(ParseNodeKind::ArgumentsLength);
110 bool isOptionalPropertyOrPrivateMemberAccess(Node node) {
111 return node->isKind(ParseNodeKind::OptionalDotExpr) ||
112 node->isKind(ParseNodeKind::OptionalElemExpr) ||
113 node->isKind(ParseNodeKind::PrivateMemberExpr);
116 bool isFunctionCall(Node node) {
117 // Note: super() is a special form, *not* a function call.
118 return node->isKind(ParseNodeKind::CallExpr);
121 static bool isUnparenthesizedDestructuringPattern(Node node) {
122 return !node->isInParens() && (node->isKind(ParseNodeKind::ObjectExpr) ||
123 node->isKind(ParseNodeKind::ArrayExpr));
126 static bool isParenthesizedDestructuringPattern(Node node) {
127 // Technically this isn't a destructuring pattern at all -- the grammar
128 // doesn't treat it as such. But we need to know when this happens to
129 // consider it a SyntaxError rather than an invalid-left-hand-side
130 // ReferenceError.
131 return node->isInParens() && (node->isKind(ParseNodeKind::ObjectExpr) ||
132 node->isKind(ParseNodeKind::ArrayExpr));
135 FullParseHandler(FrontendContext* fc, CompilationState& compilationState)
136 : allocator(fc, compilationState.parserAllocScope.alloc()),
137 previousParseCache_(compilationState.previousParseCache),
138 lazyInnerFunctionIndex(0),
139 lazyClosedOverBindingIndex(0),
140 reuseGCThings(compilationState.input.isDelazifying()) {}
142 static NullNode null() { return NullNode(); }
143 static constexpr NodeErrorResult errorResult() {
144 return NodeErrorResult(NodeError());
147 #define DECLARE_AS(typeName) \
148 static typeName##Type as##typeName(Node node) { \
149 return &node->as<typeName>(); \
151 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
152 #undef DECLARE_AS
154 NameNodeResult newName(TaggedParserAtomIndex name, const TokenPos& pos) {
155 return newResult<NameNode>(ParseNodeKind::Name, name, pos);
158 UnaryNodeResult newComputedName(Node expr, uint32_t begin, uint32_t end) {
159 TokenPos pos(begin, end);
160 return newResult<UnaryNode>(ParseNodeKind::ComputedName, pos, expr);
163 UnaryNodeResult newSyntheticComputedName(Node expr, uint32_t begin,
164 uint32_t end) {
165 TokenPos pos(begin, end);
166 UnaryNode* node;
167 MOZ_TRY_VAR(node,
168 newResult<UnaryNode>(ParseNodeKind::ComputedName, pos, expr));
169 node->setSyntheticComputedName();
170 return node;
173 NameNodeResult newObjectLiteralPropertyName(TaggedParserAtomIndex atom,
174 const TokenPos& pos) {
175 return newResult<NameNode>(ParseNodeKind::ObjectPropertyName, atom, pos);
178 NameNodeResult newPrivateName(TaggedParserAtomIndex atom,
179 const TokenPos& pos) {
180 return newResult<NameNode>(ParseNodeKind::PrivateName, atom, pos);
183 NumericLiteralResult newNumber(double value, DecimalPoint decimalPoint,
184 const TokenPos& pos) {
185 return newResult<NumericLiteral>(value, decimalPoint, pos);
188 BigIntLiteralResult newBigInt(BigIntIndex index, bool isZero,
189 const TokenPos& pos) {
190 return newResult<BigIntLiteral>(index, isZero, pos);
193 BooleanLiteralResult newBooleanLiteral(bool cond, const TokenPos& pos) {
194 return newResult<BooleanLiteral>(cond, pos);
197 NameNodeResult newStringLiteral(TaggedParserAtomIndex atom,
198 const TokenPos& pos) {
199 return newResult<NameNode>(ParseNodeKind::StringExpr, atom, pos);
202 NameNodeResult newTemplateStringLiteral(TaggedParserAtomIndex atom,
203 const TokenPos& pos) {
204 return newResult<NameNode>(ParseNodeKind::TemplateStringExpr, atom, pos);
207 CallSiteNodeResult newCallSiteObject(uint32_t begin) {
208 CallSiteNode* callSiteObj;
209 MOZ_TRY_VAR(callSiteObj, newResult<CallSiteNode>(begin));
211 ListNode* rawNodes;
212 MOZ_TRY_VAR(rawNodes, newArrayLiteral(callSiteObj->pn_pos.begin));
214 addArrayElement(callSiteObj, rawNodes);
216 return callSiteObj;
219 void addToCallSiteObject(CallSiteNodeType callSiteObj, Node rawNode,
220 Node cookedNode) {
221 MOZ_ASSERT(callSiteObj->isKind(ParseNodeKind::CallSiteObj));
222 MOZ_ASSERT(rawNode->isKind(ParseNodeKind::TemplateStringExpr));
223 MOZ_ASSERT(cookedNode->isKind(ParseNodeKind::TemplateStringExpr) ||
224 cookedNode->isKind(ParseNodeKind::RawUndefinedExpr));
226 addArrayElement(callSiteObj, cookedNode);
227 addArrayElement(callSiteObj->rawNodes(), rawNode);
230 * We don't know when the last noSubstTemplate will come in, and we
231 * don't want to deal with this outside this method
233 setEndPosition(callSiteObj, callSiteObj->rawNodes());
236 ThisLiteralResult newThisLiteral(const TokenPos& pos, Node thisName) {
237 return newResult<ThisLiteral>(pos, thisName);
240 NullLiteralResult newNullLiteral(const TokenPos& pos) {
241 return newResult<NullLiteral>(pos);
244 RawUndefinedLiteralResult newRawUndefinedLiteral(const TokenPos& pos) {
245 return newResult<RawUndefinedLiteral>(pos);
248 RegExpLiteralResult newRegExp(RegExpIndex index, const TokenPos& pos) {
249 return newResult<RegExpLiteral>(index, pos);
252 ConditionalExpressionResult newConditional(Node cond, Node thenExpr,
253 Node elseExpr) {
254 return newResult<ConditionalExpression>(cond, thenExpr, elseExpr);
257 UnaryNodeResult newDelete(uint32_t begin, Node expr) {
258 if (expr->isKind(ParseNodeKind::Name)) {
259 return newUnary(ParseNodeKind::DeleteNameExpr, begin, expr);
262 if (expr->isKind(ParseNodeKind::DotExpr)) {
263 return newUnary(ParseNodeKind::DeletePropExpr, begin, expr);
266 if (expr->isKind(ParseNodeKind::ElemExpr)) {
267 return newUnary(ParseNodeKind::DeleteElemExpr, begin, expr);
270 if (expr->isKind(ParseNodeKind::OptionalChain)) {
271 Node kid = expr->as<UnaryNode>().kid();
272 // Handle property deletion explicitly. OptionalCall is handled
273 // via DeleteExpr.
274 if (kid->isKind(ParseNodeKind::DotExpr) ||
275 kid->isKind(ParseNodeKind::OptionalDotExpr) ||
276 kid->isKind(ParseNodeKind::ElemExpr) ||
277 kid->isKind(ParseNodeKind::OptionalElemExpr)) {
278 return newUnary(ParseNodeKind::DeleteOptionalChainExpr, begin, kid);
282 return newUnary(ParseNodeKind::DeleteExpr, begin, expr);
285 UnaryNodeResult newTypeof(uint32_t begin, Node kid) {
286 ParseNodeKind pnk = kid->isKind(ParseNodeKind::Name)
287 ? ParseNodeKind::TypeOfNameExpr
288 : ParseNodeKind::TypeOfExpr;
289 return newUnary(pnk, begin, kid);
292 UnaryNodeResult newUnary(ParseNodeKind kind, uint32_t begin, Node kid) {
293 TokenPos pos(begin, kid->pn_pos.end);
294 return newResult<UnaryNode>(kind, pos, kid);
297 UnaryNodeResult newUpdate(ParseNodeKind kind, uint32_t begin, Node kid) {
298 TokenPos pos(begin, kid->pn_pos.end);
299 return newResult<UnaryNode>(kind, pos, kid);
302 UnaryNodeResult newSpread(uint32_t begin, Node kid) {
303 TokenPos pos(begin, kid->pn_pos.end);
304 return newResult<UnaryNode>(ParseNodeKind::Spread, pos, kid);
307 private:
308 BinaryNodeResult newBinary(ParseNodeKind kind, Node left, Node right) {
309 TokenPos pos(left->pn_pos.begin, right->pn_pos.end);
310 return newResult<BinaryNode>(kind, pos, left, right);
313 public:
314 NodeResult appendOrCreateList(ParseNodeKind kind, Node left, Node right,
315 ParseContext* pc) {
316 return ParseNode::appendOrCreateList(kind, left, right, this, pc);
319 // Expressions
321 ListNodeResult newArrayLiteral(uint32_t begin) {
322 return newResult<ListNode>(ParseNodeKind::ArrayExpr,
323 TokenPos(begin, begin + 1));
326 [[nodiscard]] bool addElision(ListNodeType literal, const TokenPos& pos) {
327 MOZ_ASSERT(literal->isKind(ParseNodeKind::ArrayExpr));
329 NullaryNode* elision;
330 MOZ_TRY_VAR_OR_RETURN(
331 elision, newResult<NullaryNode>(ParseNodeKind::Elision, pos), false);
332 addList(/* list = */ literal, /* kid = */ elision);
333 literal->setHasNonConstInitializer();
334 return true;
337 [[nodiscard]] bool addSpreadElement(ListNodeType literal, uint32_t begin,
338 Node inner) {
339 MOZ_ASSERT(
340 literal->isKind(ParseNodeKind::ArrayExpr) ||
341 IF_RECORD_TUPLE(literal->isKind(ParseNodeKind::TupleExpr), false));
343 UnaryNodeType spread;
344 MOZ_TRY_VAR_OR_RETURN(spread, newSpread(begin, inner), false);
345 addList(/* list = */ literal, /* kid = */ spread);
346 literal->setHasNonConstInitializer();
347 return true;
350 void addArrayElement(ListNodeType literal, Node element) {
351 MOZ_ASSERT(
352 literal->isKind(ParseNodeKind::ArrayExpr) ||
353 literal->isKind(ParseNodeKind::CallSiteObj) ||
354 IF_RECORD_TUPLE(literal->isKind(ParseNodeKind::TupleExpr), false));
355 if (!element->isConstant()) {
356 literal->setHasNonConstInitializer();
358 addList(/* list = */ literal, /* kid = */ element);
361 CallNodeResult newCall(Node callee, ListNodeType args, JSOp callOp) {
362 return newResult<CallNode>(ParseNodeKind::CallExpr, callOp, callee, args);
365 CallNodeResult newOptionalCall(Node callee, ListNodeType args, JSOp callOp) {
366 return newResult<CallNode>(ParseNodeKind::OptionalCallExpr, callOp, callee,
367 args);
370 ListNodeResult newArguments(const TokenPos& pos) {
371 return newResult<ListNode>(ParseNodeKind::Arguments, pos);
374 CallNodeResult newSuperCall(Node callee, ListNodeType args, bool isSpread) {
375 return newResult<CallNode>(
376 ParseNodeKind::SuperCallExpr,
377 isSpread ? JSOp::SpreadSuperCall : JSOp::SuperCall, callee, args);
380 CallNodeResult newTaggedTemplate(Node tag, ListNodeType args, JSOp callOp) {
381 return newResult<CallNode>(ParseNodeKind::TaggedTemplateExpr, callOp, tag,
382 args);
385 ListNodeResult newObjectLiteral(uint32_t begin) {
386 return newResult<ListNode>(ParseNodeKind::ObjectExpr,
387 TokenPos(begin, begin + 1));
390 #ifdef ENABLE_RECORD_TUPLE
391 ListNodeResult newRecordLiteral(uint32_t begin) {
392 return newResult<ListNode>(ParseNodeKind::RecordExpr,
393 TokenPos(begin, begin + 1));
396 ListNodeResult newTupleLiteral(uint32_t begin) {
397 return newResult<ListNode>(ParseNodeKind::TupleExpr,
398 TokenPos(begin, begin + 1));
400 #endif
402 ClassNodeResult newClass(Node name, Node heritage,
403 LexicalScopeNodeType memberBlock,
404 #ifdef ENABLE_DECORATORS
405 ListNodeType decorators,
406 FunctionNodeType addInitializerFunction,
407 #endif
408 const TokenPos& pos) {
409 return newResult<ClassNode>(name, heritage, memberBlock,
410 #ifdef ENABLE_DECORATORS
411 decorators, addInitializerFunction,
412 #endif
413 pos);
415 ListNodeResult newClassMemberList(uint32_t begin) {
416 return newResult<ListNode>(ParseNodeKind::ClassMemberList,
417 TokenPos(begin, begin + 1));
419 ClassNamesResult newClassNames(Node outer, Node inner, const TokenPos& pos) {
420 return newResult<ClassNames>(outer, inner, pos);
422 NewTargetNodeResult newNewTarget(NullaryNodeType newHolder,
423 NullaryNodeType targetHolder,
424 NameNodeType newTargetName) {
425 return newResult<NewTargetNode>(newHolder, targetHolder, newTargetName);
427 NullaryNodeResult newPosHolder(const TokenPos& pos) {
428 return newResult<NullaryNode>(ParseNodeKind::PosHolder, pos);
430 UnaryNodeResult newSuperBase(Node thisName, const TokenPos& pos) {
431 return newResult<UnaryNode>(ParseNodeKind::SuperBase, pos, thisName);
433 [[nodiscard]] bool addPrototypeMutation(ListNodeType literal, uint32_t begin,
434 Node expr) {
435 MOZ_ASSERT(literal->isKind(ParseNodeKind::ObjectExpr));
437 // Object literals with mutated [[Prototype]] are non-constant so that
438 // singleton objects will have Object.prototype as their [[Prototype]].
439 literal->setHasNonConstInitializer();
441 UnaryNode* mutation;
442 MOZ_TRY_VAR_OR_RETURN(
443 mutation, newUnary(ParseNodeKind::MutateProto, begin, expr), false);
444 addList(/* list = */ literal, /* kid = */ mutation);
445 return true;
448 BinaryNodeResult newPropertyDefinition(Node key, Node val) {
449 MOZ_ASSERT(isUsableAsObjectPropertyName(key));
450 checkAndSetIsDirectRHSAnonFunction(val);
451 return newResult<PropertyDefinition>(key, val, AccessorType::None);
454 void addPropertyDefinition(ListNodeType literal, BinaryNodeType propdef) {
455 MOZ_ASSERT(
456 literal->isKind(ParseNodeKind::ObjectExpr) ||
457 IF_RECORD_TUPLE(literal->isKind(ParseNodeKind::RecordExpr), false));
458 MOZ_ASSERT(propdef->isKind(ParseNodeKind::PropertyDefinition));
460 if (!propdef->right()->isConstant()) {
461 literal->setHasNonConstInitializer();
464 addList(/* list = */ literal, /* kid = */ propdef);
467 [[nodiscard]] bool addPropertyDefinition(ListNodeType literal, Node key,
468 Node val) {
469 BinaryNode* propdef;
470 MOZ_TRY_VAR_OR_RETURN(propdef, newPropertyDefinition(key, val), false);
471 addPropertyDefinition(literal, propdef);
472 return true;
475 [[nodiscard]] bool addShorthand(ListNodeType literal, NameNodeType name,
476 NameNodeType expr) {
477 MOZ_ASSERT(
478 literal->isKind(ParseNodeKind::ObjectExpr) ||
479 IF_RECORD_TUPLE(literal->isKind(ParseNodeKind::RecordExpr), false));
480 MOZ_ASSERT(name->isKind(ParseNodeKind::ObjectPropertyName));
481 MOZ_ASSERT(expr->isKind(ParseNodeKind::Name));
482 MOZ_ASSERT(name->atom() == expr->atom());
484 literal->setHasNonConstInitializer();
485 BinaryNode* propdef;
486 MOZ_TRY_VAR_OR_RETURN(
487 propdef, newBinary(ParseNodeKind::Shorthand, name, expr), false);
488 addList(/* list = */ literal, /* kid = */ propdef);
489 return true;
492 [[nodiscard]] bool addSpreadProperty(ListNodeType literal, uint32_t begin,
493 Node inner) {
494 MOZ_ASSERT(
495 literal->isKind(ParseNodeKind::ObjectExpr) ||
496 IF_RECORD_TUPLE(literal->isKind(ParseNodeKind::RecordExpr), false));
498 literal->setHasNonConstInitializer();
499 ParseNode* spread;
500 MOZ_TRY_VAR_OR_RETURN(spread, newSpread(begin, inner), false);
501 addList(/* list = */ literal, /* kid = */ spread);
502 return true;
505 [[nodiscard]] bool addObjectMethodDefinition(ListNodeType literal, Node key,
506 FunctionNodeType funNode,
507 AccessorType atype) {
508 literal->setHasNonConstInitializer();
510 checkAndSetIsDirectRHSAnonFunction(funNode);
512 ParseNode* propdef;
513 MOZ_TRY_VAR_OR_RETURN(
514 propdef, newObjectMethodOrPropertyDefinition(key, funNode, atype),
515 false);
516 addList(/* list = */ literal, /* kid = */ propdef);
517 return true;
520 [[nodiscard]] ClassMethodResult newDefaultClassConstructor(
521 Node key, FunctionNodeType funNode) {
522 MOZ_ASSERT(isUsableAsObjectPropertyName(key));
524 checkAndSetIsDirectRHSAnonFunction(funNode);
526 return newResult<ClassMethod>(
527 ParseNodeKind::DefaultConstructor, key, funNode, AccessorType::None,
528 /* isStatic = */ false, /* initializeIfPrivate = */ nullptr
529 #ifdef ENABLE_DECORATORS
531 /* decorators = */ nullptr
532 #endif
536 [[nodiscard]] ClassMethodResult newClassMethodDefinition(
537 Node key, FunctionNodeType funNode, AccessorType atype, bool isStatic,
538 mozilla::Maybe<FunctionNodeType> initializerIfPrivate
539 #ifdef ENABLE_DECORATORS
541 ListNodeType decorators
542 #endif
544 MOZ_ASSERT(isUsableAsObjectPropertyName(key));
546 checkAndSetIsDirectRHSAnonFunction(funNode);
548 if (initializerIfPrivate.isSome()) {
549 return newResult<ClassMethod>(ParseNodeKind::ClassMethod, key, funNode,
550 atype, isStatic,
551 initializerIfPrivate.value()
552 #ifdef ENABLE_DECORATORS
554 decorators
555 #endif
558 return newResult<ClassMethod>(ParseNodeKind::ClassMethod, key, funNode,
559 atype, isStatic,
560 /* initializeIfPrivate = */ nullptr
561 #ifdef ENABLE_DECORATORS
563 decorators
564 #endif
568 [[nodiscard]] ClassFieldResult newClassFieldDefinition(
569 Node name, FunctionNodeType initializer, bool isStatic
570 #ifdef ENABLE_DECORATORS
572 ListNodeType decorators, ClassMethodType accessorGetterNode,
573 ClassMethodType accessorSetterNode
574 #endif
576 MOZ_ASSERT(isUsableAsObjectPropertyName(name));
578 return newResult<ClassField>(name, initializer, isStatic
579 #if ENABLE_DECORATORS
581 decorators, accessorGetterNode,
582 accessorSetterNode
583 #endif
587 [[nodiscard]] StaticClassBlockResult newStaticClassBlock(
588 FunctionNodeType block) {
589 return newResult<StaticClassBlock>(block);
592 [[nodiscard]] bool addClassMemberDefinition(ListNodeType memberList,
593 Node member) {
594 MOZ_ASSERT(memberList->isKind(ParseNodeKind::ClassMemberList));
595 // Constructors can be surrounded by LexicalScopes.
596 MOZ_ASSERT(member->isKind(ParseNodeKind::DefaultConstructor) ||
597 member->isKind(ParseNodeKind::ClassMethod) ||
598 member->isKind(ParseNodeKind::ClassField) ||
599 member->isKind(ParseNodeKind::StaticClassBlock) ||
600 (member->isKind(ParseNodeKind::LexicalScope) &&
601 member->as<LexicalScopeNode>().scopeBody()->is<ClassMethod>()));
603 addList(/* list = */ memberList, /* kid = */ member);
604 return true;
607 UnaryNodeResult newInitialYieldExpression(uint32_t begin, Node gen) {
608 TokenPos pos(begin, begin + 1);
609 return newResult<UnaryNode>(ParseNodeKind::InitialYield, pos, gen);
612 UnaryNodeResult newYieldExpression(uint32_t begin, Node value) {
613 TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
614 return newResult<UnaryNode>(ParseNodeKind::YieldExpr, pos, value);
617 UnaryNodeResult newYieldStarExpression(uint32_t begin, Node value) {
618 TokenPos pos(begin, value->pn_pos.end);
619 return newResult<UnaryNode>(ParseNodeKind::YieldStarExpr, pos, value);
622 UnaryNodeResult newAwaitExpression(uint32_t begin, Node value) {
623 TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
624 return newResult<UnaryNode>(ParseNodeKind::AwaitExpr, pos, value);
627 UnaryNodeResult newOptionalChain(uint32_t begin, Node value) {
628 TokenPos pos(begin, value->pn_pos.end);
629 return newResult<UnaryNode>(ParseNodeKind::OptionalChain, pos, value);
632 // Statements
634 ListNodeResult newStatementList(const TokenPos& pos) {
635 return newResult<ListNode>(ParseNodeKind::StatementList, pos);
638 [[nodiscard]] bool isFunctionStmt(Node stmt) {
639 while (stmt->isKind(ParseNodeKind::LabelStmt)) {
640 stmt = stmt->as<LabeledStatement>().statement();
642 return stmt->is<FunctionNode>();
645 void addStatementToList(ListNodeType list, Node stmt) {
646 MOZ_ASSERT(list->isKind(ParseNodeKind::StatementList));
648 addList(/* list = */ list, /* kid = */ stmt);
650 if (isFunctionStmt(stmt)) {
651 // Notify the emitter that the block contains body-level function
652 // definitions that should be processed before the rest of nodes.
653 list->setHasTopLevelFunctionDeclarations();
657 void setListEndPosition(ListNodeType list, const TokenPos& pos) {
658 MOZ_ASSERT(list->isKind(ParseNodeKind::StatementList));
659 list->pn_pos.end = pos.end;
662 void addCaseStatementToList(ListNodeType list, CaseClauseType caseClause) {
663 MOZ_ASSERT(list->isKind(ParseNodeKind::StatementList));
665 addList(/* list = */ list, /* kid = */ caseClause);
667 if (caseClause->statementList()->hasTopLevelFunctionDeclarations()) {
668 list->setHasTopLevelFunctionDeclarations();
672 [[nodiscard]] bool prependInitialYield(ListNodeType stmtList, Node genName) {
673 MOZ_ASSERT(stmtList->isKind(ParseNodeKind::StatementList));
675 TokenPos yieldPos(stmtList->pn_pos.begin, stmtList->pn_pos.begin + 1);
676 NullaryNode* makeGen;
677 MOZ_TRY_VAR_OR_RETURN(
678 makeGen, newResult<NullaryNode>(ParseNodeKind::Generator, yieldPos),
679 false);
681 ParseNode* genInit;
682 MOZ_TRY_VAR_OR_RETURN(
683 genInit,
684 newAssignment(ParseNodeKind::AssignExpr, /* lhs = */ genName,
685 /* rhs = */ makeGen),
686 false);
688 UnaryNode* initialYield;
689 MOZ_TRY_VAR_OR_RETURN(initialYield,
690 newInitialYieldExpression(yieldPos.begin, genInit),
691 false);
693 stmtList->prepend(initialYield);
694 return true;
697 BinaryNodeResult newSetThis(Node thisName, Node value) {
698 return newBinary(ParseNodeKind::SetThis, thisName, value);
701 NullaryNodeResult newEmptyStatement(const TokenPos& pos) {
702 return newResult<NullaryNode>(ParseNodeKind::EmptyStmt, pos);
705 BinaryNodeResult newImportAttribute(Node keyNode, Node valueNode) {
706 return newBinary(ParseNodeKind::ImportAttribute, keyNode, valueNode);
709 BinaryNodeResult newModuleRequest(Node moduleSpec, Node importAttributeList,
710 const TokenPos& pos) {
711 return newResult<BinaryNode>(ParseNodeKind::ImportModuleRequest, pos,
712 moduleSpec, importAttributeList);
715 BinaryNodeResult newImportDeclaration(Node importSpecSet, Node moduleRequest,
716 const TokenPos& pos) {
717 return newResult<BinaryNode>(ParseNodeKind::ImportDecl, pos, importSpecSet,
718 moduleRequest);
721 BinaryNodeResult newImportSpec(Node importNameNode, Node bindingName) {
722 return newBinary(ParseNodeKind::ImportSpec, importNameNode, bindingName);
725 UnaryNodeResult newImportNamespaceSpec(uint32_t begin, Node bindingName) {
726 return newUnary(ParseNodeKind::ImportNamespaceSpec, begin, bindingName);
729 UnaryNodeResult newExportDeclaration(Node kid, const TokenPos& pos) {
730 return newResult<UnaryNode>(ParseNodeKind::ExportStmt, pos, kid);
733 BinaryNodeResult newExportFromDeclaration(uint32_t begin, Node exportSpecSet,
734 Node moduleRequest) {
735 BinaryNode* decl;
736 MOZ_TRY_VAR(decl, newResult<BinaryNode>(ParseNodeKind::ExportFromStmt,
737 exportSpecSet, moduleRequest));
738 decl->pn_pos.begin = begin;
739 return decl;
742 BinaryNodeResult newExportDefaultDeclaration(Node kid, Node maybeBinding,
743 const TokenPos& pos) {
744 if (maybeBinding) {
745 MOZ_ASSERT(maybeBinding->isKind(ParseNodeKind::Name));
746 MOZ_ASSERT(!maybeBinding->isInParens());
748 checkAndSetIsDirectRHSAnonFunction(kid);
751 return newResult<BinaryNode>(ParseNodeKind::ExportDefaultStmt, pos, kid,
752 maybeBinding);
755 BinaryNodeResult newExportSpec(Node bindingName, Node exportName) {
756 return newBinary(ParseNodeKind::ExportSpec, bindingName, exportName);
759 UnaryNodeResult newExportNamespaceSpec(uint32_t begin, Node exportName) {
760 return newUnary(ParseNodeKind::ExportNamespaceSpec, begin, exportName);
763 NullaryNodeResult newExportBatchSpec(const TokenPos& pos) {
764 return newResult<NullaryNode>(ParseNodeKind::ExportBatchSpecStmt, pos);
767 BinaryNodeResult newImportMeta(NullaryNodeType importHolder,
768 NullaryNodeType metaHolder) {
769 return newResult<BinaryNode>(ParseNodeKind::ImportMetaExpr, importHolder,
770 metaHolder);
773 BinaryNodeResult newCallImport(NullaryNodeType importHolder, Node singleArg) {
774 return newResult<BinaryNode>(ParseNodeKind::CallImportExpr, importHolder,
775 singleArg);
778 BinaryNodeResult newCallImportSpec(Node specifierArg, Node optionalArg) {
779 return newResult<BinaryNode>(ParseNodeKind::CallImportSpec, specifierArg,
780 optionalArg);
783 UnaryNodeResult newExprStatement(Node expr, uint32_t end) {
784 MOZ_ASSERT(expr->pn_pos.end <= end);
785 return newResult<UnaryNode>(ParseNodeKind::ExpressionStmt,
786 TokenPos(expr->pn_pos.begin, end), expr);
789 TernaryNodeResult newIfStatement(uint32_t begin, Node cond, Node thenBranch,
790 Node elseBranch) {
791 TernaryNode* node;
792 MOZ_TRY_VAR(node, newResult<TernaryNode>(ParseNodeKind::IfStmt, cond,
793 thenBranch, elseBranch));
794 node->pn_pos.begin = begin;
795 return node;
798 BinaryNodeResult newDoWhileStatement(Node body, Node cond,
799 const TokenPos& pos) {
800 return newResult<BinaryNode>(ParseNodeKind::DoWhileStmt, pos, body, cond);
803 BinaryNodeResult newWhileStatement(uint32_t begin, Node cond, Node body) {
804 TokenPos pos(begin, body->pn_pos.end);
805 return newResult<BinaryNode>(ParseNodeKind::WhileStmt, pos, cond, body);
808 ForNodeResult newForStatement(uint32_t begin, TernaryNodeType forHead,
809 Node body, unsigned iflags) {
810 return newResult<ForNode>(TokenPos(begin, body->pn_pos.end), forHead, body,
811 iflags);
814 TernaryNodeResult newForHead(Node init, Node test, Node update,
815 const TokenPos& pos) {
816 return newResult<TernaryNode>(ParseNodeKind::ForHead, init, test, update,
817 pos);
820 TernaryNodeResult newForInOrOfHead(ParseNodeKind kind, Node target,
821 Node iteratedExpr, const TokenPos& pos) {
822 MOZ_ASSERT(kind == ParseNodeKind::ForIn || kind == ParseNodeKind::ForOf);
823 return newResult<TernaryNode>(kind, target, nullptr, iteratedExpr, pos);
826 SwitchStatementResult newSwitchStatement(
827 uint32_t begin, Node discriminant,
828 LexicalScopeNodeType lexicalForCaseList, bool hasDefault) {
829 return newResult<SwitchStatement>(begin, discriminant, lexicalForCaseList,
830 hasDefault);
833 CaseClauseResult newCaseOrDefault(uint32_t begin, Node expr, Node body) {
834 return newResult<CaseClause>(expr, body, begin);
837 ContinueStatementResult newContinueStatement(TaggedParserAtomIndex label,
838 const TokenPos& pos) {
839 return newResult<ContinueStatement>(label, pos);
842 BreakStatementResult newBreakStatement(TaggedParserAtomIndex label,
843 const TokenPos& pos) {
844 return newResult<BreakStatement>(label, pos);
847 UnaryNodeResult newReturnStatement(Node expr, const TokenPos& pos) {
848 MOZ_ASSERT_IF(expr, pos.encloses(expr->pn_pos));
849 return newResult<UnaryNode>(ParseNodeKind::ReturnStmt, pos, expr);
852 UnaryNodeResult newExpressionBody(Node expr) {
853 return newResult<UnaryNode>(ParseNodeKind::ReturnStmt, expr->pn_pos, expr);
856 BinaryNodeResult newWithStatement(uint32_t begin, Node expr, Node body) {
857 return newResult<BinaryNode>(ParseNodeKind::WithStmt,
858 TokenPos(begin, body->pn_pos.end), expr, body);
861 LabeledStatementResult newLabeledStatement(TaggedParserAtomIndex label,
862 Node stmt, uint32_t begin) {
863 return newResult<LabeledStatement>(label, stmt, begin);
866 UnaryNodeResult newThrowStatement(Node expr, const TokenPos& pos) {
867 MOZ_ASSERT(pos.encloses(expr->pn_pos));
868 return newResult<UnaryNode>(ParseNodeKind::ThrowStmt, pos, expr);
871 TernaryNodeResult newTryStatement(uint32_t begin, Node body,
872 LexicalScopeNodeType catchScope,
873 Node finallyBlock) {
874 return newResult<TryNode>(begin, body, catchScope, finallyBlock);
877 DebuggerStatementResult newDebuggerStatement(const TokenPos& pos) {
878 return newResult<DebuggerStatement>(pos);
881 NameNodeResult newPropertyName(TaggedParserAtomIndex name,
882 const TokenPos& pos) {
883 return newResult<NameNode>(ParseNodeKind::PropertyNameExpr, name, pos);
886 PropertyAccessResult newPropertyAccess(Node expr, NameNodeType key) {
887 return newResult<PropertyAccess>(expr, key, expr->pn_pos.begin,
888 key->pn_pos.end);
891 ArgumentsLengthResult newArgumentsLength(Node expr, NameNodeType key) {
892 return newResult<ArgumentsLength>(expr, key, expr->pn_pos.begin,
893 key->pn_pos.end);
896 PropertyByValueResult newPropertyByValue(Node lhs, Node index, uint32_t end) {
897 return newResult<PropertyByValue>(lhs, index, lhs->pn_pos.begin, end);
900 OptionalPropertyAccessResult newOptionalPropertyAccess(Node expr,
901 NameNodeType key) {
902 return newResult<OptionalPropertyAccess>(expr, key, expr->pn_pos.begin,
903 key->pn_pos.end);
906 OptionalPropertyByValueResult newOptionalPropertyByValue(Node lhs, Node index,
907 uint32_t end) {
908 return newResult<OptionalPropertyByValue>(lhs, index, lhs->pn_pos.begin,
909 end);
912 PrivateMemberAccessResult newPrivateMemberAccess(Node lhs,
913 NameNodeType privateName,
914 uint32_t end) {
915 return newResult<PrivateMemberAccess>(lhs, privateName, lhs->pn_pos.begin,
916 end);
919 OptionalPrivateMemberAccessResult newOptionalPrivateMemberAccess(
920 Node lhs, NameNodeType privateName, uint32_t end) {
921 return newResult<OptionalPrivateMemberAccess>(lhs, privateName,
922 lhs->pn_pos.begin, end);
925 bool setupCatchScope(LexicalScopeNodeType lexicalScope, Node catchName,
926 Node catchBody) {
927 BinaryNode* catchClause;
928 if (catchName) {
929 MOZ_TRY_VAR_OR_RETURN(
930 catchClause,
931 newResult<BinaryNode>(ParseNodeKind::Catch, catchName, catchBody),
932 false);
933 } else {
934 MOZ_TRY_VAR_OR_RETURN(
935 catchClause,
936 newResult<BinaryNode>(ParseNodeKind::Catch, catchBody->pn_pos,
937 catchName, catchBody),
938 false);
940 lexicalScope->setScopeBody(catchClause);
941 return true;
944 [[nodiscard]] inline bool setLastFunctionFormalParameterDefault(
945 FunctionNodeType funNode, Node defaultValue);
947 void checkAndSetIsDirectRHSAnonFunction(Node pn) {
948 if (IsAnonymousFunctionDefinition(pn)) {
949 pn->setDirectRHSAnonFunction(true);
953 ParamsBodyNodeResult newParamsBody(const TokenPos& pos) {
954 return newResult<ParamsBodyNode>(pos);
957 FunctionNodeResult newFunction(FunctionSyntaxKind syntaxKind,
958 const TokenPos& pos) {
959 return newResult<FunctionNode>(syntaxKind, pos);
962 BinaryNodeResult newObjectMethodOrPropertyDefinition(Node key, Node value,
963 AccessorType atype) {
964 MOZ_ASSERT(isUsableAsObjectPropertyName(key));
966 return newResult<PropertyDefinition>(key, value, atype);
969 void setFunctionFormalParametersAndBody(FunctionNodeType funNode,
970 ParamsBodyNodeType paramsBody) {
971 funNode->setBody(paramsBody);
973 void setFunctionBox(FunctionNodeType funNode, FunctionBox* funbox) {
974 funNode->setFunbox(funbox);
975 funbox->functionNode = funNode;
977 void addFunctionFormalParameter(FunctionNodeType funNode, Node argpn) {
978 addList(/* list = */ funNode->body(), /* kid = */ argpn);
980 void setFunctionBody(FunctionNodeType funNode, LexicalScopeNodeType body) {
981 addList(/* list = */ funNode->body(), /* kid = */ body);
984 ModuleNodeResult newModule(const TokenPos& pos) {
985 return newResult<ModuleNode>(pos);
988 LexicalScopeNodeResult newLexicalScope(LexicalScope::ParserData* bindings,
989 Node body,
990 ScopeKind kind = ScopeKind::Lexical) {
991 return newResult<LexicalScopeNode>(bindings, body, kind);
994 ClassBodyScopeNodeResult newClassBodyScope(
995 ClassBodyScope::ParserData* bindings, ListNodeType body) {
996 return newResult<ClassBodyScopeNode>(bindings, body);
999 CallNodeResult newNewExpression(uint32_t begin, Node ctor, ListNodeType args,
1000 bool isSpread) {
1001 return newResult<CallNode>(ParseNodeKind::NewExpr,
1002 isSpread ? JSOp::SpreadNew : JSOp::New,
1003 TokenPos(begin, args->pn_pos.end), ctor, args);
1006 AssignmentNodeResult newAssignment(ParseNodeKind kind, Node lhs, Node rhs) {
1007 if ((kind == ParseNodeKind::AssignExpr ||
1008 kind == ParseNodeKind::CoalesceAssignExpr ||
1009 kind == ParseNodeKind::OrAssignExpr ||
1010 kind == ParseNodeKind::AndAssignExpr) &&
1011 lhs->isKind(ParseNodeKind::Name) && !lhs->isInParens()) {
1012 checkAndSetIsDirectRHSAnonFunction(rhs);
1015 return newResult<AssignmentNode>(kind, lhs, rhs);
1018 BinaryNodeResult newInitExpr(Node lhs, Node rhs) {
1019 TokenPos pos(lhs->pn_pos.begin, rhs->pn_pos.end);
1020 return newResult<BinaryNode>(ParseNodeKind::InitExpr, pos, lhs, rhs);
1023 bool isUnparenthesizedAssignment(Node node) {
1024 if ((node->isKind(ParseNodeKind::AssignExpr)) && !node->isInParens()) {
1025 return true;
1028 return false;
1031 bool isUnparenthesizedUnaryExpression(Node node) {
1032 if (!node->isInParens()) {
1033 ParseNodeKind kind = node->getKind();
1034 return kind == ParseNodeKind::VoidExpr ||
1035 kind == ParseNodeKind::NotExpr ||
1036 kind == ParseNodeKind::BitNotExpr ||
1037 kind == ParseNodeKind::PosExpr || kind == ParseNodeKind::NegExpr ||
1038 kind == ParseNodeKind::AwaitExpr || IsTypeofKind(kind) ||
1039 IsDeleteKind(kind);
1041 return false;
1044 bool isReturnStatement(Node node) {
1045 return node->isKind(ParseNodeKind::ReturnStmt);
1048 bool isStatementPermittedAfterReturnStatement(Node node) {
1049 ParseNodeKind kind = node->getKind();
1050 return kind == ParseNodeKind::Function || kind == ParseNodeKind::VarStmt ||
1051 kind == ParseNodeKind::BreakStmt ||
1052 kind == ParseNodeKind::ThrowStmt || kind == ParseNodeKind::EmptyStmt;
1055 bool isSuperBase(Node node) { return node->isKind(ParseNodeKind::SuperBase); }
1057 bool isUsableAsObjectPropertyName(Node node) {
1058 return node->isKind(ParseNodeKind::NumberExpr) ||
1059 node->isKind(ParseNodeKind::BigIntExpr) ||
1060 node->isKind(ParseNodeKind::ObjectPropertyName) ||
1061 node->isKind(ParseNodeKind::StringExpr) ||
1062 node->isKind(ParseNodeKind::ComputedName) ||
1063 node->isKind(ParseNodeKind::PrivateName);
1066 AssignmentNodeResult finishInitializerAssignment(NameNodeType nameNode,
1067 Node init) {
1068 MOZ_ASSERT(nameNode->isKind(ParseNodeKind::Name));
1069 MOZ_ASSERT(!nameNode->isInParens());
1071 checkAndSetIsDirectRHSAnonFunction(init);
1073 return newAssignment(ParseNodeKind::AssignExpr, nameNode, init);
1076 void setBeginPosition(Node pn, Node oth) {
1077 setBeginPosition(pn, oth->pn_pos.begin);
1079 void setBeginPosition(Node pn, uint32_t begin) {
1080 pn->pn_pos.begin = begin;
1081 MOZ_ASSERT(pn->pn_pos.begin <= pn->pn_pos.end);
1084 void setEndPosition(Node pn, Node oth) {
1085 setEndPosition(pn, oth->pn_pos.end);
1087 void setEndPosition(Node pn, uint32_t end) {
1088 pn->pn_pos.end = end;
1089 MOZ_ASSERT(pn->pn_pos.begin <= pn->pn_pos.end);
1092 uint32_t getFunctionNameOffset(Node func, TokenStreamAnyChars& ts) {
1093 return func->pn_pos.begin;
1096 ListNodeResult newList(ParseNodeKind kind, const TokenPos& pos) {
1097 auto list = newResult<ListNode>(kind, pos);
1098 MOZ_ASSERT_IF(list.isOk(), !list.unwrap()->is<DeclarationListNode>());
1099 MOZ_ASSERT_IF(list.isOk(), !list.unwrap()->is<ParamsBodyNode>());
1100 return list;
1103 ListNodeResult newList(ParseNodeKind kind, Node kid) {
1104 auto list = newResult<ListNode>(kind, kid);
1105 MOZ_ASSERT_IF(list.isOk(), !list.unwrap()->is<DeclarationListNode>());
1106 MOZ_ASSERT_IF(list.isOk(), !list.unwrap()->is<ParamsBodyNode>());
1107 return list;
1110 DeclarationListNodeResult newDeclarationList(ParseNodeKind kind,
1111 const TokenPos& pos) {
1112 return newResult<DeclarationListNode>(kind, pos);
1115 ListNodeResult newCommaExpressionList(Node kid) {
1116 return newResult<ListNode>(ParseNodeKind::CommaExpr, kid);
1119 void addList(ListNodeType list, Node kid) { list->append(kid); }
1121 void setListHasNonConstInitializer(ListNodeType literal) {
1122 literal->setHasNonConstInitializer();
1125 // NOTE: This is infallible.
1126 template <typename NodeType>
1127 [[nodiscard]] NodeType parenthesize(NodeType node) {
1128 node->setInParens(true);
1129 return node;
1132 // NOTE: This is infallible.
1133 template <typename NodeType>
1134 [[nodiscard]] NodeType setLikelyIIFE(NodeType node) {
1135 return parenthesize(node);
1138 bool isName(Node node) { return node->isKind(ParseNodeKind::Name); }
1140 bool isArgumentsName(Node node) {
1141 return node->isKind(ParseNodeKind::Name) &&
1142 node->as<NameNode>().atom() ==
1143 TaggedParserAtomIndex::WellKnown::arguments();
1146 bool isLengthName(Node node) {
1147 return node->isKind(ParseNodeKind::PropertyNameExpr) &&
1148 node->as<NameNode>().atom() ==
1149 TaggedParserAtomIndex::WellKnown::length();
1152 bool isEvalName(Node node) {
1153 return node->isKind(ParseNodeKind::Name) &&
1154 node->as<NameNode>().atom() ==
1155 TaggedParserAtomIndex::WellKnown::eval();
1158 bool isAsyncKeyword(Node node) {
1159 return node->isKind(ParseNodeKind::Name) &&
1160 node->pn_pos.begin + strlen("async") == node->pn_pos.end &&
1161 node->as<NameNode>().atom() ==
1162 TaggedParserAtomIndex::WellKnown::async();
1165 bool isArgumentsLength(Node node) {
1166 return node->isKind(ParseNodeKind::ArgumentsLength);
1169 bool isPrivateName(Node node) {
1170 return node->isKind(ParseNodeKind::PrivateName);
1173 bool isPrivateMemberAccess(Node node) {
1174 if (node->isKind(ParseNodeKind::OptionalChain)) {
1175 return isPrivateMemberAccess(node->as<UnaryNode>().kid());
1177 return node->is<PrivateMemberAccessBase>();
1180 TaggedParserAtomIndex maybeDottedProperty(Node pn) {
1181 return pn->is<PropertyAccessBase>() ? pn->as<PropertyAccessBase>().name()
1182 : TaggedParserAtomIndex::null();
1184 TaggedParserAtomIndex isStringExprStatement(Node pn, TokenPos* pos) {
1185 if (pn->is<UnaryNode>()) {
1186 UnaryNode* unary = &pn->as<UnaryNode>();
1187 if (auto atom = unary->isStringExprStatement()) {
1188 *pos = unary->kid()->pn_pos;
1189 return atom;
1192 return TaggedParserAtomIndex::null();
1195 bool reuseLazyInnerFunctions() { return reuseGCThings; }
1196 bool reuseClosedOverBindings() { return reuseGCThings; }
1197 bool reuseRegexpSyntaxParse() { return reuseGCThings; }
1198 void nextLazyInnerFunction() { lazyInnerFunctionIndex++; }
1199 TaggedParserAtomIndex nextLazyClosedOverBinding() {
1200 // Trailing nullptrs were elided in PerHandlerParser::finishFunction().
1201 auto closedOverBindings = previousParseCache_.closedOverBindings();
1202 if (lazyClosedOverBindingIndex >= closedOverBindings.Length()) {
1203 return TaggedParserAtomIndex::null();
1206 return closedOverBindings[lazyClosedOverBindingIndex++];
1208 const ScriptStencil& cachedScriptData() const {
1209 // lazyInnerFunctionIndex is incremented with nextLazyInnferFunction before
1210 // reading the content, thus we need -1 to access the element that we just
1211 // skipped.
1212 return previousParseCache_.scriptData(lazyInnerFunctionIndex - 1);
1214 const ScriptStencilExtra& cachedScriptExtra() const {
1215 // lazyInnerFunctionIndex is incremented with nextLazyInnferFunction before
1216 // reading the content, thus we need -1 to access the element that we just
1217 // skipped.
1218 return previousParseCache_.scriptExtra(lazyInnerFunctionIndex - 1);
1221 void setPrivateNameKind(Node node, PrivateNameKind kind) {
1222 MOZ_ASSERT(node->is<NameNode>());
1223 node->as<NameNode>().setPrivateNameKind(kind);
1227 inline bool FullParseHandler::setLastFunctionFormalParameterDefault(
1228 FunctionNodeType funNode, Node defaultValue) {
1229 ParamsBodyNode* body = funNode->body();
1230 ParseNode* arg = body->last();
1231 ParseNode* pn;
1232 MOZ_TRY_VAR_OR_RETURN(
1233 pn, newAssignment(ParseNodeKind::AssignExpr, arg, defaultValue), false);
1235 body->replaceLast(pn);
1236 return true;
1239 } // namespace frontend
1240 } // namespace js
1242 #endif /* frontend_FullParseHandler_h */