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/. */
9 #ifndef frontend_Parser_h
10 #define frontend_Parser_h
15 * JS parsers capable of generating ASTs from source text.
17 * A parser embeds token stream information, then gets and matches tokens to
18 * generate a syntax tree that, if desired, BytecodeEmitter will use to compile
21 * Like token streams (see the comment near the top of TokenStream.h), parser
22 * classes are heavily templatized -- along the token stream's character-type
23 * axis, and also along a full-parse/syntax-parse axis. Certain limitations of
24 * C++ (primarily the inability to partially specialize function templates),
25 * plus the desire to minimize compiled code size in duplicate function
26 * template instantiations wherever possible, mean that Parser exhibits much of
27 * the same unholy template/inheritance complexity as token streams.
29 * == ParserSharedBase ==
31 * ParserSharedBase is the base class for both regular JS and BinAST parsing.
32 * This class contains common fields and methods between both parsers. There is
33 * currently no BinAST parser here so this can potentially be merged into the
34 * ParserBase type below.
36 * == ParserBase → ParserSharedBase, ErrorReportMixin ==
38 * ParserBase is the base class for regular JS parser, shared by all regular JS
39 * parsers of all character types and parse-handling behavior. It stores
40 * everything character- and handler-agnostic.
42 * ParserBase's most important field is the parser's token stream's
43 * |TokenStreamAnyChars| component, for all tokenizing aspects that are
44 * character-type-agnostic. The character-type-sensitive components residing
45 * in |TokenStreamSpecific| (see the comment near the top of TokenStream.h)
46 * live elsewhere in this hierarchy. These separate locations are the reason
47 * for the |AnyCharsAccess| template parameter to |TokenStreamChars| and
48 * |TokenStreamSpecific|.
50 * == PerHandlerParser<ParseHandler> → ParserBase ==
52 * Certain parsing behavior varies between full parsing and syntax-only parsing
53 * but does not vary across source-text character types. For example, the work
54 * to "create an arguments object for a function" obviously varies between
55 * syntax and full parsing but (because no source characters are examined) does
56 * not vary by source text character type. Such functionality is implemented
57 * through functions in PerHandlerParser.
59 * Functionality only used by syntax parsing or full parsing doesn't live here:
60 * it should be implemented in the appropriate Parser<ParseHandler> (described
63 * == GeneralParser<ParseHandler, Unit> → PerHandlerParser<ParseHandler> ==
65 * Most parsing behavior varies across the character-type axis (and possibly
66 * along the full/syntax axis). For example:
68 * * Parsing ECMAScript's Expression production, implemented by
69 * GeneralParser::expr, varies in this manner: different types are used to
70 * represent nodes in full and syntax parsing (ParseNode* versus an enum),
71 * and reading the tokens comprising the expression requires inspecting
72 * individual characters (necessarily dependent upon character type).
73 * * Reporting an error or warning does not depend on the full/syntax parsing
74 * distinction. But error reports and warnings include a line of context
75 * (or a slice of one), for pointing out where a mistake was made.
76 * Computing such line of context requires inspecting the source text to
77 * make that line/slice of context, which requires knowing the source text
80 * Such functionality, implemented using identical function code across these
81 * axes, should live in GeneralParser.
83 * GeneralParser's most important field is the parser's token stream's
84 * |TokenStreamSpecific| component, for all aspects of tokenizing that (contra
85 * |TokenStreamAnyChars| in ParserBase above) are character-type-sensitive. As
86 * noted above, this field's existence separate from that in ParserBase
87 * motivates the |AnyCharsAccess| template parameters on various token stream
90 * Everything in PerHandlerParser *could* be folded into GeneralParser (below)
91 * if desired. We don't fold in this manner because all such functions would
92 * be instantiated once per Unit -- but if exactly equivalent code would be
93 * generated (because PerHandlerParser functions have no awareness of Unit),
94 * it's risky to *depend* upon the compiler coalescing the instantiations into
95 * one in the final binary. PerHandlerParser guarantees no duplication.
97 * == Parser<ParseHandler, Unit> final → GeneralParser<ParseHandler, Unit> ==
99 * The final (pun intended) axis of complexity lies in Parser.
101 * Some functionality depends on character type, yet also is defined in
102 * significantly different form in full and syntax parsing. For example,
103 * attempting to parse the source text of a module will do so in full parsing
104 * but immediately fail in syntax parsing -- so the former is a mess'o'code
105 * while the latter is effectively |return null();|. Such functionality is
106 * defined in Parser<SyntaxParseHandler or FullParseHandler, Unit> as
109 * There's a crucial distinction between GeneralParser and Parser, that
110 * explains why both must exist (despite taking exactly the same template
111 * parameters, and despite GeneralParser and Parser existing in a one-to-one
112 * relationship). GeneralParser is one unspecialized template class:
114 * template<class ParseHandler, typename Unit>
115 * class GeneralParser : ...
117 * ...parsing functions...
120 * but Parser is one undefined template class with two separate
123 * // Declare, but do not define.
124 * template<class ParseHandler, typename Unit> class Parser;
126 * // Define a syntax-parsing specialization.
127 * template<typename Unit>
128 * class Parser<SyntaxParseHandler, Unit> final
129 * : public GeneralParser<SyntaxParseHandler, Unit>
131 * ...parsing functions...
134 * // Define a full-parsing specialization.
135 * template<typename Unit>
136 * class Parser<SyntaxParseHandler, Unit> final
137 * : public GeneralParser<SyntaxParseHandler, Unit>
139 * ...parsing functions...
142 * This odd distinction is necessary because C++ unfortunately doesn't allow
143 * partial function specialization:
145 * // BAD: You can only specialize a template function if you specify *every*
146 * // template parameter, i.e. ParseHandler *and* Unit.
147 * template<typename Unit>
149 * GeneralParser<SyntaxParseHandler, Unit>::foo() {}
151 * But if you specialize Parser *as a class*, then this is allowed:
153 * template<typename Unit>
155 * Parser<SyntaxParseHandler, Unit>::foo() {}
157 * template<typename Unit>
159 * Parser<FullParseHandler, Unit>::foo() {}
161 * because the only template parameter on the function is Unit -- and so all
162 * template parameters *are* varying, not a strict subset of them.
164 * So -- any parsing functionality that is differently defined for different
165 * ParseHandlers, *but* is defined textually identically for different Unit
166 * (even if different code ends up generated for them by the compiler), should
170 #include "mozilla/Maybe.h"
172 #include <type_traits>
175 #include "frontend/CompilationStencil.h" // CompilationState
176 #include "frontend/ErrorReporter.h"
177 #include "frontend/FullParseHandler.h"
178 #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
179 #include "frontend/IteratorKind.h"
180 #include "frontend/NameAnalysisTypes.h"
181 #include "frontend/ParseContext.h"
182 #include "frontend/ParserAtom.h" // ParserAtomsTable, TaggedParserAtomIndex
183 #include "frontend/SharedContext.h"
184 #include "frontend/SyntaxParseHandler.h"
185 #include "frontend/TokenStream.h"
186 #include "js/CharacterEncoding.h" // JS::ConstUTF8CharsZ
187 #include "js/friend/ErrorMessages.h" // JSErrNum, JSMSG_*
188 #include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind
192 class FrontendContext
;
193 struct ErrorMetadata
;
197 template <class ParseHandler
, typename Unit
>
200 class SourceParseContext
: public ParseContext
{
202 template <typename ParseHandler
, typename Unit
>
203 SourceParseContext(GeneralParser
<ParseHandler
, Unit
>* prs
, SharedContext
* sc
,
204 Directives
* newDirectives
)
205 : ParseContext(prs
->fc_
, prs
->pc_
, sc
, prs
->tokenStream
,
206 prs
->compilationState_
, newDirectives
,
207 std::is_same_v
<ParseHandler
, FullParseHandler
>) {}
210 enum VarContext
{ HoistVars
, DontHoistVars
};
211 enum PropListType
{ ObjectLiteral
, ClassBody
, DerivedClassBody
};
212 enum class PropertyType
{
215 CoverInitializedName
,
221 AsyncGeneratorMethod
,
228 enum AwaitHandling
: uint8_t {
231 AwaitIsModuleKeyword
,
235 template <class ParseHandler
, typename Unit
>
236 class AutoAwaitIsKeyword
;
238 template <class ParseHandler
, typename Unit
>
239 class AutoInParametersOfAsyncFunction
;
241 class MOZ_STACK_CLASS ParserSharedBase
{
243 enum class Kind
{ Parser
};
245 ParserSharedBase(FrontendContext
* fc
, CompilationState
& compilationState
,
250 FrontendContext
* fc_
;
254 CompilationState
& compilationState_
;
256 // innermost parse context (stack-allocated)
259 // For tracking used names in this parsing session.
260 UsedNameTracker
& usedNames_
;
263 CompilationState
& getCompilationState() { return compilationState_
; }
265 ParserAtomsTable
& parserAtoms() { return compilationState_
.parserAtoms
; }
266 const ParserAtomsTable
& parserAtoms() const {
267 return compilationState_
.parserAtoms
;
270 LifoAlloc
& stencilAlloc() { return compilationState_
.alloc
; }
272 const UsedNameTracker
& usedNames() { return usedNames_
; }
274 #if defined(DEBUG) || defined(JS_JITSPEW)
275 void dumpAtom(TaggedParserAtomIndex index
) const;
279 class MOZ_STACK_CLASS ParserBase
: public ParserSharedBase
,
280 public ErrorReportMixin
{
281 using Base
= ErrorReportMixin
;
284 TokenStreamAnyChars anyChars
;
288 // Perform constant-folding; must be true when interfacing with the emitter.
289 const bool foldConstants_
: 1;
293 /* Our fallible 'checkOptions' member function has been called. */
294 bool checkOptionsCalled_
: 1;
297 /* Unexpected end of input, i.e. Eof not at top-level. */
298 bool isUnexpectedEOF_
: 1;
300 /* AwaitHandling */ uint8_t awaitHandling_
: 2;
302 bool inParametersOfAsyncFunction_
: 1;
305 JSAtom
* liftParserAtomToJSAtom(TaggedParserAtomIndex index
);
307 bool awaitIsKeyword() const {
308 return awaitHandling_
== AwaitIsKeyword
||
309 awaitHandling_
== AwaitIsModuleKeyword
;
311 bool awaitIsDisallowed() const { return awaitHandling_
== AwaitIsDisallowed
; }
313 bool inParametersOfAsyncFunction() const {
314 return inParametersOfAsyncFunction_
;
317 ParseGoal
parseGoal() const {
318 return pc_
->sc()->hasModuleGoal() ? ParseGoal::Module
: ParseGoal::Script
;
321 template <class, typename
>
322 friend class AutoAwaitIsKeyword
;
323 template <class, typename
>
324 friend class AutoInParametersOfAsyncFunction
;
326 ParserBase(FrontendContext
* fc
, const JS::ReadOnlyCompileOptions
& options
,
327 bool foldConstants
, CompilationState
& compilationState
);
332 JS::ConstUTF8CharsZ
getFilename() const { return anyChars
.getFilename(); }
333 TokenPos
pos() const { return anyChars
.currentToken().pos
; }
335 // Determine whether |yield| is a valid name in the current context.
336 bool yieldExpressionsSupported() const { return pc_
->isGenerator(); }
338 bool setLocalStrictMode(bool strict
) {
339 MOZ_ASSERT(anyChars
.debugHasNoLookahead());
340 return pc_
->sc()->setLocalStrictMode(strict
);
344 // Implement ErrorReportMixin.
346 FrontendContext
* getContext() const override
{ return fc_
; }
348 bool strictMode() const override
{ return pc_
->sc()->strict(); }
350 const JS::ReadOnlyCompileOptions
& options() const override
{
351 return anyChars
.options();
356 using Base::errorNoOffset
;
357 using Base::errorWithNotes
;
358 using Base::errorWithNotesAt
;
359 using Base::errorWithNotesNoOffset
;
360 using Base::strictModeError
;
361 using Base::strictModeErrorAt
;
362 using Base::strictModeErrorNoOffset
;
363 using Base::strictModeErrorWithNotes
;
364 using Base::strictModeErrorWithNotesAt
;
365 using Base::strictModeErrorWithNotesNoOffset
;
367 using Base::warningAt
;
368 using Base::warningNoOffset
;
371 bool isUnexpectedEOF() const { return isUnexpectedEOF_
; }
373 bool isValidStrictBinding(TaggedParserAtomIndex name
);
375 bool hasValidSimpleStrictParameterNames();
377 // A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
378 // Parser's state. Note: clients must still take care that any ParseContext
379 // that points into released ParseNodes is destroyed.
381 friend class ParserBase
;
382 LifoAlloc::Mark mark
;
383 CompilationState::CompilationStatePosition pos
;
387 m
.mark
= alloc_
.mark();
388 m
.pos
= compilationState_
.getPosition();
391 void release(Mark m
) {
392 alloc_
.release(m
.mark
);
393 compilationState_
.rewind(m
.pos
);
397 mozilla::Maybe
<GlobalScope::ParserData
*> newGlobalScopeData(
398 ParseContext::Scope
& scope
);
399 mozilla::Maybe
<ModuleScope::ParserData
*> newModuleScopeData(
400 ParseContext::Scope
& scope
);
401 mozilla::Maybe
<EvalScope::ParserData
*> newEvalScopeData(
402 ParseContext::Scope
& scope
);
403 mozilla::Maybe
<FunctionScope::ParserData
*> newFunctionScopeData(
404 ParseContext::Scope
& scope
, bool hasParameterExprs
);
405 mozilla::Maybe
<VarScope::ParserData
*> newVarScopeData(
406 ParseContext::Scope
& scope
);
407 mozilla::Maybe
<LexicalScope::ParserData
*> newLexicalScopeData(
408 ParseContext::Scope
& scope
);
409 mozilla::Maybe
<ClassBodyScope::ParserData
*> newClassBodyScopeData(
410 ParseContext::Scope
& scope
);
413 enum InvokedPrediction
{ PredictUninvoked
= false, PredictInvoked
= true };
414 enum ForInitLocation
{ InForInit
, NotInForInit
};
416 // While on a |let| Name token, examine |next| (which must already be
417 // gotten). Indicate whether |next|, the next token already gotten with
418 // modifier TokenStream::SlashIsDiv, continues a LexicalDeclaration.
419 bool nextTokenContinuesLetDeclaration(TokenKind next
);
421 bool noteUsedNameInternal(TaggedParserAtomIndex name
,
422 NameVisibility visibility
,
423 mozilla::Maybe
<TokenPos
> tokenPosition
);
425 bool checkAndMarkSuperScope();
427 bool leaveInnerFunction(ParseContext
* outerpc
);
429 TaggedParserAtomIndex
prefixAccessorName(PropertyType propType
,
430 TaggedParserAtomIndex propAtom
);
432 [[nodiscard
]] bool setSourceMapInfo();
434 void setFunctionEndFromCurrentToken(FunctionBox
* funbox
) const;
437 template <class ParseHandler
>
438 class MOZ_STACK_CLASS PerHandlerParser
: public ParserBase
{
439 using Base
= ParserBase
;
442 using Node
= typename
ParseHandler::Node
;
443 using NodeResult
= typename
ParseHandler::NodeResult
;
445 #define DECLARE_TYPE(typeName) \
446 using typeName##Type = typename ParseHandler::typeName##Type; \
447 using typeName##Result = typename ParseHandler::typeName##Result;
448 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE
)
452 /* State specific to the kind of parse being performed. */
453 ParseHandler handler_
;
455 // When ParseHandler is FullParseHandler:
457 // If non-null, this field holds the syntax parser used to attempt lazy
458 // parsing of inner functions. If null, then lazy parsing is disabled.
460 // When ParseHandler is SyntaxParseHandler:
462 // If non-null, this field must be a sentinel value signaling that the
463 // syntax parse was aborted. If null, then lazy parsing was aborted due
464 // to encountering unsupported language constructs.
466 // |internalSyntaxParser_| is really a |Parser<SyntaxParseHandler, Unit>*|
467 // where |Unit| varies per |Parser<ParseHandler, Unit>|. But this
468 // template class doesn't know |Unit|, so we store a |void*| here and make
469 // |GeneralParser<ParseHandler, Unit>::getSyntaxParser| impose the real type.
470 void* internalSyntaxParser_
;
473 // NOTE: The argument ordering here is deliberately different from the
474 // public constructor so that typos calling the public constructor
475 // are less likely to select this overload.
476 PerHandlerParser(FrontendContext
* fc
,
477 const JS::ReadOnlyCompileOptions
& options
,
478 bool foldConstants
, CompilationState
& compilationState
,
479 void* internalSyntaxParser
);
482 template <typename Unit
>
483 PerHandlerParser(FrontendContext
* fc
,
484 const JS::ReadOnlyCompileOptions
& options
,
485 bool foldConstants
, CompilationState
& compilationState
,
486 GeneralParser
<SyntaxParseHandler
, Unit
>* syntaxParser
)
487 : PerHandlerParser(fc
, options
, foldConstants
, compilationState
,
488 static_cast<void*>(syntaxParser
)) {}
490 static typename
ParseHandler::NullNode
null() { return ParseHandler::null(); }
492 // The return value for the error case in the functions that returns
494 static constexpr typename
ParseHandler::NodeErrorResult
errorResult() {
495 return ParseHandler::errorResult();
498 NameNodeResult
stringLiteral();
500 const char* nameIsArgumentsOrEval(Node node
);
502 bool noteDestructuredPositionalFormalParameter(FunctionNodeType funNode
,
506 TaggedParserAtomIndex name
,
507 NameVisibility visibility
= NameVisibility::Public
,
508 mozilla::Maybe
<TokenPos
> tokenPosition
= mozilla::Nothing()) {
509 // If the we are delazifying, the BaseScript already has all the closed-over
510 // info for bindings and there's no need to track used names.
511 if (handler_
.reuseClosedOverBindings()) {
515 return ParserBase::noteUsedNameInternal(name
, visibility
, tokenPosition
);
518 // Required on Scope exit.
519 bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope
& scope
);
521 bool checkForUndefinedPrivateFields(EvalSharedContext
* evalSc
= nullptr);
523 bool finishFunctionScopes(bool isStandaloneFunction
);
524 LexicalScopeNodeResult
finishLexicalScope(
525 ParseContext::Scope
& scope
, Node body
,
526 ScopeKind kind
= ScopeKind::Lexical
);
527 ClassBodyScopeNodeResult
finishClassBodyScope(ParseContext::Scope
& scope
,
529 bool finishFunction(bool isStandaloneFunction
= false);
531 inline NameNodeResult
newName(TaggedParserAtomIndex name
);
532 inline NameNodeResult
newName(TaggedParserAtomIndex name
, TokenPos pos
);
534 inline NameNodeResult
newPrivateName(TaggedParserAtomIndex name
);
536 NameNodeResult
newInternalDotName(TaggedParserAtomIndex name
);
537 NameNodeResult
newThisName();
538 NameNodeResult
newNewTargetName();
539 NameNodeResult
newDotGeneratorName();
541 NameNodeResult
identifierReference(TaggedParserAtomIndex name
);
542 NameNodeResult
privateNameReference(TaggedParserAtomIndex name
);
544 NodeResult
noSubstitutionTaggedTemplate();
546 inline bool processExport(Node node
);
547 inline bool processExportFrom(BinaryNodeType node
);
548 inline bool processImport(BinaryNodeType node
);
550 // If ParseHandler is SyntaxParseHandler:
552 // If ParseHandler is FullParseHandler:
553 // Disable syntax parsing of all future inner functions during this
555 inline void disableSyntaxParser();
557 // If ParseHandler is SyntaxParseHandler:
558 // Flag the current syntax parse as aborted due to unsupported language
559 // constructs and return false. Aborting the current syntax parse does
560 // not disable attempts to syntax-parse future inner functions.
561 // If ParseHandler is FullParseHandler:
562 // Disable syntax parsing of all future inner functions and return true.
563 inline bool abortIfSyntaxParser();
565 // If ParseHandler is SyntaxParseHandler:
566 // Return whether the last syntax parse was aborted due to unsupported
567 // language constructs.
568 // If ParseHandler is FullParseHandler:
570 inline bool hadAbortedSyntaxParse();
572 // If ParseHandler is SyntaxParseHandler:
573 // Clear whether the last syntax parse was aborted.
574 // If ParseHandler is FullParseHandler:
576 inline void clearAbortedSyntaxParse();
579 FunctionBox
* newFunctionBox(FunctionNodeType funNode
,
580 TaggedParserAtomIndex explicitName
,
581 FunctionFlags flags
, uint32_t toStringStart
,
582 Directives directives
,
583 GeneratorKind generatorKind
,
584 FunctionAsyncKind asyncKind
);
586 FunctionBox
* newFunctionBox(FunctionNodeType funNode
,
587 const ScriptStencil
& cachedScriptData
,
588 const ScriptStencilExtra
& cachedScriptExtra
);
595 using Base::errorNoOffset
;
596 using Base::errorWithNotes
;
597 using Base::errorWithNotesAt
;
598 using Base::errorWithNotesNoOffset
;
599 using Base::strictModeError
;
600 using Base::strictModeErrorAt
;
601 using Base::strictModeErrorNoOffset
;
602 using Base::strictModeErrorWithNotes
;
603 using Base::strictModeErrorWithNotesAt
;
604 using Base::strictModeErrorWithNotesNoOffset
;
606 using Base::warningAt
;
607 using Base::warningNoOffset
;
610 #define ABORTED_SYNTAX_PARSE_SENTINEL reinterpret_cast<void*>(0x1)
613 inline void PerHandlerParser
<SyntaxParseHandler
>::disableSyntaxParser() {}
616 inline bool PerHandlerParser
<SyntaxParseHandler
>::abortIfSyntaxParser() {
617 internalSyntaxParser_
= ABORTED_SYNTAX_PARSE_SENTINEL
;
622 inline bool PerHandlerParser
<SyntaxParseHandler
>::hadAbortedSyntaxParse() {
623 return internalSyntaxParser_
== ABORTED_SYNTAX_PARSE_SENTINEL
;
627 inline void PerHandlerParser
<SyntaxParseHandler
>::clearAbortedSyntaxParse() {
628 internalSyntaxParser_
= nullptr;
631 #undef ABORTED_SYNTAX_PARSE_SENTINEL
633 // Disable syntax parsing of all future inner functions during this
636 inline void PerHandlerParser
<FullParseHandler
>::disableSyntaxParser() {
637 internalSyntaxParser_
= nullptr;
641 inline bool PerHandlerParser
<FullParseHandler
>::abortIfSyntaxParser() {
642 disableSyntaxParser();
647 inline bool PerHandlerParser
<FullParseHandler
>::hadAbortedSyntaxParse() {
652 inline void PerHandlerParser
<FullParseHandler
>::clearAbortedSyntaxParse() {}
654 template <class Parser
>
655 class ParserAnyCharsAccess
{
657 using TokenStreamSpecific
= typename
Parser::TokenStream
;
658 using GeneralTokenStreamChars
=
659 typename
TokenStreamSpecific::GeneralCharsBase
;
661 static inline TokenStreamAnyChars
& anyChars(GeneralTokenStreamChars
* ts
);
662 static inline const TokenStreamAnyChars
& anyChars(
663 const GeneralTokenStreamChars
* ts
);
666 // Specify a value for an ES6 grammar parametrization. We have no enum for
667 // [Return] because its behavior is almost exactly equivalent to checking
668 // whether we're in a function box -- easier and simpler than passing an extra
669 // parameter everywhere.
670 enum YieldHandling
{ YieldIsName
, YieldIsKeyword
};
671 enum InHandling
{ InAllowed
, InProhibited
};
672 enum DefaultHandling
{ NameRequired
, AllowDefaultName
};
673 enum TripledotHandling
{ TripledotAllowed
, TripledotProhibited
};
675 // For Ergonomic brand checks.
676 enum PrivateNameHandling
{ PrivateNameProhibited
, PrivateNameAllowed
};
678 template <class ParseHandler
, typename Unit
>
681 template <class ParseHandler
, typename Unit
>
682 class MOZ_STACK_CLASS GeneralParser
: public PerHandlerParser
<ParseHandler
> {
685 TokenStreamSpecific
<Unit
, ParserAnyCharsAccess
<GeneralParser
>>;
688 using Base
= PerHandlerParser
<ParseHandler
>;
689 using FinalParser
= Parser
<ParseHandler
, Unit
>;
690 using Node
= typename
ParseHandler::Node
;
691 using NodeResult
= typename
ParseHandler::NodeResult
;
693 #define DECLARE_TYPE(typeName) \
694 using typeName##Type = typename ParseHandler::typeName##Type; \
695 using typeName##Result = typename ParseHandler::typeName##Result;
696 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE
)
699 using typename
Base::InvokedPrediction
;
700 using SyntaxParser
= Parser
<SyntaxParseHandler
, Unit
>;
703 using Modifier
= TokenStreamShared::Modifier
;
704 using Position
= typename
TokenStream::Position
;
706 using Base::PredictInvoked
;
707 using Base::PredictUninvoked
;
710 using Base::awaitIsDisallowed
;
711 using Base::awaitIsKeyword
;
712 using Base::inParametersOfAsyncFunction
;
713 using Base::parseGoal
;
715 using Base::checkOptionsCalled_
;
717 using Base::checkForUndefinedPrivateFields
;
718 using Base::errorResult
;
719 using Base::finishClassBodyScope
;
720 using Base::finishFunctionScopes
;
721 using Base::finishLexicalScope
;
722 using Base::foldConstants_
;
723 using Base::getFilename
;
724 using Base::hasValidSimpleStrictParameterNames
;
725 using Base::isUnexpectedEOF_
;
726 using Base::nameIsArgumentsOrEval
;
727 using Base::newDotGeneratorName
;
728 using Base::newFunctionBox
;
733 using Base::propagateFreeNamesAndMarkClosedOverBindings
;
734 using Base::setLocalStrictMode
;
735 using Base::stringLiteral
;
736 using Base::yieldExpressionsSupported
;
738 using Base::abortIfSyntaxParser
;
739 using Base::clearAbortedSyntaxParse
;
740 using Base::disableSyntaxParser
;
741 using Base::hadAbortedSyntaxParse
;
744 // Implement ErrorReportMixin.
746 [[nodiscard
]] bool computeErrorMetadata(
748 const ErrorReportMixin::ErrorOffset
& offset
) const override
;
752 using Base::errorNoOffset
;
753 using Base::errorWithNotes
;
754 using Base::errorWithNotesAt
;
755 using Base::errorWithNotesNoOffset
;
756 using Base::strictModeError
;
757 using Base::strictModeErrorAt
;
758 using Base::strictModeErrorNoOffset
;
759 using Base::strictModeErrorWithNotes
;
760 using Base::strictModeErrorWithNotesAt
;
761 using Base::strictModeErrorWithNotesNoOffset
;
763 using Base::warningAt
;
764 using Base::warningNoOffset
;
767 using Base::anyChars
;
769 using Base::handler_
;
770 using Base::noteUsedName
;
772 using Base::usedNames_
;
775 using Base::checkAndMarkSuperScope
;
776 using Base::finishFunction
;
777 using Base::identifierReference
;
778 using Base::leaveInnerFunction
;
779 using Base::newInternalDotName
;
780 using Base::newNewTargetName
;
781 using Base::newThisName
;
782 using Base::nextTokenContinuesLetDeclaration
;
783 using Base::noSubstitutionTaggedTemplate
;
784 using Base::noteDestructuredPositionalFormalParameter
;
785 using Base::prefixAccessorName
;
786 using Base::privateNameReference
;
787 using Base::processExport
;
788 using Base::processExportFrom
;
789 using Base::processImport
;
790 using Base::setFunctionEndFromCurrentToken
;
793 inline FinalParser
* asFinalParser();
794 inline const FinalParser
* asFinalParser() const;
797 * A class for temporarily stashing errors while parsing continues.
799 * The ability to stash an error is useful for handling situations where we
800 * aren't able to verify that an error has occurred until later in the parse.
801 * For instance | ({x=1}) | is always parsed as an object literal with
802 * a SyntaxError, however, in the case where it is followed by '=>' we rewind
803 * and reparse it as a valid arrow function. Here a PossibleError would be
804 * set to 'pending' when the initial SyntaxError was encountered then
805 * 'resolved' just before rewinding the parser.
807 * There are currently two kinds of PossibleErrors: Expression and
808 * Destructuring errors. Expression errors are used to mark a possible
809 * syntax error when a grammar production is used in an expression context.
810 * For example in |{x = 1}|, we mark the CoverInitializedName |x = 1| as a
811 * possible expression error, because CoverInitializedName productions
812 * are disallowed when an actual ObjectLiteral is expected.
813 * Destructuring errors are used to record possible syntax errors in
814 * destructuring contexts. For example in |[...rest, ] = []|, we initially
815 * mark the trailing comma after the spread expression as a possible
816 * destructuring error, because the ArrayAssignmentPattern grammar
817 * production doesn't allow a trailing comma after the rest element.
819 * When using PossibleError one should set a pending error at the location
820 * where an error occurs. From that point, the error may be resolved
821 * (invalidated) or left until the PossibleError is checked.
824 * PossibleError possibleError(*this);
825 * possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
826 * // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
827 * if (!possibleError.checkForExpressionError()) {
828 * return false; // we reach this point with a pending exception
831 * PossibleError possibleError(*this);
832 * possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
833 * // Returns true, no error is reported.
834 * if (!possibleError.checkForDestructuringError()) {
835 * return false; // not reached, no pending exception
838 * PossibleError possibleError(*this);
839 * // Returns true, no error is reported.
840 * if (!possibleError.checkForExpressionError()) {
841 * return false; // not reached, no pending exception
844 class MOZ_STACK_CLASS PossibleError
{
846 enum class ErrorKind
{ Expression
, Destructuring
, DestructuringWarning
};
848 enum class ErrorState
{ None
, Pending
};
851 ErrorState state_
= ErrorState::None
;
853 // Error reporting fields.
855 unsigned errorNumber_
;
858 GeneralParser
<ParseHandler
, Unit
>& parser_
;
860 Error destructuringError_
;
861 Error destructuringWarning_
;
863 // Returns the error report.
864 Error
& error(ErrorKind kind
);
866 // Return true if an error is pending without reporting.
867 bool hasError(ErrorKind kind
);
869 // Resolve any pending error.
870 void setResolved(ErrorKind kind
);
872 // Set a pending error. Only a single error may be set per instance and
874 void setPending(ErrorKind kind
, const TokenPos
& pos
, unsigned errorNumber
);
876 // If there is a pending error, report it and return false, otherwise
878 [[nodiscard
]] bool checkForError(ErrorKind kind
);
880 // Transfer an existing error to another instance.
881 void transferErrorTo(ErrorKind kind
, PossibleError
* other
);
884 explicit PossibleError(GeneralParser
<ParseHandler
, Unit
>& parser
);
886 // Return true if a pending destructuring error is present.
887 bool hasPendingDestructuringError();
889 // Set a pending destructuring error. Only a single error may be set
890 // per instance, i.e. subsequent calls to this method are ignored and
891 // won't overwrite the existing pending error.
892 void setPendingDestructuringErrorAt(const TokenPos
& pos
,
893 unsigned errorNumber
);
895 // Set a pending destructuring warning. Only a single warning may be
896 // set per instance, i.e. subsequent calls to this method are ignored
897 // and won't overwrite the existing pending warning.
898 void setPendingDestructuringWarningAt(const TokenPos
& pos
,
899 unsigned errorNumber
);
901 // Set a pending expression error. Only a single error may be set per
902 // instance, i.e. subsequent calls to this method are ignored and won't
903 // overwrite the existing pending error.
904 void setPendingExpressionErrorAt(const TokenPos
& pos
, unsigned errorNumber
);
906 // If there is a pending destructuring error or warning, report it and
907 // return false, otherwise return true. Clears any pending expression
909 [[nodiscard
]] bool checkForDestructuringErrorOrWarning();
911 // If there is a pending expression error, report it and return false,
912 // otherwise return true. Clears any pending destructuring error or
914 [[nodiscard
]] bool checkForExpressionError();
916 // Pass pending errors between possible error instances. This is useful
917 // for extending the lifetime of a pending error beyond the scope of
918 // the PossibleError where it was initially set (keeping in mind that
919 // PossibleError is a MOZ_STACK_CLASS).
920 void transferErrorsTo(PossibleError
* other
);
924 SyntaxParser
* getSyntaxParser() const {
925 return reinterpret_cast<SyntaxParser
*>(Base::internalSyntaxParser_
);
929 TokenStream tokenStream
;
932 GeneralParser(FrontendContext
* fc
, const JS::ReadOnlyCompileOptions
& options
,
933 const Unit
* units
, size_t length
, bool foldConstants
,
934 CompilationState
& compilationState
, SyntaxParser
* syntaxParser
);
936 inline void setAwaitHandling(AwaitHandling awaitHandling
);
937 inline void setInParametersOfAsyncFunction(bool inParameters
);
940 * Parse a top-level JS script.
942 ListNodeResult
parse();
946 * Gets the next token and checks if it matches to the given `condition`.
947 * If it matches, returns true.
948 * If it doesn't match, calls `errorReport` to report the error, and
950 * If other error happens, it returns false but `errorReport` may not be
951 * called and other error will be thrown in that case.
953 * In any case, the already gotten token is not ungotten.
955 * The signature of `condition` is [...](TokenKind actual) -> bool, and
956 * the signature of `errorReport` is [...](TokenKind actual).
958 template <typename ConditionT
, typename ErrorReportT
>
959 [[nodiscard
]] bool mustMatchTokenInternal(ConditionT condition
,
960 ErrorReportT errorReport
);
964 * The following mustMatchToken variants follow the behavior and parameter
965 * types of mustMatchTokenInternal above.
967 * If modifier is omitted, `SlashIsDiv` is used.
968 * If TokenKind is passed instead of `condition`, it checks if the next
969 * token is the passed token.
970 * If error number is passed instead of `errorReport`, it reports an
971 * error with the passed errorNumber.
973 [[nodiscard
]] bool mustMatchToken(TokenKind expected
, JSErrNum errorNumber
) {
974 return mustMatchTokenInternal(
975 [expected
](TokenKind actual
) { return actual
== expected
; },
976 [this, errorNumber
](TokenKind
) { this->error(errorNumber
); });
979 template <typename ConditionT
>
980 [[nodiscard
]] bool mustMatchToken(ConditionT condition
,
981 JSErrNum errorNumber
) {
982 return mustMatchTokenInternal(condition
, [this, errorNumber
](TokenKind
) {
983 this->error(errorNumber
);
987 template <typename ErrorReportT
>
988 [[nodiscard
]] bool mustMatchToken(TokenKind expected
,
989 ErrorReportT errorReport
) {
990 return mustMatchTokenInternal(
991 [expected
](TokenKind actual
) { return actual
== expected
; },
996 NameNodeResult
noSubstitutionUntaggedTemplate();
997 ListNodeResult
templateLiteral(YieldHandling yieldHandling
);
998 bool taggedTemplate(YieldHandling yieldHandling
, ListNodeType tagArgsList
,
1000 bool appendToCallSiteObj(CallSiteNodeType callSiteObj
);
1001 bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling
,
1002 ListNodeType nodeList
, TokenKind
* ttp
);
1004 inline bool trySyntaxParseInnerFunction(
1005 FunctionNodeType
* funNode
, TaggedParserAtomIndex explicitName
,
1006 FunctionFlags flags
, uint32_t toStringStart
, InHandling inHandling
,
1007 YieldHandling yieldHandling
, FunctionSyntaxKind kind
,
1008 GeneratorKind generatorKind
, FunctionAsyncKind asyncKind
, bool tryAnnexB
,
1009 Directives inheritedDirectives
, Directives
* newDirectives
);
1011 inline bool skipLazyInnerFunction(FunctionNodeType funNode
,
1012 uint32_t toStringStart
, bool tryAnnexB
);
1014 void setFunctionStartAtPosition(FunctionBox
* funbox
, TokenPos pos
) const;
1015 void setFunctionStartAtCurrentToken(FunctionBox
* funbox
) const;
1018 /* Public entry points for parsing. */
1019 NodeResult
statementListItem(YieldHandling yieldHandling
,
1020 bool canHaveDirectives
= false);
1022 // Parse an inner function given an enclosing ParseContext and a
1023 // FunctionBox for the inner function.
1024 [[nodiscard
]] FunctionNodeResult
innerFunctionForFunctionBox(
1025 FunctionNodeType funNode
, ParseContext
* outerpc
, FunctionBox
* funbox
,
1026 InHandling inHandling
, YieldHandling yieldHandling
,
1027 FunctionSyntaxKind kind
, Directives
* newDirectives
);
1029 // Parse a function's formal parameters and its body assuming its function
1030 // ParseContext is already on the stack.
1031 bool functionFormalParametersAndBody(
1032 InHandling inHandling
, YieldHandling yieldHandling
,
1033 FunctionNodeType
* funNode
, FunctionSyntaxKind kind
,
1034 const mozilla::Maybe
<uint32_t>& parameterListEnd
= mozilla::Nothing(),
1035 bool isStandaloneFunction
= false);
1039 * JS parsers, from lowest to highest precedence.
1041 * Each parser must be called during the dynamic scope of a ParseContext
1042 * object, pointed to by this->pc_.
1044 * Each returns a parse node tree or null on error.
1046 FunctionNodeResult
functionStmt(
1047 uint32_t toStringStart
, YieldHandling yieldHandling
,
1048 DefaultHandling defaultHandling
,
1049 FunctionAsyncKind asyncKind
= FunctionAsyncKind::SyncFunction
);
1050 FunctionNodeResult
functionExpr(uint32_t toStringStart
,
1051 InvokedPrediction invoked
,
1052 FunctionAsyncKind asyncKind
);
1054 NodeResult
statement(YieldHandling yieldHandling
);
1055 bool maybeParseDirective(ListNodeType list
, Node pn
, bool* cont
);
1057 LexicalScopeNodeResult
blockStatement(
1058 YieldHandling yieldHandling
,
1059 unsigned errorNumber
= JSMSG_CURLY_IN_COMPOUND
);
1060 BinaryNodeResult
doWhileStatement(YieldHandling yieldHandling
);
1061 BinaryNodeResult
whileStatement(YieldHandling yieldHandling
);
1063 NodeResult
forStatement(YieldHandling yieldHandling
);
1064 bool forHeadStart(YieldHandling yieldHandling
, IteratorKind iterKind
,
1065 ParseNodeKind
* forHeadKind
, Node
* forInitialPart
,
1066 mozilla::Maybe
<ParseContext::Scope
>& forLetImpliedScope
,
1067 Node
* forInOrOfExpression
);
1068 NodeResult
expressionAfterForInOrOf(ParseNodeKind forHeadKind
,
1069 YieldHandling yieldHandling
);
1071 SwitchStatementResult
switchStatement(YieldHandling yieldHandling
);
1072 ContinueStatementResult
continueStatement(YieldHandling yieldHandling
);
1073 BreakStatementResult
breakStatement(YieldHandling yieldHandling
);
1074 UnaryNodeResult
returnStatement(YieldHandling yieldHandling
);
1075 BinaryNodeResult
withStatement(YieldHandling yieldHandling
);
1076 UnaryNodeResult
throwStatement(YieldHandling yieldHandling
);
1077 TernaryNodeResult
tryStatement(YieldHandling yieldHandling
);
1078 LexicalScopeNodeResult
catchBlockStatement(
1079 YieldHandling yieldHandling
, ParseContext::Scope
& catchParamScope
);
1080 DebuggerStatementResult
debuggerStatement();
1082 DeclarationListNodeResult
variableStatement(YieldHandling yieldHandling
);
1084 LabeledStatementResult
labeledStatement(YieldHandling yieldHandling
);
1085 NodeResult
labeledItem(YieldHandling yieldHandling
);
1087 TernaryNodeResult
ifStatement(YieldHandling yieldHandling
);
1088 NodeResult
consequentOrAlternative(YieldHandling yieldHandling
);
1090 DeclarationListNodeResult
lexicalDeclaration(YieldHandling yieldHandling
,
1091 DeclarationKind kind
);
1093 NameNodeResult
moduleExportName();
1095 bool assertClause(ListNodeType assertionsSet
);
1097 BinaryNodeResult
importDeclaration();
1098 NodeResult
importDeclarationOrImportExpr(YieldHandling yieldHandling
);
1099 bool namedImports(ListNodeType importSpecSet
);
1100 bool namespaceImport(ListNodeType importSpecSet
);
1102 TaggedParserAtomIndex
importedBinding() {
1103 return bindingIdentifier(YieldIsName
);
1106 BinaryNodeResult
exportFrom(uint32_t begin
, Node specList
);
1107 BinaryNodeResult
exportBatch(uint32_t begin
);
1108 inline bool checkLocalExportNames(ListNodeType node
);
1109 NodeResult
exportClause(uint32_t begin
);
1110 UnaryNodeResult
exportFunctionDeclaration(
1111 uint32_t begin
, uint32_t toStringStart
,
1112 FunctionAsyncKind asyncKind
= FunctionAsyncKind::SyncFunction
);
1113 UnaryNodeResult
exportVariableStatement(uint32_t begin
);
1114 UnaryNodeResult
exportClassDeclaration(uint32_t begin
);
1115 UnaryNodeResult
exportLexicalDeclaration(uint32_t begin
,
1116 DeclarationKind kind
);
1117 BinaryNodeResult
exportDefaultFunctionDeclaration(
1118 uint32_t begin
, uint32_t toStringStart
,
1119 FunctionAsyncKind asyncKind
= FunctionAsyncKind::SyncFunction
);
1120 BinaryNodeResult
exportDefaultClassDeclaration(uint32_t begin
);
1121 BinaryNodeResult
exportDefaultAssignExpr(uint32_t begin
);
1122 BinaryNodeResult
exportDefault(uint32_t begin
);
1123 NodeResult
exportDeclaration();
1125 UnaryNodeResult
expressionStatement(
1126 YieldHandling yieldHandling
,
1127 InvokedPrediction invoked
= PredictUninvoked
);
1129 // Declaration parsing. The main entrypoint is Parser::declarationList,
1130 // with sub-functionality split out into the remaining methods.
1132 // |blockScope| may be non-null only when |kind| corresponds to a lexical
1133 // declaration (that is, ParseNodeKind::LetDecl or ParseNodeKind::ConstDecl).
1135 // The for* parameters, for normal declarations, should be null/ignored.
1136 // They should be non-null only when Parser::forHeadStart parses a
1137 // declaration at the start of a for-loop head.
1139 // In this case, on success |*forHeadKind| is ParseNodeKind::ForHead,
1140 // ParseNodeKind::ForIn, or ParseNodeKind::ForOf, corresponding to the three
1141 // for-loop kinds. The precise value indicates what was parsed.
1143 // If parsing recognized a for(;;) loop, the next token is the ';' within
1144 // the loop-head that separates the init/test parts.
1146 // Otherwise, for for-in/of loops, the next token is the ')' ending the
1147 // loop-head. Additionally, the expression that the loop iterates over was
1148 // parsed into |*forInOrOfExpression|.
1149 DeclarationListNodeResult
declarationList(
1150 YieldHandling yieldHandling
, ParseNodeKind kind
,
1151 ParseNodeKind
* forHeadKind
= nullptr,
1152 Node
* forInOrOfExpression
= nullptr);
1154 // The items in a declaration list are either patterns or names, with or
1155 // without initializers. These two methods parse a single pattern/name and
1156 // any associated initializer -- and if parsing an |initialDeclaration|
1157 // will, if parsing in a for-loop head (as specified by |forHeadKind| being
1158 // non-null), consume additional tokens up to the closing ')' in a
1159 // for-in/of loop head, returning the iterated expression in
1160 // |*forInOrOfExpression|. (An "initial declaration" is the first
1161 // declaration in a declaration list: |a| but not |b| in |var a, b|, |{c}|
1162 // but not |d| in |let {c} = 3, d|.)
1163 NodeResult
declarationPattern(DeclarationKind declKind
, TokenKind tt
,
1164 bool initialDeclaration
,
1165 YieldHandling yieldHandling
,
1166 ParseNodeKind
* forHeadKind
,
1167 Node
* forInOrOfExpression
);
1168 NodeResult
declarationName(DeclarationKind declKind
, TokenKind tt
,
1169 bool initialDeclaration
,
1170 YieldHandling yieldHandling
,
1171 ParseNodeKind
* forHeadKind
,
1172 Node
* forInOrOfExpression
);
1174 // Having parsed a name (not found in a destructuring pattern) declared by
1175 // a declaration, with the current token being the '=' separating the name
1176 // from its initializer, parse and bind that initializer -- and possibly
1177 // consume trailing in/of and subsequent expression, if so directed by
1179 AssignmentNodeResult
initializerInNameDeclaration(NameNodeType binding
,
1180 DeclarationKind declKind
,
1181 bool initialDeclaration
,
1182 YieldHandling yieldHandling
,
1183 ParseNodeKind
* forHeadKind
,
1184 Node
* forInOrOfExpression
);
1186 NodeResult
expr(InHandling inHandling
, YieldHandling yieldHandling
,
1187 TripledotHandling tripledotHandling
,
1188 PossibleError
* possibleError
= nullptr,
1189 InvokedPrediction invoked
= PredictUninvoked
);
1190 NodeResult
assignExpr(InHandling inHandling
, YieldHandling yieldHandling
,
1191 TripledotHandling tripledotHandling
,
1192 PossibleError
* possibleError
= nullptr,
1193 InvokedPrediction invoked
= PredictUninvoked
);
1194 NodeResult
assignExprWithoutYieldOrAwait(YieldHandling yieldHandling
);
1195 UnaryNodeResult
yieldExpression(InHandling inHandling
);
1196 NodeResult
condExpr(InHandling inHandling
, YieldHandling yieldHandling
,
1197 TripledotHandling tripledotHandling
,
1198 PossibleError
* possibleError
, InvokedPrediction invoked
);
1199 NodeResult
orExpr(InHandling inHandling
, YieldHandling yieldHandling
,
1200 TripledotHandling tripledotHandling
,
1201 PossibleError
* possibleError
, InvokedPrediction invoked
);
1202 NodeResult
unaryExpr(YieldHandling yieldHandling
,
1203 TripledotHandling tripledotHandling
,
1204 PossibleError
* possibleError
= nullptr,
1205 InvokedPrediction invoked
= PredictUninvoked
,
1206 PrivateNameHandling privateNameHandling
=
1207 PrivateNameHandling::PrivateNameProhibited
);
1208 NodeResult
optionalExpr(YieldHandling yieldHandling
,
1209 TripledotHandling tripledotHandling
, TokenKind tt
,
1210 PossibleError
* possibleError
= nullptr,
1211 InvokedPrediction invoked
= PredictUninvoked
);
1212 NodeResult
memberExpr(YieldHandling yieldHandling
,
1213 TripledotHandling tripledotHandling
, TokenKind tt
,
1214 bool allowCallSyntax
, PossibleError
* possibleError
,
1215 InvokedPrediction invoked
);
1216 NodeResult
decoratorExpr(YieldHandling yieldHandling
, TokenKind tt
);
1217 NodeResult
primaryExpr(YieldHandling yieldHandling
,
1218 TripledotHandling tripledotHandling
, TokenKind tt
,
1219 PossibleError
* possibleError
,
1220 InvokedPrediction invoked
);
1221 NodeResult
exprInParens(InHandling inHandling
, YieldHandling yieldHandling
,
1222 TripledotHandling tripledotHandling
,
1223 PossibleError
* possibleError
= nullptr);
1225 bool tryNewTarget(NewTargetNodeType
* newTarget
);
1227 BinaryNodeResult
importExpr(YieldHandling yieldHandling
,
1228 bool allowCallSyntax
);
1230 FunctionNodeResult
methodDefinition(uint32_t toStringStart
,
1231 PropertyType propType
,
1232 TaggedParserAtomIndex funName
);
1235 * Additional JS parsers.
1237 bool functionArguments(YieldHandling yieldHandling
, FunctionSyntaxKind kind
,
1238 FunctionNodeType funNode
);
1240 FunctionNodeResult
functionDefinition(
1241 FunctionNodeType funNode
, uint32_t toStringStart
, InHandling inHandling
,
1242 YieldHandling yieldHandling
, TaggedParserAtomIndex name
,
1243 FunctionSyntaxKind kind
, GeneratorKind generatorKind
,
1244 FunctionAsyncKind asyncKind
, bool tryAnnexB
= false);
1246 // Parse a function body. Pass StatementListBody if the body is a list of
1247 // statements; pass ExpressionBody if the body is a single expression.
1249 // Don't include opening LeftCurly token when invoking.
1250 enum FunctionBodyType
{ StatementListBody
, ExpressionBody
};
1251 LexicalScopeNodeResult
functionBody(InHandling inHandling
,
1252 YieldHandling yieldHandling
,
1253 FunctionSyntaxKind kind
,
1254 FunctionBodyType type
);
1256 UnaryNodeResult
unaryOpExpr(YieldHandling yieldHandling
, ParseNodeKind kind
,
1259 NodeResult
condition(InHandling inHandling
, YieldHandling yieldHandling
);
1261 ListNodeResult
argumentList(YieldHandling yieldHandling
, bool* isSpread
,
1262 PossibleError
* possibleError
= nullptr);
1263 NodeResult
destructuringDeclaration(DeclarationKind kind
,
1264 YieldHandling yieldHandling
,
1266 NodeResult
destructuringDeclarationWithoutYieldOrAwait(
1267 DeclarationKind kind
, YieldHandling yieldHandling
, TokenKind tt
);
1269 inline bool checkExportedName(TaggedParserAtomIndex exportName
);
1270 inline bool checkExportedNamesForArrayBinding(ListNodeType array
);
1271 inline bool checkExportedNamesForObjectBinding(ListNodeType obj
);
1272 inline bool checkExportedNamesForDeclaration(Node node
);
1273 inline bool checkExportedNamesForDeclarationList(
1274 DeclarationListNodeType node
);
1275 inline bool checkExportedNameForFunction(FunctionNodeType funNode
);
1276 inline bool checkExportedNameForClass(ClassNodeType classNode
);
1277 inline bool checkExportedNameForClause(NameNodeType nameNode
);
1279 enum ClassContext
{ ClassStatement
, ClassExpression
};
1280 ClassNodeResult
classDefinition(YieldHandling yieldHandling
,
1281 ClassContext classContext
,
1282 DefaultHandling defaultHandling
);
1284 struct ClassInitializedMembers
{
1285 // The number of instance class fields.
1286 size_t instanceFields
= 0;
1288 // The number of instance class fields with computed property names.
1289 size_t instanceFieldKeys
= 0;
1291 // The number of static class fields.
1292 size_t staticFields
= 0;
1294 // The number of static blocks
1295 size_t staticBlocks
= 0;
1297 // The number of static class fields with computed property names.
1298 size_t staticFieldKeys
= 0;
1300 // The number of instance class private methods.
1301 size_t privateMethods
= 0;
1303 // The number of instance class private accessors.
1304 size_t privateAccessors
= 0;
1306 bool hasPrivateBrand() const {
1307 return privateMethods
> 0 || privateAccessors
> 0;
1310 #ifdef ENABLE_DECORATORS
1311 ListNodeResult
decoratorList(YieldHandling yieldHandling
);
1313 [[nodiscard
]] bool classMember(
1314 YieldHandling yieldHandling
,
1315 const ParseContext::ClassStatement
& classStmt
,
1316 TaggedParserAtomIndex className
, uint32_t classStartOffset
,
1317 HasHeritage hasHeritage
, ClassInitializedMembers
& classInitializedMembers
,
1318 ListNodeType
& classMembers
, bool* done
);
1319 [[nodiscard
]] bool finishClassConstructor(
1320 const ParseContext::ClassStatement
& classStmt
,
1321 TaggedParserAtomIndex className
, HasHeritage hasHeritage
,
1322 uint32_t classStartOffset
, uint32_t classEndOffset
,
1323 const ClassInitializedMembers
& classInitializedMembers
,
1324 ListNodeType
& classMembers
);
1326 FunctionNodeResult
privateMethodInitializer(
1327 TokenPos propNamePos
, TaggedParserAtomIndex propAtom
,
1328 TaggedParserAtomIndex storedMethodAtom
);
1329 FunctionNodeResult
fieldInitializerOpt(
1330 TokenPos propNamePos
, Node name
, TaggedParserAtomIndex atom
,
1331 ClassInitializedMembers
& classInitializedMembers
, bool isStatic
,
1332 HasHeritage hasHeritage
);
1334 FunctionNodeResult
synthesizePrivateMethodInitializer(
1335 TaggedParserAtomIndex propAtom
, AccessorType accessorType
,
1336 TokenPos propNamePos
);
1338 #ifdef ENABLE_DECORATORS
1339 ClassMethodResult
synthesizeAccessor(
1340 Node propName
, TokenPos propNamePos
, TaggedParserAtomIndex propAtom
,
1341 TaggedParserAtomIndex privateStateNameAtom
, bool isStatic
,
1342 FunctionSyntaxKind syntaxKind
,
1343 ClassInitializedMembers
& classInitializedMembers
);
1345 FunctionNodeResult
synthesizeAccessorBody(TaggedParserAtomIndex funNameAtom
,
1346 TokenPos propNamePos
,
1347 TaggedParserAtomIndex propNameAtom
,
1348 FunctionSyntaxKind syntaxKind
);
1351 FunctionNodeResult
staticClassBlock(
1352 ClassInitializedMembers
& classInitializedMembers
);
1354 FunctionNodeResult
synthesizeConstructor(TaggedParserAtomIndex className
,
1355 TokenPos synthesizedBodyPos
,
1356 HasHeritage hasHeritage
);
1359 bool synthesizeConstructorBody(TokenPos synthesizedBodyPos
,
1360 HasHeritage hasHeritage
,
1361 FunctionNodeType funNode
, FunctionBox
* funbox
);
1364 bool checkBindingIdentifier(TaggedParserAtomIndex ident
, uint32_t offset
,
1365 YieldHandling yieldHandling
,
1366 TokenKind hint
= TokenKind::Limit
);
1368 TaggedParserAtomIndex
labelOrIdentifierReference(YieldHandling yieldHandling
);
1370 TaggedParserAtomIndex
labelIdentifier(YieldHandling yieldHandling
) {
1371 return labelOrIdentifierReference(yieldHandling
);
1374 TaggedParserAtomIndex
identifierReference(YieldHandling yieldHandling
) {
1375 return labelOrIdentifierReference(yieldHandling
);
1378 bool matchLabel(YieldHandling yieldHandling
, TaggedParserAtomIndex
* labelOut
);
1380 // Indicate if the next token (tokenized with SlashIsRegExp) is |in| or |of|.
1381 // If so, consume it.
1382 bool matchInOrOf(bool* isForInp
, bool* isForOfp
);
1385 bool checkIncDecOperand(Node operand
, uint32_t operandOffset
);
1386 bool checkStrictAssignment(Node lhs
);
1388 void reportMissingClosing(unsigned errorNumber
, unsigned noteNumber
,
1389 uint32_t openedPos
);
1391 void reportRedeclarationHelper(TaggedParserAtomIndex
& name
,
1392 DeclarationKind
& prevKind
, TokenPos
& pos
,
1393 uint32_t& prevPos
, const unsigned& errorNumber
,
1394 const unsigned& noteErrorNumber
);
1396 void reportRedeclaration(TaggedParserAtomIndex name
, DeclarationKind prevKind
,
1397 TokenPos pos
, uint32_t prevPos
);
1399 void reportMismatchedPlacement(TaggedParserAtomIndex name
,
1400 DeclarationKind prevKind
, TokenPos pos
,
1403 bool notePositionalFormalParameter(FunctionNodeType funNode
,
1404 TaggedParserAtomIndex name
,
1406 bool disallowDuplicateParams
,
1407 bool* duplicatedParam
);
1409 enum PropertyNameContext
{
1410 PropertyNameInLiteral
,
1411 PropertyNameInPattern
,
1412 PropertyNameInClass
,
1413 #ifdef ENABLE_RECORD_TUPLE
1414 PropertyNameInRecord
1417 NodeResult
propertyName(YieldHandling yieldHandling
,
1418 PropertyNameContext propertyNameContext
,
1419 const mozilla::Maybe
<DeclarationKind
>& maybeDecl
,
1420 ListNodeType propList
,
1421 TaggedParserAtomIndex
* propAtomOut
);
1422 NodeResult
propertyOrMethodName(
1423 YieldHandling yieldHandling
, PropertyNameContext propertyNameContext
,
1424 const mozilla::Maybe
<DeclarationKind
>& maybeDecl
, ListNodeType propList
,
1425 PropertyType
* propType
, TaggedParserAtomIndex
* propAtomOut
);
1426 UnaryNodeResult
computedPropertyName(
1427 YieldHandling yieldHandling
,
1428 const mozilla::Maybe
<DeclarationKind
>& maybeDecl
,
1429 PropertyNameContext propertyNameContext
, ListNodeType literal
);
1430 ListNodeResult
arrayInitializer(YieldHandling yieldHandling
,
1431 PossibleError
* possibleError
);
1432 inline RegExpLiteralResult
newRegExp();
1434 ListNodeResult
objectLiteral(YieldHandling yieldHandling
,
1435 PossibleError
* possibleError
);
1437 #ifdef ENABLE_RECORD_TUPLE
1438 ListNodeResult
recordLiteral(YieldHandling yieldHandling
);
1439 ListNodeResult
tupleLiteral(YieldHandling yieldHandling
);
1442 BinaryNodeResult
bindingInitializer(Node lhs
, DeclarationKind kind
,
1443 YieldHandling yieldHandling
);
1444 NameNodeResult
bindingIdentifier(DeclarationKind kind
,
1445 YieldHandling yieldHandling
);
1446 NodeResult
bindingIdentifierOrPattern(DeclarationKind kind
,
1447 YieldHandling yieldHandling
,
1449 ListNodeResult
objectBindingPattern(DeclarationKind kind
,
1450 YieldHandling yieldHandling
);
1451 ListNodeResult
arrayBindingPattern(DeclarationKind kind
,
1452 YieldHandling yieldHandling
);
1454 enum class TargetBehavior
{
1455 PermitAssignmentPattern
,
1456 ForbidAssignmentPattern
1458 bool checkDestructuringAssignmentTarget(
1459 Node expr
, TokenPos exprPos
, PossibleError
* exprPossibleError
,
1460 PossibleError
* possibleError
,
1461 TargetBehavior behavior
= TargetBehavior::PermitAssignmentPattern
);
1462 void checkDestructuringAssignmentName(NameNodeType name
, TokenPos namePos
,
1463 PossibleError
* possibleError
);
1464 bool checkDestructuringAssignmentElement(Node expr
, TokenPos exprPos
,
1465 PossibleError
* exprPossibleError
,
1466 PossibleError
* possibleError
);
1468 NumericLiteralResult
newNumber(const Token
& tok
) {
1469 return handler_
.newNumber(tok
.number(), tok
.decimalPoint(), tok
.pos
);
1472 inline BigIntLiteralResult
newBigInt();
1474 enum class OptionalKind
{
1478 NodeResult
memberPropertyAccess(
1479 Node lhs
, OptionalKind optionalKind
= OptionalKind::NonOptional
);
1480 NodeResult
memberPrivateAccess(
1481 Node lhs
, OptionalKind optionalKind
= OptionalKind::NonOptional
);
1482 NodeResult
memberElemAccess(
1483 Node lhs
, YieldHandling yieldHandling
,
1484 OptionalKind optionalKind
= OptionalKind::NonOptional
);
1485 NodeResult
memberSuperCall(Node lhs
, YieldHandling yieldHandling
);
1486 NodeResult
memberCall(TokenKind tt
, Node lhs
, YieldHandling yieldHandling
,
1487 PossibleError
* possibleError
,
1488 OptionalKind optionalKind
= OptionalKind::NonOptional
);
1491 // Match the current token against the BindingIdentifier production with
1492 // the given Yield parameter. If there is no match, report a syntax
1494 TaggedParserAtomIndex
bindingIdentifier(YieldHandling yieldHandling
);
1496 bool checkLabelOrIdentifierReference(TaggedParserAtomIndex ident
,
1498 YieldHandling yieldHandling
,
1499 TokenKind hint
= TokenKind::Limit
);
1501 ListNodeResult
statementList(YieldHandling yieldHandling
);
1503 [[nodiscard
]] FunctionNodeResult
innerFunction(
1504 FunctionNodeType funNode
, ParseContext
* outerpc
,
1505 TaggedParserAtomIndex explicitName
, FunctionFlags flags
,
1506 uint32_t toStringStart
, InHandling inHandling
,
1507 YieldHandling yieldHandling
, FunctionSyntaxKind kind
,
1508 GeneratorKind generatorKind
, FunctionAsyncKind asyncKind
, bool tryAnnexB
,
1509 Directives inheritedDirectives
, Directives
* newDirectives
);
1511 // Implements Automatic Semicolon Insertion.
1513 // Use this to match `;` in contexts where ASI is allowed. Call this after
1514 // ruling out all other possibilities except `;`, by peeking ahead if
1517 // Unlike most optional Modifiers, this method's `modifier` argument defaults
1518 // to SlashIsRegExp, since that's by far the most common case: usually an
1519 // optional semicolon is at the end of a statement or declaration, and the
1520 // next token could be a RegExp literal beginning a new ExpressionStatement.
1521 bool matchOrInsertSemicolon(Modifier modifier
= TokenStream::SlashIsRegExp
);
1523 bool noteDeclaredName(TaggedParserAtomIndex name
, DeclarationKind kind
,
1524 TokenPos pos
, ClosedOver isClosedOver
= ClosedOver::No
);
1526 bool noteDeclaredPrivateName(Node nameNode
, TaggedParserAtomIndex name
,
1527 PropertyType propType
, FieldPlacement placement
,
1531 inline bool asmJS(ListNodeType list
);
1534 template <typename Unit
>
1535 class MOZ_STACK_CLASS Parser
<SyntaxParseHandler
, Unit
> final
1536 : public GeneralParser
<SyntaxParseHandler
, Unit
> {
1537 using Base
= GeneralParser
<SyntaxParseHandler
, Unit
>;
1538 using Node
= SyntaxParseHandler::Node
;
1539 using NodeResult
= typename
SyntaxParseHandler::NodeResult
;
1541 #define DECLARE_TYPE(typeName) \
1542 using typeName##Type = SyntaxParseHandler::typeName##Type; \
1543 using typeName##Result = SyntaxParseHandler::typeName##Result;
1544 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE
)
1547 using SyntaxParser
= Parser
<SyntaxParseHandler
, Unit
>;
1549 // Numerous Base::* functions have bodies like
1551 // return asFinalParser()->func(...);
1553 // and must be able to call functions here. Add a friendship relationship
1554 // so functions here can be hidden when appropriate.
1555 friend class GeneralParser
<SyntaxParseHandler
, Unit
>;
1560 // Inherited types, listed here to have non-dependent names.
1561 using typename
Base::Modifier
;
1562 using typename
Base::Position
;
1563 using typename
Base::TokenStream
;
1565 // Inherited functions, listed here to have non-dependent names.
1568 using Base::anyChars
;
1569 using Base::clearAbortedSyntaxParse
;
1570 using Base::hadAbortedSyntaxParse
;
1571 using Base::innerFunctionForFunctionBox
;
1572 using Base::tokenStream
;
1575 // ErrorReportMixin.
1578 using Base::errorAt
;
1579 using Base::errorNoOffset
;
1580 using Base::errorWithNotes
;
1581 using Base::errorWithNotesAt
;
1582 using Base::errorWithNotesNoOffset
;
1583 using Base::strictModeError
;
1584 using Base::strictModeErrorAt
;
1585 using Base::strictModeErrorNoOffset
;
1586 using Base::strictModeErrorWithNotes
;
1587 using Base::strictModeErrorWithNotesAt
;
1588 using Base::strictModeErrorWithNotesNoOffset
;
1589 using Base::warning
;
1590 using Base::warningAt
;
1591 using Base::warningNoOffset
;
1596 using Base::checkOptionsCalled_
;
1598 using Base::checkForUndefinedPrivateFields
;
1599 using Base::errorResult
;
1600 using Base::finishFunctionScopes
;
1601 using Base::functionFormalParametersAndBody
;
1602 using Base::handler_
;
1603 using Base::innerFunction
;
1604 using Base::matchOrInsertSemicolon
;
1605 using Base::mustMatchToken
;
1606 using Base::newFunctionBox
;
1607 using Base::newLexicalScopeData
;
1608 using Base::newModuleScopeData
;
1609 using Base::newName
;
1610 using Base::noteDeclaredName
;
1612 using Base::options
;
1615 using Base::propagateFreeNamesAndMarkClosedOverBindings
;
1617 using Base::statementList
;
1618 using Base::stringLiteral
;
1619 using Base::usedNames_
;
1622 using Base::abortIfSyntaxParser
;
1623 using Base::disableSyntaxParser
;
1626 // Functions with multiple overloads of different visibility. We can't
1627 // |using| the whole thing into existence because of the visibility
1628 // distinction, so we instead must manually delegate the required overload.
1630 TaggedParserAtomIndex
bindingIdentifier(YieldHandling yieldHandling
) {
1631 return Base::bindingIdentifier(yieldHandling
);
1634 // Functions present in both Parser<ParseHandler, Unit> specializations.
1636 inline void setAwaitHandling(AwaitHandling awaitHandling
);
1637 inline void setInParametersOfAsyncFunction(bool inParameters
);
1639 RegExpLiteralResult
newRegExp();
1640 BigIntLiteralResult
newBigInt();
1643 ModuleNodeResult
moduleBody(ModuleSharedContext
* modulesc
);
1645 inline bool checkLocalExportNames(ListNodeType node
);
1646 inline bool checkExportedName(TaggedParserAtomIndex exportName
);
1647 inline bool checkExportedNamesForArrayBinding(ListNodeType array
);
1648 inline bool checkExportedNamesForObjectBinding(ListNodeType obj
);
1649 inline bool checkExportedNamesForDeclaration(Node node
);
1650 inline bool checkExportedNamesForDeclarationList(
1651 DeclarationListNodeType node
);
1652 inline bool checkExportedNameForFunction(FunctionNodeType funNode
);
1653 inline bool checkExportedNameForClass(ClassNodeType classNode
);
1654 inline bool checkExportedNameForClause(NameNodeType nameNode
);
1656 bool trySyntaxParseInnerFunction(
1657 FunctionNodeType
* funNode
, TaggedParserAtomIndex explicitName
,
1658 FunctionFlags flags
, uint32_t toStringStart
, InHandling inHandling
,
1659 YieldHandling yieldHandling
, FunctionSyntaxKind kind
,
1660 GeneratorKind generatorKind
, FunctionAsyncKind asyncKind
, bool tryAnnexB
,
1661 Directives inheritedDirectives
, Directives
* newDirectives
);
1663 bool skipLazyInnerFunction(FunctionNodeType funNode
, uint32_t toStringStart
,
1666 bool asmJS(ListNodeType list
);
1668 // Functions present only in Parser<SyntaxParseHandler, Unit>.
1671 template <typename Unit
>
1672 class MOZ_STACK_CLASS Parser
<FullParseHandler
, Unit
> final
1673 : public GeneralParser
<FullParseHandler
, Unit
> {
1674 using Base
= GeneralParser
<FullParseHandler
, Unit
>;
1675 using Node
= FullParseHandler::Node
;
1676 using NodeResult
= typename
FullParseHandler::NodeResult
;
1678 #define DECLARE_TYPE(typeName) \
1679 using typeName##Type = FullParseHandler::typeName##Type; \
1680 using typeName##Result = FullParseHandler::typeName##Result;
1681 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE
)
1684 using SyntaxParser
= Parser
<SyntaxParseHandler
, Unit
>;
1686 // Numerous Base::* functions have bodies like
1688 // return asFinalParser()->func(...);
1690 // and must be able to call functions here. Add a friendship relationship
1691 // so functions here can be hidden when appropriate.
1692 friend class GeneralParser
<FullParseHandler
, Unit
>;
1697 // Inherited types, listed here to have non-dependent names.
1698 using typename
Base::Modifier
;
1699 using typename
Base::Position
;
1700 using typename
Base::TokenStream
;
1702 // Inherited functions, listed here to have non-dependent names.
1705 using Base::anyChars
;
1706 using Base::clearAbortedSyntaxParse
;
1707 using Base::functionFormalParametersAndBody
;
1708 using Base::hadAbortedSyntaxParse
;
1709 using Base::handler_
;
1710 using Base::newFunctionBox
;
1711 using Base::options
;
1715 using Base::tokenStream
;
1718 // ErrorReportMixin.
1721 using Base::errorAt
;
1722 using Base::errorNoOffset
;
1723 using Base::errorWithNotes
;
1724 using Base::errorWithNotesAt
;
1725 using Base::errorWithNotesNoOffset
;
1726 using Base::strictModeError
;
1727 using Base::strictModeErrorAt
;
1728 using Base::strictModeErrorNoOffset
;
1729 using Base::strictModeErrorWithNotes
;
1730 using Base::strictModeErrorWithNotesAt
;
1731 using Base::strictModeErrorWithNotesNoOffset
;
1732 using Base::warning
;
1733 using Base::warningAt
;
1734 using Base::warningNoOffset
;
1738 using Base::checkLabelOrIdentifierReference
;
1740 using Base::checkOptionsCalled_
;
1742 using Base::checkForUndefinedPrivateFields
;
1743 using Base::errorResult
;
1745 using Base::finishClassBodyScope
;
1746 using Base::finishFunctionScopes
;
1747 using Base::finishLexicalScope
;
1748 using Base::innerFunction
;
1749 using Base::innerFunctionForFunctionBox
;
1750 using Base::matchOrInsertSemicolon
;
1751 using Base::mustMatchToken
;
1752 using Base::newEvalScopeData
;
1753 using Base::newFunctionScopeData
;
1754 using Base::newGlobalScopeData
;
1755 using Base::newLexicalScopeData
;
1756 using Base::newModuleScopeData
;
1757 using Base::newName
;
1758 using Base::newVarScopeData
;
1759 using Base::noteDeclaredName
;
1760 using Base::noteUsedName
;
1762 using Base::propagateFreeNamesAndMarkClosedOverBindings
;
1763 using Base::statementList
;
1764 using Base::stringLiteral
;
1765 using Base::usedNames_
;
1767 using Base::abortIfSyntaxParser
;
1768 using Base::disableSyntaxParser
;
1769 using Base::getSyntaxParser
;
1772 // Functions with multiple overloads of different visibility. We can't
1773 // |using| the whole thing into existence because of the visibility
1774 // distinction, so we instead must manually delegate the required overload.
1776 TaggedParserAtomIndex
bindingIdentifier(YieldHandling yieldHandling
) {
1777 return Base::bindingIdentifier(yieldHandling
);
1780 // Functions present in both Parser<ParseHandler, Unit> specializations.
1782 friend class AutoAwaitIsKeyword
<SyntaxParseHandler
, Unit
>;
1783 inline void setAwaitHandling(AwaitHandling awaitHandling
);
1785 friend class AutoInParametersOfAsyncFunction
<SyntaxParseHandler
, Unit
>;
1786 inline void setInParametersOfAsyncFunction(bool inParameters
);
1788 RegExpLiteralResult
newRegExp();
1789 BigIntLiteralResult
newBigInt();
1792 ModuleNodeResult
moduleBody(ModuleSharedContext
* modulesc
);
1794 bool checkLocalExportNames(ListNodeType node
);
1795 bool checkExportedName(TaggedParserAtomIndex exportName
);
1796 bool checkExportedNamesForArrayBinding(ListNodeType array
);
1797 bool checkExportedNamesForObjectBinding(ListNodeType obj
);
1798 bool checkExportedNamesForDeclaration(Node node
);
1799 bool checkExportedNamesForDeclarationList(DeclarationListNodeType node
);
1800 bool checkExportedNameForFunction(FunctionNodeType funNode
);
1801 bool checkExportedNameForClass(ClassNodeType classNode
);
1802 inline bool checkExportedNameForClause(NameNodeType nameNode
);
1804 bool trySyntaxParseInnerFunction(
1805 FunctionNodeType
* funNode
, TaggedParserAtomIndex explicitName
,
1806 FunctionFlags flags
, uint32_t toStringStart
, InHandling inHandling
,
1807 YieldHandling yieldHandling
, FunctionSyntaxKind kind
,
1808 GeneratorKind generatorKind
, FunctionAsyncKind asyncKind
, bool tryAnnexB
,
1809 Directives inheritedDirectives
, Directives
* newDirectives
);
1811 [[nodiscard
]] bool advancePastSyntaxParsedFunction(
1812 SyntaxParser
* syntaxParser
);
1814 bool skipLazyInnerFunction(FunctionNodeType funNode
, uint32_t toStringStart
,
1817 // Functions present only in Parser<FullParseHandler, Unit>.
1819 // Parse the body of an eval.
1821 // Eval scripts are distinguished from global scripts in that in ES6, per
1822 // 18.2.1.1 steps 9 and 10, all eval scripts are executed under a fresh
1824 LexicalScopeNodeResult
evalBody(EvalSharedContext
* evalsc
);
1826 // Parse a function, given only its arguments and body. Used for lazily
1827 // parsed functions.
1828 FunctionNodeResult
standaloneLazyFunction(CompilationInput
& input
,
1829 uint32_t toStringStart
, bool strict
,
1830 GeneratorKind generatorKind
,
1831 FunctionAsyncKind asyncKind
);
1833 // Parse a function, used for the Function, GeneratorFunction, and
1834 // AsyncFunction constructors.
1835 FunctionNodeResult
standaloneFunction(
1836 const mozilla::Maybe
<uint32_t>& parameterListEnd
,
1837 FunctionSyntaxKind syntaxKind
, GeneratorKind generatorKind
,
1838 FunctionAsyncKind asyncKind
, Directives inheritedDirectives
,
1839 Directives
* newDirectives
);
1841 bool checkStatementsEOF();
1843 // Parse the body of a global script.
1844 ListNodeResult
globalBody(GlobalSharedContext
* globalsc
);
1846 bool checkLocalExportName(TaggedParserAtomIndex ident
, uint32_t offset
) {
1847 return checkLabelOrIdentifierReference(ident
, offset
, YieldIsName
);
1850 bool asmJS(ListNodeType list
);
1853 template <class Parser
>
1854 /* static */ inline const TokenStreamAnyChars
&
1855 ParserAnyCharsAccess
<Parser
>::anyChars(const GeneralTokenStreamChars
* ts
) {
1856 // The structure we're walking through looks like this:
1858 // struct ParserBase
1861 // TokenStreamAnyChars anyChars;
1864 // struct Parser : <class that ultimately inherits from ParserBase>
1867 // TokenStreamSpecific tokenStream;
1871 // We're passed a GeneralTokenStreamChars* (this being a base class of
1872 // Parser::tokenStream). We cast that pointer to a TokenStreamSpecific*,
1873 // then translate that to the enclosing Parser*, then return the |anyChars|
1876 static_assert(std::is_base_of_v
<GeneralTokenStreamChars
, TokenStreamSpecific
>,
1877 "the static_cast<> below assumes a base-class relationship");
1878 const auto* tss
= static_cast<const TokenStreamSpecific
*>(ts
);
1880 auto tssAddr
= reinterpret_cast<uintptr_t>(tss
);
1882 using ActualTokenStreamType
= decltype(std::declval
<Parser
>().tokenStream
);
1883 static_assert(std::is_same_v
<ActualTokenStreamType
, TokenStreamSpecific
>,
1884 "Parser::tokenStream must have type TokenStreamSpecific");
1886 uintptr_t parserAddr
= tssAddr
- offsetof(Parser
, tokenStream
);
1888 return reinterpret_cast<const Parser
*>(parserAddr
)->anyChars
;
1891 template <class Parser
>
1892 /* static */ inline TokenStreamAnyChars
& ParserAnyCharsAccess
<Parser
>::anyChars(
1893 GeneralTokenStreamChars
* ts
) {
1894 const TokenStreamAnyChars
& anyCharsConst
=
1895 anyChars(const_cast<const GeneralTokenStreamChars
*>(ts
));
1897 return const_cast<TokenStreamAnyChars
&>(anyCharsConst
);
1900 template <class ParseHandler
, typename Unit
>
1901 class MOZ_STACK_CLASS AutoAwaitIsKeyword
{
1902 using GeneralParser
= frontend::GeneralParser
<ParseHandler
, Unit
>;
1905 GeneralParser
* parser_
;
1906 AwaitHandling oldAwaitHandling_
;
1909 AutoAwaitIsKeyword(GeneralParser
* parser
, AwaitHandling awaitHandling
) {
1911 oldAwaitHandling_
= static_cast<AwaitHandling
>(parser_
->awaitHandling_
);
1913 // 'await' is always a keyword in module contexts, so we don't modify
1914 // the state when the original handling is AwaitIsModuleKeyword.
1915 if (oldAwaitHandling_
!= AwaitIsModuleKeyword
) {
1916 parser_
->setAwaitHandling(awaitHandling
);
1920 ~AutoAwaitIsKeyword() { parser_
->setAwaitHandling(oldAwaitHandling_
); }
1923 template <class ParseHandler
, typename Unit
>
1924 class MOZ_STACK_CLASS AutoInParametersOfAsyncFunction
{
1925 using GeneralParser
= frontend::GeneralParser
<ParseHandler
, Unit
>;
1928 GeneralParser
* parser_
;
1929 bool oldInParametersOfAsyncFunction_
;
1932 AutoInParametersOfAsyncFunction(GeneralParser
* parser
, bool inParameters
) {
1934 oldInParametersOfAsyncFunction_
= parser_
->inParametersOfAsyncFunction_
;
1935 parser_
->setInParametersOfAsyncFunction(inParameters
);
1938 ~AutoInParametersOfAsyncFunction() {
1939 parser_
->setInParametersOfAsyncFunction(oldInParametersOfAsyncFunction_
);
1943 GlobalScope::ParserData
* NewEmptyGlobalScopeData(FrontendContext
* fc
,
1945 uint32_t numBindings
);
1947 VarScope::ParserData
* NewEmptyVarScopeData(FrontendContext
* fc
,
1949 uint32_t numBindings
);
1951 LexicalScope::ParserData
* NewEmptyLexicalScopeData(FrontendContext
* fc
,
1953 uint32_t numBindings
);
1955 FunctionScope::ParserData
* NewEmptyFunctionScopeData(FrontendContext
* fc
,
1957 uint32_t numBindings
);
1959 bool FunctionScopeHasClosedOverBindings(ParseContext
* pc
);
1960 bool LexicalScopeHasClosedOverBindings(ParseContext
* pc
,
1961 ParseContext::Scope
& scope
);
1963 } /* namespace frontend */
1964 } /* namespace js */
1966 #endif /* frontend_Parser_h */