Source code

Revision control

Other Tools

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/. */
6
7
/* JS parser. */
8
9
#ifndef frontend_Parser_h
10
#define frontend_Parser_h
11
12
/*
13
* [SMDOC] JS Parser
14
*
15
* JS parsers capable of generating ASTs from source text.
16
*
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
19
* bytecode.
20
*
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.
28
*
29
* == ParserSharedBase → JS::AutoGCRooter ==
30
*
31
* ParserSharedBase is the base class for both regular JS and BinAST parser.
32
* This class contains common fields and methods between both parsers.
33
*
34
* Of particular note: making ParserSharedBase inherit JS::AutoGCRooter (rather
35
* than placing it under one of the more-derived parser classes) means that all
36
* parsers can be traced using the same AutoGCRooter mechanism: it's not
37
* necessary to have separate tracing functionality for syntax/full parsers or
38
* parsers of different character types.
39
*
40
* == ParserBase → ParserSharedBase, ErrorReportMixin ==
41
*
42
* ParserBase is the base class for regular JS parser, shared by all regular JS
43
* parsers of all character types and parse-handling behavior. It stores
44
* everything character- and handler-agnostic.
45
*
46
* ParserBase's most important field is the parser's token stream's
47
* |TokenStreamAnyChars| component, for all tokenizing aspects that are
48
* character-type-agnostic. The character-type-sensitive components residing
49
* in |TokenStreamSpecific| (see the comment near the top of TokenStream.h)
50
* live elsewhere in this hierarchy. These separate locations are the reason
51
* for the |AnyCharsAccess| template parameter to |TokenStreamChars| and
52
* |TokenStreamSpecific|.
53
*
54
* == PerHandlerParser<ParseHandler> → ParserBase ==
55
*
56
* Certain parsing behavior varies between full parsing and syntax-only parsing
57
* but does not vary across source-text character types. For example, the work
58
* to "create an arguments object for a function" obviously varies between
59
* syntax and full parsing but (because no source characters are examined) does
60
* not vary by source text character type. Such functionality is implemented
61
* through functions in PerHandlerParser.
62
*
63
* Functionality only used by syntax parsing or full parsing doesn't live here:
64
* it should be implemented in the appropriate Parser<ParseHandler> (described
65
* further below).
66
*
67
* == GeneralParser<ParseHandler, Unit> → PerHandlerParser<ParseHandler> ==
68
*
69
* Most parsing behavior varies across the character-type axis (and possibly
70
* along the full/syntax axis). For example:
71
*
72
* * Parsing ECMAScript's Expression production, implemented by
73
* GeneralParser::expr, varies in this manner: different types are used to
74
* represent nodes in full and syntax parsing (ParseNode* versus an enum),
75
* and reading the tokens comprising the expression requires inspecting
76
* individual characters (necessarily dependent upon character type).
77
* * Reporting an error or warning does not depend on the full/syntax parsing
78
* distinction. But error reports and warnings include a line of context
79
* (or a slice of one), for pointing out where a mistake was made.
80
* Computing such line of context requires inspecting the source text to
81
* make that line/slice of context, which requires knowing the source text
82
* character type.
83
*
84
* Such functionality, implemented using identical function code across these
85
* axes, should live in GeneralParser.
86
*
87
* GeneralParser's most important field is the parser's token stream's
88
* |TokenStreamSpecific| component, for all aspects of tokenizing that (contra
89
* |TokenStreamAnyChars| in ParserBase above) are character-type-sensitive. As
90
* noted above, this field's existence separate from that in ParserBase
91
* motivates the |AnyCharsAccess| template parameters on various token stream
92
* classes.
93
*
94
* Everything in PerHandlerParser *could* be folded into GeneralParser (below)
95
* if desired. We don't fold in this manner because all such functions would
96
* be instantiated once per Unit -- but if exactly equivalent code would be
97
* generated (because PerHandlerParser functions have no awareness of Unit),
98
* it's risky to *depend* upon the compiler coalescing the instantiations into
99
* one in the final binary. PerHandlerParser guarantees no duplication.
100
*
101
* == Parser<ParseHandler, Unit> final → GeneralParser<ParseHandler, Unit> ==
102
*
103
* The final (pun intended) axis of complexity lies in Parser.
104
*
105
* Some functionality depends on character type, yet also is defined in
106
* significantly different form in full and syntax parsing. For example,
107
* attempting to parse the source text of a module will do so in full parsing
108
* but immediately fail in syntax parsing -- so the former is a mess'o'code
109
* while the latter is effectively |return null();|. Such functionality is
110
* defined in Parser<SyntaxParseHandler or FullParseHandler, Unit> as
111
* appropriate.
112
*
113
* There's a crucial distinction between GeneralParser and Parser, that
114
* explains why both must exist (despite taking exactly the same template
115
* parameters, and despite GeneralParser and Parser existing in a one-to-one
116
* relationship). GeneralParser is one unspecialized template class:
117
*
118
* template<class ParseHandler, typename Unit>
119
* class GeneralParser : ...
120
* {
121
* ...parsing functions...
122
* };
123
*
124
* but Parser is one undefined template class with two separate
125
* specializations:
126
*
127
* // Declare, but do not define.
128
* template<class ParseHandler, typename Unit> class Parser;
129
*
130
* // Define a syntax-parsing specialization.
131
* template<typename Unit>
132
* class Parser<SyntaxParseHandler, Unit> final
133
* : public GeneralParser<SyntaxParseHandler, Unit>
134
* {
135
* ...parsing functions...
136
* };
137
*
138
* // Define a full-parsing specialization.
139
* template<typename Unit>
140
* class Parser<SyntaxParseHandler, Unit> final
141
* : public GeneralParser<SyntaxParseHandler, Unit>
142
* {
143
* ...parsing functions...
144
* };
145
*
146
* This odd distinction is necessary because C++ unfortunately doesn't allow
147
* partial function specialization:
148
*
149
* // BAD: You can only specialize a template function if you specify *every*
150
* // template parameter, i.e. ParseHandler *and* Unit.
151
* template<typename Unit>
152
* void
153
* GeneralParser<SyntaxParseHandler, Unit>::foo() {}
154
*
155
* But if you specialize Parser *as a class*, then this is allowed:
156
*
157
* template<typename Unit>
158
* void
159
* Parser<SyntaxParseHandler, Unit>::foo() {}
160
*
161
* template<typename Unit>
162
* void
163
* Parser<FullParseHandler, Unit>::foo() {}
164
*
165
* because the only template parameter on the function is Unit -- and so all
166
* template parameters *are* varying, not a strict subset of them.
167
*
168
* So -- any parsing functionality that is differently defined for different
169
* ParseHandlers, *but* is defined textually identically for different Unit
170
* (even if different code ends up generated for them by the compiler), should
171
* reside in Parser.
172
*/
173
174
#include "mozilla/Array.h"
175
#include "mozilla/Maybe.h"
176
#include "mozilla/TypeTraits.h"
177
178
#include "jspubtd.h"
179
180
#include "ds/Nestable.h"
181
#include "frontend/BytecodeCompiler.h"
182
#include "frontend/ErrorReporter.h"
183
#include "frontend/FullParseHandler.h"
184
#include "frontend/FunctionTree.h"
185
#include "frontend/NameAnalysisTypes.h"
186
#include "frontend/NameCollections.h"
187
#include "frontend/ParseContext.h"
188
#include "frontend/ParseInfo.h"
189
#include "frontend/SharedContext.h"
190
#include "frontend/SyntaxParseHandler.h"
191
#include "frontend/TokenStream.h"
192
#include "js/Vector.h"
193
194
#include "vm/ErrorReporting.h"
195
196
namespace js {
197
198
class ModuleObject;
199
200
namespace frontend {
201
202
template <class ParseHandler, typename Unit>
203
class GeneralParser;
204
205
class SourceParseContext : public ParseContext {
206
public:
207
template <typename ParseHandler, typename Unit>
208
SourceParseContext(GeneralParser<ParseHandler, Unit>* prs, SharedContext* sc,
209
Directives* newDirectives)
210
: ParseContext(prs->cx_, prs->pc_, sc, prs->tokenStream,
211
prs->getParseInfo(), newDirectives,
212
mozilla::IsSame<ParseHandler, FullParseHandler>::value) {}
213
};
214
215
enum VarContext { HoistVars, DontHoistVars };
216
enum PropListType { ObjectLiteral, ClassBody, DerivedClassBody };
217
enum class PropertyType {
218
Normal,
219
Shorthand,
220
CoverInitializedName,
221
Getter,
222
Setter,
223
Method,
224
GeneratorMethod,
225
AsyncMethod,
226
AsyncGeneratorMethod,
227
Constructor,
228
DerivedConstructor,
229
Field,
230
};
231
232
enum AwaitHandling : uint8_t {
233
AwaitIsName,
234
AwaitIsKeyword,
235
AwaitIsModuleKeyword
236
};
237
238
template <class ParseHandler, typename Unit>
239
class AutoAwaitIsKeyword;
240
241
template <class ParseHandler, typename Unit>
242
class AutoInParametersOfAsyncFunction;
243
244
class MOZ_STACK_CLASS ParserSharedBase : private JS::AutoGCRooter {
245
public:
246
enum class Kind { Parser, BinASTParser };
247
248
ParserSharedBase(JSContext* cx, ParseInfo& parserInfo,
249
ScriptSourceObject* sourceObject, Kind kind);
250
~ParserSharedBase();
251
252
public:
253
JSContext* const cx_;
254
255
LifoAlloc& alloc_;
256
257
// Information for parsing with a lifetime longer than the parser itself.
258
ParseInfo& parseInfo_;
259
260
// list of parsed objects and BigInts for GC tracing
261
TraceListNode* traceListHead_;
262
263
// innermost parse context (stack-allocated)
264
ParseContext* pc_;
265
266
// For tracking used names in this parsing session.
267
UsedNameTracker& usedNames_;
268
269
RootedScriptSourceObject sourceObject_;
270
271
// Root atoms and objects allocated for the parsed tree.
272
AutoKeepAtoms keepAtoms_;
273
274
private:
275
// This is needed to cast a parser to JS::AutoGCRooter.
276
friend void js::frontend::TraceParser(JSTracer* trc,
277
JS::AutoGCRooter* parser);
278
279
#if defined(JS_BUILD_BINAST)
280
friend void js::frontend::TraceBinASTParser(JSTracer* trc,
281
JS::AutoGCRooter* parser);
282
#endif // JS_BUILD_BINAST
283
284
private:
285
// Create a new traceable node and store it into the trace list.
286
template <typename BoxT, typename ArgT>
287
BoxT* newTraceListNode(ArgT* arg);
288
289
void cleanupTraceList();
290
291
public:
292
ParseInfo& getParseInfo() { return parseInfo_; }
293
294
// Create a new JSObject and store it into the trace list.
295
ObjectBox* newObjectBox(JSObject* obj);
296
297
// Create a new BigInt and store it into the trace list.
298
BigIntBox* newBigIntBox(BigInt* val);
299
};
300
301
class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
302
public ErrorReportMixin {
303
using Base = ErrorReportMixin;
304
305
public:
306
TokenStreamAnyChars anyChars;
307
308
ScriptSource* ss;
309
310
// Perform constant-folding; must be true when interfacing with the emitter.
311
const bool foldConstants_ : 1;
312
313
protected:
314
#if DEBUG
315
/* Our fallible 'checkOptions' member function has been called. */
316
bool checkOptionsCalled_ : 1;
317
#endif
318
319
/* Unexpected end of input, i.e. Eof not at top-level. */
320
bool isUnexpectedEOF_ : 1;
321
322
/* AwaitHandling */ uint8_t awaitHandling_ : 2;
323
324
bool inParametersOfAsyncFunction_ : 1;
325
326
/* ParseGoal */ uint8_t parseGoal_ : 1;
327
328
FunctionTreeHolder& treeHolder_;
329
330
MOZ_MUST_USE bool publishDeferredItems(FunctionTree* root) {
331
// Publish deferred functions before LazyScripts, as the
332
// LazyScripts need the functions.
333
if (!publishDeferredFunctions(root)) {
334
return false;
335
}
336
if (!publishLazyScripts(root)) {
337
return false;
338
}
339
340
return true;
341
}
342
343
bool publishLazyScripts(FunctionTree* root);
344
bool publishDeferredFunctions(FunctionTree* root);
345
346
public:
347
FunctionTreeHolder& getTreeHolder() { return treeHolder_; }
348
349
MOZ_MUST_USE bool publishDeferredItems() {
350
return publishDeferredItems(getTreeHolder().getFunctionTree());
351
}
352
353
bool awaitIsKeyword() const { return awaitHandling_ != AwaitIsName; }
354
355
bool inParametersOfAsyncFunction() const {
356
return inParametersOfAsyncFunction_;
357
}
358
359
ParseGoal parseGoal() const { return ParseGoal(parseGoal_); }
360
361
template <class, typename>
362
friend class AutoAwaitIsKeyword;
363
template <class, typename>
364
friend class AutoInParametersOfAsyncFunction;
365
366
ParserBase(JSContext* cx, const JS::ReadOnlyCompileOptions& options,
367
bool foldConstants, ParseInfo& parseInfo,
368
ScriptSourceObject* sourceObject, ParseGoal parseGoal);
369
~ParserBase();
370
371
bool checkOptions();
372
373
void trace(JSTracer* trc);
374
375
const char* getFilename() const { return anyChars.getFilename(); }
376
TokenPos pos() const { return anyChars.currentToken().pos; }
377
378
// Determine whether |yield| is a valid name in the current context.
379
bool yieldExpressionsSupported() const { return pc_->isGenerator(); }
380
381
bool setLocalStrictMode(bool strict) {
382
MOZ_ASSERT(anyChars.debugHasNoLookahead());
383
return pc_->sc()->setLocalStrictMode(strict);
384
}
385
386
public:
387
// Implement ErrorReportMixin.
388
389
JSContext* getContext() const override { return cx_; }
390
391
bool strictMode() const override { return pc_->sc()->strict(); }
392
393
const JS::ReadOnlyCompileOptions& options() const override {
394
return anyChars.options();
395
}
396
397
using Base::error;
398
using Base::errorAt;
399
using Base::errorNoOffset;
400
using Base::errorWithNotes;
401
using Base::errorWithNotesAt;
402
using Base::errorWithNotesNoOffset;
403
using Base::extraWarning;
404
using Base::extraWarningAt;
405
using Base::extraWarningNoOffset;
406
using Base::extraWarningWithNotes;
407
using Base::extraWarningWithNotesAt;
408
using Base::extraWarningWithNotesNoOffset;
409
using Base::strictModeError;
410
using Base::strictModeErrorAt;
411
using Base::strictModeErrorNoOffset;
412
using Base::strictModeErrorWithNotes;
413
using Base::strictModeErrorWithNotesAt;
414
using Base::strictModeErrorWithNotesNoOffset;
415
using Base::warning;
416
using Base::warningAt;
417
using Base::warningNoOffset;
418
using Base::warningWithNotes;
419
using Base::warningWithNotesAt;
420
using Base::warningWithNotesNoOffset;
421
422
public:
423
bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
424
425
bool isValidStrictBinding(PropertyName* name);
426
427
bool hasValidSimpleStrictParameterNames();
428
429
/*
430
* Create a new function object given a name (which is optional if this is
431
* a function expression).
432
*/
433
JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind,
434
GeneratorKind generatorKind,
435
FunctionAsyncKind asyncKind);
436
437
// A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
438
// Parser's state. Note: clients must still take care that any ParseContext
439
// that points into released ParseNodes is destroyed.
440
class Mark {
441
friend class ParserBase;
442
LifoAlloc::Mark mark;
443
TraceListNode* traceListHead;
444
};
445
Mark mark() const {
446
Mark m;
447
m.mark = alloc_.mark();
448
m.traceListHead = traceListHead_;
449
return m;
450
}
451
void release(Mark m) {
452
alloc_.release(m.mark);
453
traceListHead_ = m.traceListHead;
454
}
455
456
public:
457
mozilla::Maybe<GlobalScope::Data*> newGlobalScopeData(
458
ParseContext::Scope& scope);
459
mozilla::Maybe<ModuleScope::Data*> newModuleScopeData(
460
ParseContext::Scope& scope);
461
mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope);
462
mozilla::Maybe<FunctionScope::Data*> newFunctionScopeData(
463
ParseContext::Scope& scope, bool hasParameterExprs,
464
IsFieldInitializer isFieldInitializer);
465
mozilla::Maybe<VarScope::Data*> newVarScopeData(ParseContext::Scope& scope);
466
mozilla::Maybe<LexicalScope::Data*> newLexicalScopeData(
467
ParseContext::Scope& scope);
468
469
protected:
470
enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
471
enum ForInitLocation { InForInit, NotInForInit };
472
473
// While on a |let| Name token, examine |next| (which must already be
474
// gotten). Indicate whether |next|, the next token already gotten with
475
// modifier TokenStream::SlashIsDiv, continues a LexicalDeclaration.
476
bool nextTokenContinuesLetDeclaration(TokenKind next);
477
478
bool noteUsedNameInternal(HandlePropertyName name);
479
480
bool checkAndMarkSuperScope();
481
482
bool leaveInnerFunction(ParseContext* outerpc);
483
484
JSAtom* prefixAccessorName(PropertyType propType, HandleAtom propAtom);
485
486
MOZ_MUST_USE bool setSourceMapInfo();
487
488
void setFunctionEndFromCurrentToken(FunctionBox* funbox) const;
489
};
490
491
enum FunctionCallBehavior {
492
PermitAssignmentToFunctionCalls,
493
ForbidAssignmentToFunctionCalls
494
};
495
496
template <class ParseHandler>
497
class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
498
using Base = ParserBase;
499
500
private:
501
using Node = typename ParseHandler::Node;
502
503
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
504
using longTypeName = typename ParseHandler::longTypeName;
505
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
506
#undef DECLARE_TYPE
507
508
protected:
509
/* State specific to the kind of parse being performed. */
510
ParseHandler handler_;
511
512
// When ParseHandler is FullParseHandler:
513
//
514
// If non-null, this field holds the syntax parser used to attempt lazy
515
// parsing of inner functions. If null, then lazy parsing is disabled.
516
//
517
// When ParseHandler is SyntaxParseHandler:
518
//
519
// If non-null, this field must be a sentinel value signaling that the
520
// syntax parse was aborted. If null, then lazy parsing was aborted due
521
// to encountering unsupported language constructs.
522
//
523
// |internalSyntaxParser_| is really a |Parser<SyntaxParseHandler, Unit>*|
524
// where |Unit| varies per |Parser<ParseHandler, Unit>|. But this
525
// template class doesn't know |Unit|, so we store a |void*| here and make
526
// |GeneralParser<ParseHandler, Unit>::getSyntaxParser| impose the real type.
527
void* internalSyntaxParser_;
528
529
private:
530
// NOTE: The argument ordering here is deliberately different from the
531
// public constructor so that typos calling the public constructor
532
// are less likely to select this overload.
533
PerHandlerParser(JSContext* cx, const JS::ReadOnlyCompileOptions& options,
534
bool foldConstants, ParseInfo& parserInfo,
535
LazyScript* lazyOuterFunction,
536
ScriptSourceObject* sourceObject, ParseGoal parseGoal,
537
void* internalSyntaxParser);
538
539
protected:
540
template <typename Unit>
541
PerHandlerParser(JSContext* cx, const JS::ReadOnlyCompileOptions& options,
542
bool foldConstants, ParseInfo& parserInfo,
543
GeneralParser<SyntaxParseHandler, Unit>* syntaxParser,
544
LazyScript* lazyOuterFunction,
545
ScriptSourceObject* sourceObject, ParseGoal parseGoal)
546
: PerHandlerParser(
547
cx, options, foldConstants, parserInfo, lazyOuterFunction,
548
sourceObject, parseGoal,
549
// JSOPTION_EXTRA_WARNINGS adds extra warnings not
550
// generated when functions are parsed lazily.
551
// ("use strict" doesn't inhibit lazy parsing.)
552
static_cast<void*>(options.extraWarningsOption ? nullptr
553
: syntaxParser)) {}
554
555
static typename ParseHandler::NullNode null() { return ParseHandler::null(); }
556
557
NameNodeType stringLiteral();
558
559
const char* nameIsArgumentsOrEval(Node node);
560
561
bool noteDestructuredPositionalFormalParameter(FunctionNodeType funNode,
562
Node destruct);
563
564
bool noteUsedName(HandlePropertyName name) {
565
// If the we are delazifying, the LazyScript already has all the
566
// closed-over info for bindings and there's no need to track used
567
// names.
568
if (handler_.canSkipLazyClosedOverBindings()) {
569
return true;
570
}
571
572
return ParserBase::noteUsedNameInternal(name);
573
}
574
575
// Required on Scope exit.
576
bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
577
578
bool finishFunctionScopes(bool isStandaloneFunction);
579
LexicalScopeNodeType finishLexicalScope(ParseContext::Scope& scope, Node body,
580
ScopeKind kind = ScopeKind::Lexical);
581
bool finishFunction(
582
bool isStandaloneFunction = false,
583
IsFieldInitializer isFieldInitializer = IsFieldInitializer::No);
584
585
inline NameNodeType newName(PropertyName* name);
586
inline NameNodeType newName(PropertyName* name, TokenPos pos);
587
588
NameNodeType newInternalDotName(HandlePropertyName name);
589
NameNodeType newThisName();
590
NameNodeType newDotGeneratorName();
591
592
NameNodeType identifierReference(Handle<PropertyName*> name);
593
594
Node noSubstitutionTaggedTemplate();
595
596
inline bool processExport(Node node);
597
inline bool processExportFrom(BinaryNodeType node);
598
599
// If ParseHandler is SyntaxParseHandler:
600
// Do nothing.
601
// If ParseHandler is FullParseHandler:
602
// Disable syntax parsing of all future inner functions during this
603
// full-parse.
604
inline void disableSyntaxParser();
605
606
// If ParseHandler is SyntaxParseHandler:
607
// Flag the current syntax parse as aborted due to unsupported language
608
// constructs and return false. Aborting the current syntax parse does
609
// not disable attempts to syntax-parse future inner functions.
610
// If ParseHandler is FullParseHandler:
611
// Disable syntax parsing of all future inner functions and return true.
612
inline bool abortIfSyntaxParser();
613
614
// If ParseHandler is SyntaxParseHandler:
615
// Return whether the last syntax parse was aborted due to unsupported
616
// language constructs.
617
// If ParseHandler is FullParseHandler:
618
// Return false.
619
inline bool hadAbortedSyntaxParse();
620
621
// If ParseHandler is SyntaxParseHandler:
622
// Clear whether the last syntax parse was aborted.
623
// If ParseHandler is FullParseHandler:
624
// Do nothing.
625
inline void clearAbortedSyntaxParse();
626
627
public:
628
bool isValidSimpleAssignmentTarget(
629
Node node,
630
FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls);
631
632
NameNodeType newPropertyName(PropertyName* key, const TokenPos& pos) {
633
return handler_.newPropertyName(key, pos);
634
}
635
636
PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) {
637
return handler_.newPropertyAccess(expr, key);
638
}
639
640
FunctionBox* newFunctionBox(FunctionNodeType funNode, JSFunction* fun,
641
uint32_t toStringStart, Directives directives,
642
GeneratorKind generatorKind,
643
FunctionAsyncKind asyncKind);
644
645
FunctionBox* newFunctionBox(FunctionNodeType funNode,
646
Handle<FunctionCreationData> fcd,
647
uint32_t toStringStart, Directives directives,
648
GeneratorKind generatorKind,
649
FunctionAsyncKind asyncKind);
650
651
public:
652
// ErrorReportMixin.
653
654
using Base::error;
655
using Base::errorAt;
656
using Base::errorNoOffset;
657
using Base::errorWithNotes;
658
using Base::errorWithNotesAt;
659
using Base::errorWithNotesNoOffset;
660
using Base::extraWarning;
661
using Base::extraWarningAt;
662
using Base::extraWarningNoOffset;
663
using Base::extraWarningWithNotes;
664
using Base::extraWarningWithNotesAt;
665
using Base::extraWarningWithNotesNoOffset;
666
using Base::strictModeError;
667
using Base::strictModeErrorAt;
668
using Base::strictModeErrorNoOffset;
669
using Base::strictModeErrorWithNotes;
670
using Base::strictModeErrorWithNotesAt;
671
using Base::strictModeErrorWithNotesNoOffset;
672
using Base::warning;
673
using Base::warningAt;
674
using Base::warningNoOffset;
675
using Base::warningWithNotes;
676
using Base::warningWithNotesAt;
677
using Base::warningWithNotesNoOffset;
678
};
679
680
#define ABORTED_SYNTAX_PARSE_SENTINEL reinterpret_cast<void*>(0x1)
681
682
template <>
683
inline void PerHandlerParser<SyntaxParseHandler>::disableSyntaxParser() {}
684
685
template <>
686
inline bool PerHandlerParser<SyntaxParseHandler>::abortIfSyntaxParser() {
687
internalSyntaxParser_ = ABORTED_SYNTAX_PARSE_SENTINEL;
688
return false;
689
}
690
691
template <>
692
inline bool PerHandlerParser<SyntaxParseHandler>::hadAbortedSyntaxParse() {
693
return internalSyntaxParser_ == ABORTED_SYNTAX_PARSE_SENTINEL;
694
}
695
696
template <>
697
inline void PerHandlerParser<SyntaxParseHandler>::clearAbortedSyntaxParse() {
698
internalSyntaxParser_ = nullptr;
699
}
700
701
#undef ABORTED_SYNTAX_PARSE_SENTINEL
702
703
// Disable syntax parsing of all future inner functions during this
704
// full-parse.
705
template <>
706
inline void PerHandlerParser<FullParseHandler>::disableSyntaxParser() {
707
internalSyntaxParser_ = nullptr;
708
}
709
710
template <>
711
inline bool PerHandlerParser<FullParseHandler>::abortIfSyntaxParser() {
712
disableSyntaxParser();
713
return true;
714
}
715
716
template <>
717
inline bool PerHandlerParser<FullParseHandler>::hadAbortedSyntaxParse() {
718
return false;
719
}
720
721
template <>
722
inline void PerHandlerParser<FullParseHandler>::clearAbortedSyntaxParse() {}
723
724
template <class Parser>
725
class ParserAnyCharsAccess {
726
public:
727
using TokenStreamSpecific = typename Parser::TokenStream;
728
using GeneralTokenStreamChars =
729
typename TokenStreamSpecific::GeneralCharsBase;
730
731
static inline TokenStreamAnyChars& anyChars(GeneralTokenStreamChars* ts);
732
static inline const TokenStreamAnyChars& anyChars(
733
const GeneralTokenStreamChars* ts);
734
};
735
736
// Specify a value for an ES6 grammar parametrization. We have no enum for
737
// [Return] because its behavior is exactly equivalent to checking whether
738
// we're in a function box -- easier and simpler than passing an extra
739
// parameter everywhere.
740
enum YieldHandling { YieldIsName, YieldIsKeyword };
741
enum InHandling { InAllowed, InProhibited };
742
enum DefaultHandling { NameRequired, AllowDefaultName };
743
enum TripledotHandling { TripledotAllowed, TripledotProhibited };
744
745
template <class ParseHandler, typename Unit>
746
class Parser;
747
748
template <class ParseHandler, typename Unit>
749
class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
750
public:
751
using TokenStream =
752
TokenStreamSpecific<Unit, ParserAnyCharsAccess<GeneralParser>>;
753
754
private:
755
using Base = PerHandlerParser<ParseHandler>;
756
using FinalParser = Parser<ParseHandler, Unit>;
757
using Node = typename ParseHandler::Node;
758
759
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
760
using longTypeName = typename ParseHandler::longTypeName;
761
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
762
#undef DECLARE_TYPE
763
764
using typename Base::InvokedPrediction;
765
using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
766
767
protected:
768
using Modifier = TokenStreamShared::Modifier;
769
using Position = typename TokenStream::Position;
770
771
using Base::PredictInvoked;
772
using Base::PredictUninvoked;
773
774
using Base::alloc_;
775
using Base::awaitIsKeyword;
776
using Base::inParametersOfAsyncFunction;
777
using Base::parseGoal;
778
#if DEBUG
779
using Base::checkOptionsCalled_;
780
#endif
781
using Base::finishFunctionScopes;
782
using Base::finishLexicalScope;
783
using Base::foldConstants_;
784
using Base::getFilename;
785
using Base::hasValidSimpleStrictParameterNames;
786
using Base::isUnexpectedEOF_;
787
using Base::keepAtoms_;
788
using Base::nameIsArgumentsOrEval;
789
using Base::newFunction;
790
using Base::newFunctionBox;
791
using Base::newName;
792
using Base::null;
793
using Base::options;
794
using Base::pos;
795
using Base::propagateFreeNamesAndMarkClosedOverBindings;
796
using Base::setLocalStrictMode;
797
using Base::stringLiteral;
798
using Base::traceListHead_;
799
using Base::yieldExpressionsSupported;
800
801
using Base::abortIfSyntaxParser;
802
using Base::clearAbortedSyntaxParse;
803
using Base::disableSyntaxParser;
804
using Base::hadAbortedSyntaxParse;
805
806
public:
807
// Implement ErrorReportMixin.
808
809
MOZ_MUST_USE bool computeErrorMetadata(
810
ErrorMetadata* err, const ErrorReportMixin::ErrorOffset& offset) override;
811
812
using Base::error;
813
using Base::errorAt;
814
using Base::errorNoOffset;
815
using Base::errorWithNotes;
816
using Base::errorWithNotesAt;
817
using Base::errorWithNotesNoOffset;
818
using Base::extraWarning;
819
using Base::extraWarningAt;
820
using Base::extraWarningNoOffset;
821
using Base::extraWarningWithNotes;
822
using Base::extraWarningWithNotesAt;
823
using Base::extraWarningWithNotesNoOffset;
824
using Base::strictModeError;
825
using Base::strictModeErrorAt;
826
using Base::strictModeErrorNoOffset;
827
using Base::strictModeErrorWithNotes;
828
using Base::strictModeErrorWithNotesAt;
829
using Base::strictModeErrorWithNotesNoOffset;
830
using Base::warning;
831
using Base::warningAt;
832
using Base::warningNoOffset;
833
using Base::warningWithNotes;
834
using Base::warningWithNotesAt;
835
using Base::warningWithNotesNoOffset;
836
837
public:
838
using Base::anyChars;
839
using Base::cx_;
840
using Base::handler_;
841
using Base::isValidSimpleAssignmentTarget;
842
using Base::pc_;
843
using Base::usedNames_;
844
845
private:
846
using Base::checkAndMarkSuperScope;
847
using Base::finishFunction;
848
using Base::identifierReference;
849
using Base::leaveInnerFunction;
850
using Base::newDotGeneratorName;
851
using Base::newInternalDotName;
852
using Base::newThisName;
853
using Base::nextTokenContinuesLetDeclaration;
854
using Base::noSubstitutionTaggedTemplate;
855
using Base::noteDestructuredPositionalFormalParameter;
856
using Base::noteUsedName;
857
using Base::prefixAccessorName;
858
using Base::processExport;
859
using Base::processExportFrom;
860
using Base::setFunctionEndFromCurrentToken;
861
862
private:
863
inline FinalParser* asFinalParser();
864
inline const FinalParser* asFinalParser() const;
865
866
/*
867
* A class for temporarily stashing errors while parsing continues.
868
*
869
* The ability to stash an error is useful for handling situations where we
870
* aren't able to verify that an error has occurred until later in the parse.
871
* For instance | ({x=1}) | is always parsed as an object literal with
872
* a SyntaxError, however, in the case where it is followed by '=>' we rewind
873
* and reparse it as a valid arrow function. Here a PossibleError would be
874
* set to 'pending' when the initial SyntaxError was encountered then
875
* 'resolved' just before rewinding the parser.
876
*
877
* There are currently two kinds of PossibleErrors: Expression and
878
* Destructuring errors. Expression errors are used to mark a possible
879
* syntax error when a grammar production is used in an expression context.
880
* For example in |{x = 1}|, we mark the CoverInitializedName |x = 1| as a
881
* possible expression error, because CoverInitializedName productions
882
* are disallowed when an actual ObjectLiteral is expected.
883
* Destructuring errors are used to record possible syntax errors in
884
* destructuring contexts. For example in |[...rest, ] = []|, we initially
885
* mark the trailing comma after the spread expression as a possible
886
* destructuring error, because the ArrayAssignmentPattern grammar
887
* production doesn't allow a trailing comma after the rest element.
888
*
889
* When using PossibleError one should set a pending error at the location
890
* where an error occurs. From that point, the error may be resolved
891
* (invalidated) or left until the PossibleError is checked.
892
*
893
* Ex:
894
* PossibleError possibleError(*this);
895
* possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
896
* // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
897
* if (!possibleError.checkForExpressionError()) {
898
* return false; // we reach this point with a pending exception
899
* }
900
*
901
* PossibleError possibleError(*this);
902
* possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
903
* // Returns true, no error is reported.
904
* if (!possibleError.checkForDestructuringError()) {
905
* return false; // not reached, no pending exception
906
* }
907
*
908
* PossibleError possibleError(*this);
909
* // Returns true, no error is reported.
910
* if (!possibleError.checkForExpressionError()) {
911
* return false; // not reached, no pending exception
912
* }
913
*/
914
class MOZ_STACK_CLASS PossibleError {
915
private:
916
enum class ErrorKind { Expression, Destructuring, DestructuringWarning };
917
918
enum class ErrorState { None, Pending };
919
920
struct Error {
921
ErrorState state_ = ErrorState::None;
922
923
// Error reporting fields.
924
uint32_t offset_;
925
unsigned errorNumber_;
926
};
927
928
GeneralParser<ParseHandler, Unit>& parser_;
929
Error exprError_;
930
Error destructuringError_;
931
Error destructuringWarning_;
932
933
// Returns the error report.
934
Error& error(ErrorKind kind);
935
936
// Return true if an error is pending without reporting.
937
bool hasError(ErrorKind kind);
938
939
// Resolve any pending error.
940
void setResolved(ErrorKind kind);
941
942
// Set a pending error. Only a single error may be set per instance and
943
// error kind.
944
void setPending(ErrorKind kind, const TokenPos& pos, unsigned errorNumber);
945
946
// If there is a pending error, report it and return false, otherwise
947
// return true.
948
MOZ_MUST_USE bool checkForError(ErrorKind kind);
949
950
// If there is a pending warning, report it and return either false or
951
// true depending on the werror option, otherwise return true.
952
MOZ_MUST_USE bool checkForWarning(ErrorKind kind);
953
954
// Transfer an existing error to another instance.
955
void transferErrorTo(ErrorKind kind, PossibleError* other);
956
957
public:
958
explicit PossibleError(GeneralParser<ParseHandler, Unit>& parser);
959
960
// Return true if a pending destructuring error is present.
961
bool hasPendingDestructuringError();
962
963
// Set a pending destructuring error. Only a single error may be set
964
// per instance, i.e. subsequent calls to this method are ignored and
965
// won't overwrite the existing pending error.
966
void setPendingDestructuringErrorAt(const TokenPos& pos,
967
unsigned errorNumber);
968
969
// Set a pending destructuring warning. Only a single warning may be
970
// set per instance, i.e. subsequent calls to this method are ignored
971
// and won't overwrite the existing pending warning.
972
void setPendingDestructuringWarningAt(const TokenPos& pos,
973
unsigned errorNumber);
974
975
// Set a pending expression error. Only a single error may be set per
976
// instance, i.e. subsequent calls to this method are ignored and won't
977
// overwrite the existing pending error.
978
void setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber);
979
980
// If there is a pending destructuring error or warning, report it and
981
// return false, otherwise return true. Clears any pending expression
982
// error.
983
MOZ_MUST_USE bool checkForDestructuringErrorOrWarning();
984
985
// If there is a pending expression error, report it and return false,
986
// otherwise return true. Clears any pending destructuring error or
987
// warning.
988
MOZ_MUST_USE bool checkForExpressionError();
989
990
// Pass pending errors between possible error instances. This is useful
991
// for extending the lifetime of a pending error beyond the scope of
992
// the PossibleError where it was initially set (keeping in mind that
993
// PossibleError is a MOZ_STACK_CLASS).
994
void transferErrorsTo(PossibleError* other);
995
};
996
997
protected:
998
SyntaxParser* getSyntaxParser() const {
999
return reinterpret_cast<SyntaxParser*>(Base::internalSyntaxParser_);
1000
}
1001
1002
public:
1003
TokenStream tokenStream;
1004
1005
public:
1006
GeneralParser(JSContext* cx, const JS::ReadOnlyCompileOptions& options,
1007
const Unit* units, size_t length, bool foldConstants,
1008
ParseInfo& parserInfo, SyntaxParser* syntaxParser,
1009
LazyScript* lazyOuterFunction, ScriptSourceObject* sourceObject,
1010
ParseGoal parseGoal);
1011
1012
inline void setAwaitHandling(AwaitHandling awaitHandling);
1013
inline void setInParametersOfAsyncFunction(bool inParameters);
1014
1015
/*
1016
* Parse a top-level JS script.
1017
*/
1018
ListNodeType parse();
1019
1020
private:
1021
/*
1022
* Gets the next token and checks if it matches to the given `condition`.
1023
* If it matches, returns true.
1024
* If it doesn't match, calls `errorReport` to report the error, and
1025
* returns false.
1026
* If other error happens, it returns false but `errorReport` may not be
1027
* called and other error will be thrown in that case.
1028
*
1029
* In any case, the already gotten token is not ungotten.
1030
*
1031
* The signature of `condition` is [...](TokenKind actual) -> bool, and
1032
* the signature of `errorReport` is [...](TokenKind actual).
1033
*/
1034
template <typename ConditionT, typename ErrorReportT>
1035
MOZ_MUST_USE bool mustMatchTokenInternal(ConditionT condition,
1036
ErrorReportT errorReport);
1037
1038
public:
1039
/*
1040
* The following mustMatchToken variants follow the behavior and parameter
1041
* types of mustMatchTokenInternal above.
1042
*
1043
* If modifier is omitted, `SlashIsDiv` is used.
1044
* If TokenKind is passed instead of `condition`, it checks if the next
1045
* token is the passed token.
1046
* If error number is passed instead of `errorReport`, it reports an
1047
* error with the passed errorNumber.
1048
*/
1049
MOZ_MUST_USE bool mustMatchToken(TokenKind expected, JSErrNum errorNumber) {
1050
return mustMatchTokenInternal(
1051
[expected](TokenKind actual) { return actual == expected; },
1052
[this, errorNumber](TokenKind) { this->error(errorNumber); });
1053
}
1054
1055
template <typename ConditionT>
1056
MOZ_MUST_USE bool mustMatchToken(ConditionT condition, JSErrNum errorNumber) {
1057
return mustMatchTokenInternal(condition, [this, errorNumber](TokenKind) {
1058
this->error(errorNumber);
1059
});
1060
}
1061
1062
template <typename ErrorReportT>
1063
MOZ_MUST_USE bool mustMatchToken(TokenKind expected,
1064
ErrorReportT errorReport) {
1065
return mustMatchTokenInternal(
1066
[expected](TokenKind actual) { return actual == expected; },
1067
errorReport);
1068
}
1069
1070
private:
1071
NameNodeType noSubstitutionUntaggedTemplate();
1072
ListNodeType templateLiteral(YieldHandling yieldHandling);
1073
bool taggedTemplate(YieldHandling yieldHandling, ListNodeType tagArgsList,
1074
TokenKind tt);
1075
bool appendToCallSiteObj(CallSiteNodeType callSiteObj);
1076
bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling,
1077
ListNodeType nodeList, TokenKind* ttp);
1078
1079
inline bool trySyntaxParseInnerFunction(
1080
FunctionNodeType* funNode, Handle<FunctionCreationData> fcd,
1081
uint32_t toStringStart, InHandling inHandling,
1082
YieldHandling yieldHandling, FunctionSyntaxKind kind,
1083
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
1084
Directives inheritedDirectives, Directives* newDirectives);
1085
1086
inline bool skipLazyInnerFunction(FunctionNodeType funNode,
1087
uint32_t toStringStart,
1088
FunctionSyntaxKind kind, bool tryAnnexB);
1089
1090
void setFunctionStartAtCurrentToken(FunctionBox* funbox) const;
1091
1092
public:
1093
/* Public entry points for parsing. */
1094
Node statementListItem(YieldHandling yieldHandling,
1095
bool canHaveDirectives = false);
1096
1097
// Parse an inner function given an enclosing ParseContext and a
1098
// FunctionBox for the inner function.
1099
MOZ_MUST_USE FunctionNodeType innerFunctionForFunctionBox(
1100
FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
1101
InHandling inHandling, YieldHandling yieldHandling,
1102
FunctionSyntaxKind kind, Directives* newDirectives);
1103
1104
// Parse a function's formal parameters and its body assuming its function
1105
// ParseContext is already on the stack.
1106
bool functionFormalParametersAndBody(
1107
InHandling inHandling, YieldHandling yieldHandling,
1108
FunctionNodeType* funNode, FunctionSyntaxKind kind,
1109
const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing(),
1110
bool isStandaloneFunction = false);
1111
1112
private:
1113
/*
1114
* JS parsers, from lowest to highest precedence.
1115
*
1116
* Each parser must be called during the dynamic scope of a ParseContext
1117
* object, pointed to by this->pc_.
1118
*
1119
* Each returns a parse node tree or null on error.
1120
*/
1121
FunctionNodeType functionStmt(
1122
uint32_t toStringStart, YieldHandling yieldHandling,
1123
DefaultHandling defaultHandling,
1124
FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1125
FunctionNodeType functionExpr(uint32_t toStringStart,
1126
InvokedPrediction invoked,
1127
FunctionAsyncKind asyncKind);
1128
1129
Node statement(YieldHandling yieldHandling);
1130
bool maybeParseDirective(ListNodeType list, Node pn, bool* cont);
1131
1132
LexicalScopeNodeType blockStatement(
1133
YieldHandling yieldHandling,
1134
unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
1135
BinaryNodeType doWhileStatement(YieldHandling yieldHandling);
1136
BinaryNodeType whileStatement(YieldHandling yieldHandling);
1137
1138
Node forStatement(YieldHandling yieldHandling);
1139
bool forHeadStart(YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
1140
Node* forInitialPart,
1141
mozilla::Maybe<ParseContext::Scope>& forLetImpliedScope,
1142
Node* forInOrOfExpression);
1143
Node expressionAfterForInOrOf(ParseNodeKind forHeadKind,
1144
YieldHandling yieldHandling);
1145
1146
SwitchStatementType switchStatement(YieldHandling yieldHandling);
1147
ContinueStatementType continueStatement(YieldHandling yieldHandling);
1148
BreakStatementType breakStatement(YieldHandling yieldHandling);
1149
UnaryNodeType returnStatement(YieldHandling yieldHandling);
1150
BinaryNodeType withStatement(YieldHandling yieldHandling);
1151
UnaryNodeType throwStatement(YieldHandling yieldHandling);
1152
TernaryNodeType tryStatement(YieldHandling yieldHandling);
1153
LexicalScopeNodeType catchBlockStatement(
1154
YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
1155
DebuggerStatementType debuggerStatement();
1156
1157
ListNodeType variableStatement(YieldHandling yieldHandling);
1158
1159
LabeledStatementType labeledStatement(YieldHandling yieldHandling);
1160
Node labeledItem(YieldHandling yieldHandling);
1161
1162
TernaryNodeType ifStatement(YieldHandling yieldHandling);
1163
Node consequentOrAlternative(YieldHandling yieldHandling);
1164
1165
ListNodeType lexicalDeclaration(YieldHandling yieldHandling,
1166
DeclarationKind kind);
1167
1168
inline BinaryNodeType importDeclaration();
1169
Node importDeclarationOrImportExpr(YieldHandling yieldHandling);
1170
1171
BinaryNodeType exportFrom(uint32_t begin, Node specList);
1172
BinaryNodeType exportBatch(uint32_t begin);
1173
inline bool checkLocalExportNames(ListNodeType node);
1174
Node exportClause(uint32_t begin);
1175
UnaryNodeType exportFunctionDeclaration(
1176
uint32_t begin, uint32_t toStringStart,
1177
FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1178
UnaryNodeType exportVariableStatement(uint32_t begin);
1179
UnaryNodeType exportClassDeclaration(uint32_t begin);
1180
UnaryNodeType exportLexicalDeclaration(uint32_t begin, DeclarationKind kind);
1181
BinaryNodeType exportDefaultFunctionDeclaration(
1182
uint32_t begin, uint32_t toStringStart,
1183
FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1184
BinaryNodeType exportDefaultClassDeclaration(uint32_t begin);
1185
BinaryNodeType exportDefaultAssignExpr(uint32_t begin);
1186
BinaryNodeType exportDefault(uint32_t begin);
1187
Node exportDeclaration();
1188
1189
UnaryNodeType expressionStatement(
1190
YieldHandling yieldHandling,
1191
InvokedPrediction invoked = PredictUninvoked);
1192
1193
// Declaration parsing. The main entrypoint is Parser::declarationList,
1194
// with sub-functionality split out into the remaining methods.
1195
1196
// |blockScope| may be non-null only when |kind| corresponds to a lexical
1197
// declaration (that is, PNK_LET or PNK_CONST).
1198
//
1199
// The for* parameters, for normal declarations, should be null/ignored.
1200
// They should be non-null only when Parser::forHeadStart parses a
1201
// declaration at the start of a for-loop head.
1202
//
1203
// In this case, on success |*forHeadKind| is PNK_FORHEAD, PNK_FORIN, or
1204
// PNK_FOROF, corresponding to the three for-loop kinds. The precise value
1205
// indicates what was parsed.
1206
//
1207
// If parsing recognized a for(;;) loop, the next token is the ';' within
1208
// the loop-head that separates the init/test parts.
1209
//
1210
// Otherwise, for for-in/of loops, the next token is the ')' ending the
1211
// loop-head. Additionally, the expression that the loop iterates over was
1212
// parsed into |*forInOrOfExpression|.
1213
ListNodeType declarationList(YieldHandling yieldHandling, ParseNodeKind kind,
1214
ParseNodeKind* forHeadKind = nullptr,
1215
Node* forInOrOfExpression = nullptr);
1216
1217
// The items in a declaration list are either patterns or names, with or
1218
// without initializers. These two methods parse a single pattern/name and
1219
// any associated initializer -- and if parsing an |initialDeclaration|
1220
// will, if parsing in a for-loop head (as specified by |forHeadKind| being
1221
// non-null), consume additional tokens up to the closing ')' in a
1222
// for-in/of loop head, returning the iterated expression in
1223
// |*forInOrOfExpression|. (An "initial declaration" is the first
1224
// declaration in a declaration list: |a| but not |b| in |var a, b|, |{c}|
1225
// but not |d| in |let {c} = 3, d|.)
1226
Node declarationPattern(DeclarationKind declKind, TokenKind tt,
1227
bool initialDeclaration, YieldHandling yieldHandling,
1228
ParseNodeKind* forHeadKind,
1229
Node* forInOrOfExpression);
1230
Node declarationName(DeclarationKind declKind, TokenKind tt,
1231
bool initialDeclaration, YieldHandling yieldHandling,
1232
ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
1233
1234
// Having parsed a name (not found in a destructuring pattern) declared by
1235
// a declaration, with the current token being the '=' separating the name
1236
// from its initializer, parse and bind that initializer -- and possibly
1237
// consume trailing in/of and subsequent expression, if so directed by
1238
// |forHeadKind|.
1239
AssignmentNodeType initializerInNameDeclaration(NameNodeType binding,
1240
DeclarationKind declKind,
1241
bool initialDeclaration,
1242
YieldHandling yieldHandling,
1243
ParseNodeKind* forHeadKind,
1244
Node* forInOrOfExpression);
1245
1246
Node expr(InHandling inHandling, YieldHandling yieldHandling,
1247
TripledotHandling tripledotHandling,
1248
PossibleError* possibleError = nullptr,
1249
InvokedPrediction invoked = PredictUninvoked);
1250
Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
1251
TripledotHandling tripledotHandling,
1252
PossibleError* possibleError = nullptr,
1253
InvokedPrediction invoked = PredictUninvoked);
1254
Node assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
1255
UnaryNodeType yieldExpression(InHandling inHandling);
1256
Node condExpr(InHandling inHandling, YieldHandling yieldHandling,
1257
TripledotHandling tripledotHandling,
1258
PossibleError* possibleError,
1259
InvokedPrediction invoked = PredictUninvoked);
1260
Node orExpr(InHandling inHandling, YieldHandling yieldHandling,
1261
TripledotHandling tripledotHandling, PossibleError* possibleError,
1262
InvokedPrediction invoked = PredictUninvoked);
1263
Node unaryExpr(YieldHandling yieldHandling,
1264
TripledotHandling tripledotHandling,
1265
PossibleError* possibleError = nullptr,
1266
InvokedPrediction invoked = PredictUninvoked);
1267
Node memberExpr(YieldHandling yieldHandling,
1268
TripledotHandling tripledotHandling, TokenKind tt,
1269
bool allowCallSyntax = true,
1270
PossibleError* possibleError = nullptr,
1271
InvokedPrediction invoked = PredictUninvoked);
1272
Node primaryExpr(YieldHandling yieldHandling,
1273
TripledotHandling tripledotHandling, TokenKind tt,
1274
PossibleError* possibleError,
1275
InvokedPrediction invoked = PredictUninvoked);
1276
Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
1277
TripledotHandling tripledotHandling,
1278
PossibleError* possibleError = nullptr);
1279
1280
bool tryNewTarget(BinaryNodeType* newTarget);
1281
1282
BinaryNodeType importExpr(YieldHandling yieldHandling, bool allowCallSyntax);
1283
1284
FunctionNodeType methodDefinition(uint32_t toStringStart,
1285
PropertyType propType, HandleAtom funName);
1286
1287
/*
1288
* Additional JS parsers.
1289
*/
1290
bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
1291
FunctionNodeType funNode);
1292
1293
FunctionNodeType functionDefinition(
1294
FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
1295
YieldHandling yieldHandling, HandleAtom name, FunctionSyntaxKind kind,
1296
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
1297
bool tryAnnexB = false);
1298
1299
// Parse a function body. Pass StatementListBody if the body is a list of
1300
// statements; pass ExpressionBody if the body is a single expression.
1301
enum FunctionBodyType { StatementListBody, ExpressionBody };
1302
LexicalScopeNodeType functionBody(InHandling inHandling,
1303
YieldHandling yieldHandling,
1304
FunctionSyntaxKind kind,
1305
FunctionBodyType type);
1306
1307
UnaryNodeType unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind,
1308
uint32_t begin);
1309
1310
Node condition(InHandling inHandling, YieldHandling yieldHandling);
1311
1312
ListNodeType argumentList(YieldHandling yieldHandling, bool* isSpread,
1313
PossibleError* possibleError = nullptr);
1314
Node destructuringDeclaration(DeclarationKind kind,
1315
YieldHandling yieldHandling, TokenKind tt);
1316
Node destructuringDeclarationWithoutYieldOrAwait(DeclarationKind kind,
1317
YieldHandling yieldHandling,
1318
TokenKind tt);
1319
1320
inline bool checkExportedName(JSAtom* exportName);
1321
inline bool checkExportedNamesForArrayBinding(ListNodeType array);
1322
inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
1323
inline bool checkExportedNamesForDeclaration(Node node);
1324
inline bool checkExportedNamesForDeclarationList(ListNodeType node);
1325
inline bool checkExportedNameForFunction(FunctionNodeType funNode);
1326
inline bool checkExportedNameForClass(ClassNodeType classNode);
1327
inline bool checkExportedNameForClause(NameNodeType nameNode);
1328
1329
enum ClassContext { ClassStatement, ClassExpression };
1330
ClassNodeType classDefinition(YieldHandling yieldHandling,
1331
ClassContext classContext,
1332
DefaultHandling defaultHandling);
1333
MOZ_MUST_USE bool classMember(
1334
YieldHandling yieldHandling, DefaultHandling defaultHandling,
1335
const ParseContext::ClassStatement& classStmt,
1336
HandlePropertyName className, uint32_t classStartOffset,
1337
HasHeritage hasHeritage, size_t& numFieldsWithInitializers,
1338
size_t& numFieldKeys, ListNodeType& classMembers, bool* done);
1339
MOZ_MUST_USE bool finishClassConstructor(
1340
const ParseContext::ClassStatement& classStmt,
1341
HandlePropertyName className, HasHeritage hasHeritage,
1342
uint32_t classStartOffset, uint32_t classEndOffset,
1343
size_t numFieldsWithInitializers, ListNodeType& classMembers);
1344
1345
FunctionNodeType fieldInitializerOpt(YieldHandling yieldHandling,
1346
HasHeritage hasHeritage, Node name,
1347
HandleAtom atom, size_t& numFieldKeys);
1348
FunctionNodeType synthesizeConstructor(HandleAtom className,
1349
uint32_t classNameOffset,
1350
HasHeritage hasHeritage);
1351
1352
bool checkBindingIdentifier(PropertyName* ident, uint32_t offset,
1353
YieldHandling yieldHandling,
1354
TokenKind hint = TokenKind::Limit);
1355
1356
PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling);
1357
1358
PropertyName* labelIdentifier(YieldHandling yieldHandling) {
1359
return labelOrIdentifierReference(yieldHandling);
1360
}
1361
1362
PropertyName* identifierReference(YieldHandling yieldHandling) {
1363
return labelOrIdentifierReference(yieldHandling);
1364
}
1365
1366
bool matchLabel(YieldHandling yieldHandling,
1367
MutableHandle<PropertyName*> label);
1368
1369
// Indicate if the next token (tokenized with SlashIsRegExp) is |in| or |of|.
1370
// If so, consume it.
1371
bool matchInOrOf(bool* isForInp, bool* isForOfp);
1372
1373
private:
1374
bool checkIncDecOperand(Node operand, uint32_t operandOffset);
1375
bool checkStrictAssignment(Node lhs);
1376
1377
void reportMissingClosing(unsigned errorNumber, unsigned noteNumber,
1378
uint32_t openedPos);
1379
1380
void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind,
1381
TokenPos pos, uint32_t prevPos);
1382
bool notePositionalFormalParameter(FunctionNodeType funNode,
1383
HandlePropertyName name, uint32_t beginPos,
1384
bool disallowDuplicateParams,
1385
bool* duplicatedParam);
1386
1387
bool checkLexicalDeclarationDirectlyWithinBlock(ParseContext::Statement& stmt,
1388
DeclarationKind kind,
1389
TokenPos pos);
1390
1391
enum PropertyNameContext {
1392
PropertyNameInLiteral,
1393
PropertyNameInPattern,
1394
PropertyNameInClass
1395
};
1396
Node propertyName(YieldHandling yieldHandling,
1397
PropertyNameContext propertyNameContext,
1398
const mozilla::Maybe<DeclarationKind>& maybeDecl,
1399
ListNodeType propList, MutableHandleAtom propAtom);
1400
Node propertyOrMethodName(YieldHandling yieldHandling,
1401
PropertyNameContext propertyNameContext,
1402
const mozilla::Maybe<DeclarationKind>& maybeDecl,
1403
ListNodeType propList, PropertyType* propType,
1404
MutableHandleAtom propAtom);
1405
UnaryNodeType computedPropertyName(
1406
YieldHandling yieldHandling,
1407
const mozilla::Maybe<DeclarationKind>& maybeDecl,
1408
PropertyNameContext propertyNameContext, ListNodeType literal);
1409
ListNodeType arrayInitializer(YieldHandling yieldHandling,
1410
PossibleError* possibleError);
1411
inline RegExpLiteralType newRegExp();
1412
1413
ListNodeType objectLiteral(YieldHandling yieldHandling,
1414
PossibleError* possibleError);
1415
1416
BinaryNodeType bindingInitializer(Node lhs, DeclarationKind kind,
1417
YieldHandling yieldHandling);
1418
NameNodeType bindingIdentifier(DeclarationKind kind,
1419
YieldHandling yieldHandling);
1420
Node bindingIdentifierOrPattern(DeclarationKind kind,
1421
YieldHandling yieldHandling, TokenKind tt);
1422
ListNodeType objectBindingPattern(DeclarationKind kind,
1423
YieldHandling yieldHandling);
1424
ListNodeType arrayBindingPattern(DeclarationKind kind,
1425
YieldHandling yieldHandling);
1426
1427
enum class TargetBehavior {
1428
PermitAssignmentPattern,
1429
ForbidAssignmentPattern
1430
};
1431
bool checkDestructuringAssignmentTarget(
1432
Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
1433
PossibleError* possibleError,
1434
TargetBehavior behavior = TargetBehavior::PermitAssignmentPattern);
1435
void checkDestructuringAssignmentName(NameNodeType name, TokenPos namePos,
1436
PossibleError* possibleError);
1437
bool checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
1438
PossibleError* exprPossibleError,
1439
PossibleError* possibleError);
1440
1441
NumericLiteralType newNumber(const Token& tok) {
1442
return handler_.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
1443
}
1444
1445
inline BigIntLiteralType newBigInt();
1446
1447
protected:
1448
// Match the current token against the BindingIdentifier production with
1449
// the given Yield parameter. If there is no match, report a syntax
1450
// error.
1451
PropertyName* bindingIdentifier(YieldHandling yieldHandling);
1452
1453
bool checkLabelOrIdentifierReference(PropertyName* ident, uint32_t offset,
1454
YieldHandling yieldHandling,
1455
TokenKind hint = TokenKind::Limit);
1456
1457
ListNodeType statementList(YieldHandling yieldHandling);
1458
1459
MOZ_MUST_USE FunctionNodeType
1460
innerFunction(FunctionNodeType funNode, ParseContext* outerpc,
1461
Handle<FunctionCreationData> fcd, uint32_t toStringStart,
1462
InHandling inHandling, YieldHandling yieldHandling,
1463
FunctionSyntaxKind kind, GeneratorKind generatorKind,
1464
FunctionAsyncKind asyncKind, bool tryAnnexB,
1465
Directives inheritedDirectives, Directives* newDirectives);
1466
1467
// Implements Automatic Semicolon Insertion.
1468
//
1469
// Use this to match `;` in contexts where ASI is allowed. Call this after
1470
// ruling out all other possibilities except `;`, by peeking ahead if
1471
// necessary.
1472
//
1473
// Unlike most optional Modifiers, this method's `modifier` argument defaults
1474
// to SlashIsRegExp, since that's by far the most common case: usually an
1475
// optional semicolon is at the end of a statement or declaration, and the
1476
// next token could be a RegExp literal beginning a new ExpressionStatement.
1477
bool matchOrInsertSemicolon(Modifier modifier = TokenStream::SlashIsRegExp);
1478
1479
bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind,
1480
TokenPos pos);
1481
1482
private:
1483
inline bool asmJS(ListNodeType list);
1484
};
1485
1486
template <typename Unit>
1487
class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
1488
: public GeneralParser<SyntaxParseHandler, Unit> {
1489
using Base = GeneralParser<SyntaxParseHandler, Unit>;
1490
using Node = SyntaxParseHandler::Node;
1491
1492
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
1493
using longTypeName = SyntaxParseHandler::longTypeName;
1494
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
1495
#undef DECLARE_TYPE
1496
1497
using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
1498
1499
// Numerous Base::* functions have bodies like
1500
//
1501
// return asFinalParser()->func(...);
1502
//
1503
// and must be able to call functions here. Add a friendship relationship
1504
// so functions here can be hidden when appropriate.
1505
friend class GeneralParser<SyntaxParseHandler, Unit>;
1506
1507
public:
1508
using Base::Base;
1509
1510
// Inherited types, listed here to have non-dependent names.
1511
using typename Base::Modifier;
1512
using typename Base::Position;
1513
using typename Base::TokenStream;
1514
1515
// Inherited functions, listed here to have non-dependent names.
1516
1517
public:
1518
using Base::anyChars;
1519
using Base::clearAbortedSyntaxParse;
1520
using Base::cx_;
1521
using Base::hadAbortedSyntaxParse;
1522
using Base::innerFunctionForFunctionBox;
1523
using Base::tokenStream;
1524
1525
public:
1526
// ErrorReportMixin.
1527
1528
using Base::error;
1529
using Base::errorAt;
1530
using Base::errorNoOffset;
1531
using Base::errorWithNotes;
1532
using Base::errorWithNotesAt;
1533
using Base::errorWithNotesNoOffset;
1534
using Base::extraWarning;
1535
using Base::extraWarningAt;
1536
using Base::extraWarningNoOffset;
1537
using Base::extraWarningWithNotes;
1538
using Base::extraWarningWithNotesAt;
1539
using Base::extraWarningWithNotesNoOffset;
1540
using Base::strictModeError;
1541
using Base::strictModeErrorAt;
1542
using Base::strictModeErrorNoOffset;
1543
using Base::strictModeErrorWithNotes;
1544
using Base::strictModeErrorWithNotesAt;
1545
using Base::strictModeErrorWithNotesNoOffset;
1546
using Base::warning;
1547
using Base::warningAt;
1548
using Base::warningNoOffset;
1549
using Base::warningWithNotes;
1550
using Base::warningWithNotesAt;
1551
using Base::warningWithNotesNoOffset;
1552
1553
private:
1554
using Base::alloc_;
1555
#if DEBUG
1556
using Base::checkOptionsCalled_;
1557
#endif
1558
using Base::finishFunctionScopes;
1559
using Base::functionFormalParametersAndBody;
1560
using Base::handler_;
1561
using Base::innerFunction;
1562
using Base::keepAtoms_;
1563
using Base::matchOrInsertSemicolon;
1564
using Base::mustMatchToken;
1565
using Base::newFunctionBox;
1566
using Base::newLexicalScopeData;
1567
using Base::newModuleScopeData;
1568
using Base::newName;
1569
using Base::noteDeclaredName;
1570
using Base::null;
1571
using Base::options;
1572
using Base::pc_;
1573
using Base::pos;
1574
using Base::propagateFreeNamesAndMarkClosedOverBindings;
1575
using Base::ss;
1576
using Base::statementList;
1577
using Base::stringLiteral;
1578
using Base::usedNames_;
1579
1580
private:
1581
using Base::abortIfSyntaxParser;
1582
using Base::disableSyntaxParser;
1583
1584
public:
1585
// Functions with multiple overloads of different visibility. We can't
1586
// |using| the whole thing into existence because of the visibility
1587
// distinction, so we instead must manually delegate the required overload.
1588
1589
PropertyName* bindingIdentifier(YieldHandling yieldHandling) {
1590
return Base::bindingIdentifier(yieldHandling);
1591
}
1592
1593
// Functions present in both Parser<ParseHandler, Unit> specializations.
1594
1595
inline void setAwaitHandling(AwaitHandling awaitHandling);
1596
inline void setInParametersOfAsyncFunction(bool inParameters);
1597
1598
RegExpLiteralType newRegExp();
1599
BigIntLiteralType newBigInt();
1600
1601
// Parse a module.
1602
ModuleNodeType moduleBody(ModuleSharedContext* modulesc);
1603
1604
inline BinaryNodeType importDeclaration();
1605
inline bool checkLocalExportNames(ListNodeType node);
1606
inline bool checkExportedName(JSAtom* exportName);
1607
inline bool checkExportedNamesForArrayBinding(ListNodeType array);
1608
inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
1609
inline bool checkExportedNamesForDeclaration(Node node);
1610
inline bool checkExportedNamesForDeclarationList(ListNodeType node);
1611
inline bool checkExportedNameForFunction(FunctionNodeType funNode);
1612
inline bool checkExportedNameForClass(ClassNodeType classNode);
1613
inline bool checkExportedNameForClause(NameNodeType nameNode);
1614
1615
bool trySyntaxParseInnerFunction(
1616
FunctionNodeType* funNode, Handle<FunctionCreationData> fcd,
1617
uint32_t toStringStart, InHandling inHandling,
1618
YieldHandling yieldHandling, FunctionSyntaxKind kind,
1619
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
1620
Directives inheritedDirectives, Directives* newDirectives);
1621
1622
bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart,
1623
FunctionSyntaxKind kind, bool tryAnnexB);
1624
1625
bool asmJS(ListNodeType list);
1626
1627
// Functions present only in Parser<SyntaxParseHandler, Unit>.
1628
};
1629
1630
template <typename Unit>
1631
class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
1632
: public GeneralParser<FullParseHandler, Unit> {
1633
using Base = GeneralParser<FullParseHandler, Unit>;
1634
using Node = FullParseHandler::Node;
1635
1636
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
1637
using longTypeName = FullParseHandler::longTypeName;
1638
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
1639
#undef DECLARE_TYPE
1640
1641
using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
1642
1643
// Numerous Base::* functions have bodies like
1644
//
1645
// return asFinalParser()->func(...);
1646
//
1647
// and must be able to call functions here. Add a friendship relationship
1648
// so functions here can be hidden when appropriate.
1649
friend class GeneralParser<FullParseHandler, Unit>;
1650
1651
public:
1652
using Base::Base;
1653
1654
// Inherited types, listed here to have non-dependent names.
1655
using typename Base::Modifier;
1656
using typename Base::Position;
1657
using typename Base::TokenStream;
1658
1659
// Inherited functions, listed here to have non-dependent names.
1660
1661
public:
1662
using Base::anyChars;
1663
using Base::clearAbortedSyntaxParse;
1664
using Base::functionFormalParametersAndBody;
1665
using Base::hadAbortedSyntaxParse;
1666
using Base::handler_;
1667
using Base::newFunctionBox;
1668
using Base::options;
1669
using Base::pc_;
1670
using Base::pos;
1671
using Base::ss;
1672
using Base::tokenStream;
1673
1674
public:
1675
// ErrorReportMixin.
1676
1677
using Base::error;
1678
using Base::errorAt;
1679
using Base::errorNoOffset;
1680
using Base::errorWithNotes;
1681
using Base::errorWithNotesAt;
1682
using Base::errorWithNotesNoOffset;
1683
using Base::extraWarning;
1684
using Base::extraWarningAt;
1685
using Base::extraWarningNoOffset;
1686
using Base::extraWarningWithNotes;
1687
using Base::extraWarningWithNotesAt;
1688
using Base::extraWarningWithNotesNoOffset;
1689
using Base::strictModeError;
1690
using Base::strictModeErrorAt;
1691
using Base::strictModeErrorNoOffset;
1692
using Base::strictModeErrorWithNotes;
1693
using Base::strictModeErrorWithNotesAt;
1694
using Base::strictModeErrorWithNotesNoOffset;
1695
using Base::warning;
1696
using Base::warningAt;
1697
using Base::warningNoOffset;
1698
using Base::warningWithNotes;
1699
using Base::warningWithNotesAt;
1700
using Base::warningWithNotesNoOffset;
1701
1702
private:
1703
using Base::alloc_;
1704
using Base::checkLabelOrIdentifierReference;
1705
#if DEBUG
1706
using Base::checkOptionsCalled_;
1707
#endif
1708
using Base::cx_;
1709
using Base::finishFunctionScopes;
1710
using Base::finishLexicalScope;
1711
using Base::innerFunction;
1712
using Base::innerFunctionForFunctionBox;
1713
using Base::keepAtoms_;
1714
using Base::matchOrInsertSemicolon;
1715
using Base::mustMatchToken;
1716
using Base::newEvalScopeData;
1717
using Base::newFunctionScopeData;
1718
using Base::newGlobalScopeData;
1719
using Base::newLexicalScopeData;
1720
using Base::newModuleScopeData;
1721
using Base::newName;
1722
using Base::newVarScopeData;
1723
using Base::noteDeclaredName;
1724
using Base::null;
1725
using Base::propagateFreeNamesAndMarkClosedOverBindings;
1726
using Base::statementList;
1727
using Base::stringLiteral;
1728
using Base::usedNames_;
1729
1730
using Base::abortIfSyntaxParser;
1731
using Base::disableSyntaxParser;
1732
using Base::getSyntaxParser;
1733
1734
public:
1735
// Functions with multiple overloads of different visibility. We can't
1736
// |using| the whole thing into existence because of the visibility
1737
// distinction, so we instead must manually delegate the required overload.
1738
1739
PropertyName* bindingIdentifier(YieldHandling yieldHandling) {
1740
return Base::bindingIdentifier(yieldHandling);
1741
}
1742
1743
// Functions present in both Parser<ParseHandler, Unit> specializations.
1744
1745
friend class AutoAwaitIsKeyword<SyntaxParseHandler, Unit>;
1746
inline void setAwaitHandling(AwaitHandling awaitHandling);
1747
1748
friend class AutoInParametersOfAsyncFunction<SyntaxParseHandler, Unit>;
1749
inline void setInParametersOfAsyncFunction(bool inParameters);
1750
1751
RegExpLiteralType newRegExp();
1752
BigIntLiteralType newBigInt();
1753
1754
// Parse a module.
1755
ModuleNodeType moduleBody(ModuleSharedContext* modulesc);
1756
1757
BinaryNodeType importDeclaration();
1758
bool checkLocalExportNames(ListNodeType node);
1759
bool checkExportedName(JSAtom* exportName);
1760
bool checkExportedNamesForArrayBinding(ListNodeType array);
1761
bool checkExportedNamesForObjectBinding(ListNodeType obj);
1762
bool checkExportedNamesForDeclaration(Node node);
1763
bool checkExportedNamesForDeclarationList(ListNodeType node);
1764
bool checkExportedNameForFunction(FunctionNodeType funNode);
1765
bool checkExportedNameForClass(ClassNodeType classNode);
1766
inline bool checkExportedNameForClause(NameNodeType nameNode);
1767