1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "src/bailout-reason.h"
9 #include "src/expression-classifier.h"
10 #include "src/func-name-inferrer.h"
11 #include "src/hashmap.h"
12 #include "src/messages.h"
13 #include "src/scanner.h"
14 #include "src/scopes.h"
15 #include "src/token.h"
21 enum FunctionNameValidity {
22 kFunctionNameIsStrictReserved,
23 kSkipFunctionNameCheck,
24 kFunctionNameValidityUnknown
28 struct FormalParametersBase {
29 explicit FormalParametersBase(Scope* scope) : scope(scope) {}
31 bool has_rest = false;
32 bool is_simple = true;
33 int materialized_literals_count = 0;
34 mutable int rest_array_literal_index = -1;
38 // Common base class shared between parser and pre-parser. Traits encapsulate
39 // the differences between Parser and PreParser:
41 // - Return types: For example, Parser functions return Expression* and
42 // PreParser functions return PreParserExpression.
44 // - Creating parse tree nodes: Parser generates an AST during the recursive
45 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
46 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
47 // just enough data for the upper layer functions. PreParserFactory is
48 // responsible for creating these dummy objects. It provides a similar kind of
49 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
52 // - Miscellaneous other tasks interleaved with the recursive descent. For
53 // example, Parser keeps track of which function literals should be marked as
54 // pretenured, and PreParser doesn't care.
56 // The traits are expected to contain the following typedefs:
58 // // In particular...
60 // // Used by FunctionState and BlockState.
62 // typedef GeneratorVariable;
63 // // Return types for traversing functions.
64 // typedef Identifier;
65 // typedef Expression;
66 // typedef FunctionLiteral;
67 // typedef ClassLiteral;
68 // typedef ObjectLiteralProperty;
70 // typedef ExpressionList;
71 // typedef PropertyList;
72 // typedef FormalParameter;
73 // typedef FormalParameters;
74 // // For constructing objects returned by the traversing functions.
80 template <typename Traits>
81 class ParserBase : public Traits {
83 // Shorten type names defined by Traits.
84 typedef typename Traits::Type::Expression ExpressionT;
85 typedef typename Traits::Type::Identifier IdentifierT;
86 typedef typename Traits::Type::FormalParameter FormalParameterT;
87 typedef typename Traits::Type::FormalParameters FormalParametersT;
88 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
89 typedef typename Traits::Type::Literal LiteralT;
90 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
92 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
93 v8::Extension* extension, AstValueFactory* ast_value_factory,
94 ParserRecorder* log, typename Traits::Type::Parser this_object)
95 : Traits(this_object),
96 parenthesized_function_(false),
98 function_state_(NULL),
99 extension_(extension),
101 ast_value_factory_(ast_value_factory),
103 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
104 stack_limit_(stack_limit),
107 stack_overflow_(false),
109 allow_natives_(false),
110 allow_harmony_arrow_functions_(false),
111 allow_harmony_sloppy_(false),
112 allow_harmony_sloppy_function_(false),
113 allow_harmony_sloppy_let_(false),
114 allow_harmony_rest_parameters_(false),
115 allow_harmony_default_parameters_(false),
116 allow_harmony_spread_calls_(false),
117 allow_harmony_destructuring_(false),
118 allow_harmony_spread_arrays_(false),
119 allow_harmony_new_target_(false),
120 allow_strong_mode_(false),
121 allow_legacy_const_(true) {}
123 #define ALLOW_ACCESSORS(name) \
124 bool allow_##name() const { return allow_##name##_; } \
125 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
127 ALLOW_ACCESSORS(lazy);
128 ALLOW_ACCESSORS(natives);
129 ALLOW_ACCESSORS(harmony_arrow_functions);
130 ALLOW_ACCESSORS(harmony_sloppy);
131 ALLOW_ACCESSORS(harmony_sloppy_function);
132 ALLOW_ACCESSORS(harmony_sloppy_let);
133 ALLOW_ACCESSORS(harmony_rest_parameters);
134 ALLOW_ACCESSORS(harmony_default_parameters);
135 ALLOW_ACCESSORS(harmony_spread_calls);
136 ALLOW_ACCESSORS(harmony_destructuring);
137 ALLOW_ACCESSORS(harmony_spread_arrays);
138 ALLOW_ACCESSORS(harmony_new_target);
139 ALLOW_ACCESSORS(strong_mode);
140 ALLOW_ACCESSORS(legacy_const);
141 #undef ALLOW_ACCESSORS
144 enum AllowRestrictedIdentifiers {
145 kAllowRestrictedIdentifiers,
146 kDontAllowRestrictedIdentifiers
154 enum VariableDeclarationContext {
161 class ObjectLiteralCheckerBase;
163 // ---------------------------------------------------------------------------
164 // FunctionState and BlockState together implement the parser's scope stack.
165 // The parser's current scope is in scope_. BlockState and FunctionState
166 // constructors push on the scope stack and the destructors pop. They are also
167 // used to hold the parser's per-function and per-block state.
168 class BlockState BASE_EMBEDDED {
170 BlockState(Scope** scope_stack, Scope* scope)
171 : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
172 *scope_stack_ = scope;
174 ~BlockState() { *scope_stack_ = outer_scope_; }
177 Scope** scope_stack_;
181 class FunctionState BASE_EMBEDDED {
183 FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
184 Scope* scope, FunctionKind kind,
185 typename Traits::Type::Factory* factory);
188 int NextMaterializedLiteralIndex() {
189 return next_materialized_literal_index_++;
191 int materialized_literal_count() {
192 return next_materialized_literal_index_;
195 void SkipMaterializedLiterals(int count) {
196 next_materialized_literal_index_ += count;
199 void AddProperty() { expected_property_count_++; }
200 int expected_property_count() { return expected_property_count_; }
202 Scanner::Location this_location() const { return this_location_; }
203 Scanner::Location super_location() const { return super_location_; }
204 Scanner::Location return_location() const { return return_location_; }
205 void set_this_location(Scanner::Location location) {
206 this_location_ = location;
208 void set_super_location(Scanner::Location location) {
209 super_location_ = location;
211 void set_return_location(Scanner::Location location) {
212 return_location_ = location;
215 bool is_generator() const { return IsGeneratorFunction(kind_); }
217 FunctionKind kind() const { return kind_; }
218 FunctionState* outer() const { return outer_function_state_; }
220 void set_generator_object_variable(
221 typename Traits::Type::GeneratorVariable* variable) {
222 DCHECK(variable != NULL);
223 DCHECK(is_generator());
224 generator_object_variable_ = variable;
226 typename Traits::Type::GeneratorVariable* generator_object_variable()
228 return generator_object_variable_;
231 typename Traits::Type::Factory* factory() { return factory_; }
234 // Used to assign an index to each literal that needs materialization in
235 // the function. Includes regexp literals, and boilerplate for object and
237 int next_materialized_literal_index_;
239 // Properties count estimation.
240 int expected_property_count_;
242 // Location of most recent use of 'this' (invalid if none).
243 Scanner::Location this_location_;
245 // Location of most recent 'return' statement (invalid if none).
246 Scanner::Location return_location_;
248 // Location of call to the "super" constructor (invalid if none).
249 Scanner::Location super_location_;
252 // For generators, this variable may hold the generator object. It variable
253 // is used by yield expressions and return statements. It is not necessary
254 // for generator functions to have this variable set.
255 Variable* generator_object_variable_;
257 FunctionState** function_state_stack_;
258 FunctionState* outer_function_state_;
259 Scope** scope_stack_;
261 typename Traits::Type::Factory* factory_;
263 friend class ParserTraits;
264 friend class Checkpoint;
267 // Annoyingly, arrow functions first parse as comma expressions, then when we
268 // see the => we have to go back and reinterpret the arguments as being formal
269 // parameters. To do so we need to reset some of the parser state back to
270 // what it was before the arguments were first seen.
271 class Checkpoint BASE_EMBEDDED {
273 explicit Checkpoint(ParserBase* parser) {
274 function_state_ = parser->function_state_;
275 next_materialized_literal_index_ =
276 function_state_->next_materialized_literal_index_;
277 expected_property_count_ = function_state_->expected_property_count_;
280 void Restore(int* materialized_literal_index_delta) {
281 *materialized_literal_index_delta =
282 function_state_->next_materialized_literal_index_ -
283 next_materialized_literal_index_;
284 function_state_->next_materialized_literal_index_ =
285 next_materialized_literal_index_;
286 function_state_->expected_property_count_ = expected_property_count_;
290 FunctionState* function_state_;
291 int next_materialized_literal_index_;
292 int expected_property_count_;
295 class ParsingModeScope BASE_EMBEDDED {
297 ParsingModeScope(ParserBase* parser, Mode mode)
299 old_mode_(parser->mode()) {
300 parser_->mode_ = mode;
302 ~ParsingModeScope() {
303 parser_->mode_ = old_mode_;
311 Scope* NewScope(Scope* parent, ScopeType scope_type) {
312 // Must always pass the function kind for FUNCTION_SCOPE and ARROW_SCOPE.
313 DCHECK(scope_type != FUNCTION_SCOPE);
314 DCHECK(scope_type != ARROW_SCOPE);
315 return NewScope(parent, scope_type, kNormalFunction);
318 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
319 DCHECK(ast_value_factory());
320 DCHECK(scope_type != MODULE_SCOPE || FLAG_harmony_modules);
321 DCHECK(!IsArrowFunction(kind) || scope_type == ARROW_SCOPE);
322 Scope* result = new (zone())
323 Scope(zone(), parent, scope_type, ast_value_factory(), kind);
324 result->Initialize();
328 Scanner* scanner() const { return scanner_; }
329 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
330 int position() { return scanner_->location().beg_pos; }
331 int peek_position() { return scanner_->peek_location().beg_pos; }
332 bool stack_overflow() const { return stack_overflow_; }
333 void set_stack_overflow() { stack_overflow_ = true; }
334 Mode mode() const { return mode_; }
335 Zone* zone() const { return zone_; }
337 INLINE(Token::Value peek()) {
338 if (stack_overflow_) return Token::ILLEGAL;
339 return scanner()->peek();
342 INLINE(Token::Value PeekAhead()) {
343 if (stack_overflow_) return Token::ILLEGAL;
344 return scanner()->PeekAhead();
347 INLINE(Token::Value Next()) {
348 if (stack_overflow_) return Token::ILLEGAL;
350 if (GetCurrentStackPosition() < stack_limit_) {
351 // Any further calls to Next or peek will return the illegal token.
352 // The current call must return the next token, which might already
353 // have been peek'ed.
354 stack_overflow_ = true;
357 return scanner()->Next();
360 void Consume(Token::Value token) {
361 Token::Value next = Next();
364 DCHECK(next == token);
367 bool Check(Token::Value token) {
368 Token::Value next = peek();
376 void Expect(Token::Value token, bool* ok) {
377 Token::Value next = Next();
379 ReportUnexpectedToken(next);
384 void ExpectSemicolon(bool* ok) {
385 // Check for automatic semicolon insertion according to
386 // the rules given in ECMA-262, section 7.9, page 21.
387 Token::Value tok = peek();
388 if (tok == Token::SEMICOLON) {
392 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
393 tok == Token::RBRACE ||
397 Expect(Token::SEMICOLON, ok);
400 bool peek_any_identifier() {
401 Token::Value next = peek();
402 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
403 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
404 next == Token::STATIC || next == Token::YIELD;
407 bool CheckContextualKeyword(Vector<const char> keyword) {
408 if (PeekContextualKeyword(keyword)) {
409 Consume(Token::IDENTIFIER);
415 bool PeekContextualKeyword(Vector<const char> keyword) {
416 return peek() == Token::IDENTIFIER &&
417 scanner()->is_next_contextual_keyword(keyword);
420 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
421 Expect(Token::IDENTIFIER, ok);
423 if (!scanner()->is_literal_contextual_keyword(keyword)) {
424 ReportUnexpectedToken(scanner()->current_token());
430 bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) {
431 if (Check(Token::IN)) {
432 if (is_strong(language_mode())) {
433 ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn);
436 *visit_mode = ForEachStatement::ENUMERATE;
439 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
440 *visit_mode = ForEachStatement::ITERATE;
446 // Checks whether an octal literal was last seen between beg_pos and end_pos.
447 // If so, reports an error. Only called for strict mode and template strings.
448 void CheckOctalLiteral(int beg_pos, int end_pos,
449 MessageTemplate::Template message, bool* ok) {
450 Scanner::Location octal = scanner()->octal_position();
451 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
452 octal.end_pos <= end_pos) {
453 ReportMessageAt(octal, message);
454 scanner()->clear_octal_position();
459 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
460 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
464 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
465 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
469 // Checking the name of a function literal. This has to be done after parsing
470 // the function, since the function can declare itself strict.
471 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
472 FunctionNameValidity function_name_validity,
473 const Scanner::Location& function_name_loc, bool* ok) {
474 if (function_name_validity == kSkipFunctionNameCheck) return;
475 // The function name needs to be checked in strict mode.
476 if (is_sloppy(language_mode)) return;
478 if (this->IsEvalOrArguments(function_name)) {
479 Traits::ReportMessageAt(function_name_loc,
480 MessageTemplate::kStrictEvalArguments);
484 if (function_name_validity == kFunctionNameIsStrictReserved) {
485 Traits::ReportMessageAt(function_name_loc,
486 MessageTemplate::kUnexpectedStrictReserved);
490 if (is_strong(language_mode) && this->IsUndefined(function_name)) {
491 Traits::ReportMessageAt(function_name_loc,
492 MessageTemplate::kStrongUndefined);
498 // Determine precedence of given token.
499 static int Precedence(Token::Value token, bool accept_IN) {
500 if (token == Token::IN && !accept_IN)
501 return 0; // 0 precedence will terminate binary expression parsing
502 return Token::Precedence(token);
505 typename Traits::Type::Factory* factory() {
506 return function_state_->factory();
509 LanguageMode language_mode() { return scope_->language_mode(); }
510 bool is_generator() const { return function_state_->is_generator(); }
513 return is_strict(language_mode()) || allow_harmony_sloppy() ||
514 allow_legacy_const();
518 return is_strict(language_mode()) || allow_harmony_sloppy_let();
521 // Report syntax errors.
522 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
523 ParseErrorType error_type = kSyntaxError) {
524 Scanner::Location source_location = scanner()->location();
525 Traits::ReportMessageAt(source_location, message, arg, error_type);
528 void ReportMessageAt(Scanner::Location location,
529 MessageTemplate::Template message,
530 ParseErrorType error_type = kSyntaxError) {
531 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
535 void GetUnexpectedTokenMessage(
536 Token::Value token, MessageTemplate::Template* message, const char** arg,
537 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
539 void ReportUnexpectedToken(Token::Value token);
540 void ReportUnexpectedTokenAt(
541 Scanner::Location location, Token::Value token,
542 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
545 void ReportClassifierError(const ExpressionClassifier::Error& error) {
546 Traits::ReportMessageAt(error.location, error.message, error.arg,
550 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
551 if (!classifier->is_valid_expression()) {
552 ReportClassifierError(classifier->expression_error());
557 void ValidateFormalParameterInitializer(
558 const ExpressionClassifier* classifier, bool* ok) {
559 if (!classifier->is_valid_formal_parameter_initializer()) {
560 ReportClassifierError(classifier->formal_parameter_initializer_error());
565 void ValidateBindingPattern(const ExpressionClassifier* classifier,
567 if (!classifier->is_valid_binding_pattern()) {
568 ReportClassifierError(classifier->binding_pattern_error());
573 void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
575 if (!classifier->is_valid_assignment_pattern()) {
576 ReportClassifierError(classifier->assignment_pattern_error());
581 void ValidateFormalParameters(const ExpressionClassifier* classifier,
582 LanguageMode language_mode,
583 bool allow_duplicates, bool* ok) {
584 if (!allow_duplicates &&
585 !classifier->is_valid_formal_parameter_list_without_duplicates()) {
586 ReportClassifierError(classifier->duplicate_formal_parameter_error());
588 } else if (is_strict(language_mode) &&
589 !classifier->is_valid_strict_mode_formal_parameters()) {
590 ReportClassifierError(classifier->strict_mode_formal_parameter_error());
592 } else if (is_strong(language_mode) &&
593 !classifier->is_valid_strong_mode_formal_parameters()) {
594 ReportClassifierError(classifier->strong_mode_formal_parameter_error());
599 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
601 bool parenthesized_formals, bool* ok) {
602 if (classifier->is_valid_binding_pattern()) {
603 // A simple arrow formal parameter: IDENTIFIER => BODY.
604 if (!this->IsIdentifier(expr)) {
605 Traits::ReportMessageAt(scanner()->location(),
606 MessageTemplate::kUnexpectedToken,
607 Token::String(scanner()->current_token()));
610 } else if (!classifier->is_valid_arrow_formal_parameters()) {
611 // If after parsing the expr, we see an error but the expression is
612 // neither a valid binding pattern nor a valid parenthesized formal
613 // parameter list, show the "arrow formal parameters" error if the formals
614 // started with a parenthesis, and the binding pattern error otherwise.
615 const ExpressionClassifier::Error& error =
616 parenthesized_formals ? classifier->arrow_formal_parameters_error()
617 : classifier->binding_pattern_error();
618 ReportClassifierError(error);
623 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
624 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
626 GetUnexpectedTokenMessage(peek(), &message, &arg);
627 classifier->RecordExpressionError(scanner()->peek_location(), message, arg);
630 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
631 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
633 GetUnexpectedTokenMessage(peek(), &message, &arg);
634 classifier->RecordBindingPatternError(scanner()->peek_location(), message,
638 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
639 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
641 GetUnexpectedTokenMessage(peek(), &message, &arg);
642 classifier->RecordArrowFormalParametersError(scanner()->peek_location(),
646 void FormalParameterInitializerUnexpectedToken(
647 ExpressionClassifier* classifier) {
648 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
650 GetUnexpectedTokenMessage(peek(), &message, &arg);
651 classifier->RecordFormalParameterInitializerError(
652 scanner()->peek_location(), message, arg);
655 // Recursive descent functions:
657 // Parses an identifier that is valid for the current scope, in particular it
658 // fails on strict mode future reserved keywords in a strict scope. If
659 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
660 // "arguments" as identifier even in strict mode (this is needed in cases like
661 // "var foo = eval;").
662 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
663 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
665 // Parses an identifier or a strict mode future reserved word, and indicate
666 // whether it is strict mode future reserved.
667 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
669 IdentifierT ParseIdentifierName(bool* ok);
670 // Parses an identifier and determines whether or not it is 'get' or 'set'.
671 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
675 ExpressionT ParseRegExpLiteral(bool seen_equal,
676 ExpressionClassifier* classifier, bool* ok);
678 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
680 ExpressionT ParseExpression(bool accept_IN, bool* ok);
681 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
683 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
684 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
685 bool* is_static, bool* is_computed_name,
686 ExpressionClassifier* classifier, bool* ok);
687 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
688 ObjectLiteralPropertyT ParsePropertyDefinition(
689 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
690 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
691 ExpressionClassifier* classifier, bool* ok);
692 typename Traits::Type::ExpressionList ParseArguments(
693 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
695 ExpressionT ParseAssignmentExpression(bool accept_IN,
696 ExpressionClassifier* classifier,
698 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
699 ExpressionT ParseConditionalExpression(bool accept_IN,
700 ExpressionClassifier* classifier,
702 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
703 ExpressionClassifier* classifier, bool* ok);
704 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
705 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
707 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
709 ExpressionT ParseMemberWithNewPrefixesExpression(
710 ExpressionClassifier* classifier, bool* ok);
711 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
712 ExpressionT ParseMemberExpressionContinuation(
713 ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
714 ExpressionT ParseArrowFunctionLiteral(
715 const FormalParametersT& parameters,
716 const ExpressionClassifier& classifier, bool* ok);
717 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
718 ExpressionClassifier* classifier, bool* ok);
719 void AddTemplateExpression(ExpressionT);
720 ExpressionT ParseSuperExpression(bool is_new,
721 ExpressionClassifier* classifier, bool* ok);
722 ExpressionT ParseNewTargetExpression(bool* ok);
723 ExpressionT ParseStrongInitializationExpression(
724 ExpressionClassifier* classifier, bool* ok);
725 ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
728 void ParseFormalParameter(FormalParametersT* parameters,
729 ExpressionClassifier* classifier, bool* ok);
730 void ParseFormalParameterList(FormalParametersT* parameters,
731 ExpressionClassifier* classifier, bool* ok);
732 void CheckArityRestrictions(
733 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
734 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
736 bool IsNextLetKeyword();
738 // Checks if the expression is a valid reference expression (e.g., on the
739 // left-hand side of assignments). Although ruled out by ECMA as early errors,
740 // we allow calls for web compatibility and rewrite them to a runtime throw.
741 ExpressionT CheckAndRewriteReferenceExpression(
742 ExpressionT expression, int beg_pos, int end_pos,
743 MessageTemplate::Template message, bool* ok);
744 ExpressionT CheckAndRewriteReferenceExpression(
745 ExpressionT expression, int beg_pos, int end_pos,
746 MessageTemplate::Template message, ParseErrorType type, bool* ok);
748 // Used to validate property names in object literals and class literals
755 class ObjectLiteralCheckerBase {
757 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
759 virtual void CheckProperty(Token::Value property, PropertyKind type,
760 bool is_static, bool is_generator, bool* ok) = 0;
762 virtual ~ObjectLiteralCheckerBase() {}
765 ParserBase* parser() const { return parser_; }
766 Scanner* scanner() const { return parser_->scanner(); }
772 // Validation per ES6 object literals.
773 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
775 explicit ObjectLiteralChecker(ParserBase* parser)
776 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
778 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
779 bool is_generator, bool* ok) override;
782 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
784 bool has_seen_proto_;
787 // Validation per ES6 class literals.
788 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
790 explicit ClassLiteralChecker(ParserBase* parser)
791 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
793 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
794 bool is_generator, bool* ok) override;
797 bool IsConstructor() {
798 return this->scanner()->LiteralMatches("constructor", 11);
801 return this->scanner()->LiteralMatches("prototype", 9);
804 bool has_seen_constructor_;
807 // If true, the next (and immediately following) function literal is
808 // preceded by a parenthesis.
809 // Heuristically that means that the function will be called immediately,
810 // so never lazily compile it.
811 bool parenthesized_function_;
813 Scope* scope_; // Scope stack.
814 FunctionState* function_state_; // Function state stack.
815 v8::Extension* extension_;
816 FuncNameInferrer* fni_;
817 AstValueFactory* ast_value_factory_; // Not owned.
818 ParserRecorder* log_;
820 uintptr_t stack_limit_;
826 bool stack_overflow_;
830 bool allow_harmony_arrow_functions_;
831 bool allow_harmony_sloppy_;
832 bool allow_harmony_sloppy_function_;
833 bool allow_harmony_sloppy_let_;
834 bool allow_harmony_rest_parameters_;
835 bool allow_harmony_default_parameters_;
836 bool allow_harmony_spread_calls_;
837 bool allow_harmony_destructuring_;
838 bool allow_harmony_spread_arrays_;
839 bool allow_harmony_new_target_;
840 bool allow_strong_mode_;
841 bool allow_legacy_const_;
845 class PreParserIdentifier {
847 PreParserIdentifier() : type_(kUnknownIdentifier) {}
848 static PreParserIdentifier Default() {
849 return PreParserIdentifier(kUnknownIdentifier);
851 static PreParserIdentifier Eval() {
852 return PreParserIdentifier(kEvalIdentifier);
854 static PreParserIdentifier Arguments() {
855 return PreParserIdentifier(kArgumentsIdentifier);
857 static PreParserIdentifier Undefined() {
858 return PreParserIdentifier(kUndefinedIdentifier);
860 static PreParserIdentifier FutureReserved() {
861 return PreParserIdentifier(kFutureReservedIdentifier);
863 static PreParserIdentifier FutureStrictReserved() {
864 return PreParserIdentifier(kFutureStrictReservedIdentifier);
866 static PreParserIdentifier Let() {
867 return PreParserIdentifier(kLetIdentifier);
869 static PreParserIdentifier Static() {
870 return PreParserIdentifier(kStaticIdentifier);
872 static PreParserIdentifier Yield() {
873 return PreParserIdentifier(kYieldIdentifier);
875 static PreParserIdentifier Prototype() {
876 return PreParserIdentifier(kPrototypeIdentifier);
878 static PreParserIdentifier Constructor() {
879 return PreParserIdentifier(kConstructorIdentifier);
881 bool IsEval() const { return type_ == kEvalIdentifier; }
882 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
883 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
884 bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
885 bool IsLet() const { return type_ == kLetIdentifier; }
886 bool IsStatic() const { return type_ == kStaticIdentifier; }
887 bool IsYield() const { return type_ == kYieldIdentifier; }
888 bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
889 bool IsConstructor() const { return type_ == kConstructorIdentifier; }
890 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
891 bool IsFutureStrictReserved() const {
892 return type_ == kFutureStrictReservedIdentifier ||
893 type_ == kLetIdentifier || type_ == kStaticIdentifier ||
894 type_ == kYieldIdentifier;
897 // Allow identifier->name()[->length()] to work. The preparser
898 // does not need the actual positions/lengths of the identifiers.
899 const PreParserIdentifier* operator->() const { return this; }
900 const PreParserIdentifier raw_name() const { return *this; }
902 int position() const { return 0; }
903 int length() const { return 0; }
908 kFutureReservedIdentifier,
909 kFutureStrictReservedIdentifier,
914 kArgumentsIdentifier,
915 kUndefinedIdentifier,
916 kPrototypeIdentifier,
917 kConstructorIdentifier
920 explicit PreParserIdentifier(Type type) : type_(type) {}
923 friend class PreParserExpression;
927 class PreParserExpression {
929 static PreParserExpression Default() {
930 return PreParserExpression(TypeField::encode(kExpression));
933 static PreParserExpression Spread(PreParserExpression expression) {
934 return PreParserExpression(TypeField::encode(kSpreadExpression));
937 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
938 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
939 IdentifierTypeField::encode(id.type_));
942 static PreParserExpression BinaryOperation(PreParserExpression left,
944 PreParserExpression right) {
945 return PreParserExpression(
946 TypeField::encode(kBinaryOperationExpression) |
947 HasRestField::encode(op == Token::COMMA &&
948 right->IsSpreadExpression()));
951 static PreParserExpression StringLiteral() {
952 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
955 static PreParserExpression UseStrictStringLiteral() {
956 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
957 IsUseStrictField::encode(true));
960 static PreParserExpression UseStrongStringLiteral() {
961 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
962 IsUseStrongField::encode(true));
965 static PreParserExpression This() {
966 return PreParserExpression(TypeField::encode(kExpression) |
967 ExpressionTypeField::encode(kThisExpression));
970 static PreParserExpression ThisProperty() {
971 return PreParserExpression(
972 TypeField::encode(kExpression) |
973 ExpressionTypeField::encode(kThisPropertyExpression));
976 static PreParserExpression Property() {
977 return PreParserExpression(
978 TypeField::encode(kExpression) |
979 ExpressionTypeField::encode(kPropertyExpression));
982 static PreParserExpression Call() {
983 return PreParserExpression(TypeField::encode(kExpression) |
984 ExpressionTypeField::encode(kCallExpression));
987 static PreParserExpression SuperCallReference() {
988 return PreParserExpression(
989 TypeField::encode(kExpression) |
990 ExpressionTypeField::encode(kSuperCallReference));
993 static PreParserExpression NoTemplateTag() {
994 return PreParserExpression(
995 TypeField::encode(kExpression) |
996 ExpressionTypeField::encode(kNoTemplateTagExpression));
999 bool IsIdentifier() const {
1000 return TypeField::decode(code_) == kIdentifierExpression;
1003 PreParserIdentifier AsIdentifier() const {
1004 DCHECK(IsIdentifier());
1005 return PreParserIdentifier(IdentifierTypeField::decode(code_));
1008 bool IsStringLiteral() const {
1009 return TypeField::decode(code_) == kStringLiteralExpression;
1012 bool IsUseStrictLiteral() const {
1013 return TypeField::decode(code_) == kStringLiteralExpression &&
1014 IsUseStrictField::decode(code_);
1017 bool IsUseStrongLiteral() const {
1018 return TypeField::decode(code_) == kStringLiteralExpression &&
1019 IsUseStrongField::decode(code_);
1022 bool IsThis() const {
1023 return TypeField::decode(code_) == kExpression &&
1024 ExpressionTypeField::decode(code_) == kThisExpression;
1027 bool IsThisProperty() const {
1028 return TypeField::decode(code_) == kExpression &&
1029 ExpressionTypeField::decode(code_) == kThisPropertyExpression;
1032 bool IsProperty() const {
1033 return TypeField::decode(code_) == kExpression &&
1034 (ExpressionTypeField::decode(code_) == kPropertyExpression ||
1035 ExpressionTypeField::decode(code_) == kThisPropertyExpression);
1038 bool IsCall() const {
1039 return TypeField::decode(code_) == kExpression &&
1040 ExpressionTypeField::decode(code_) == kCallExpression;
1043 bool IsSuperCallReference() const {
1044 return TypeField::decode(code_) == kExpression &&
1045 ExpressionTypeField::decode(code_) == kSuperCallReference;
1048 bool IsValidReferenceExpression() const {
1049 return IsIdentifier() || IsProperty();
1052 // At the moment PreParser doesn't track these expression types.
1053 bool IsFunctionLiteral() const { return false; }
1054 bool IsCallNew() const { return false; }
1056 bool IsNoTemplateTag() const {
1057 return TypeField::decode(code_) == kExpression &&
1058 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
1061 bool IsSpreadExpression() const {
1062 return TypeField::decode(code_) == kSpreadExpression;
1065 bool IsArrowFunctionFormalParametersWithRestParameter() const {
1066 // Iff the expression classifier has determined that this expression is a
1067 // valid arrow fformal parameter list, return true if the formal parameter
1068 // list ends with a rest parameter.
1069 return IsSpreadExpression() ||
1070 (IsBinaryOperation() && HasRestField::decode(code_));
1073 PreParserExpression AsFunctionLiteral() { return *this; }
1075 bool IsBinaryOperation() const {
1076 return TypeField::decode(code_) == kBinaryOperationExpression;
1079 // Dummy implementation for making expression->somefunc() work in both Parser
1081 PreParserExpression* operator->() { return this; }
1083 // More dummy implementations of things PreParser doesn't need to track:
1084 void set_index(int index) {} // For YieldExpressions
1085 void set_should_eager_compile() {}
1087 int position() const { return RelocInfo::kNoPosition; }
1088 void set_function_token_position(int position) {}
1093 kIdentifierExpression,
1094 kStringLiteralExpression,
1095 kBinaryOperationExpression,
1099 enum ExpressionType {
1101 kThisPropertyExpression,
1102 kPropertyExpression,
1104 kSuperCallReference,
1105 kNoTemplateTagExpression
1108 explicit PreParserExpression(uint32_t expression_code)
1109 : code_(expression_code) {}
1111 // The first three bits are for the Type.
1112 typedef BitField<Type, 0, 3> TypeField;
1114 // The rest of the bits are interpreted depending on the value
1115 // of the Type field, so they can share the storage.
1116 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
1117 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
1118 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
1119 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
1120 IdentifierTypeField;
1121 typedef BitField<bool, TypeField::kNext, 1> HasRestField;
1127 // The pre-parser doesn't need to build lists of expressions, identifiers, or
1129 template <typename T>
1130 class PreParserList {
1132 // These functions make list->Add(some_expression) work (and do nothing).
1133 PreParserList() : length_(0) {}
1134 PreParserList* operator->() { return this; }
1135 void Add(T, void*) { ++length_; }
1136 int length() const { return length_; }
1142 typedef PreParserList<PreParserExpression> PreParserExpressionList;
1145 class PreParserStatement {
1147 static PreParserStatement Default() {
1148 return PreParserStatement(kUnknownStatement);
1151 static PreParserStatement Jump() {
1152 return PreParserStatement(kJumpStatement);
1155 static PreParserStatement FunctionDeclaration() {
1156 return PreParserStatement(kFunctionDeclaration);
1159 // Creates expression statement from expression.
1160 // Preserves being an unparenthesized string literal, possibly
1162 static PreParserStatement ExpressionStatement(
1163 PreParserExpression expression) {
1164 if (expression.IsUseStrictLiteral()) {
1165 return PreParserStatement(kUseStrictExpressionStatement);
1167 if (expression.IsUseStrongLiteral()) {
1168 return PreParserStatement(kUseStrongExpressionStatement);
1170 if (expression.IsStringLiteral()) {
1171 return PreParserStatement(kStringLiteralExpressionStatement);
1176 bool IsStringLiteral() {
1177 return code_ == kStringLiteralExpressionStatement;
1180 bool IsUseStrictLiteral() {
1181 return code_ == kUseStrictExpressionStatement;
1184 bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
1186 bool IsFunctionDeclaration() {
1187 return code_ == kFunctionDeclaration;
1190 bool IsJumpStatement() {
1191 return code_ == kJumpStatement;
1198 kStringLiteralExpressionStatement,
1199 kUseStrictExpressionStatement,
1200 kUseStrongExpressionStatement,
1201 kFunctionDeclaration
1204 explicit PreParserStatement(Type code) : code_(code) {}
1209 typedef PreParserList<PreParserStatement> PreParserStatementList;
1212 class PreParserFactory {
1214 explicit PreParserFactory(void* unused_value_factory) {}
1215 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
1217 return PreParserExpression::Default();
1219 PreParserExpression NewNumberLiteral(double number,
1221 return PreParserExpression::Default();
1223 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
1224 PreParserIdentifier js_flags,
1228 return PreParserExpression::Default();
1230 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1234 return PreParserExpression::Default();
1236 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1237 int first_spread_index, int literal_index,
1238 bool is_strong, int pos) {
1239 return PreParserExpression::Default();
1241 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1242 PreParserExpression value,
1243 ObjectLiteralProperty::Kind kind,
1245 bool is_computed_name) {
1246 return PreParserExpression::Default();
1248 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1249 PreParserExpression value,
1251 bool is_computed_name) {
1252 return PreParserExpression::Default();
1254 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
1256 int boilerplate_properties,
1260 return PreParserExpression::Default();
1262 PreParserExpression NewVariableProxy(void* variable) {
1263 return PreParserExpression::Default();
1265 PreParserExpression NewProperty(PreParserExpression obj,
1266 PreParserExpression key,
1269 return PreParserExpression::ThisProperty();
1271 return PreParserExpression::Property();
1273 PreParserExpression NewUnaryOperation(Token::Value op,
1274 PreParserExpression expression,
1276 return PreParserExpression::Default();
1278 PreParserExpression NewBinaryOperation(Token::Value op,
1279 PreParserExpression left,
1280 PreParserExpression right, int pos) {
1281 return PreParserExpression::BinaryOperation(left, op, right);
1283 PreParserExpression NewCompareOperation(Token::Value op,
1284 PreParserExpression left,
1285 PreParserExpression right, int pos) {
1286 return PreParserExpression::Default();
1288 PreParserExpression NewAssignment(Token::Value op,
1289 PreParserExpression left,
1290 PreParserExpression right,
1292 return PreParserExpression::Default();
1294 PreParserExpression NewYield(PreParserExpression generator_object,
1295 PreParserExpression expression,
1296 Yield::Kind yield_kind,
1298 return PreParserExpression::Default();
1300 PreParserExpression NewConditional(PreParserExpression condition,
1301 PreParserExpression then_expression,
1302 PreParserExpression else_expression,
1304 return PreParserExpression::Default();
1306 PreParserExpression NewCountOperation(Token::Value op,
1308 PreParserExpression expression,
1310 return PreParserExpression::Default();
1312 PreParserExpression NewCall(PreParserExpression expression,
1313 PreParserExpressionList arguments,
1315 return PreParserExpression::Call();
1317 PreParserExpression NewCallNew(PreParserExpression expression,
1318 PreParserExpressionList arguments,
1320 return PreParserExpression::Default();
1322 PreParserExpression NewCallRuntime(const AstRawString* name,
1323 const Runtime::Function* function,
1324 PreParserExpressionList arguments,
1326 return PreParserExpression::Default();
1328 PreParserStatement NewReturnStatement(PreParserExpression expression,
1330 return PreParserStatement::Default();
1332 PreParserExpression NewFunctionLiteral(
1333 PreParserIdentifier name, AstValueFactory* ast_value_factory,
1334 Scope* scope, PreParserStatementList body, int materialized_literal_count,
1335 int expected_property_count, int parameter_count,
1336 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1337 FunctionLiteral::FunctionType function_type,
1338 FunctionLiteral::IsFunctionFlag is_function,
1339 FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
1341 return PreParserExpression::Default();
1344 PreParserExpression NewSpread(PreParserExpression expression, int pos) {
1345 return PreParserExpression::Spread(expression);
1348 PreParserExpression NewEmptyParentheses(int pos) {
1349 return PreParserExpression::Default();
1352 // Return the object itself as AstVisitor and implement the needed
1353 // dummy method right in this class.
1354 PreParserFactory* visitor() { return this; }
1355 int* ast_properties() {
1356 static int dummy = 42;
1362 struct PreParserFormalParameters : FormalParametersBase {
1363 explicit PreParserFormalParameters(Scope* scope)
1364 : FormalParametersBase(scope) {}
1367 int Arity() const { return arity; }
1368 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
1374 class PreParserTraits {
1377 // TODO(marja): To be removed. The Traits object should contain all the data
1379 typedef PreParser* Parser;
1381 // PreParser doesn't need to store generator variables.
1382 typedef void GeneratorVariable;
1384 typedef int AstProperties;
1386 // Return types for traversing functions.
1387 typedef PreParserIdentifier Identifier;
1388 typedef PreParserExpression Expression;
1389 typedef PreParserExpression YieldExpression;
1390 typedef PreParserExpression FunctionLiteral;
1391 typedef PreParserExpression ClassLiteral;
1392 typedef PreParserExpression ObjectLiteralProperty;
1393 typedef PreParserExpression Literal;
1394 typedef PreParserExpressionList ExpressionList;
1395 typedef PreParserExpressionList PropertyList;
1396 typedef PreParserIdentifier FormalParameter;
1397 typedef PreParserFormalParameters FormalParameters;
1398 typedef PreParserStatementList StatementList;
1400 // For constructing objects returned by the traversing functions.
1401 typedef PreParserFactory Factory;
1404 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
1406 // Helper functions for recursive descent.
1407 static bool IsEval(PreParserIdentifier identifier) {
1408 return identifier.IsEval();
1411 static bool IsArguments(PreParserIdentifier identifier) {
1412 return identifier.IsArguments();
1415 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
1416 return identifier.IsEvalOrArguments();
1419 static bool IsUndefined(PreParserIdentifier identifier) {
1420 return identifier.IsUndefined();
1423 static bool IsPrototype(PreParserIdentifier identifier) {
1424 return identifier.IsPrototype();
1427 static bool IsConstructor(PreParserIdentifier identifier) {
1428 return identifier.IsConstructor();
1431 // Returns true if the expression is of type "this.foo".
1432 static bool IsThisProperty(PreParserExpression expression) {
1433 return expression.IsThisProperty();
1436 static bool IsIdentifier(PreParserExpression expression) {
1437 return expression.IsIdentifier();
1440 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
1441 return expression.AsIdentifier();
1444 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1445 return identifier.IsFutureStrictReserved();
1448 static bool IsBoilerplateProperty(PreParserExpression property) {
1449 // PreParser doesn't count boilerplate properties.
1453 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
1457 static PreParserExpression GetPropertyValue(PreParserExpression property) {
1458 return PreParserExpression::Default();
1461 // Functions for encapsulating the differences between parsing and preparsing;
1462 // operations interleaved with the recursive descent.
1463 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1464 // PreParser should not use FuncNameInferrer.
1468 static void PushPropertyName(FuncNameInferrer* fni,
1469 PreParserExpression expression) {
1470 // PreParser should not use FuncNameInferrer.
1474 static void InferFunctionName(FuncNameInferrer* fni,
1475 PreParserExpression expression) {
1476 // PreParser should not use FuncNameInferrer.
1480 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
1481 Scope* scope, PreParserExpression property, bool* has_function) {}
1483 static void CheckAssigningFunctionLiteralToProperty(
1484 PreParserExpression left, PreParserExpression right) {}
1486 static void CheckPossibleEvalCall(PreParserExpression expression,
1488 if (IsIdentifier(expression) && IsEval(AsIdentifier(expression))) {
1489 scope->DeclarationScope()->RecordEvalCall();
1490 scope->RecordEvalCall();
1494 static PreParserExpression MarkExpressionAsAssigned(
1495 PreParserExpression expression) {
1496 // TODO(marja): To be able to produce the same errors, the preparser needs
1497 // to start tracking which expressions are variables and which are assigned.
1501 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
1502 PreParserExpression y,
1505 PreParserFactory* factory) {
1509 PreParserExpression BuildUnaryExpression(PreParserExpression expression,
1510 Token::Value op, int pos,
1511 PreParserFactory* factory) {
1512 return PreParserExpression::Default();
1515 PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
1517 return PreParserExpression::Default();
1519 PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
1520 Handle<Object> arg, int pos) {
1521 return PreParserExpression::Default();
1523 PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
1524 Handle<Object> arg, int pos) {
1525 return PreParserExpression::Default();
1528 // Reporting errors.
1529 void ReportMessageAt(Scanner::Location location,
1530 MessageTemplate::Template message,
1531 const char* arg = NULL,
1532 ParseErrorType error_type = kSyntaxError);
1533 void ReportMessageAt(int start_pos, int end_pos,
1534 MessageTemplate::Template message,
1535 const char* arg = NULL,
1536 ParseErrorType error_type = kSyntaxError);
1538 // "null" return type creators.
1539 static PreParserIdentifier EmptyIdentifier() {
1540 return PreParserIdentifier::Default();
1542 static PreParserIdentifier EmptyIdentifierString() {
1543 return PreParserIdentifier::Default();
1545 static PreParserExpression EmptyExpression() {
1546 return PreParserExpression::Default();
1548 static PreParserExpression EmptyLiteral() {
1549 return PreParserExpression::Default();
1551 static PreParserExpression EmptyObjectLiteralProperty() {
1552 return PreParserExpression::Default();
1554 static PreParserExpression EmptyFunctionLiteral() {
1555 return PreParserExpression::Default();
1557 static PreParserExpressionList NullExpressionList() {
1558 return PreParserExpressionList();
1561 // Odd-ball literal creators.
1562 static PreParserExpression GetLiteralTheHole(int position,
1563 PreParserFactory* factory) {
1564 return PreParserExpression::Default();
1567 // Producing data during the recursive descent.
1568 PreParserIdentifier GetSymbol(Scanner* scanner);
1569 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
1571 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1572 return PreParserIdentifier::Default();
1575 static PreParserExpression ThisExpression(Scope* scope,
1576 PreParserFactory* factory,
1578 return PreParserExpression::This();
1581 static PreParserExpression SuperPropertyReference(Scope* scope,
1582 PreParserFactory* factory,
1584 return PreParserExpression::Default();
1587 static PreParserExpression SuperCallReference(Scope* scope,
1588 PreParserFactory* factory,
1590 return PreParserExpression::SuperCallReference();
1593 static PreParserExpression NewTargetExpression(Scope* scope,
1594 PreParserFactory* factory,
1596 return PreParserExpression::Default();
1599 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
1600 int pos, int end_pos) {
1601 return PreParserExpression::Default();
1604 static PreParserExpression ExpressionFromLiteral(
1605 Token::Value token, int pos, Scanner* scanner,
1606 PreParserFactory* factory) {
1607 return PreParserExpression::Default();
1610 static PreParserExpression ExpressionFromIdentifier(
1611 PreParserIdentifier name, int start_position, int end_position,
1612 Scope* scope, PreParserFactory* factory) {
1613 return PreParserExpression::FromIdentifier(name);
1616 PreParserExpression ExpressionFromString(int pos,
1618 PreParserFactory* factory = NULL);
1620 PreParserExpression GetIterator(PreParserExpression iterable,
1621 PreParserFactory* factory) {
1622 return PreParserExpression::Default();
1625 static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
1626 return PreParserExpressionList();
1629 static PreParserStatementList NewStatementList(int size, Zone* zone) {
1630 return PreParserStatementList();
1633 static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
1634 return PreParserExpressionList();
1637 static void AddParameterInitializationBlock(
1638 const PreParserFormalParameters& parameters,
1639 PreParserStatementList list, bool* ok) {}
1641 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1642 int* expected_property_count, bool* ok) {
1646 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1647 PreParserIdentifier function_name, int pos,
1648 const PreParserFormalParameters& parameters, FunctionKind kind,
1649 FunctionLiteral::FunctionType function_type, bool* ok);
1651 V8_INLINE void ParseArrowFunctionFormalParameterList(
1652 PreParserFormalParameters* parameters,
1653 PreParserExpression expression, const Scanner::Location& params_loc,
1654 Scanner::Location* duplicate_loc, bool* ok);
1656 void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
1658 struct TemplateLiteralState {};
1660 TemplateLiteralState OpenTemplateLiteral(int pos) {
1661 return TemplateLiteralState();
1663 void AddTemplateSpan(TemplateLiteralState*, bool) {}
1664 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
1665 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
1666 PreParserExpression tag) {
1667 if (IsTaggedTemplate(tag)) {
1668 // Emulate generation of array literals for tag callsite
1669 // 1st is array of cooked strings, second is array of raw strings
1670 MaterializeTemplateCallsiteLiterals();
1672 return EmptyExpression();
1674 inline void MaterializeTemplateCallsiteLiterals();
1675 PreParserExpression NoTemplateTag() {
1676 return PreParserExpression::NoTemplateTag();
1678 static bool IsTaggedTemplate(const PreParserExpression tag) {
1679 return !tag.IsNoTemplateTag();
1682 void AddFormalParameter(
1683 PreParserFormalParameters* parameters, PreParserExpression pattern,
1684 PreParserExpression initializer, bool is_rest) {
1685 ++parameters->arity;
1687 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
1688 ExpressionClassifier* classifier) {
1689 if (!classifier->is_simple_parameter_list()) {
1690 scope->SetHasNonSimpleParameters();
1694 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
1696 // Temporary glue; these functions will move to ParserBase.
1697 PreParserExpression ParseV8Intrinsic(bool* ok);
1698 PreParserExpression ParseFunctionLiteral(
1699 PreParserIdentifier name, Scanner::Location function_name_location,
1700 FunctionNameValidity function_name_validity, FunctionKind kind,
1701 int function_token_position, FunctionLiteral::FunctionType type,
1702 FunctionLiteral::ArityRestriction arity_restriction,
1703 LanguageMode language_mode, bool* ok);
1705 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1706 Scanner::Location class_name_location,
1707 bool name_is_strict_reserved, int pos,
1710 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
1714 inline void MaterializeUnspreadArgumentsLiterals(int count);
1716 inline PreParserExpression SpreadCall(PreParserExpression function,
1717 PreParserExpressionList args, int pos);
1719 inline PreParserExpression SpreadCallNew(PreParserExpression function,
1720 PreParserExpressionList args,
1724 PreParser* pre_parser_;
1728 // Preparsing checks a JavaScript program and emits preparse-data that helps
1729 // a later parsing to be faster.
1730 // See preparse-data-format.h for the data format.
1732 // The PreParser checks that the syntax follows the grammar for JavaScript,
1733 // and collects some information about the program along the way.
1734 // The grammar check is only performed in order to understand the program
1735 // sufficiently to deduce some information about it, that can be used
1736 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
1737 // rather it is to speed up properly written and correct programs.
1738 // That means that contextual checks (like a label being declared where
1739 // it is used) are generally omitted.
1740 class PreParser : public ParserBase<PreParserTraits> {
1742 typedef PreParserIdentifier Identifier;
1743 typedef PreParserExpression Expression;
1744 typedef PreParserStatement Statement;
1746 enum PreParseResult {
1747 kPreParseStackOverflow,
1751 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
1752 ParserRecorder* log, uintptr_t stack_limit)
1753 : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
1754 ast_value_factory, log, this) {}
1756 // Pre-parse the program from the character stream; returns true on
1757 // success (even if parsing failed, the pre-parse data successfully
1758 // captured the syntax error), and false if a stack-overflow happened
1760 PreParseResult PreParseProgram(int* materialized_literals = 0) {
1761 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1762 PreParserFactory factory(NULL);
1763 FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
1766 int start_position = scanner()->peek_location().beg_pos;
1767 ParseStatementList(Token::EOS, &ok);
1768 if (stack_overflow()) return kPreParseStackOverflow;
1770 ReportUnexpectedToken(scanner()->current_token());
1771 } else if (is_strict(scope_->language_mode())) {
1772 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
1775 if (materialized_literals) {
1776 *materialized_literals = function_state_->materialized_literal_count();
1778 return kPreParseSuccess;
1781 // Parses a single function literal, from the opening parentheses before
1782 // parameters to the closing brace after the body.
1783 // Returns a FunctionEntry describing the body of the function in enough
1784 // detail that it can be lazily compiled.
1785 // The scanner is expected to have matched the "function" or "function*"
1786 // keyword and parameters, and have consumed the initial '{'.
1787 // At return, unless an error occurred, the scanner is positioned before the
1789 PreParseResult PreParseLazyFunction(
1790 LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
1791 ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr);
1794 friend class PreParserTraits;
1796 static const int kLazyParseTrialLimit = 200;
1798 // These types form an algebra over syntactic categories that is just
1799 // rich enough to let us recognize and propagate the constructs that
1800 // are either being counted in the preparser data, or is important
1801 // to throw the correct syntax error exceptions.
1803 // All ParseXXX functions take as the last argument an *ok parameter
1804 // which is set to false if parsing failed; it is unchanged otherwise.
1805 // By making the 'exception handling' explicit, we are forced to check
1806 // for failure at the call sites.
1807 Statement ParseStatementListItem(bool* ok);
1808 void ParseStatementList(int end_token, bool* ok,
1809 Scanner::BookmarkScope* bookmark = nullptr);
1810 Statement ParseStatement(bool* ok);
1811 Statement ParseSubStatement(bool* ok);
1812 Statement ParseFunctionDeclaration(bool* ok);
1813 Statement ParseClassDeclaration(bool* ok);
1814 Statement ParseBlock(bool* ok);
1815 Statement ParseVariableStatement(VariableDeclarationContext var_context,
1817 Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1819 Scanner::Location* first_initializer_loc,
1820 Scanner::Location* bindings_loc,
1822 Statement ParseExpressionOrLabelledStatement(bool* ok);
1823 Statement ParseIfStatement(bool* ok);
1824 Statement ParseContinueStatement(bool* ok);
1825 Statement ParseBreakStatement(bool* ok);
1826 Statement ParseReturnStatement(bool* ok);
1827 Statement ParseWithStatement(bool* ok);
1828 Statement ParseSwitchStatement(bool* ok);
1829 Statement ParseDoWhileStatement(bool* ok);
1830 Statement ParseWhileStatement(bool* ok);
1831 Statement ParseForStatement(bool* ok);
1832 Statement ParseThrowStatement(bool* ok);
1833 Statement ParseTryStatement(bool* ok);
1834 Statement ParseDebuggerStatement(bool* ok);
1835 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1836 Expression ParseObjectLiteral(bool* ok);
1837 Expression ParseV8Intrinsic(bool* ok);
1839 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1840 int* expected_property_count, bool* ok);
1841 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1842 PreParserIdentifier function_name, int pos,
1843 const PreParserFormalParameters& parameters, FunctionKind kind,
1844 FunctionLiteral::FunctionType function_type, bool* ok);
1846 Expression ParseFunctionLiteral(
1847 Identifier name, Scanner::Location function_name_location,
1848 FunctionNameValidity function_name_validity, FunctionKind kind,
1849 int function_token_pos, FunctionLiteral::FunctionType function_type,
1850 FunctionLiteral::ArityRestriction arity_restriction,
1851 LanguageMode language_mode, bool* ok);
1852 void ParseLazyFunctionLiteralBody(bool* ok,
1853 Scanner::BookmarkScope* bookmark = nullptr);
1855 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1856 Scanner::Location class_name_location,
1857 bool name_is_strict_reserved, int pos,
1862 void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1863 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1864 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1868 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
1869 for (int i = 0; i < count; ++i) {
1870 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1875 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
1876 PreParserExpressionList args,
1878 return pre_parser_->factory()->NewCall(function, args, pos);
1881 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1882 PreParserExpressionList args,
1884 return pre_parser_->factory()->NewCallNew(function, args, pos);
1888 void PreParserTraits::ParseArrowFunctionFormalParameterList(
1889 PreParserFormalParameters* parameters,
1890 PreParserExpression params, const Scanner::Location& params_loc,
1891 Scanner::Location* duplicate_loc, bool* ok) {
1892 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1893 // lists that are too long.
1895 // Accomodate array literal for rest parameter.
1896 if (params.IsArrowFunctionFormalParametersWithRestParameter()) {
1897 ++parameters->materialized_literals_count;
1898 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1903 PreParserStatementList PreParser::ParseEagerFunctionBody(
1904 PreParserIdentifier function_name, int pos,
1905 const PreParserFormalParameters& parameters, FunctionKind kind,
1906 FunctionLiteral::FunctionType function_type, bool* ok) {
1907 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1909 ParseStatementList(Token::RBRACE, ok);
1910 if (!*ok) return PreParserStatementList();
1912 Expect(Token::RBRACE, ok);
1913 return PreParserStatementList();
1917 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1918 PreParserIdentifier function_name, int pos,
1919 const PreParserFormalParameters& parameters, FunctionKind kind,
1920 FunctionLiteral::FunctionType function_type, bool* ok) {
1921 return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
1922 kind, function_type, ok);
1926 template <class Traits>
1927 ParserBase<Traits>::FunctionState::FunctionState(
1928 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1929 FunctionKind kind, typename Traits::Type::Factory* factory)
1930 : next_materialized_literal_index_(0),
1931 expected_property_count_(0),
1932 this_location_(Scanner::Location::invalid()),
1933 return_location_(Scanner::Location::invalid()),
1934 super_location_(Scanner::Location::invalid()),
1936 generator_object_variable_(NULL),
1937 function_state_stack_(function_state_stack),
1938 outer_function_state_(*function_state_stack),
1939 scope_stack_(scope_stack),
1940 outer_scope_(*scope_stack),
1942 *scope_stack_ = scope;
1943 *function_state_stack = this;
1947 template <class Traits>
1948 ParserBase<Traits>::FunctionState::~FunctionState() {
1949 *scope_stack_ = outer_scope_;
1950 *function_state_stack_ = outer_function_state_;
1954 template <class Traits>
1955 void ParserBase<Traits>::GetUnexpectedTokenMessage(
1956 Token::Value token, MessageTemplate::Template* message, const char** arg,
1957 MessageTemplate::Template default_) {
1958 // Four of the tokens are treated specially
1961 *message = MessageTemplate::kUnexpectedEOS;
1966 *message = MessageTemplate::kUnexpectedTokenNumber;
1970 *message = MessageTemplate::kUnexpectedTokenString;
1973 case Token::IDENTIFIER:
1974 *message = MessageTemplate::kUnexpectedTokenIdentifier;
1977 case Token::FUTURE_RESERVED_WORD:
1978 *message = MessageTemplate::kUnexpectedReserved;
1984 case Token::FUTURE_STRICT_RESERVED_WORD:
1985 *message = is_strict(language_mode())
1986 ? MessageTemplate::kUnexpectedStrictReserved
1987 : MessageTemplate::kUnexpectedTokenIdentifier;
1990 case Token::TEMPLATE_SPAN:
1991 case Token::TEMPLATE_TAIL:
1992 *message = MessageTemplate::kUnexpectedTemplateString;
1996 const char* name = Token::String(token);
1997 DCHECK(name != NULL);
2004 template <class Traits>
2005 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
2006 return ReportUnexpectedTokenAt(scanner_->location(), token);
2010 template <class Traits>
2011 void ParserBase<Traits>::ReportUnexpectedTokenAt(
2012 Scanner::Location source_location, Token::Value token,
2013 MessageTemplate::Template message) {
2015 GetUnexpectedTokenMessage(token, &message, &arg);
2016 Traits::ReportMessageAt(source_location, message, arg);
2020 template <class Traits>
2021 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
2022 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
2023 ExpressionClassifier classifier;
2024 auto result = ParseAndClassifyIdentifier(&classifier, ok);
2025 if (!*ok) return Traits::EmptyIdentifier();
2027 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
2028 ValidateAssignmentPattern(&classifier, ok);
2029 if (!*ok) return Traits::EmptyIdentifier();
2030 ValidateBindingPattern(&classifier, ok);
2031 if (!*ok) return Traits::EmptyIdentifier();
2033 ValidateExpression(&classifier, ok);
2034 if (!*ok) return Traits::EmptyIdentifier();
2041 template <class Traits>
2042 typename ParserBase<Traits>::IdentifierT
2043 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
2045 Token::Value next = Next();
2046 if (next == Token::IDENTIFIER) {
2047 IdentifierT name = this->GetSymbol(scanner());
2048 // When this function is used to read a formal parameter, we don't always
2049 // know whether the function is going to be strict or sloppy. Indeed for
2050 // arrow functions we don't always know that the identifier we are reading
2051 // is actually a formal parameter. Therefore besides the errors that we
2052 // must detect because we know we're in strict mode, we also record any
2053 // error that we might make in the future once we know the language mode.
2054 if (this->IsEval(name)) {
2055 classifier->RecordStrictModeFormalParameterError(
2056 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2057 if (is_strict(language_mode())) {
2058 classifier->RecordBindingPatternError(
2059 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2062 if (this->IsArguments(name)) {
2063 scope_->RecordArgumentsUsage();
2064 classifier->RecordStrictModeFormalParameterError(
2065 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2066 if (is_strict(language_mode())) {
2067 classifier->RecordBindingPatternError(
2068 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2070 if (is_strong(language_mode())) {
2071 classifier->RecordExpressionError(scanner()->location(),
2072 MessageTemplate::kStrongArguments);
2075 if (this->IsUndefined(name)) {
2076 classifier->RecordStrongModeFormalParameterError(
2077 scanner()->location(), MessageTemplate::kStrongUndefined);
2078 if (is_strong(language_mode())) {
2079 // TODO(dslomov): allow 'undefined' in nested patterns.
2080 classifier->RecordBindingPatternError(
2081 scanner()->location(), MessageTemplate::kStrongUndefined);
2082 classifier->RecordAssignmentPatternError(
2083 scanner()->location(), MessageTemplate::kStrongUndefined);
2087 if (classifier->duplicate_finder() != nullptr &&
2088 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2089 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2092 } else if (is_sloppy(language_mode()) &&
2093 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
2094 next == Token::LET || next == Token::STATIC ||
2095 (next == Token::YIELD && !is_generator()))) {
2096 classifier->RecordStrictModeFormalParameterError(
2097 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
2098 return this->GetSymbol(scanner());
2100 this->ReportUnexpectedToken(next);
2102 return Traits::EmptyIdentifier();
2107 template <class Traits>
2108 typename ParserBase<Traits>::IdentifierT ParserBase<
2109 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
2111 Token::Value next = Next();
2112 if (next == Token::IDENTIFIER) {
2113 *is_strict_reserved = false;
2114 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
2115 next == Token::STATIC ||
2116 (next == Token::YIELD && !this->is_generator())) {
2117 *is_strict_reserved = true;
2119 ReportUnexpectedToken(next);
2121 return Traits::EmptyIdentifier();
2124 IdentifierT name = this->GetSymbol(scanner());
2125 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
2130 template <class Traits>
2131 typename ParserBase<Traits>::IdentifierT
2132 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
2133 Token::Value next = Next();
2134 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
2135 next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
2136 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
2137 this->ReportUnexpectedToken(next);
2139 return Traits::EmptyIdentifier();
2142 IdentifierT name = this->GetSymbol(scanner());
2143 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
2148 template <class Traits>
2149 typename ParserBase<Traits>::IdentifierT
2150 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
2153 IdentifierT result = ParseIdentifierName(ok);
2154 if (!*ok) return Traits::EmptyIdentifier();
2155 scanner()->IsGetOrSet(is_get, is_set);
2160 template <class Traits>
2161 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
2162 bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
2163 int pos = peek_position();
2164 if (!scanner()->ScanRegExpPattern(seen_equal)) {
2166 ReportMessage(MessageTemplate::kUnterminatedRegExp);
2168 return Traits::EmptyExpression();
2171 int literal_index = function_state_->NextMaterializedLiteralIndex();
2173 IdentifierT js_pattern = this->GetNextSymbol(scanner());
2174 if (!scanner()->ScanRegExpFlags()) {
2176 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
2178 return Traits::EmptyExpression();
2180 IdentifierT js_flags = this->GetNextSymbol(scanner());
2182 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index,
2183 is_strong(language_mode()), pos);
2187 #define CHECK_OK ok); \
2188 if (!*ok) return this->EmptyExpression(); \
2190 #define DUMMY ) // to make indentation work
2193 // Used in functions where the return type is not ExpressionT.
2194 #define CHECK_OK_CUSTOM(x) ok); \
2195 if (!*ok) return this->x(); \
2197 #define DUMMY ) // to make indentation work
2201 template <class Traits>
2202 typename ParserBase<Traits>::ExpressionT
2203 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
2205 // PrimaryExpression ::
2217 // '(' Expression ')'
2220 int beg_pos = scanner()->peek_location().beg_pos;
2221 int end_pos = scanner()->peek_location().end_pos;
2222 ExpressionT result = this->EmptyExpression();
2223 Token::Value token = peek();
2226 BindingPatternUnexpectedToken(classifier);
2227 Consume(Token::THIS);
2228 if (FLAG_strong_this && is_strong(language_mode())) {
2229 // Constructors' usages of 'this' in strong mode are parsed separately.
2230 // TODO(rossberg): this does not work with arrow functions yet.
2231 if (IsClassConstructor(function_state_->kind())) {
2232 ReportMessage(MessageTemplate::kStrongConstructorThis);
2237 result = this->ThisExpression(scope_, factory(), beg_pos);
2241 case Token::NULL_LITERAL:
2242 case Token::TRUE_LITERAL:
2243 case Token::FALSE_LITERAL:
2244 BindingPatternUnexpectedToken(classifier);
2247 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2251 classifier->RecordBindingPatternError(
2252 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
2255 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2258 case Token::IDENTIFIER:
2262 case Token::FUTURE_STRICT_RESERVED_WORD: {
2263 // Using eval or arguments in this context is OK even in strict mode.
2264 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
2265 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
2270 case Token::STRING: {
2271 classifier->RecordBindingPatternError(
2272 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString);
2273 Consume(Token::STRING);
2274 result = this->ExpressionFromString(beg_pos, scanner(), factory());
2278 case Token::ASSIGN_DIV:
2279 classifier->RecordBindingPatternError(
2280 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
2281 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK);
2285 classifier->RecordBindingPatternError(
2286 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
2287 result = this->ParseRegExpLiteral(false, classifier, CHECK_OK);
2291 if (!allow_harmony_destructuring()) {
2292 BindingPatternUnexpectedToken(classifier);
2294 result = this->ParseArrayLiteral(classifier, CHECK_OK);
2298 if (!allow_harmony_destructuring()) {
2299 BindingPatternUnexpectedToken(classifier);
2301 result = this->ParseObjectLiteral(classifier, CHECK_OK);
2305 // Arrow function formal parameters are either a single identifier or a
2306 // list of BindingPattern productions enclosed in parentheses.
2307 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
2308 // is_valid_binding_pattern() check to detect multiple levels of
2309 // parenthesization.
2310 if (!classifier->is_valid_binding_pattern()) {
2311 ArrowFormalParametersUnexpectedToken(classifier);
2313 BindingPatternUnexpectedToken(classifier);
2314 Consume(Token::LPAREN);
2315 if (Check(Token::RPAREN)) {
2316 // ()=>x. The continuation that looks for the => is in
2317 // ParseAssignmentExpression.
2318 classifier->RecordExpressionError(scanner()->location(),
2319 MessageTemplate::kUnexpectedToken,
2320 Token::String(Token::RPAREN));
2321 classifier->RecordBindingPatternError(scanner()->location(),
2322 MessageTemplate::kUnexpectedToken,
2323 Token::String(Token::RPAREN));
2324 result = factory()->NewEmptyParentheses(beg_pos);
2325 } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
2326 // (...x)=>x. The continuation that looks for the => is in
2327 // ParseAssignmentExpression.
2328 int ellipsis_pos = scanner()->location().beg_pos;
2329 classifier->RecordExpressionError(scanner()->location(),
2330 MessageTemplate::kUnexpectedToken,
2331 Token::String(Token::ELLIPSIS));
2332 classifier->RecordNonSimpleParameter();
2333 Scanner::Location expr_loc = scanner()->peek_location();
2334 Token::Value tok = peek();
2335 result = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2336 // Patterns are not allowed as rest parameters. There is no way we can
2337 // succeed so go ahead and use the convenient ReportUnexpectedToken
2339 if (!Traits::IsIdentifier(result)) {
2340 ReportUnexpectedTokenAt(expr_loc, tok);
2342 return this->EmptyExpression();
2344 result = factory()->NewSpread(result, ellipsis_pos);
2346 if (peek() == Token::COMMA) {
2347 ReportMessageAt(scanner()->peek_location(),
2348 MessageTemplate::kParamAfterRest);
2350 return this->EmptyExpression();
2352 Expect(Token::RPAREN, CHECK_OK);
2354 // Heuristically try to detect immediately called functions before
2355 // seeing the call parentheses.
2356 parenthesized_function_ = (peek() == Token::FUNCTION);
2357 result = this->ParseExpression(true, classifier, CHECK_OK);
2358 Expect(Token::RPAREN, CHECK_OK);
2362 case Token::CLASS: {
2363 BindingPatternUnexpectedToken(classifier);
2364 Consume(Token::CLASS);
2365 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2366 ReportMessage(MessageTemplate::kSloppyLexical);
2370 int class_token_position = position();
2371 IdentifierT name = this->EmptyIdentifier();
2372 bool is_strict_reserved_name = false;
2373 Scanner::Location class_name_location = Scanner::Location::invalid();
2374 if (peek_any_identifier()) {
2375 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2377 class_name_location = scanner()->location();
2379 result = this->ParseClassLiteral(name, class_name_location,
2380 is_strict_reserved_name,
2381 class_token_position, CHECK_OK);
2385 case Token::TEMPLATE_SPAN:
2386 case Token::TEMPLATE_TAIL:
2387 classifier->RecordBindingPatternError(
2388 scanner()->peek_location(),
2389 MessageTemplate::kUnexpectedTemplateString);
2390 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
2391 classifier, CHECK_OK);
2395 if (allow_natives() || extension_ != NULL) {
2396 result = this->ParseV8Intrinsic(CHECK_OK);
2399 // If we're not allowing special syntax we fall-through to the
2404 ReportUnexpectedToken(token);
2413 template <class Traits>
2414 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2415 bool accept_IN, bool* ok) {
2416 ExpressionClassifier classifier;
2417 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
2418 ValidateExpression(&classifier, CHECK_OK);
2424 template <class Traits>
2425 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2426 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2428 // AssignmentExpression
2429 // Expression ',' AssignmentExpression
2431 ExpressionClassifier binding_classifier;
2432 ExpressionT result =
2433 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
2434 classifier->Accumulate(binding_classifier,
2435 ExpressionClassifier::AllProductions);
2436 bool is_simple_parameter_list = this->IsIdentifier(result);
2437 bool seen_rest = false;
2438 while (peek() == Token::COMMA) {
2440 // At this point the production can't possibly be valid, but we don't know
2441 // which error to signal.
2442 classifier->RecordArrowFormalParametersError(
2443 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2445 Consume(Token::COMMA);
2446 bool is_rest = false;
2447 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) {
2448 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2449 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2450 // valid expression or binding pattern.
2451 ExpressionUnexpectedToken(classifier);
2452 BindingPatternUnexpectedToken(classifier);
2453 Consume(Token::ELLIPSIS);
2454 seen_rest = is_rest = true;
2456 int pos = position();
2457 ExpressionT right = this->ParseAssignmentExpression(
2458 accept_IN, &binding_classifier, CHECK_OK);
2459 if (is_rest) right = factory()->NewSpread(right, pos);
2460 is_simple_parameter_list =
2461 is_simple_parameter_list && this->IsIdentifier(right);
2462 classifier->Accumulate(binding_classifier,
2463 ExpressionClassifier::AllProductions);
2464 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2466 if (!is_simple_parameter_list || seen_rest) {
2467 classifier->RecordNonSimpleParameter();
2473 template <class Traits>
2474 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2475 ExpressionClassifier* classifier, bool* ok) {
2477 // '[' Expression? (',' Expression?)* ']'
2479 int pos = peek_position();
2480 typename Traits::Type::ExpressionList values =
2481 this->NewExpressionList(4, zone_);
2482 int first_spread_index = -1;
2483 Expect(Token::LBRACK, CHECK_OK);
2484 while (peek() != Token::RBRACK) {
2485 bool seen_spread = false;
2486 ExpressionT elem = this->EmptyExpression();
2487 if (peek() == Token::COMMA) {
2488 if (is_strong(language_mode())) {
2489 ReportMessageAt(scanner()->peek_location(),
2490 MessageTemplate::kStrongEllision);
2492 return this->EmptyExpression();
2494 elem = this->GetLiteralTheHole(peek_position(), factory());
2495 } else if (peek() == Token::ELLIPSIS) {
2496 if (!allow_harmony_spread_arrays()) {
2497 ExpressionUnexpectedToken(classifier);
2499 int start_pos = peek_position();
2500 Consume(Token::ELLIPSIS);
2501 ExpressionT argument =
2502 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2503 elem = factory()->NewSpread(argument, start_pos);
2505 if (first_spread_index < 0) {
2506 first_spread_index = values->length();
2509 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2511 values->Add(elem, zone_);
2512 if (peek() != Token::RBRACK) {
2514 BindingPatternUnexpectedToken(classifier);
2516 Expect(Token::COMMA, CHECK_OK);
2519 Expect(Token::RBRACK, CHECK_OK);
2521 // Update the scope information before the pre-parsing bailout.
2522 int literal_index = function_state_->NextMaterializedLiteralIndex();
2524 return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
2525 is_strong(language_mode()), pos);
2529 template <class Traits>
2530 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2531 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2532 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
2533 Token::Value token = peek();
2534 int pos = peek_position();
2536 // For non computed property names we normalize the name a bit:
2541 // identifier -> "identifier"
2543 // This is important because we use the property name as a key in a hash
2544 // table when we compute constant properties.
2547 Consume(Token::STRING);
2548 *name = this->GetSymbol(scanner());
2552 Consume(Token::SMI);
2553 *name = this->GetNumberAsSymbol(scanner());
2557 Consume(Token::NUMBER);
2558 *name = this->GetNumberAsSymbol(scanner());
2561 case Token::LBRACK: {
2562 *is_computed_name = true;
2563 Consume(Token::LBRACK);
2564 ExpressionClassifier computed_name_classifier;
2565 ExpressionT expression =
2566 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
2567 classifier->Accumulate(computed_name_classifier,
2568 ExpressionClassifier::ExpressionProductions);
2569 Expect(Token::RBRACK, CHECK_OK);
2578 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2583 return this->IsArrayIndex(*name, &index)
2584 ? factory()->NewNumberLiteral(index, pos)
2585 : factory()->NewStringLiteral(*name, pos);
2589 template <class Traits>
2590 typename ParserBase<Traits>::ObjectLiteralPropertyT
2591 ParserBase<Traits>::ParsePropertyDefinition(
2592 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2593 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
2594 ExpressionClassifier* classifier, bool* ok) {
2595 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2596 ExpressionT value = this->EmptyExpression();
2597 IdentifierT name = this->EmptyIdentifier();
2598 bool is_get = false;
2599 bool is_set = false;
2600 bool name_is_static = false;
2601 bool is_generator = Check(Token::MUL);
2603 Token::Value name_token = peek();
2604 int next_beg_pos = scanner()->peek_location().beg_pos;
2605 int next_end_pos = scanner()->peek_location().end_pos;
2606 ExpressionT name_expression = ParsePropertyName(
2607 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier,
2608 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2610 if (fni_ != nullptr && !*is_computed_name) {
2611 this->PushLiteralName(fni_, name);
2614 if (!in_class && !is_generator) {
2617 if (peek() == Token::COLON) {
2618 // PropertyDefinition
2619 // PropertyName ':' AssignmentExpression
2620 if (!*is_computed_name) {
2621 checker->CheckProperty(name_token, kValueProperty, false, false,
2622 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2624 Consume(Token::COLON);
2625 value = this->ParseAssignmentExpression(
2626 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2627 return factory()->NewObjectLiteralProperty(name_expression, value, false,
2631 if (Token::IsIdentifier(name_token, language_mode(),
2632 this->is_generator()) &&
2633 (peek() == Token::COMMA || peek() == Token::RBRACE ||
2634 peek() == Token::ASSIGN)) {
2635 // PropertyDefinition
2636 // IdentifierReference
2637 // CoverInitializedName
2639 // CoverInitializedName
2640 // IdentifierReference Initializer?
2641 if (classifier->duplicate_finder() != nullptr &&
2642 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2643 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2646 ExpressionT lhs = this->ExpressionFromIdentifier(
2647 name, next_beg_pos, next_end_pos, scope_, factory());
2649 if (peek() == Token::ASSIGN) {
2650 this->ExpressionUnexpectedToken(classifier);
2651 Consume(Token::ASSIGN);
2652 ExpressionClassifier rhs_classifier;
2653 ExpressionT rhs = this->ParseAssignmentExpression(
2654 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2655 classifier->Accumulate(rhs_classifier,
2656 ExpressionClassifier::ExpressionProductions);
2657 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2658 RelocInfo::kNoPosition);
2663 return factory()->NewObjectLiteralProperty(
2664 name_expression, value, ObjectLiteralProperty::COMPUTED, false,
2670 if (is_generator || peek() == Token::LPAREN) {
2672 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2673 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2674 if (!*is_computed_name) {
2675 checker->CheckProperty(name_token, kMethodProperty, is_static,
2677 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2680 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2681 : FunctionKind::kConciseMethod;
2683 if (in_class && !is_static && this->IsConstructor(name)) {
2684 *has_seen_constructor = true;
2685 kind = has_extends ? FunctionKind::kSubclassConstructor
2686 : FunctionKind::kBaseConstructor;
2689 if (!in_class) kind = WithObjectLiteralBit(kind);
2691 value = this->ParseFunctionLiteral(
2692 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2693 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2694 FunctionLiteral::NORMAL_ARITY, language_mode(),
2695 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2697 return factory()->NewObjectLiteralProperty(name_expression, value,
2698 ObjectLiteralProperty::COMPUTED,
2699 is_static, *is_computed_name);
2702 if (in_class && name_is_static && !is_static) {
2703 // ClassElement (static)
2704 // 'static' MethodDefinition
2705 return ParsePropertyDefinition(checker, true, has_extends, true,
2706 is_computed_name, nullptr, classifier, ok);
2709 if (is_get || is_set) {
2710 // MethodDefinition (Accessors)
2711 // get PropertyName '(' ')' '{' FunctionBody '}'
2712 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2713 name = this->EmptyIdentifier();
2714 bool dont_care = false;
2715 name_token = peek();
2717 name_expression = ParsePropertyName(
2718 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2719 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2721 if (!*is_computed_name) {
2722 checker->CheckProperty(name_token, kAccessorProperty, is_static,
2724 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2727 FunctionKind kind = FunctionKind::kAccessorFunction;
2728 if (!in_class) kind = WithObjectLiteralBit(kind);
2729 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2730 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2731 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2732 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2733 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2735 // Make sure the name expression is a string since we need a Name for
2736 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2737 // statically we can skip the extra runtime check.
2738 if (!*is_computed_name) {
2740 factory()->NewStringLiteral(name, name_expression->position());
2743 return factory()->NewObjectLiteralProperty(
2744 name_expression, value,
2745 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2746 is_static, *is_computed_name);
2749 Token::Value next = Next();
2750 ReportUnexpectedToken(next);
2752 return this->EmptyObjectLiteralProperty();
2756 template <class Traits>
2757 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2758 ExpressionClassifier* classifier, bool* ok) {
2760 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2762 int pos = peek_position();
2763 typename Traits::Type::PropertyList properties =
2764 this->NewPropertyList(4, zone_);
2765 int number_of_boilerplate_properties = 0;
2766 bool has_function = false;
2767 bool has_computed_names = false;
2768 ObjectLiteralChecker checker(this);
2770 Expect(Token::LBRACE, CHECK_OK);
2772 while (peek() != Token::RBRACE) {
2773 if (fni_ != nullptr) fni_->Enter();
2775 const bool in_class = false;
2776 const bool is_static = false;
2777 const bool has_extends = false;
2778 bool is_computed_name = false;
2779 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2780 &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
2781 classifier, CHECK_OK);
2783 if (is_computed_name) {
2784 has_computed_names = true;
2787 // Mark top-level object literals that contain function literals and
2788 // pretenure the literal so it can be added as a constant function
2789 // property. (Parser only.)
2790 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2793 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2794 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2795 number_of_boilerplate_properties++;
2797 properties->Add(property, zone());
2799 if (peek() != Token::RBRACE) {
2800 // Need {} because of the CHECK_OK macro.
2801 Expect(Token::COMMA, CHECK_OK);
2804 if (fni_ != nullptr) {
2809 Expect(Token::RBRACE, CHECK_OK);
2811 // Computation of literal_index must happen before pre parse bailout.
2812 int literal_index = function_state_->NextMaterializedLiteralIndex();
2814 return factory()->NewObjectLiteral(properties,
2816 number_of_boilerplate_properties,
2818 is_strong(language_mode()),
2823 template <class Traits>
2824 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
2825 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier,
2828 // '(' (AssignmentExpression)*[','] ')'
2830 Scanner::Location spread_arg = Scanner::Location::invalid();
2831 typename Traits::Type::ExpressionList result =
2832 this->NewExpressionList(4, zone_);
2833 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2834 bool done = (peek() == Token::RPAREN);
2835 bool was_unspread = false;
2836 int unspread_sequences_count = 0;
2839 allow_harmony_spread_calls() && (peek() == Token::ELLIPSIS);
2840 int start_pos = peek_position();
2841 if (is_spread) Consume(Token::ELLIPSIS);
2843 ExpressionT argument = this->ParseAssignmentExpression(
2844 true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
2846 if (!spread_arg.IsValid()) {
2847 spread_arg.beg_pos = start_pos;
2848 spread_arg.end_pos = peek_position();
2850 argument = factory()->NewSpread(argument, start_pos);
2852 result->Add(argument, zone_);
2854 // unspread_sequences_count is the number of sequences of parameters which
2855 // are not prefixed with a spread '...' operator.
2857 was_unspread = false;
2858 } else if (!was_unspread) {
2859 was_unspread = true;
2860 unspread_sequences_count++;
2863 if (result->length() > Code::kMaxArguments) {
2864 ReportMessage(MessageTemplate::kTooManyArguments);
2866 return this->NullExpressionList();
2868 done = (peek() != Token::COMMA);
2873 Scanner::Location location = scanner_->location();
2874 if (Token::RPAREN != Next()) {
2875 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2877 return this->NullExpressionList();
2879 *first_spread_arg_loc = spread_arg;
2881 if (spread_arg.IsValid()) {
2882 // Unspread parameter sequences are translated into array literals in the
2883 // parser. Ensure that the number of materialized literals matches between
2884 // the parser and preparser
2885 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2892 template <class Traits>
2893 typename ParserBase<Traits>::ExpressionT
2894 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
2895 ExpressionClassifier* classifier,
2897 // AssignmentExpression ::
2898 // ConditionalExpression
2901 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2903 int lhs_beg_pos = peek_position();
2905 if (peek() == Token::YIELD && is_generator()) {
2906 return this->ParseYieldExpression(classifier, ok);
2909 if (fni_ != NULL) fni_->Enter();
2910 ParserBase<Traits>::Checkpoint checkpoint(this);
2911 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
2912 bool parenthesized_formals = peek() == Token::LPAREN;
2913 if (!parenthesized_formals) {
2914 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2916 ExpressionT expression = this->ParseConditionalExpression(
2917 accept_IN, &arrow_formals_classifier, CHECK_OK);
2918 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2919 BindingPatternUnexpectedToken(classifier);
2920 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2921 parenthesized_formals, CHECK_OK);
2922 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2924 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2925 FormalParametersT parameters(scope);
2926 if (!arrow_formals_classifier.is_simple_parameter_list()) {
2927 scope->SetHasNonSimpleParameters();
2928 parameters.is_simple = false;
2931 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2932 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc,
2933 &duplicate_loc, CHECK_OK);
2935 checkpoint.Restore(¶meters.materialized_literals_count);
2937 scope->set_start_position(lhs_beg_pos);
2938 if (duplicate_loc.IsValid()) {
2939 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2942 expression = this->ParseArrowFunctionLiteral(
2943 parameters, arrow_formals_classifier, CHECK_OK);
2947 // "expression" was not itself an arrow function parameter list, but it might
2948 // form part of one. Propagate speculative formal parameter error locations.
2949 classifier->Accumulate(arrow_formals_classifier,
2950 ExpressionClassifier::StandardProductions |
2951 ExpressionClassifier::FormalParametersProductions);
2953 if (!Token::IsAssignmentOp(peek())) {
2954 if (fni_ != NULL) fni_->Leave();
2955 // Parsed conditional expression only (no assignment).
2959 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) {
2960 BindingPatternUnexpectedToken(classifier);
2963 expression = this->CheckAndRewriteReferenceExpression(
2964 expression, lhs_beg_pos, scanner()->location().end_pos,
2965 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2966 expression = this->MarkExpressionAsAssigned(expression);
2968 Token::Value op = Next(); // Get assignment operator.
2969 if (op != Token::ASSIGN) {
2970 classifier->RecordBindingPatternError(scanner()->location(),
2971 MessageTemplate::kUnexpectedToken,
2974 int pos = position();
2976 ExpressionClassifier rhs_classifier;
2978 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
2979 classifier->Accumulate(rhs_classifier,
2980 ExpressionClassifier::ExpressionProductions);
2982 // TODO(1231235): We try to estimate the set of properties set by
2983 // constructors. We define a new property whenever there is an
2984 // assignment to a property of 'this'. We should probably only add
2985 // properties if we haven't seen them before. Otherwise we'll
2986 // probably overestimate the number of properties.
2987 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2988 function_state_->AddProperty();
2991 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2994 // Check if the right hand side is a call to avoid inferring a
2995 // name if we're dealing with "a = function(){...}();"-like
2997 if ((op == Token::INIT_VAR
2998 || op == Token::INIT_CONST_LEGACY
2999 || op == Token::ASSIGN)
3000 && (!right->IsCall() && !right->IsCallNew())) {
3003 fni_->RemoveLastFunction();
3008 return factory()->NewAssignment(op, expression, right, pos);
3011 template <class Traits>
3012 typename ParserBase<Traits>::ExpressionT
3013 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
3015 // YieldExpression ::
3016 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
3017 int pos = peek_position();
3018 BindingPatternUnexpectedToken(classifier);
3019 FormalParameterInitializerUnexpectedToken(classifier);
3020 Expect(Token::YIELD, CHECK_OK);
3021 ExpressionT generator_object =
3022 factory()->NewVariableProxy(function_state_->generator_object_variable());
3023 ExpressionT expression = Traits::EmptyExpression();
3024 Yield::Kind kind = Yield::kSuspend;
3025 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
3026 if (Check(Token::MUL)) kind = Yield::kDelegating;
3029 case Token::SEMICOLON:
3035 // The above set of tokens is the complete set of tokens that can appear
3036 // after an AssignmentExpression, and none of them can start an
3037 // AssignmentExpression. This allows us to avoid looking for an RHS for
3038 // a Yield::kSuspend operation, given only one look-ahead token.
3039 if (kind == Yield::kSuspend)
3041 DCHECK_EQ(Yield::kDelegating, kind);
3042 // Delegating yields require an RHS; fall through.
3044 expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
3048 if (kind == Yield::kDelegating) {
3049 // var iterator = subject[Symbol.iterator]();
3050 expression = this->GetIterator(expression, factory());
3052 typename Traits::Type::YieldExpression yield =
3053 factory()->NewYield(generator_object, expression, kind, pos);
3059 template <class Traits>
3060 typename ParserBase<Traits>::ExpressionT
3061 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
3062 ExpressionClassifier* classifier,
3064 // ConditionalExpression ::
3065 // LogicalOrExpression
3066 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3068 int pos = peek_position();
3069 // We start using the binary expression parser for prec >= 4 only!
3070 ExpressionT expression =
3071 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
3072 if (peek() != Token::CONDITIONAL) return expression;
3073 ArrowFormalParametersUnexpectedToken(classifier);
3074 BindingPatternUnexpectedToken(classifier);
3075 Consume(Token::CONDITIONAL);
3076 // In parsing the first assignment expression in conditional
3077 // expressions we always accept the 'in' keyword; see ECMA-262,
3078 // section 11.12, page 58.
3079 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
3080 Expect(Token::COLON, CHECK_OK);
3082 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
3083 return factory()->NewConditional(expression, left, right, pos);
3088 template <class Traits>
3089 typename ParserBase<Traits>::ExpressionT
3090 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
3091 ExpressionClassifier* classifier,
3094 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
3095 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3097 while (Precedence(peek(), accept_IN) == prec1) {
3098 BindingPatternUnexpectedToken(classifier);
3099 ArrowFormalParametersUnexpectedToken(classifier);
3100 Token::Value op = Next();
3101 Scanner::Location op_location = scanner()->location();
3102 int pos = position();
3104 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
3106 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
3111 // For now we distinguish between comparisons and other binary
3112 // operations. (We could combine the two and get rid of this
3113 // code and AST node eventually.)
3114 if (Token::IsCompareOp(op)) {
3115 // We have a comparison.
3116 Token::Value cmp = op;
3118 case Token::NE: cmp = Token::EQ; break;
3119 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
3122 if (cmp == Token::EQ && is_strong(language_mode())) {
3123 ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
3125 return this->EmptyExpression();
3127 x = factory()->NewCompareOperation(cmp, x, y, pos);
3129 // The comparison was negated - add a NOT.
3130 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3134 // We have a "normal" binary operation.
3135 x = factory()->NewBinaryOperation(op, x, y, pos);
3143 template <class Traits>
3144 typename ParserBase<Traits>::ExpressionT
3145 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
3147 // UnaryExpression ::
3148 // PostfixExpression
3149 // 'delete' UnaryExpression
3150 // 'void' UnaryExpression
3151 // 'typeof' UnaryExpression
3152 // '++' UnaryExpression
3153 // '--' UnaryExpression
3154 // '+' UnaryExpression
3155 // '-' UnaryExpression
3156 // '~' UnaryExpression
3157 // '!' UnaryExpression
3159 Token::Value op = peek();
3160 if (Token::IsUnaryOp(op)) {
3161 BindingPatternUnexpectedToken(classifier);
3162 ArrowFormalParametersUnexpectedToken(classifier);
3165 int pos = position();
3166 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
3168 if (op == Token::DELETE && is_strict(language_mode())) {
3169 if (is_strong(language_mode())) {
3170 ReportMessage(MessageTemplate::kStrongDelete);
3172 return this->EmptyExpression();
3173 } else if (this->IsIdentifier(expression)) {
3174 // "delete identifier" is a syntax error in strict mode.
3175 ReportMessage(MessageTemplate::kStrictDelete);
3177 return this->EmptyExpression();
3181 // Allow Traits do rewrite the expression.
3182 return this->BuildUnaryExpression(expression, op, pos, factory());
3183 } else if (Token::IsCountOp(op)) {
3184 BindingPatternUnexpectedToken(classifier);
3185 ArrowFormalParametersUnexpectedToken(classifier);
3187 int beg_pos = peek_position();
3188 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
3189 expression = this->CheckAndRewriteReferenceExpression(
3190 expression, beg_pos, scanner()->location().end_pos,
3191 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
3192 this->MarkExpressionAsAssigned(expression);
3194 return factory()->NewCountOperation(op,
3200 return this->ParsePostfixExpression(classifier, ok);
3205 template <class Traits>
3206 typename ParserBase<Traits>::ExpressionT
3207 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
3209 // PostfixExpression ::
3210 // LeftHandSideExpression ('++' | '--')?
3212 int lhs_beg_pos = peek_position();
3213 ExpressionT expression =
3214 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
3215 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
3216 Token::IsCountOp(peek())) {
3217 BindingPatternUnexpectedToken(classifier);
3218 ArrowFormalParametersUnexpectedToken(classifier);
3220 expression = this->CheckAndRewriteReferenceExpression(
3221 expression, lhs_beg_pos, scanner()->location().end_pos,
3222 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
3223 expression = this->MarkExpressionAsAssigned(expression);
3225 Token::Value next = Next();
3227 factory()->NewCountOperation(next,
3228 false /* postfix */,
3236 template <class Traits>
3237 typename ParserBase<Traits>::ExpressionT
3238 ParserBase<Traits>::ParseLeftHandSideExpression(
3239 ExpressionClassifier* classifier, bool* ok) {
3240 // LeftHandSideExpression ::
3241 // (NewExpression | MemberExpression) ...
3243 ExpressionT result =
3244 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3248 case Token::LBRACK: {
3249 BindingPatternUnexpectedToken(classifier);
3250 ArrowFormalParametersUnexpectedToken(classifier);
3251 Consume(Token::LBRACK);
3252 int pos = position();
3253 ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
3254 result = factory()->NewProperty(result, index, pos);
3255 Expect(Token::RBRACK, CHECK_OK);
3259 case Token::LPAREN: {
3260 BindingPatternUnexpectedToken(classifier);
3261 ArrowFormalParametersUnexpectedToken(classifier);
3263 if (is_strong(language_mode()) && this->IsIdentifier(result) &&
3264 this->IsEval(this->AsIdentifier(result))) {
3265 ReportMessage(MessageTemplate::kStrongDirectEval);
3267 return this->EmptyExpression();
3270 if (scanner()->current_token() == Token::IDENTIFIER) {
3271 // For call of an identifier we want to report position of
3272 // the identifier as position of the call in the stack trace.
3275 // For other kinds of calls we record position of the parenthesis as
3276 // position of the call. Note that this is extremely important for
3277 // expressions of the form function(){...}() for which call position
3278 // should not point to the closing brace otherwise it will intersect
3279 // with positions recorded for function literal and confuse debugger.
3280 pos = peek_position();
3281 // Also the trailing parenthesis are a hint that the function will
3282 // be called immediately. If we happen to have parsed a preceding
3283 // function literal eagerly, we can also compile it eagerly.
3284 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3285 result->AsFunctionLiteral()->set_should_eager_compile();
3288 Scanner::Location spread_pos;
3289 typename Traits::Type::ExpressionList args =
3290 ParseArguments(&spread_pos, classifier, CHECK_OK);
3292 // Keep track of eval() calls since they disable all local variable
3294 // The calls that need special treatment are the
3295 // direct eval calls. These calls are all of the form eval(...), with
3296 // no explicit receiver.
3297 // These calls are marked as potentially direct eval calls. Whether
3298 // they are actually direct calls to eval is determined at run time.
3299 this->CheckPossibleEvalCall(result, scope_);
3301 bool is_super_call = result->IsSuperCallReference();
3302 if (spread_pos.IsValid()) {
3303 args = Traits::PrepareSpreadArguments(args);
3304 result = Traits::SpreadCall(result, args, pos);
3306 result = factory()->NewCall(result, args, pos);
3309 // Explicit calls to the super constructor using super() perform an
3310 // implicit binding assignment to the 'this' variable.
3311 if (is_super_call) {
3312 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3313 result = factory()->NewAssignment(Token::INIT_CONST, this_expr,
3317 if (fni_ != NULL) fni_->RemoveLastFunction();
3321 case Token::PERIOD: {
3322 BindingPatternUnexpectedToken(classifier);
3323 ArrowFormalParametersUnexpectedToken(classifier);
3324 Consume(Token::PERIOD);
3325 int pos = position();
3326 IdentifierT name = ParseIdentifierName(CHECK_OK);
3327 result = factory()->NewProperty(
3328 result, factory()->NewStringLiteral(name, pos), pos);
3329 if (fni_ != NULL) this->PushLiteralName(fni_, name);
3333 case Token::TEMPLATE_SPAN:
3334 case Token::TEMPLATE_TAIL: {
3335 BindingPatternUnexpectedToken(classifier);
3336 ArrowFormalParametersUnexpectedToken(classifier);
3337 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
3348 template <class Traits>
3349 typename ParserBase<Traits>::ExpressionT
3350 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
3351 ExpressionClassifier* classifier, bool* ok) {
3353 // ('new')+ MemberExpression
3356 // 'new' '.' 'target'
3358 // The grammar for new expressions is pretty warped. We can have several 'new'
3359 // keywords following each other, and then a MemberExpression. When we see '('
3360 // after the MemberExpression, it's associated with the rightmost unassociated
3361 // 'new' to create a NewExpression with arguments. However, a NewExpression
3362 // can also occur without arguments.
3364 // Examples of new expression:
3365 // new foo.bar().baz means (new (foo.bar)()).baz
3366 // new foo()() means (new foo())()
3367 // new new foo()() means (new (new foo())())
3368 // new new foo means new (new foo)
3369 // new new foo() means new (new foo())
3370 // new new foo().bar().baz means (new (new foo()).bar()).baz
3372 if (peek() == Token::NEW) {
3373 BindingPatternUnexpectedToken(classifier);
3374 ArrowFormalParametersUnexpectedToken(classifier);
3375 Consume(Token::NEW);
3376 int new_pos = position();
3377 ExpressionT result = this->EmptyExpression();
3378 if (peek() == Token::SUPER) {
3379 const bool is_new = true;
3380 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3381 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) {
3382 return ParseNewTargetExpression(CHECK_OK);
3384 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3386 if (peek() == Token::LPAREN) {
3387 // NewExpression with arguments.
3388 Scanner::Location spread_pos;
3389 typename Traits::Type::ExpressionList args =
3390 this->ParseArguments(&spread_pos, classifier, CHECK_OK);
3392 if (spread_pos.IsValid()) {
3393 args = Traits::PrepareSpreadArguments(args);
3394 result = Traits::SpreadCallNew(result, args, new_pos);
3396 result = factory()->NewCallNew(result, args, new_pos);
3398 // The expression can still continue with . or [ after the arguments.
3400 this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
3403 // NewExpression without arguments.
3404 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
3407 // No 'new' or 'super' keyword.
3408 return this->ParseMemberExpression(classifier, ok);
3412 template <class Traits>
3413 typename ParserBase<Traits>::ExpressionT
3414 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
3416 // MemberExpression ::
3417 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
3418 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3420 // The '[' Expression ']' and '.' Identifier parts are parsed by
3421 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3424 // Parse the initial primary or function expression.
3425 ExpressionT result = this->EmptyExpression();
3426 if (peek() == Token::FUNCTION) {
3427 BindingPatternUnexpectedToken(classifier);
3428 ArrowFormalParametersUnexpectedToken(classifier);
3430 Consume(Token::FUNCTION);
3431 int function_token_position = position();
3432 bool is_generator = Check(Token::MUL);
3433 IdentifierT name = this->EmptyIdentifier();
3434 bool is_strict_reserved_name = false;
3435 Scanner::Location function_name_location = Scanner::Location::invalid();
3436 FunctionLiteral::FunctionType function_type =
3437 FunctionLiteral::ANONYMOUS_EXPRESSION;
3438 if (peek_any_identifier()) {
3439 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3441 function_name_location = scanner()->location();
3442 function_type = FunctionLiteral::NAMED_EXPRESSION;
3444 result = this->ParseFunctionLiteral(
3445 name, function_name_location,
3446 is_strict_reserved_name ? kFunctionNameIsStrictReserved
3447 : kFunctionNameValidityUnknown,
3448 is_generator ? FunctionKind::kGeneratorFunction
3449 : FunctionKind::kNormalFunction,
3450 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
3451 language_mode(), CHECK_OK);
3452 } else if (peek() == Token::SUPER) {
3453 const bool is_new = false;
3454 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3456 result = ParsePrimaryExpression(classifier, CHECK_OK);
3459 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
3464 template <class Traits>
3465 typename ParserBase<Traits>::ExpressionT
3466 ParserBase<Traits>::ParseStrongInitializationExpression(
3467 ExpressionClassifier* classifier, bool* ok) {
3468 // InitializationExpression :: (strong mode)
3469 // 'this' '.' IdentifierName '=' AssignmentExpression
3470 // 'this' '[' Expression ']' '=' AssignmentExpression
3472 if (fni_ != NULL) fni_->Enter();
3474 Consume(Token::THIS);
3475 int pos = position();
3476 function_state_->set_this_location(scanner()->location());
3477 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3479 ExpressionT left = this->EmptyExpression();
3481 case Token::LBRACK: {
3482 Consume(Token::LBRACK);
3483 int pos = position();
3484 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3485 left = factory()->NewProperty(this_expr, index, pos);
3487 this->PushPropertyName(fni_, index);
3489 Expect(Token::RBRACK, CHECK_OK);
3492 case Token::PERIOD: {
3493 Consume(Token::PERIOD);
3494 int pos = position();
3495 IdentifierT name = ParseIdentifierName(CHECK_OK);
3496 left = factory()->NewProperty(
3497 this_expr, factory()->NewStringLiteral(name, pos), pos);
3499 this->PushLiteralName(fni_, name);
3504 ReportMessage(MessageTemplate::kStrongConstructorThis);
3506 return this->EmptyExpression();
3509 if (peek() != Token::ASSIGN) {
3510 ReportMessageAt(function_state_->this_location(),
3511 MessageTemplate::kStrongConstructorThis);
3513 return this->EmptyExpression();
3515 Consume(Token::ASSIGN);
3516 left = this->MarkExpressionAsAssigned(left);
3519 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
3520 this->CheckAssigningFunctionLiteralToProperty(left, right);
3521 function_state_->AddProperty();
3523 // Check if the right hand side is a call to avoid inferring a
3524 // name if we're dealing with "this.a = function(){...}();"-like
3526 if (!right->IsCall() && !right->IsCallNew()) {
3529 fni_->RemoveLastFunction();
3534 if (function_state_->return_location().IsValid()) {
3535 ReportMessageAt(function_state_->return_location(),
3536 MessageTemplate::kStrongConstructorReturnMisplaced);
3538 return this->EmptyExpression();
3541 return factory()->NewAssignment(Token::ASSIGN, left, right, pos);
3545 template <class Traits>
3546 typename ParserBase<Traits>::ExpressionT
3547 ParserBase<Traits>::ParseStrongSuperCallExpression(
3548 ExpressionClassifier* classifier, bool* ok) {
3549 // SuperCallExpression :: (strong mode)
3550 // 'super' '(' ExpressionList ')'
3551 BindingPatternUnexpectedToken(classifier);
3553 Consume(Token::SUPER);
3554 int pos = position();
3555 Scanner::Location super_loc = scanner()->location();
3556 ExpressionT expr = this->SuperCallReference(scope_, factory(), pos);
3558 if (peek() != Token::LPAREN) {
3559 ReportMessage(MessageTemplate::kStrongConstructorSuper);
3561 return this->EmptyExpression();
3564 Scanner::Location spread_pos;
3565 typename Traits::Type::ExpressionList args =
3566 ParseArguments(&spread_pos, classifier, CHECK_OK);
3568 // TODO(rossberg): This doesn't work with arrow functions yet.
3569 if (!IsSubclassConstructor(function_state_->kind())) {
3570 ReportMessage(MessageTemplate::kUnexpectedSuper);
3572 return this->EmptyExpression();
3573 } else if (function_state_->super_location().IsValid()) {
3574 ReportMessageAt(scanner()->location(),
3575 MessageTemplate::kStrongSuperCallDuplicate);
3577 return this->EmptyExpression();
3578 } else if (function_state_->this_location().IsValid()) {
3579 ReportMessageAt(scanner()->location(),
3580 MessageTemplate::kStrongSuperCallMisplaced);
3582 return this->EmptyExpression();
3583 } else if (function_state_->return_location().IsValid()) {
3584 ReportMessageAt(function_state_->return_location(),
3585 MessageTemplate::kStrongConstructorReturnMisplaced);
3587 return this->EmptyExpression();
3590 function_state_->set_super_location(super_loc);
3591 if (spread_pos.IsValid()) {
3592 args = Traits::PrepareSpreadArguments(args);
3593 expr = Traits::SpreadCall(expr, args, pos);
3595 expr = factory()->NewCall(expr, args, pos);
3598 // Explicit calls to the super constructor using super() perform an implicit
3599 // binding assignment to the 'this' variable.
3600 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3601 return factory()->NewAssignment(Token::INIT_CONST, this_expr, expr, pos);
3605 template <class Traits>
3606 typename ParserBase<Traits>::ExpressionT
3607 ParserBase<Traits>::ParseSuperExpression(bool is_new,
3608 ExpressionClassifier* classifier,
3610 int pos = position();
3611 Expect(Token::SUPER, CHECK_OK);
3613 Scope* scope = scope_->ReceiverScope();
3614 FunctionKind kind = scope->function_kind();
3615 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3616 IsClassConstructor(kind)) {
3617 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3618 scope->RecordSuperPropertyUsage();
3619 return this->SuperPropertyReference(scope_, factory(), pos);
3621 // new super() is never allowed.
3622 // super() is only allowed in derived constructor
3623 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
3624 if (is_strong(language_mode())) {
3625 // Super calls in strong mode are parsed separately.
3626 ReportMessageAt(scanner()->location(),
3627 MessageTemplate::kStrongConstructorSuper);
3629 return this->EmptyExpression();
3631 // TODO(rossberg): This might not be the correct FunctionState for the
3633 function_state_->set_super_location(scanner()->location());
3634 return this->SuperCallReference(scope_, factory(), pos);
3638 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
3640 return this->EmptyExpression();
3644 template <class Traits>
3645 typename ParserBase<Traits>::ExpressionT
3646 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
3647 int pos = position();
3648 Consume(Token::PERIOD);
3649 ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
3651 if (!scope_->ReceiverScope()->is_function_scope()) {
3652 ReportMessageAt(scanner()->location(),
3653 MessageTemplate::kUnexpectedNewTarget);
3655 return this->EmptyExpression();
3658 return this->NewTargetExpression(scope_, factory(), pos);
3662 template <class Traits>
3663 typename ParserBase<Traits>::ExpressionT
3664 ParserBase<Traits>::ParseMemberExpressionContinuation(
3665 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
3666 // Parses this part of MemberExpression:
3667 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3670 case Token::LBRACK: {
3671 BindingPatternUnexpectedToken(classifier);
3672 ArrowFormalParametersUnexpectedToken(classifier);
3674 Consume(Token::LBRACK);
3675 int pos = position();
3676 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3677 expression = factory()->NewProperty(expression, index, pos);
3679 this->PushPropertyName(fni_, index);
3681 Expect(Token::RBRACK, CHECK_OK);
3684 case Token::PERIOD: {
3685 BindingPatternUnexpectedToken(classifier);
3686 ArrowFormalParametersUnexpectedToken(classifier);
3688 Consume(Token::PERIOD);
3689 int pos = position();
3690 IdentifierT name = ParseIdentifierName(CHECK_OK);
3691 expression = factory()->NewProperty(
3692 expression, factory()->NewStringLiteral(name, pos), pos);
3694 this->PushLiteralName(fni_, name);
3698 case Token::TEMPLATE_SPAN:
3699 case Token::TEMPLATE_TAIL: {
3700 BindingPatternUnexpectedToken(classifier);
3701 ArrowFormalParametersUnexpectedToken(classifier);
3703 if (scanner()->current_token() == Token::IDENTIFIER) {
3706 pos = peek_position();
3707 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3708 // If the tag function looks like an IIFE, set_parenthesized() to
3709 // force eager compilation.
3710 expression->AsFunctionLiteral()->set_should_eager_compile();
3714 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
3722 return this->EmptyExpression();
3726 template <class Traits>
3727 void ParserBase<Traits>::ParseFormalParameter(
3728 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3729 // FormalParameter[Yield,GeneratorParameter] :
3730 // BindingElement[?Yield, ?GeneratorParameter]
3731 bool is_rest = parameters->has_rest;
3733 Token::Value next = peek();
3734 ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
3737 ValidateBindingPattern(classifier, ok);
3740 if (!Traits::IsIdentifier(pattern)) {
3741 if (is_rest || !allow_harmony_destructuring()) {
3742 ReportUnexpectedToken(next);
3746 parameters->is_simple = false;
3747 ValidateFormalParameterInitializer(classifier, ok);
3749 classifier->RecordNonSimpleParameter();
3753 parameters->rest_array_literal_index =
3754 function_state_->NextMaterializedLiteralIndex();
3755 ++parameters->materialized_literals_count;
3758 ExpressionT initializer = Traits::EmptyExpression();
3759 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
3760 ExpressionClassifier init_classifier;
3761 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3763 ValidateExpression(&init_classifier, ok);
3764 ValidateFormalParameterInitializer(&init_classifier, ok);
3766 parameters->is_simple = false;
3767 classifier->RecordNonSimpleParameter();
3770 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest);
3774 template <class Traits>
3775 void ParserBase<Traits>::ParseFormalParameterList(
3776 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3777 // FormalParameters[Yield,GeneratorParameter] :
3779 // FormalParameterList[?Yield, ?GeneratorParameter]
3781 // FormalParameterList[Yield,GeneratorParameter] :
3782 // FunctionRestParameter[?Yield]
3783 // FormalsList[?Yield, ?GeneratorParameter]
3784 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
3786 // FormalsList[Yield,GeneratorParameter] :
3787 // FormalParameter[?Yield, ?GeneratorParameter]
3788 // FormalsList[?Yield, ?GeneratorParameter] ,
3789 // FormalParameter[?Yield,?GeneratorParameter]
3791 DCHECK_EQ(0, parameters->Arity());
3793 if (peek() != Token::RPAREN) {
3795 if (parameters->Arity() > Code::kMaxArguments) {
3796 ReportMessage(MessageTemplate::kTooManyParameters);
3800 parameters->has_rest =
3801 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
3802 ParseFormalParameter(parameters, classifier, ok);
3804 } while (!parameters->has_rest && Check(Token::COMMA));
3806 if (parameters->has_rest) {
3807 parameters->is_simple = false;
3808 classifier->RecordNonSimpleParameter();
3809 if (peek() == Token::COMMA) {
3810 ReportMessageAt(scanner()->peek_location(),
3811 MessageTemplate::kParamAfterRest);
3818 for (int i = 0; i < parameters->Arity(); ++i) {
3819 auto parameter = parameters->at(i);
3820 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
3825 template <class Traits>
3826 void ParserBase<Traits>::CheckArityRestrictions(
3827 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
3828 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
3829 switch (arity_restriction) {
3830 case FunctionLiteral::GETTER_ARITY:
3831 if (param_count != 0) {
3832 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3833 MessageTemplate::kBadGetterArity);
3837 case FunctionLiteral::SETTER_ARITY:
3838 if (param_count != 1) {
3839 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3840 MessageTemplate::kBadSetterArity);
3844 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3845 MessageTemplate::kBadSetterRestParameter);
3855 template <class Traits>
3856 bool ParserBase<Traits>::IsNextLetKeyword() {
3857 DCHECK(peek() == Token::LET);
3861 Token::Value next_next = PeekAhead();
3862 switch (next_next) {
3865 case Token::IDENTIFIER:
3867 case Token::LET: // Yes, you can do let let = ... in sloppy mode
3876 template <class Traits>
3877 typename ParserBase<Traits>::ExpressionT
3878 ParserBase<Traits>::ParseArrowFunctionLiteral(
3879 const FormalParametersT& formal_parameters,
3880 const ExpressionClassifier& formals_classifier, bool* ok) {
3881 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3882 // ASI inserts `;` after arrow parameters if a line terminator is found.
3883 // `=> ...` is never a valid expression, so report as syntax error.
3884 // If next token is not `=>`, it's a syntax error anyways.
3885 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3887 return this->EmptyExpression();
3890 typename Traits::Type::StatementList body;
3891 int num_parameters = formal_parameters.scope->num_parameters();
3892 int materialized_literal_count = -1;
3893 int expected_property_count = -1;
3894 Scanner::Location super_loc;
3897 typename Traits::Type::Factory function_factory(ast_value_factory());
3898 FunctionState function_state(&function_state_, &scope_,
3899 formal_parameters.scope, kArrowFunction,
3902 function_state.SkipMaterializedLiterals(
3903 formal_parameters.materialized_literals_count);
3905 this->ReindexLiterals(formal_parameters);
3907 Expect(Token::ARROW, CHECK_OK);
3909 if (peek() == Token::LBRACE) {
3910 // Multiple statement body
3911 Consume(Token::LBRACE);
3912 bool is_lazily_parsed =
3913 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
3914 if (is_lazily_parsed) {
3915 body = this->NewStatementList(0, zone());
3916 this->SkipLazyFunctionBody(&materialized_literal_count,
3917 &expected_property_count, CHECK_OK);
3919 if (formal_parameters.materialized_literals_count > 0) {
3920 materialized_literal_count +=
3921 formal_parameters.materialized_literals_count;
3924 body = this->ParseEagerFunctionBody(
3925 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
3926 kArrowFunction, FunctionLiteral::ANONYMOUS_EXPRESSION, CHECK_OK);
3927 materialized_literal_count =
3928 function_state.materialized_literal_count();
3929 expected_property_count = function_state.expected_property_count();
3932 // Single-expression body
3933 int pos = position();
3934 parenthesized_function_ = false;
3935 ExpressionClassifier classifier;
3936 ExpressionT expression =
3937 ParseAssignmentExpression(true, &classifier, CHECK_OK);
3938 ValidateExpression(&classifier, CHECK_OK);
3939 body = this->NewStatementList(1, zone());
3940 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
3941 body->Add(factory()->NewReturnStatement(expression, pos), zone());
3942 materialized_literal_count = function_state.materialized_literal_count();
3943 expected_property_count = function_state.expected_property_count();
3945 super_loc = function_state.super_location();
3947 formal_parameters.scope->set_end_position(scanner()->location().end_pos);
3949 // Arrow function formal parameters are parsed as StrictFormalParameterList,
3950 // which is not the same as "parameters of a strict function"; it only means
3951 // that duplicates are not allowed. Of course, the arrow function may
3952 // itself be strict as well.
3953 const bool allow_duplicate_parameters = false;
3954 this->ValidateFormalParameters(&formals_classifier, language_mode(),
3955 allow_duplicate_parameters, CHECK_OK);
3957 // Validate strict mode.
3958 if (is_strict(language_mode())) {
3959 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
3960 scanner()->location().end_pos, CHECK_OK);
3962 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
3963 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
3967 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
3968 this->EmptyIdentifierString(), ast_value_factory(),
3969 formal_parameters.scope, body, materialized_literal_count,
3970 expected_property_count, num_parameters,
3971 FunctionLiteral::kNoDuplicateParameters,
3972 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
3973 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
3974 formal_parameters.scope->start_position());
3976 function_literal->set_function_token_position(
3977 formal_parameters.scope->start_position());
3978 if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
3980 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
3982 return function_literal;
3986 template <typename Traits>
3987 typename ParserBase<Traits>::ExpressionT
3988 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
3989 ExpressionClassifier* classifier,
3991 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3992 // text followed by a substitution expression), finalized by a single
3995 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3996 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3997 // NoSubstitutionTemplate.
3999 // When parsing a TemplateLiteral, we must have scanned either an initial
4000 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
4001 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4003 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
4004 // In this case we may simply consume the token and build a template with a
4005 // single TEMPLATE_SPAN and no expressions.
4006 if (peek() == Token::TEMPLATE_TAIL) {
4007 Consume(Token::TEMPLATE_TAIL);
4008 int pos = position();
4009 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4010 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
4011 Traits::AddTemplateSpan(&ts, true);
4012 return Traits::CloseTemplateLiteral(&ts, start, tag);
4015 Consume(Token::TEMPLATE_SPAN);
4016 int pos = position();
4017 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
4018 Traits::AddTemplateSpan(&ts, false);
4021 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
4022 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
4023 // case, representing a TemplateMiddle).
4026 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4028 if (next == Token::EOS) {
4029 ReportMessageAt(Scanner::Location(start, peek_position()),
4030 MessageTemplate::kUnterminatedTemplate);
4032 return Traits::EmptyExpression();
4033 } else if (next == Token::ILLEGAL) {
4034 Traits::ReportMessageAt(
4035 Scanner::Location(position() + 1, peek_position()),
4036 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4038 return Traits::EmptyExpression();
4041 int expr_pos = peek_position();
4042 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
4043 Traits::AddTemplateExpression(&ts, expression);
4045 if (peek() != Token::RBRACE) {
4046 ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
4047 MessageTemplate::kUnterminatedTemplateExpr);
4049 return Traits::EmptyExpression();
4052 // If we didn't die parsing that expression, our next token should be a
4053 // TEMPLATE_SPAN or TEMPLATE_TAIL.
4054 next = scanner()->ScanTemplateContinuation();
4058 if (next == Token::EOS) {
4059 ReportMessageAt(Scanner::Location(start, pos),
4060 MessageTemplate::kUnterminatedTemplate);
4062 return Traits::EmptyExpression();
4063 } else if (next == Token::ILLEGAL) {
4064 Traits::ReportMessageAt(
4065 Scanner::Location(position() + 1, peek_position()),
4066 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4068 return Traits::EmptyExpression();
4071 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
4072 } while (next == Token::TEMPLATE_SPAN);
4074 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
4075 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4076 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4077 return Traits::CloseTemplateLiteral(&ts, start, tag);
4081 template <typename Traits>
4082 typename ParserBase<Traits>::ExpressionT
4083 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
4084 ExpressionT expression, int beg_pos, int end_pos,
4085 MessageTemplate::Template message, bool* ok) {
4086 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
4087 message, kReferenceError, ok);
4091 template <typename Traits>
4092 typename ParserBase<Traits>::ExpressionT
4093 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
4094 ExpressionT expression, int beg_pos, int end_pos,
4095 MessageTemplate::Template message, ParseErrorType type, bool* ok) {
4096 Scanner::Location location(beg_pos, end_pos);
4097 if (this->IsIdentifier(expression)) {
4098 if (is_strict(language_mode()) &&
4099 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
4100 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments,
4103 return this->EmptyExpression();
4105 if (is_strong(language_mode()) &&
4106 this->IsUndefined(this->AsIdentifier(expression))) {
4107 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined,
4110 return this->EmptyExpression();
4113 if (expression->IsValidReferenceExpression()) {
4115 } else if (expression->IsCall()) {
4116 // If it is a call, make it a runtime error for legacy web compatibility.
4117 // Rewrite `expr' to `expr[throw ReferenceError]'.
4118 int pos = location.beg_pos;
4119 ExpressionT error = this->NewThrowReferenceError(message, pos);
4120 return factory()->NewProperty(expression, error, pos);
4122 this->ReportMessageAt(location, message, type);
4124 return this->EmptyExpression();
4130 #undef CHECK_OK_CUSTOM
4133 template <typename Traits>
4134 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
4135 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
4138 DCHECK(!is_generator || type == kMethodProperty);
4140 if (property == Token::SMI || property == Token::NUMBER) return;
4142 if (type == kValueProperty && IsProto()) {
4143 if (has_seen_proto_) {
4144 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
4148 has_seen_proto_ = true;
4154 template <typename Traits>
4155 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
4156 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
4158 DCHECK(type == kMethodProperty || type == kAccessorProperty);
4160 if (property == Token::SMI || property == Token::NUMBER) return;
4163 if (IsPrototype()) {
4164 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
4168 } else if (IsConstructor()) {
4169 if (is_generator || type == kAccessorProperty) {
4170 MessageTemplate::Template msg =
4171 is_generator ? MessageTemplate::kConstructorIsGenerator
4172 : MessageTemplate::kConstructorIsAccessor;
4173 this->parser()->ReportMessage(msg);
4177 if (has_seen_constructor_) {
4178 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
4182 has_seen_constructor_ = true;
4188 #endif // V8_PREPARSER_H