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.
10 #include "src/bailout-reason.h"
11 #include "src/func-name-inferrer.h"
12 #include "src/hashmap.h"
13 #include "src/scanner.h"
14 #include "src/scopes.h"
15 #include "src/token.h"
20 // Common base class shared between parser and pre-parser. Traits encapsulate
21 // the differences between Parser and PreParser:
23 // - Return types: For example, Parser functions return Expression* and
24 // PreParser functions return PreParserExpression.
26 // - Creating parse tree nodes: Parser generates an AST during the recursive
27 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
28 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
29 // just enough data for the upper layer functions. PreParserFactory is
30 // responsible for creating these dummy objects. It provides a similar kind of
31 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
34 // - Miscellaneous other tasks interleaved with the recursive descent. For
35 // example, Parser keeps track of which function literals should be marked as
36 // pretenured, and PreParser doesn't care.
38 // The traits are expected to contain the following typedefs:
40 // // In particular...
42 // // Used by FunctionState and BlockState.
44 // typedef GeneratorVariable;
45 // // Return types for traversing functions.
46 // typedef Identifier;
47 // typedef Expression;
48 // typedef FunctionLiteral;
49 // typedef ClassLiteral;
50 // typedef ObjectLiteralProperty;
52 // typedef ExpressionList;
53 // typedef PropertyList;
54 // // For constructing objects returned by the traversing functions.
60 template <typename Traits>
61 class ParserBase : public Traits {
63 // Shorten type names defined by Traits.
64 typedef typename Traits::Type::Expression ExpressionT;
65 typedef typename Traits::Type::Identifier IdentifierT;
66 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
67 typedef typename Traits::Type::Literal LiteralT;
68 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
70 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
71 v8::Extension* extension, AstValueFactory* ast_value_factory,
72 ParserRecorder* log, typename Traits::Type::Parser this_object)
73 : Traits(this_object),
74 parenthesized_function_(false),
76 function_state_(NULL),
77 extension_(extension),
79 ast_value_factory_(ast_value_factory),
81 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
82 stack_limit_(stack_limit),
85 stack_overflow_(false),
87 allow_natives_(false),
88 allow_harmony_arrow_functions_(false),
89 allow_harmony_object_literals_(false),
90 allow_harmony_sloppy_(false),
91 allow_harmony_computed_property_names_(false),
92 allow_harmony_rest_params_(false),
93 allow_strong_mode_(false) {}
95 // Getters that indicate whether certain syntactical constructs are
96 // allowed to be parsed by this instance of the parser.
97 bool allow_lazy() const { return allow_lazy_; }
98 bool allow_natives() const { return allow_natives_; }
99 bool allow_harmony_arrow_functions() const {
100 return allow_harmony_arrow_functions_;
102 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); }
103 bool allow_harmony_numeric_literals() const {
104 return scanner()->HarmonyNumericLiterals();
106 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); }
107 bool allow_harmony_object_literals() const {
108 return allow_harmony_object_literals_;
110 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; }
111 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
112 bool allow_harmony_computed_property_names() const {
113 return allow_harmony_computed_property_names_;
115 bool allow_harmony_rest_params() const {
116 return allow_harmony_rest_params_;
119 bool allow_strong_mode() const { return allow_strong_mode_; }
121 // Setters that determine whether certain syntactical constructs are
122 // allowed to be parsed by this instance of the parser.
123 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
124 void set_allow_natives(bool allow) { allow_natives_ = allow; }
125 void set_allow_harmony_arrow_functions(bool allow) {
126 allow_harmony_arrow_functions_ = allow;
128 void set_allow_harmony_modules(bool allow) {
129 scanner()->SetHarmonyModules(allow);
131 void set_allow_harmony_numeric_literals(bool allow) {
132 scanner()->SetHarmonyNumericLiterals(allow);
134 void set_allow_harmony_classes(bool allow) {
135 scanner()->SetHarmonyClasses(allow);
137 void set_allow_harmony_object_literals(bool allow) {
138 allow_harmony_object_literals_ = allow;
140 void set_allow_harmony_sloppy(bool allow) {
141 allow_harmony_sloppy_ = allow;
143 void set_allow_harmony_unicode(bool allow) {
144 scanner()->SetHarmonyUnicode(allow);
146 void set_allow_harmony_computed_property_names(bool allow) {
147 allow_harmony_computed_property_names_ = allow;
149 void set_allow_harmony_rest_params(bool allow) {
150 allow_harmony_rest_params_ = allow;
152 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
155 enum AllowEvalOrArgumentsAsIdentifier {
156 kAllowEvalOrArguments,
157 kDontAllowEvalOrArguments
165 enum VariableDeclarationContext {
171 // If a list of variable declarations includes any initializers.
172 enum VariableDeclarationProperties { kHasInitializers, kHasNoInitializers };
175 class ObjectLiteralCheckerBase;
177 // ---------------------------------------------------------------------------
178 // FunctionState and BlockState together implement the parser's scope stack.
179 // The parser's current scope is in scope_. BlockState and FunctionState
180 // constructors push on the scope stack and the destructors pop. They are also
181 // used to hold the parser's per-function and per-block state.
182 class BlockState BASE_EMBEDDED {
184 BlockState(Scope** scope_stack, Scope* scope)
185 : scope_stack_(scope_stack), outer_scope_(*scope_stack), scope_(scope) {
186 *scope_stack_ = scope_;
188 ~BlockState() { *scope_stack_ = outer_scope_; }
191 Scope** scope_stack_;
196 class FunctionState BASE_EMBEDDED {
198 FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
199 Scope* scope, FunctionKind kind,
200 typename Traits::Type::Factory* factory);
203 int NextMaterializedLiteralIndex() {
204 return next_materialized_literal_index_++;
206 int materialized_literal_count() {
207 return next_materialized_literal_index_;
210 int NextHandlerIndex() { return next_handler_index_++; }
211 int handler_count() { return next_handler_index_; }
213 void AddProperty() { expected_property_count_++; }
214 int expected_property_count() { return expected_property_count_; }
216 Scanner::Location return_location() const { return return_location_; }
217 Scanner::Location super_call_location() const {
218 return super_call_location_;
220 void set_return_location(Scanner::Location location) {
221 return_location_ = location;
223 void set_super_call_location(Scanner::Location location) {
224 super_call_location_ = location;
227 bool is_generator() const { return IsGeneratorFunction(kind_); }
229 FunctionKind kind() const { return kind_; }
230 FunctionState* outer() const { return outer_function_state_; }
232 void set_generator_object_variable(
233 typename Traits::Type::GeneratorVariable* variable) {
234 DCHECK(variable != NULL);
235 DCHECK(is_generator());
236 generator_object_variable_ = variable;
238 typename Traits::Type::GeneratorVariable* generator_object_variable()
240 return generator_object_variable_;
243 typename Traits::Type::Factory* factory() { return factory_; }
246 // Used to assign an index to each literal that needs materialization in
247 // the function. Includes regexp literals, and boilerplate for object and
249 int next_materialized_literal_index_;
251 // Used to assign a per-function index to try and catch handlers.
252 int next_handler_index_;
254 // Properties count estimation.
255 int expected_property_count_;
257 // Location of most recent 'return' statement (invalid if none).
258 Scanner::Location return_location_;
260 // Location of call to the "super" constructor (invalid if none).
261 Scanner::Location super_call_location_;
264 // For generators, this variable may hold the generator object. It variable
265 // is used by yield expressions and return statements. It is not necessary
266 // for generator functions to have this variable set.
267 Variable* generator_object_variable_;
269 FunctionState** function_state_stack_;
270 FunctionState* outer_function_state_;
271 Scope** scope_stack_;
273 typename Traits::Type::Factory* factory_;
275 friend class ParserTraits;
276 friend class Checkpoint;
279 // Annoyingly, arrow functions first parse as comma expressions, then when we
280 // see the => we have to go back and reinterpret the arguments as being formal
281 // parameters. To do so we need to reset some of the parser state back to
282 // what it was before the arguments were first seen.
283 class Checkpoint BASE_EMBEDDED {
285 explicit Checkpoint(ParserBase* parser) {
286 function_state_ = parser->function_state_;
287 next_materialized_literal_index_ =
288 function_state_->next_materialized_literal_index_;
289 next_handler_index_ = function_state_->next_handler_index_;
290 expected_property_count_ = function_state_->expected_property_count_;
294 function_state_->next_materialized_literal_index_ =
295 next_materialized_literal_index_;
296 function_state_->next_handler_index_ = next_handler_index_;
297 function_state_->expected_property_count_ = expected_property_count_;
301 FunctionState* function_state_;
302 int next_materialized_literal_index_;
303 int next_handler_index_;
304 int expected_property_count_;
307 class ParsingModeScope BASE_EMBEDDED {
309 ParsingModeScope(ParserBase* parser, Mode mode)
311 old_mode_(parser->mode()) {
312 parser_->mode_ = mode;
314 ~ParsingModeScope() {
315 parser_->mode_ = old_mode_;
323 Scope* NewScope(Scope* parent, ScopeType scope_type,
324 FunctionKind kind = kNormalFunction) {
325 DCHECK(ast_value_factory());
326 DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules());
327 DCHECK((scope_type == FUNCTION_SCOPE && IsValidFunctionKind(kind)) ||
328 kind == kNormalFunction);
329 Scope* result = new (zone())
330 Scope(zone(), parent, scope_type, ast_value_factory(), kind);
331 result->Initialize();
335 Scanner* scanner() const { return scanner_; }
336 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
337 int position() { return scanner_->location().beg_pos; }
338 int peek_position() { return scanner_->peek_location().beg_pos; }
339 bool stack_overflow() const { return stack_overflow_; }
340 void set_stack_overflow() { stack_overflow_ = true; }
341 Mode mode() const { return mode_; }
342 Zone* zone() const { return zone_; }
344 INLINE(Token::Value peek()) {
345 if (stack_overflow_) return Token::ILLEGAL;
346 return scanner()->peek();
349 INLINE(Token::Value Next()) {
350 if (stack_overflow_) return Token::ILLEGAL;
352 if (GetCurrentStackPosition() < stack_limit_) {
353 // Any further calls to Next or peek will return the illegal token.
354 // The current call must return the next token, which might already
355 // have been peek'ed.
356 stack_overflow_ = true;
359 return scanner()->Next();
362 void Consume(Token::Value token) {
363 Token::Value next = Next();
366 DCHECK(next == token);
369 bool Check(Token::Value token) {
370 Token::Value next = peek();
378 void Expect(Token::Value token, bool* ok) {
379 Token::Value next = Next();
381 ReportUnexpectedToken(next);
386 void ExpectSemicolon(bool* ok) {
387 // Check for automatic semicolon insertion according to
388 // the rules given in ECMA-262, section 7.9, page 21.
389 Token::Value tok = peek();
390 if (tok == Token::SEMICOLON) {
394 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
395 tok == Token::RBRACE ||
399 Expect(Token::SEMICOLON, ok);
402 bool peek_any_identifier() {
403 Token::Value next = peek();
404 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
405 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
406 next == Token::STATIC || next == Token::YIELD;
409 bool CheckContextualKeyword(Vector<const char> keyword) {
410 if (PeekContextualKeyword(keyword)) {
411 Consume(Token::IDENTIFIER);
417 bool PeekContextualKeyword(Vector<const char> keyword) {
418 return peek() == Token::IDENTIFIER &&
419 scanner()->is_next_contextual_keyword(keyword);
422 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
423 Expect(Token::IDENTIFIER, ok);
425 if (!scanner()->is_literal_contextual_keyword(keyword)) {
426 ReportUnexpectedToken(scanner()->current_token());
432 bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) {
433 if (Check(Token::IN)) {
434 if (is_strong(language_mode())) {
435 ReportMessageAt(scanner()->location(), "strong_for_in");
438 *visit_mode = ForEachStatement::ENUMERATE;
441 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
442 *visit_mode = ForEachStatement::ITERATE;
448 // Checks whether an octal literal was last seen between beg_pos and end_pos.
449 // If so, reports an error. Only called for strict mode and template strings.
450 void CheckOctalLiteral(int beg_pos, int end_pos, const char* error,
452 Scanner::Location octal = scanner()->octal_position();
453 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
454 octal.end_pos <= end_pos) {
455 ReportMessageAt(octal, error);
456 scanner()->clear_octal_position();
461 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
462 CheckOctalLiteral(beg_pos, end_pos, "strict_octal_literal", ok);
465 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
466 CheckOctalLiteral(beg_pos, end_pos, "template_octal_literal", ok);
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, FunctionKind kind,
472 IdentifierT function_name,
473 bool function_name_is_strict_reserved,
474 const Scanner::Location& function_name_loc,
476 // Property names are never checked.
477 if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return;
478 // The function name needs to be checked in strict mode.
479 if (is_sloppy(language_mode)) return;
481 if (this->IsEvalOrArguments(function_name)) {
482 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments");
486 if (function_name_is_strict_reserved) {
487 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved");
493 // Checking the parameter names of a function literal. This has to be done
494 // after parsing the function, since the function can declare itself strict.
495 void CheckFunctionParameterNames(LanguageMode language_mode,
497 const Scanner::Location& eval_args_error_loc,
498 const Scanner::Location& dupe_error_loc,
499 const Scanner::Location& reserved_loc,
501 if (is_sloppy(language_mode) && !strict_params) return;
503 if (is_strict(language_mode) && eval_args_error_loc.IsValid()) {
504 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
508 // TODO(arv): When we add support for destructuring in setters we also need
509 // to check for duplicate names.
510 if (dupe_error_loc.IsValid()) {
511 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe");
515 if (reserved_loc.IsValid()) {
516 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
522 // Determine precedence of given token.
523 static int Precedence(Token::Value token, bool accept_IN) {
524 if (token == Token::IN && !accept_IN)
525 return 0; // 0 precedence will terminate binary expression parsing
526 return Token::Precedence(token);
529 typename Traits::Type::Factory* factory() {
530 return function_state_->factory();
533 LanguageMode language_mode() { return scope_->language_mode(); }
534 bool is_generator() const { return function_state_->is_generator(); }
536 // Report syntax errors.
537 void ReportMessage(const char* message, const char* arg = NULL,
538 ParseErrorType error_type = kSyntaxError) {
539 Scanner::Location source_location = scanner()->location();
540 Traits::ReportMessageAt(source_location, message, arg, error_type);
543 void ReportMessageAt(Scanner::Location location, const char* message,
544 ParseErrorType error_type = kSyntaxError) {
545 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
549 void ReportUnexpectedToken(Token::Value token);
550 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token);
552 // Recursive descent functions:
554 // Parses an identifier that is valid for the current scope, in particular it
555 // fails on strict mode future reserved keywords in a strict scope. If
556 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
557 // "arguments" as identifier even in strict mode (this is needed in cases like
558 // "var foo = eval;").
559 IdentifierT ParseIdentifier(
560 AllowEvalOrArgumentsAsIdentifier,
562 // Parses an identifier or a strict mode future reserved word, and indicate
563 // whether it is strict mode future reserved.
564 IdentifierT ParseIdentifierOrStrictReservedWord(
565 bool* is_strict_reserved,
567 IdentifierT ParseIdentifierName(bool* ok);
568 // Parses an identifier and determines whether or not it is 'get' or 'set'.
569 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
573 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
575 ExpressionT ParsePrimaryExpression(bool* ok);
576 ExpressionT ParseExpression(bool accept_IN, bool* ok);
577 ExpressionT ParseArrayLiteral(bool* ok);
578 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
579 bool* is_static, bool* is_computed_name,
581 ExpressionT ParseObjectLiteral(bool* ok);
582 ObjectLiteralPropertyT ParsePropertyDefinition(
583 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
584 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
586 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
587 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
588 ExpressionT ParseYieldExpression(bool* ok);
589 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
590 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
591 ExpressionT ParseUnaryExpression(bool* ok);
592 ExpressionT ParsePostfixExpression(bool* ok);
593 ExpressionT ParseLeftHandSideExpression(bool* ok);
594 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
595 ExpressionT ParseMemberExpression(bool* ok);
596 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
598 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
600 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
601 void AddTemplateExpression(ExpressionT);
602 ExpressionT ParseSuperExpression(bool is_new, bool* ok);
604 // Checks if the expression is a valid reference expression (e.g., on the
605 // left-hand side of assignments). Although ruled out by ECMA as early errors,
606 // we allow calls for web compatibility and rewrite them to a runtime throw.
607 ExpressionT CheckAndRewriteReferenceExpression(
608 ExpressionT expression,
609 Scanner::Location location, const char* message, bool* ok);
611 // Used to validate property names in object literals and class literals
618 class ObjectLiteralCheckerBase {
620 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
622 virtual void CheckProperty(Token::Value property, PropertyKind type,
623 bool is_static, bool is_generator, bool* ok) = 0;
625 virtual ~ObjectLiteralCheckerBase() {}
628 ParserBase* parser() const { return parser_; }
629 Scanner* scanner() const { return parser_->scanner(); }
635 // Validation per ES6 object literals.
636 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
638 explicit ObjectLiteralChecker(ParserBase* parser)
639 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
641 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
642 bool is_generator, bool* ok) OVERRIDE;
645 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
647 bool has_seen_proto_;
650 // Validation per ES6 class literals.
651 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
653 explicit ClassLiteralChecker(ParserBase* parser)
654 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
656 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
657 bool is_generator, bool* ok) OVERRIDE;
660 bool IsConstructor() {
661 return this->scanner()->LiteralMatches("constructor", 11);
664 return this->scanner()->LiteralMatches("prototype", 9);
667 bool has_seen_constructor_;
670 // If true, the next (and immediately following) function literal is
671 // preceded by a parenthesis.
672 // Heuristically that means that the function will be called immediately,
673 // so never lazily compile it.
674 bool parenthesized_function_;
676 Scope* scope_; // Scope stack.
677 FunctionState* function_state_; // Function state stack.
678 v8::Extension* extension_;
679 FuncNameInferrer* fni_;
680 AstValueFactory* ast_value_factory_; // Not owned.
681 ParserRecorder* log_;
683 uintptr_t stack_limit_;
689 bool stack_overflow_;
693 bool allow_harmony_arrow_functions_;
694 bool allow_harmony_object_literals_;
695 bool allow_harmony_sloppy_;
696 bool allow_harmony_computed_property_names_;
697 bool allow_harmony_rest_params_;
698 bool allow_strong_mode_;
702 class PreParserIdentifier {
704 PreParserIdentifier() : type_(kUnknownIdentifier) {}
705 static PreParserIdentifier Default() {
706 return PreParserIdentifier(kUnknownIdentifier);
708 static PreParserIdentifier Eval() {
709 return PreParserIdentifier(kEvalIdentifier);
711 static PreParserIdentifier Arguments() {
712 return PreParserIdentifier(kArgumentsIdentifier);
714 static PreParserIdentifier FutureReserved() {
715 return PreParserIdentifier(kFutureReservedIdentifier);
717 static PreParserIdentifier FutureStrictReserved() {
718 return PreParserIdentifier(kFutureStrictReservedIdentifier);
720 static PreParserIdentifier Let() {
721 return PreParserIdentifier(kLetIdentifier);
723 static PreParserIdentifier Static() {
724 return PreParserIdentifier(kStaticIdentifier);
726 static PreParserIdentifier Yield() {
727 return PreParserIdentifier(kYieldIdentifier);
729 static PreParserIdentifier Prototype() {
730 return PreParserIdentifier(kPrototypeIdentifier);
732 static PreParserIdentifier Constructor() {
733 return PreParserIdentifier(kConstructorIdentifier);
735 bool IsEval() const { return type_ == kEvalIdentifier; }
736 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
737 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
738 bool IsLet() const { return type_ == kLetIdentifier; }
739 bool IsStatic() const { return type_ == kStaticIdentifier; }
740 bool IsYield() const { return type_ == kYieldIdentifier; }
741 bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
742 bool IsConstructor() const { return type_ == kConstructorIdentifier; }
743 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
744 bool IsFutureStrictReserved() const {
745 return type_ == kFutureStrictReservedIdentifier ||
746 type_ == kLetIdentifier || type_ == kStaticIdentifier ||
747 type_ == kYieldIdentifier;
749 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; }
750 V8_INLINE bool IsValidArrowParam() const {
751 // A valid identifier can be an arrow function parameter
752 // except for eval, arguments, yield, and reserved keywords.
753 return !(IsEval() || IsArguments() || IsFutureStrictReserved());
756 // Allow identifier->name()[->length()] to work. The preparser
757 // does not need the actual positions/lengths of the identifiers.
758 const PreParserIdentifier* operator->() const { return this; }
759 const PreParserIdentifier raw_name() const { return *this; }
761 int position() const { return 0; }
762 int length() const { return 0; }
767 kFutureReservedIdentifier,
768 kFutureStrictReservedIdentifier,
773 kArgumentsIdentifier,
774 kPrototypeIdentifier,
775 kConstructorIdentifier
777 explicit PreParserIdentifier(Type type) : type_(type) {}
780 friend class PreParserExpression;
784 class PreParserExpression {
786 static PreParserExpression Default() {
787 return PreParserExpression(TypeField::encode(kExpression));
790 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
791 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
792 IdentifierTypeField::encode(id.type_));
795 static PreParserExpression BinaryOperation(PreParserExpression left,
797 PreParserExpression right) {
798 bool valid_arrow_param_list =
799 op == Token::COMMA && !left.is_parenthesized() &&
800 !right.is_parenthesized() && left.IsValidArrowParams() &&
801 right.IsValidArrowParams();
802 return PreParserExpression(
803 TypeField::encode(kBinaryOperationExpression) |
804 IsValidArrowParamListField::encode(valid_arrow_param_list));
807 static PreParserExpression EmptyArrowParamList() {
808 // Any expression for which IsValidArrowParamList() returns true
810 return FromIdentifier(PreParserIdentifier::Default());
813 static PreParserExpression StringLiteral() {
814 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
817 static PreParserExpression UseStrictStringLiteral() {
818 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
819 IsUseStrictField::encode(true));
822 static PreParserExpression UseStrongStringLiteral() {
823 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
824 IsUseStrongField::encode(true));
827 static PreParserExpression This() {
828 return PreParserExpression(TypeField::encode(kExpression) |
829 ExpressionTypeField::encode(kThisExpression));
832 static PreParserExpression ThisProperty() {
833 return PreParserExpression(
834 TypeField::encode(kExpression) |
835 ExpressionTypeField::encode(kThisPropertyExpression));
838 static PreParserExpression Property() {
839 return PreParserExpression(
840 TypeField::encode(kExpression) |
841 ExpressionTypeField::encode(kPropertyExpression));
844 static PreParserExpression Call() {
845 return PreParserExpression(TypeField::encode(kExpression) |
846 ExpressionTypeField::encode(kCallExpression));
849 static PreParserExpression NoTemplateTag() {
850 return PreParserExpression(TypeField::encode(kExpression) |
851 ExpressionTypeField::encode(
852 kNoTemplateTagExpression));
855 bool IsIdentifier() const {
856 return TypeField::decode(code_) == kIdentifierExpression;
859 PreParserIdentifier AsIdentifier() const {
860 DCHECK(IsIdentifier());
861 return PreParserIdentifier(IdentifierTypeField::decode(code_));
864 bool IsStringLiteral() const {
865 return TypeField::decode(code_) == kStringLiteralExpression;
868 bool IsUseStrictLiteral() const {
869 return TypeField::decode(code_) == kStringLiteralExpression &&
870 IsUseStrictField::decode(code_);
873 bool IsUseStrongLiteral() const {
874 return TypeField::decode(code_) == kStringLiteralExpression &&
875 IsUseStrongField::decode(code_);
878 bool IsThis() const {
879 return TypeField::decode(code_) == kExpression &&
880 ExpressionTypeField::decode(code_) == kThisExpression;
883 bool IsThisProperty() const {
884 return TypeField::decode(code_) == kExpression &&
885 ExpressionTypeField::decode(code_) == kThisPropertyExpression;
888 bool IsProperty() const {
889 return TypeField::decode(code_) == kExpression &&
890 (ExpressionTypeField::decode(code_) == kPropertyExpression ||
891 ExpressionTypeField::decode(code_) == kThisPropertyExpression);
894 bool IsCall() const {
895 return TypeField::decode(code_) == kExpression &&
896 ExpressionTypeField::decode(code_) == kCallExpression;
899 bool IsValidReferenceExpression() const {
900 return IsIdentifier() || IsProperty();
903 bool IsValidArrowParamList() const {
904 return IsValidArrowParams() &&
905 ParenthesizationField::decode(code_) !=
906 kMultiParenthesizedExpression;
909 // At the moment PreParser doesn't track these expression types.
910 bool IsFunctionLiteral() const { return false; }
911 bool IsCallNew() const { return false; }
913 bool IsNoTemplateTag() const {
914 return TypeField::decode(code_) == kExpression &&
915 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
918 PreParserExpression AsFunctionLiteral() { return *this; }
920 bool IsBinaryOperation() const {
921 return TypeField::decode(code_) == kBinaryOperationExpression;
924 bool is_parenthesized() const {
925 return ParenthesizationField::decode(code_) != kNotParenthesized;
928 void increase_parenthesization_level() {
929 code_ = ParenthesizationField::update(
930 code_, is_parenthesized() ? kMultiParenthesizedExpression
931 : kParanthesizedExpression);
934 // Dummy implementation for making expression->somefunc() work in both Parser
936 PreParserExpression* operator->() { return this; }
938 // More dummy implementations of things PreParser doesn't need to track:
939 void set_index(int index) {} // For YieldExpressions
940 void set_parenthesized() {}
942 int position() const { return RelocInfo::kNoPosition; }
943 void set_function_token_position(int position) {}
948 kIdentifierExpression,
949 kStringLiteralExpression,
950 kBinaryOperationExpression
953 enum Parenthesization {
955 kParanthesizedExpression,
956 kMultiParenthesizedExpression
959 enum ExpressionType {
961 kThisPropertyExpression,
964 kNoTemplateTagExpression
967 explicit PreParserExpression(uint32_t expression_code)
968 : code_(expression_code) {}
970 V8_INLINE bool IsValidArrowParams() const {
971 return IsBinaryOperation()
972 ? IsValidArrowParamListField::decode(code_)
973 : (IsIdentifier() && AsIdentifier().IsValidArrowParam());
976 // The first four bits are for the Type and Parenthesization.
977 typedef BitField<Type, 0, 2> TypeField;
978 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField;
980 // The rest of the bits are interpreted depending on the value
981 // of the Type field, so they can share the storage.
982 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3>
984 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField;
985 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
986 typedef BitField<bool, ParenthesizationField::kNext, 1>
987 IsValidArrowParamListField;
988 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10>
995 // PreParserExpressionList doesn't actually store the expressions because
996 // PreParser doesn't need to.
997 class PreParserExpressionList {
999 // These functions make list->Add(some_expression) work (and do nothing).
1000 PreParserExpressionList() : length_(0) {}
1001 PreParserExpressionList* operator->() { return this; }
1002 void Add(PreParserExpression, void*) { ++length_; }
1003 int length() const { return length_; }
1009 class PreParserStatement {
1011 static PreParserStatement Default() {
1012 return PreParserStatement(kUnknownStatement);
1015 static PreParserStatement FunctionDeclaration() {
1016 return PreParserStatement(kFunctionDeclaration);
1019 // Creates expression statement from expression.
1020 // Preserves being an unparenthesized string literal, possibly
1022 static PreParserStatement ExpressionStatement(
1023 PreParserExpression expression) {
1024 if (expression.IsUseStrictLiteral()) {
1025 return PreParserStatement(kUseStrictExpressionStatement);
1027 if (expression.IsUseStrongLiteral()) {
1028 return PreParserStatement(kUseStrongExpressionStatement);
1030 if (expression.IsStringLiteral()) {
1031 return PreParserStatement(kStringLiteralExpressionStatement);
1036 bool IsStringLiteral() {
1037 return code_ == kStringLiteralExpressionStatement;
1040 bool IsUseStrictLiteral() {
1041 return code_ == kUseStrictExpressionStatement;
1044 bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
1046 bool IsFunctionDeclaration() {
1047 return code_ == kFunctionDeclaration;
1053 kStringLiteralExpressionStatement,
1054 kUseStrictExpressionStatement,
1055 kUseStrongExpressionStatement,
1056 kFunctionDeclaration
1059 explicit PreParserStatement(Type code) : code_(code) {}
1065 // PreParserStatementList doesn't actually store the statements because
1066 // the PreParser does not need them.
1067 class PreParserStatementList {
1069 // These functions make list->Add(some_expression) work as no-ops.
1070 PreParserStatementList() {}
1071 PreParserStatementList* operator->() { return this; }
1072 void Add(PreParserStatement, void*) {}
1076 class PreParserFactory {
1078 explicit PreParserFactory(void* unused_value_factory) {}
1079 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
1081 return PreParserExpression::Default();
1083 PreParserExpression NewNumberLiteral(double number,
1085 return PreParserExpression::Default();
1087 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
1088 PreParserIdentifier js_flags,
1091 return PreParserExpression::Default();
1093 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1096 return PreParserExpression::Default();
1098 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1099 PreParserExpression value,
1100 ObjectLiteralProperty::Kind kind,
1102 bool is_computed_name) {
1103 return PreParserExpression::Default();
1105 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1106 PreParserExpression value,
1108 bool is_computed_name) {
1109 return PreParserExpression::Default();
1111 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
1113 int boilerplate_properties,
1116 return PreParserExpression::Default();
1118 PreParserExpression NewVariableProxy(void* variable) {
1119 return PreParserExpression::Default();
1121 PreParserExpression NewProperty(PreParserExpression obj,
1122 PreParserExpression key,
1125 return PreParserExpression::ThisProperty();
1127 return PreParserExpression::Property();
1129 PreParserExpression NewUnaryOperation(Token::Value op,
1130 PreParserExpression expression,
1132 return PreParserExpression::Default();
1134 PreParserExpression NewBinaryOperation(Token::Value op,
1135 PreParserExpression left,
1136 PreParserExpression right, int pos) {
1137 return PreParserExpression::BinaryOperation(left, op, right);
1139 PreParserExpression NewCompareOperation(Token::Value op,
1140 PreParserExpression left,
1141 PreParserExpression right, int pos) {
1142 return PreParserExpression::Default();
1144 PreParserExpression NewAssignment(Token::Value op,
1145 PreParserExpression left,
1146 PreParserExpression right,
1148 return PreParserExpression::Default();
1150 PreParserExpression NewYield(PreParserExpression generator_object,
1151 PreParserExpression expression,
1152 Yield::Kind yield_kind,
1154 return PreParserExpression::Default();
1156 PreParserExpression NewConditional(PreParserExpression condition,
1157 PreParserExpression then_expression,
1158 PreParserExpression else_expression,
1160 return PreParserExpression::Default();
1162 PreParserExpression NewCountOperation(Token::Value op,
1164 PreParserExpression expression,
1166 return PreParserExpression::Default();
1168 PreParserExpression NewCall(PreParserExpression expression,
1169 PreParserExpressionList arguments,
1171 return PreParserExpression::Call();
1173 PreParserExpression NewCallNew(PreParserExpression expression,
1174 PreParserExpressionList arguments,
1176 return PreParserExpression::Default();
1178 PreParserStatement NewReturnStatement(PreParserExpression expression,
1180 return PreParserStatement::Default();
1182 PreParserExpression NewFunctionLiteral(
1183 PreParserIdentifier name, AstValueFactory* ast_value_factory,
1184 Scope* scope, PreParserStatementList body, int materialized_literal_count,
1185 int expected_property_count, int handler_count, int parameter_count,
1186 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1187 FunctionLiteral::FunctionType function_type,
1188 FunctionLiteral::IsFunctionFlag is_function,
1189 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
1191 return PreParserExpression::Default();
1194 // Return the object itself as AstVisitor and implement the needed
1195 // dummy method right in this class.
1196 PreParserFactory* visitor() { return this; }
1197 int* ast_properties() {
1198 static int dummy = 42;
1206 class PreParserTraits {
1209 // TODO(marja): To be removed. The Traits object should contain all the data
1211 typedef PreParser* Parser;
1213 // PreParser doesn't need to store generator variables.
1214 typedef void GeneratorVariable;
1216 typedef int AstProperties;
1218 // Return types for traversing functions.
1219 typedef PreParserIdentifier Identifier;
1220 typedef PreParserExpression Expression;
1221 typedef PreParserExpression YieldExpression;
1222 typedef PreParserExpression FunctionLiteral;
1223 typedef PreParserExpression ClassLiteral;
1224 typedef PreParserExpression ObjectLiteralProperty;
1225 typedef PreParserExpression Literal;
1226 typedef PreParserExpressionList ExpressionList;
1227 typedef PreParserExpressionList PropertyList;
1228 typedef PreParserStatementList StatementList;
1230 // For constructing objects returned by the traversing functions.
1231 typedef PreParserFactory Factory;
1234 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
1236 // Helper functions for recursive descent.
1237 static bool IsEval(PreParserIdentifier identifier) {
1238 return identifier.IsEval();
1241 static bool IsArguments(PreParserIdentifier identifier) {
1242 return identifier.IsArguments();
1245 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
1246 return identifier.IsEvalOrArguments();
1249 static bool IsPrototype(PreParserIdentifier identifier) {
1250 return identifier.IsPrototype();
1253 static bool IsConstructor(PreParserIdentifier identifier) {
1254 return identifier.IsConstructor();
1257 // Returns true if the expression is of type "this.foo".
1258 static bool IsThisProperty(PreParserExpression expression) {
1259 return expression.IsThisProperty();
1262 static bool IsIdentifier(PreParserExpression expression) {
1263 return expression.IsIdentifier();
1266 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
1267 return expression.AsIdentifier();
1270 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1271 return identifier.IsFutureStrictReserved();
1274 static bool IsBoilerplateProperty(PreParserExpression property) {
1275 // PreParser doesn't count boilerplate properties.
1279 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
1283 static PreParserExpression GetPropertyValue(PreParserExpression property) {
1284 return PreParserExpression::Default();
1287 // Functions for encapsulating the differences between parsing and preparsing;
1288 // operations interleaved with the recursive descent.
1289 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1290 // PreParser should not use FuncNameInferrer.
1294 static void PushPropertyName(FuncNameInferrer* fni,
1295 PreParserExpression expression) {
1296 // PreParser should not use FuncNameInferrer.
1300 static void InferFunctionName(FuncNameInferrer* fni,
1301 PreParserExpression expression) {
1302 // PreParser should not use FuncNameInferrer.
1306 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
1307 Scope* scope, PreParserExpression property, bool* has_function) {}
1309 static void CheckAssigningFunctionLiteralToProperty(
1310 PreParserExpression left, PreParserExpression right) {}
1312 // PreParser doesn't need to keep track of eval calls.
1313 static void CheckPossibleEvalCall(PreParserExpression expression,
1316 static PreParserExpression MarkExpressionAsAssigned(
1317 PreParserExpression expression) {
1318 // TODO(marja): To be able to produce the same errors, the preparser needs
1319 // to start tracking which expressions are variables and which are assigned.
1323 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
1324 PreParserExpression y,
1327 PreParserFactory* factory) {
1331 PreParserExpression BuildUnaryExpression(PreParserExpression expression,
1332 Token::Value op, int pos,
1333 PreParserFactory* factory) {
1334 return PreParserExpression::Default();
1337 PreParserExpression NewThrowReferenceError(const char* type, int pos) {
1338 return PreParserExpression::Default();
1340 PreParserExpression NewThrowSyntaxError(
1341 const char* type, Handle<Object> arg, int pos) {
1342 return PreParserExpression::Default();
1344 PreParserExpression NewThrowTypeError(
1345 const char* type, Handle<Object> arg, int pos) {
1346 return PreParserExpression::Default();
1349 // Reporting errors.
1350 void ReportMessageAt(Scanner::Location location, const char* message,
1351 const char* arg = NULL,
1352 ParseErrorType error_type = kSyntaxError);
1353 void ReportMessageAt(int start_pos, int end_pos, const char* message,
1354 const char* arg = NULL,
1355 ParseErrorType error_type = kSyntaxError);
1357 // "null" return type creators.
1358 static PreParserIdentifier EmptyIdentifier() {
1359 return PreParserIdentifier::Default();
1361 static PreParserIdentifier EmptyIdentifierString() {
1362 return PreParserIdentifier::Default();
1364 static PreParserExpression EmptyExpression() {
1365 return PreParserExpression::Default();
1367 static PreParserExpression EmptyArrowParamList() {
1368 return PreParserExpression::EmptyArrowParamList();
1370 static PreParserExpression EmptyLiteral() {
1371 return PreParserExpression::Default();
1373 static PreParserExpression EmptyObjectLiteralProperty() {
1374 return PreParserExpression::Default();
1376 static PreParserExpression EmptyFunctionLiteral() {
1377 return PreParserExpression::Default();
1379 static PreParserExpressionList NullExpressionList() {
1380 return PreParserExpressionList();
1383 // Odd-ball literal creators.
1384 static PreParserExpression GetLiteralTheHole(int position,
1385 PreParserFactory* factory) {
1386 return PreParserExpression::Default();
1389 // Producing data during the recursive descent.
1390 PreParserIdentifier GetSymbol(Scanner* scanner);
1391 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
1393 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1394 return PreParserIdentifier::Default();
1397 static PreParserExpression ThisExpression(Scope* scope,
1398 PreParserFactory* factory,
1400 return PreParserExpression::This();
1403 static PreParserExpression SuperReference(Scope* scope,
1404 PreParserFactory* factory) {
1405 return PreParserExpression::Default();
1408 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
1409 int pos, int end_pos) {
1410 return PreParserExpression::Default();
1413 static PreParserExpression ExpressionFromLiteral(
1414 Token::Value token, int pos, Scanner* scanner,
1415 PreParserFactory* factory) {
1416 return PreParserExpression::Default();
1419 static PreParserExpression ExpressionFromIdentifier(
1420 PreParserIdentifier name, int start_position, int end_position,
1421 Scope* scope, PreParserFactory* factory) {
1422 return PreParserExpression::FromIdentifier(name);
1425 PreParserExpression ExpressionFromString(int pos,
1427 PreParserFactory* factory = NULL);
1429 PreParserExpression GetIterator(PreParserExpression iterable,
1430 PreParserFactory* factory) {
1431 return PreParserExpression::Default();
1434 static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
1435 return PreParserExpressionList();
1438 static PreParserStatementList NewStatementList(int size, Zone* zone) {
1439 return PreParserStatementList();
1442 static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
1443 return PreParserExpressionList();
1446 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
1447 int* materialized_literal_count,
1448 int* expected_property_count, bool* ok) {
1452 V8_INLINE PreParserStatementList
1453 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
1454 Variable* fvar, Token::Value fvar_init_op,
1455 FunctionKind kind, bool* ok);
1457 // Utility functions
1458 int DeclareArrowParametersFromExpression(PreParserExpression expression,
1460 Scanner::Location* dupe_loc,
1462 // TODO(aperez): Detect duplicated identifiers in paramlists.
1463 *ok = expression.IsValidArrowParamList();
1467 struct TemplateLiteralState {};
1469 TemplateLiteralState OpenTemplateLiteral(int pos) {
1470 return TemplateLiteralState();
1472 void AddTemplateSpan(TemplateLiteralState*, bool) {}
1473 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
1474 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
1475 PreParserExpression tag) {
1476 if (IsTaggedTemplate(tag)) {
1477 // Emulate generation of array literals for tag callsite
1478 // 1st is array of cooked strings, second is array of raw strings
1479 MaterializeTemplateCallsiteLiterals();
1481 return EmptyExpression();
1483 inline void MaterializeTemplateCallsiteLiterals();
1484 PreParserExpression NoTemplateTag() {
1485 return PreParserExpression::NoTemplateTag();
1487 static bool IsTaggedTemplate(const PreParserExpression tag) {
1488 return !tag.IsNoTemplateTag();
1491 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
1493 // Temporary glue; these functions will move to ParserBase.
1494 PreParserExpression ParseV8Intrinsic(bool* ok);
1495 PreParserExpression ParseFunctionLiteral(
1496 PreParserIdentifier name, Scanner::Location function_name_location,
1497 bool name_is_strict_reserved, FunctionKind kind,
1498 int function_token_position, FunctionLiteral::FunctionType type,
1499 FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
1501 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1502 Scanner::Location class_name_location,
1503 bool name_is_strict_reserved, int pos,
1507 PreParser* pre_parser_;
1511 // Preparsing checks a JavaScript program and emits preparse-data that helps
1512 // a later parsing to be faster.
1513 // See preparse-data-format.h for the data format.
1515 // The PreParser checks that the syntax follows the grammar for JavaScript,
1516 // and collects some information about the program along the way.
1517 // The grammar check is only performed in order to understand the program
1518 // sufficiently to deduce some information about it, that can be used
1519 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
1520 // rather it is to speed up properly written and correct programs.
1521 // That means that contextual checks (like a label being declared where
1522 // it is used) are generally omitted.
1523 class PreParser : public ParserBase<PreParserTraits> {
1525 typedef PreParserIdentifier Identifier;
1526 typedef PreParserExpression Expression;
1527 typedef PreParserStatement Statement;
1529 enum PreParseResult {
1530 kPreParseStackOverflow,
1534 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
1535 ParserRecorder* log, uintptr_t stack_limit)
1536 : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
1537 ast_value_factory, log, this) {}
1539 // Pre-parse the program from the character stream; returns true on
1540 // success (even if parsing failed, the pre-parse data successfully
1541 // captured the syntax error), and false if a stack-overflow happened
1543 PreParseResult PreParseProgram(int* materialized_literals = 0) {
1544 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1545 PreParserFactory factory(NULL);
1546 FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
1549 int start_position = scanner()->peek_location().beg_pos;
1550 ParseStatementList(Token::EOS, &ok);
1551 if (stack_overflow()) return kPreParseStackOverflow;
1553 ReportUnexpectedToken(scanner()->current_token());
1554 } else if (is_strict(scope_->language_mode())) {
1555 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
1558 if (materialized_literals) {
1559 *materialized_literals = function_state_->materialized_literal_count();
1561 return kPreParseSuccess;
1564 // Parses a single function literal, from the opening parentheses before
1565 // parameters to the closing brace after the body.
1566 // Returns a FunctionEntry describing the body of the function in enough
1567 // detail that it can be lazily compiled.
1568 // The scanner is expected to have matched the "function" or "function*"
1569 // keyword and parameters, and have consumed the initial '{'.
1570 // At return, unless an error occurred, the scanner is positioned before the
1572 PreParseResult PreParseLazyFunction(LanguageMode language_mode,
1573 FunctionKind kind, ParserRecorder* log);
1576 friend class PreParserTraits;
1578 // These types form an algebra over syntactic categories that is just
1579 // rich enough to let us recognize and propagate the constructs that
1580 // are either being counted in the preparser data, or is important
1581 // to throw the correct syntax error exceptions.
1583 // All ParseXXX functions take as the last argument an *ok parameter
1584 // which is set to false if parsing failed; it is unchanged otherwise.
1585 // By making the 'exception handling' explicit, we are forced to check
1586 // for failure at the call sites.
1587 Statement ParseStatementListItem(bool* ok);
1588 void ParseStatementList(int end_token, bool* ok);
1589 Statement ParseStatement(bool* ok);
1590 Statement ParseSubStatement(bool* ok);
1591 Statement ParseFunctionDeclaration(bool* ok);
1592 Statement ParseClassDeclaration(bool* ok);
1593 Statement ParseBlock(bool* ok);
1594 Statement ParseVariableStatement(VariableDeclarationContext var_context,
1596 Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1597 VariableDeclarationProperties* decl_props,
1600 Statement ParseExpressionOrLabelledStatement(bool* ok);
1601 Statement ParseIfStatement(bool* ok);
1602 Statement ParseContinueStatement(bool* ok);
1603 Statement ParseBreakStatement(bool* ok);
1604 Statement ParseReturnStatement(bool* ok);
1605 Statement ParseWithStatement(bool* ok);
1606 Statement ParseSwitchStatement(bool* ok);
1607 Statement ParseDoWhileStatement(bool* ok);
1608 Statement ParseWhileStatement(bool* ok);
1609 Statement ParseForStatement(bool* ok);
1610 Statement ParseThrowStatement(bool* ok);
1611 Statement ParseTryStatement(bool* ok);
1612 Statement ParseDebuggerStatement(bool* ok);
1613 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1614 Expression ParseObjectLiteral(bool* ok);
1615 Expression ParseV8Intrinsic(bool* ok);
1617 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
1618 int* materialized_literal_count,
1619 int* expected_property_count, bool* ok);
1620 V8_INLINE PreParserStatementList
1621 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
1622 Variable* fvar, Token::Value fvar_init_op,
1623 FunctionKind kind, bool* ok);
1625 Expression ParseFunctionLiteral(
1626 Identifier name, Scanner::Location function_name_location,
1627 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
1628 FunctionLiteral::FunctionType function_type,
1629 FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
1630 void ParseLazyFunctionLiteralBody(bool* ok);
1632 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1633 Scanner::Location class_name_location,
1634 bool name_is_strict_reserved, int pos,
1639 void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1640 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1641 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1645 PreParserStatementList PreParser::ParseEagerFunctionBody(
1646 PreParserIdentifier function_name, int pos, Variable* fvar,
1647 Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
1648 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1650 ParseStatementList(Token::RBRACE, ok);
1651 if (!*ok) return PreParserStatementList();
1653 Expect(Token::RBRACE, ok);
1654 return PreParserStatementList();
1658 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1659 PreParserIdentifier function_name, int pos, Variable* fvar,
1660 Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
1661 return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar,
1662 fvar_init_op, kind, ok);
1666 template <class Traits>
1667 ParserBase<Traits>::FunctionState::FunctionState(
1668 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1669 FunctionKind kind, typename Traits::Type::Factory* factory)
1670 : next_materialized_literal_index_(0),
1671 next_handler_index_(0),
1672 expected_property_count_(0),
1673 return_location_(Scanner::Location::invalid()),
1674 super_call_location_(Scanner::Location::invalid()),
1676 generator_object_variable_(NULL),
1677 function_state_stack_(function_state_stack),
1678 outer_function_state_(*function_state_stack),
1679 scope_stack_(scope_stack),
1680 outer_scope_(*scope_stack),
1682 *scope_stack_ = scope;
1683 *function_state_stack = this;
1687 template <class Traits>
1688 ParserBase<Traits>::FunctionState::~FunctionState() {
1689 *scope_stack_ = outer_scope_;
1690 *function_state_stack_ = outer_function_state_;
1694 template<class Traits>
1695 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1696 return ReportUnexpectedTokenAt(scanner_->location(), token);
1700 template<class Traits>
1701 void ParserBase<Traits>::ReportUnexpectedTokenAt(
1702 Scanner::Location source_location, Token::Value token) {
1704 // Four of the tokens are treated specially
1707 return ReportMessageAt(source_location, "unexpected_eos");
1710 return ReportMessageAt(source_location, "unexpected_token_number");
1712 return ReportMessageAt(source_location, "unexpected_token_string");
1713 case Token::IDENTIFIER:
1714 return ReportMessageAt(source_location, "unexpected_token_identifier");
1715 case Token::FUTURE_RESERVED_WORD:
1716 return ReportMessageAt(source_location, "unexpected_reserved");
1720 case Token::FUTURE_STRICT_RESERVED_WORD:
1721 return ReportMessageAt(source_location,
1722 is_strict(language_mode())
1723 ? "unexpected_strict_reserved"
1724 : "unexpected_token_identifier");
1725 case Token::TEMPLATE_SPAN:
1726 case Token::TEMPLATE_TAIL:
1727 return Traits::ReportMessageAt(source_location,
1728 "unexpected_template_string");
1730 const char* name = Token::String(token);
1731 DCHECK(name != NULL);
1732 Traits::ReportMessageAt(source_location, "unexpected_token", name);
1737 template<class Traits>
1738 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1739 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1741 Token::Value next = Next();
1742 if (next == Token::IDENTIFIER) {
1743 IdentifierT name = this->GetSymbol(scanner());
1744 if (allow_eval_or_arguments == kDontAllowEvalOrArguments) {
1745 if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) {
1746 ReportMessage("strict_eval_arguments");
1750 if (is_strong(language_mode()) && this->IsArguments(name)) {
1751 ReportMessage("strong_arguments");
1755 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1757 } else if (is_sloppy(language_mode()) &&
1758 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1759 next == Token::LET || next == Token::STATIC ||
1760 (next == Token::YIELD && !is_generator()))) {
1761 return this->GetSymbol(scanner());
1763 this->ReportUnexpectedToken(next);
1765 return Traits::EmptyIdentifier();
1770 template <class Traits>
1771 typename ParserBase<Traits>::IdentifierT ParserBase<
1772 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1774 Token::Value next = Next();
1775 if (next == Token::IDENTIFIER) {
1776 *is_strict_reserved = false;
1777 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1778 next == Token::STATIC ||
1779 (next == Token::YIELD && !this->is_generator())) {
1780 *is_strict_reserved = true;
1782 ReportUnexpectedToken(next);
1784 return Traits::EmptyIdentifier();
1787 IdentifierT name = this->GetSymbol(scanner());
1788 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1793 template <class Traits>
1794 typename ParserBase<Traits>::IdentifierT
1795 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1796 Token::Value next = Next();
1797 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
1798 next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
1799 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1800 this->ReportUnexpectedToken(next);
1802 return Traits::EmptyIdentifier();
1805 IdentifierT name = this->GetSymbol(scanner());
1806 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1811 template <class Traits>
1812 typename ParserBase<Traits>::IdentifierT
1813 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
1816 IdentifierT result = ParseIdentifierName(ok);
1817 if (!*ok) return Traits::EmptyIdentifier();
1818 scanner()->IsGetOrSet(is_get, is_set);
1823 template <class Traits>
1824 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1825 bool seen_equal, bool* ok) {
1826 int pos = peek_position();
1827 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1829 ReportMessage("unterminated_regexp");
1831 return Traits::EmptyExpression();
1834 int literal_index = function_state_->NextMaterializedLiteralIndex();
1836 IdentifierT js_pattern = this->GetNextSymbol(scanner());
1837 if (!scanner()->ScanRegExpFlags()) {
1839 ReportMessage("malformed_regexp_flags");
1841 return Traits::EmptyExpression();
1843 IdentifierT js_flags = this->GetNextSymbol(scanner());
1845 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1849 #define CHECK_OK ok); \
1850 if (!*ok) return this->EmptyExpression(); \
1852 #define DUMMY ) // to make indentation work
1855 // Used in functions where the return type is not ExpressionT.
1856 #define CHECK_OK_CUSTOM(x) ok); \
1857 if (!*ok) return this->x(); \
1859 #define DUMMY ) // to make indentation work
1862 template <class Traits>
1863 typename ParserBase<Traits>::ExpressionT
1864 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
1865 // PrimaryExpression ::
1877 // '(' Expression ')'
1880 int beg_pos = scanner()->peek_location().beg_pos;
1881 int end_pos = scanner()->peek_location().end_pos;
1882 ExpressionT result = this->EmptyExpression();
1883 Token::Value token = peek();
1886 Consume(Token::THIS);
1887 scope_->RecordThisUsage();
1888 result = this->ThisExpression(scope_, factory(), beg_pos);
1892 case Token::NULL_LITERAL:
1893 case Token::TRUE_LITERAL:
1894 case Token::FALSE_LITERAL:
1899 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
1902 case Token::IDENTIFIER:
1906 case Token::FUTURE_STRICT_RESERVED_WORD: {
1907 // Using eval or arguments in this context is OK even in strict mode.
1908 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1909 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
1914 case Token::STRING: {
1915 Consume(Token::STRING);
1916 result = this->ExpressionFromString(beg_pos, scanner(), factory());
1920 case Token::ASSIGN_DIV:
1921 result = this->ParseRegExpLiteral(true, CHECK_OK);
1925 result = this->ParseRegExpLiteral(false, CHECK_OK);
1929 result = this->ParseArrayLiteral(CHECK_OK);
1933 result = this->ParseObjectLiteral(CHECK_OK);
1937 Consume(Token::LPAREN);
1938 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) {
1939 // Arrow functions are the only expression type constructions
1940 // for which an empty parameter list "()" is valid input.
1941 Consume(Token::RPAREN);
1942 result = this->ParseArrowFunctionLiteral(
1943 beg_pos, this->EmptyArrowParamList(), CHECK_OK);
1945 // Heuristically try to detect immediately called functions before
1946 // seeing the call parentheses.
1947 parenthesized_function_ = (peek() == Token::FUNCTION);
1948 result = this->ParseExpression(true, CHECK_OK);
1949 result->increase_parenthesization_level();
1950 Expect(Token::RPAREN, CHECK_OK);
1954 case Token::CLASS: {
1955 Consume(Token::CLASS);
1956 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
1957 ReportMessage("sloppy_lexical", NULL);
1961 int class_token_position = position();
1962 IdentifierT name = this->EmptyIdentifier();
1963 bool is_strict_reserved_name = false;
1964 Scanner::Location class_name_location = Scanner::Location::invalid();
1965 if (peek_any_identifier()) {
1966 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1968 class_name_location = scanner()->location();
1970 result = this->ParseClassLiteral(name, class_name_location,
1971 is_strict_reserved_name,
1972 class_token_position, CHECK_OK);
1976 case Token::TEMPLATE_SPAN:
1977 case Token::TEMPLATE_TAIL:
1978 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
1983 if (allow_natives() || extension_ != NULL) {
1984 result = this->ParseV8Intrinsic(CHECK_OK);
1987 // If we're not allowing special syntax we fall-through to the
1992 ReportUnexpectedToken(token);
2001 template <class Traits>
2002 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2003 bool accept_IN, bool* ok) {
2005 // AssignmentExpression
2006 // Expression ',' AssignmentExpression
2008 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
2009 while (peek() == Token::COMMA) {
2010 Expect(Token::COMMA, CHECK_OK);
2011 int pos = position();
2012 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
2013 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2019 template <class Traits>
2020 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2023 // '[' Expression? (',' Expression?)* ']'
2025 int pos = peek_position();
2026 typename Traits::Type::ExpressionList values =
2027 this->NewExpressionList(4, zone_);
2028 Expect(Token::LBRACK, CHECK_OK);
2029 while (peek() != Token::RBRACK) {
2030 ExpressionT elem = this->EmptyExpression();
2031 if (peek() == Token::COMMA) {
2032 if (is_strong(language_mode())) {
2033 ReportMessageAt(scanner()->peek_location(), "strong_ellision");
2035 return this->EmptyExpression();
2037 elem = this->GetLiteralTheHole(peek_position(), factory());
2039 elem = this->ParseAssignmentExpression(true, CHECK_OK);
2041 values->Add(elem, zone_);
2042 if (peek() != Token::RBRACK) {
2043 Expect(Token::COMMA, CHECK_OK);
2046 Expect(Token::RBRACK, CHECK_OK);
2048 // Update the scope information before the pre-parsing bailout.
2049 int literal_index = function_state_->NextMaterializedLiteralIndex();
2051 return factory()->NewArrayLiteral(values, literal_index, pos);
2055 template <class Traits>
2056 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2057 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2058 bool* is_computed_name, bool* ok) {
2059 Token::Value token = peek();
2060 int pos = peek_position();
2062 // For non computed property names we normalize the name a bit:
2067 // identifier -> "identifier"
2069 // This is important because we use the property name as a key in a hash
2070 // table when we compute constant properties.
2073 Consume(Token::STRING);
2074 *name = this->GetSymbol(scanner());
2078 Consume(Token::SMI);
2079 *name = this->GetNumberAsSymbol(scanner());
2083 Consume(Token::NUMBER);
2084 *name = this->GetNumberAsSymbol(scanner());
2088 if (allow_harmony_computed_property_names_) {
2089 *is_computed_name = true;
2090 Consume(Token::LBRACK);
2091 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2092 Expect(Token::RBRACK, CHECK_OK);
2102 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2107 return this->IsArrayIndex(*name, &index)
2108 ? factory()->NewNumberLiteral(index, pos)
2109 : factory()->NewStringLiteral(*name, pos);
2113 template <class Traits>
2114 typename ParserBase<Traits>::ObjectLiteralPropertyT
2115 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
2116 bool in_class, bool has_extends,
2118 bool* is_computed_name,
2119 bool* has_seen_constructor,
2121 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2122 ExpressionT value = this->EmptyExpression();
2123 IdentifierT name = this->EmptyIdentifier();
2124 bool is_get = false;
2125 bool is_set = false;
2126 bool name_is_static = false;
2127 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
2129 Token::Value name_token = peek();
2130 int next_beg_pos = scanner()->peek_location().beg_pos;
2131 int next_end_pos = scanner()->peek_location().end_pos;
2132 ExpressionT name_expression = ParsePropertyName(
2133 &name, &is_get, &is_set, &name_is_static, is_computed_name,
2134 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2136 if (fni_ != nullptr && !*is_computed_name) {
2137 this->PushLiteralName(fni_, name);
2140 if (!in_class && !is_generator && peek() == Token::COLON) {
2141 // PropertyDefinition : PropertyName ':' AssignmentExpression
2142 if (!*is_computed_name) {
2143 checker->CheckProperty(name_token, kValueProperty, is_static,
2145 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2147 Consume(Token::COLON);
2148 value = this->ParseAssignmentExpression(
2149 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2151 } else if (is_generator ||
2152 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
2154 if (!*is_computed_name) {
2155 checker->CheckProperty(name_token, kMethodProperty, is_static,
2157 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2160 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2161 : FunctionKind::kConciseMethod;
2163 if (in_class && !is_static && this->IsConstructor(name)) {
2164 *has_seen_constructor = true;
2165 kind = has_extends ? FunctionKind::kSubclassConstructor
2166 : FunctionKind::kBaseConstructor;
2169 if (!in_class) kind = WithObjectLiteralBit(kind);
2171 value = this->ParseFunctionLiteral(
2172 name, scanner()->location(),
2173 false, // reserved words are allowed here
2174 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2175 FunctionLiteral::NORMAL_ARITY,
2176 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2178 return factory()->NewObjectLiteralProperty(name_expression, value,
2179 ObjectLiteralProperty::COMPUTED,
2180 is_static, *is_computed_name);
2182 } else if (in_class && name_is_static && !is_static) {
2183 // static MethodDefinition
2184 return ParsePropertyDefinition(checker, true, has_extends, true,
2185 is_computed_name, nullptr, ok);
2186 } else if (is_get || is_set) {
2188 name = this->EmptyIdentifier();
2189 bool dont_care = false;
2190 name_token = peek();
2192 name_expression = ParsePropertyName(
2193 &name, &dont_care, &dont_care, &dont_care, is_computed_name,
2194 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2196 if (!*is_computed_name) {
2197 checker->CheckProperty(name_token, kAccessorProperty, is_static,
2199 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2202 FunctionKind kind = FunctionKind::kAccessorFunction;
2203 if (!in_class) kind = WithObjectLiteralBit(kind);
2204 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2205 name, scanner()->location(),
2206 false, // reserved words are allowed here
2207 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2208 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2209 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2211 // Make sure the name expression is a string since we need a Name for
2212 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2213 // statically we can skip the extra runtime check.
2214 if (!*is_computed_name) {
2216 factory()->NewStringLiteral(name, name_expression->position());
2219 return factory()->NewObjectLiteralProperty(
2220 name_expression, value,
2221 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2222 is_static, *is_computed_name);
2224 } else if (!in_class && allow_harmony_object_literals_ &&
2225 Token::IsIdentifier(name_token, language_mode(),
2226 this->is_generator())) {
2227 DCHECK(!*is_computed_name);
2229 value = this->ExpressionFromIdentifier(name, next_beg_pos, next_end_pos,
2231 return factory()->NewObjectLiteralProperty(
2232 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false);
2235 Token::Value next = Next();
2236 ReportUnexpectedToken(next);
2238 return this->EmptyObjectLiteralProperty();
2241 return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
2246 template <class Traits>
2247 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2250 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2252 int pos = peek_position();
2253 typename Traits::Type::PropertyList properties =
2254 this->NewPropertyList(4, zone_);
2255 int number_of_boilerplate_properties = 0;
2256 bool has_function = false;
2257 bool has_computed_names = false;
2258 ObjectLiteralChecker checker(this);
2260 Expect(Token::LBRACE, CHECK_OK);
2262 while (peek() != Token::RBRACE) {
2263 if (fni_ != nullptr) fni_->Enter();
2265 const bool in_class = false;
2266 const bool is_static = false;
2267 const bool has_extends = false;
2268 bool is_computed_name = false;
2269 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2270 &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
2273 if (is_computed_name) {
2274 has_computed_names = true;
2277 // Mark top-level object literals that contain function literals and
2278 // pretenure the literal so it can be added as a constant function
2279 // property. (Parser only.)
2280 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2283 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2284 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2285 number_of_boilerplate_properties++;
2287 properties->Add(property, zone());
2289 if (peek() != Token::RBRACE) {
2290 // Need {} because of the CHECK_OK macro.
2291 Expect(Token::COMMA, CHECK_OK);
2294 if (fni_ != nullptr) {
2299 Expect(Token::RBRACE, CHECK_OK);
2301 // Computation of literal_index must happen before pre parse bailout.
2302 int literal_index = function_state_->NextMaterializedLiteralIndex();
2304 return factory()->NewObjectLiteral(properties,
2306 number_of_boilerplate_properties,
2312 template <class Traits>
2313 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
2316 // '(' (AssignmentExpression)*[','] ')'
2318 typename Traits::Type::ExpressionList result =
2319 this->NewExpressionList(4, zone_);
2320 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2321 bool done = (peek() == Token::RPAREN);
2323 ExpressionT argument = this->ParseAssignmentExpression(
2324 true, CHECK_OK_CUSTOM(NullExpressionList));
2325 result->Add(argument, zone_);
2326 if (result->length() > Code::kMaxArguments) {
2327 ReportMessage("too_many_arguments");
2329 return this->NullExpressionList();
2331 done = (peek() != Token::COMMA);
2336 Scanner::Location location = scanner_->location();
2337 if (Token::RPAREN != Next()) {
2338 ReportMessageAt(location, "unterminated_arg_list");
2340 return this->NullExpressionList();
2346 template <class Traits>
2347 typename ParserBase<Traits>::ExpressionT
2348 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2349 // AssignmentExpression ::
2350 // ConditionalExpression
2353 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2355 Scanner::Location lhs_location = scanner()->peek_location();
2357 if (peek() == Token::YIELD && is_generator()) {
2358 return this->ParseYieldExpression(ok);
2361 if (fni_ != NULL) fni_->Enter();
2362 ParserBase<Traits>::Checkpoint checkpoint(this);
2363 ExpressionT expression =
2364 this->ParseConditionalExpression(accept_IN, CHECK_OK);
2366 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2367 checkpoint.Restore();
2368 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2369 expression, CHECK_OK);
2373 if (!Token::IsAssignmentOp(peek())) {
2374 if (fni_ != NULL) fni_->Leave();
2375 // Parsed conditional expression only (no assignment).
2379 expression = this->CheckAndRewriteReferenceExpression(
2380 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
2381 expression = this->MarkExpressionAsAssigned(expression);
2383 Token::Value op = Next(); // Get assignment operator.
2384 int pos = position();
2385 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
2387 // TODO(1231235): We try to estimate the set of properties set by
2388 // constructors. We define a new property whenever there is an
2389 // assignment to a property of 'this'. We should probably only add
2390 // properties if we haven't seen them before. Otherwise we'll
2391 // probably overestimate the number of properties.
2392 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2393 function_state_->AddProperty();
2396 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2399 // Check if the right hand side is a call to avoid inferring a
2400 // name if we're dealing with "a = function(){...}();"-like
2402 if ((op == Token::INIT_VAR
2403 || op == Token::INIT_CONST_LEGACY
2404 || op == Token::ASSIGN)
2405 && (!right->IsCall() && !right->IsCallNew())) {
2408 fni_->RemoveLastFunction();
2413 return factory()->NewAssignment(op, expression, right, pos);
2416 template <class Traits>
2417 typename ParserBase<Traits>::ExpressionT
2418 ParserBase<Traits>::ParseYieldExpression(bool* ok) {
2419 // YieldExpression ::
2420 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2421 int pos = peek_position();
2422 Expect(Token::YIELD, CHECK_OK);
2423 ExpressionT generator_object =
2424 factory()->NewVariableProxy(function_state_->generator_object_variable());
2425 ExpressionT expression = Traits::EmptyExpression();
2426 Yield::Kind kind = Yield::kSuspend;
2427 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2428 if (Check(Token::MUL)) kind = Yield::kDelegating;
2431 case Token::SEMICOLON:
2437 // The above set of tokens is the complete set of tokens that can appear
2438 // after an AssignmentExpression, and none of them can start an
2439 // AssignmentExpression. This allows us to avoid looking for an RHS for
2440 // a Yield::kSuspend operation, given only one look-ahead token.
2441 if (kind == Yield::kSuspend)
2443 DCHECK_EQ(Yield::kDelegating, kind);
2444 // Delegating yields require an RHS; fall through.
2446 expression = ParseAssignmentExpression(false, CHECK_OK);
2450 if (kind == Yield::kDelegating) {
2451 // var iterator = subject[Symbol.iterator]();
2452 expression = this->GetIterator(expression, factory());
2454 typename Traits::Type::YieldExpression yield =
2455 factory()->NewYield(generator_object, expression, kind, pos);
2456 if (kind == Yield::kDelegating) {
2457 yield->set_index(function_state_->NextHandlerIndex());
2464 template <class Traits>
2465 typename ParserBase<Traits>::ExpressionT
2466 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) {
2467 // ConditionalExpression ::
2468 // LogicalOrExpression
2469 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2471 int pos = peek_position();
2472 // We start using the binary expression parser for prec >= 4 only!
2473 ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK);
2474 if (peek() != Token::CONDITIONAL) return expression;
2475 Consume(Token::CONDITIONAL);
2476 // In parsing the first assignment expression in conditional
2477 // expressions we always accept the 'in' keyword; see ECMA-262,
2478 // section 11.12, page 58.
2479 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK);
2480 Expect(Token::COLON, CHECK_OK);
2481 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2482 return factory()->NewConditional(expression, left, right, pos);
2487 template <class Traits>
2488 typename ParserBase<Traits>::ExpressionT
2489 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
2491 ExpressionT x = this->ParseUnaryExpression(CHECK_OK);
2492 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2494 while (Precedence(peek(), accept_IN) == prec1) {
2495 Token::Value op = Next();
2496 Scanner::Location op_location = scanner()->location();
2497 int pos = position();
2498 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
2500 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2505 // For now we distinguish between comparisons and other binary
2506 // operations. (We could combine the two and get rid of this
2507 // code and AST node eventually.)
2508 if (Token::IsCompareOp(op)) {
2509 // We have a comparison.
2510 Token::Value cmp = op;
2512 case Token::NE: cmp = Token::EQ; break;
2513 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2516 if (cmp == Token::EQ && is_strong(language_mode())) {
2517 ReportMessageAt(op_location, "strong_equal");
2519 return this->EmptyExpression();
2521 x = factory()->NewCompareOperation(cmp, x, y, pos);
2523 // The comparison was negated - add a NOT.
2524 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2528 // We have a "normal" binary operation.
2529 x = factory()->NewBinaryOperation(op, x, y, pos);
2537 template <class Traits>
2538 typename ParserBase<Traits>::ExpressionT
2539 ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
2540 // UnaryExpression ::
2541 // PostfixExpression
2542 // 'delete' UnaryExpression
2543 // 'void' UnaryExpression
2544 // 'typeof' UnaryExpression
2545 // '++' UnaryExpression
2546 // '--' UnaryExpression
2547 // '+' UnaryExpression
2548 // '-' UnaryExpression
2549 // '~' UnaryExpression
2550 // '!' UnaryExpression
2552 Token::Value op = peek();
2553 if (Token::IsUnaryOp(op)) {
2555 int pos = position();
2556 ExpressionT expression = ParseUnaryExpression(CHECK_OK);
2558 if (op == Token::DELETE && is_strict(language_mode())) {
2559 if (is_strong(language_mode())) {
2560 ReportMessage("strong_delete");
2562 return this->EmptyExpression();
2563 } else if (this->IsIdentifier(expression)) {
2564 // "delete identifier" is a syntax error in strict mode.
2565 ReportMessage("strict_delete");
2567 return this->EmptyExpression();
2571 // Allow Traits do rewrite the expression.
2572 return this->BuildUnaryExpression(expression, op, pos, factory());
2573 } else if (Token::IsCountOp(op)) {
2575 Scanner::Location lhs_location = scanner()->peek_location();
2576 ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
2577 expression = this->CheckAndRewriteReferenceExpression(
2578 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
2579 this->MarkExpressionAsAssigned(expression);
2581 return factory()->NewCountOperation(op,
2587 return this->ParsePostfixExpression(ok);
2592 template <class Traits>
2593 typename ParserBase<Traits>::ExpressionT
2594 ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
2595 // PostfixExpression ::
2596 // LeftHandSideExpression ('++' | '--')?
2598 Scanner::Location lhs_location = scanner()->peek_location();
2599 ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK);
2600 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2601 Token::IsCountOp(peek())) {
2602 expression = this->CheckAndRewriteReferenceExpression(
2603 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
2604 expression = this->MarkExpressionAsAssigned(expression);
2606 Token::Value next = Next();
2608 factory()->NewCountOperation(next,
2609 false /* postfix */,
2617 template <class Traits>
2618 typename ParserBase<Traits>::ExpressionT
2619 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
2620 // LeftHandSideExpression ::
2621 // (NewExpression | MemberExpression) ...
2623 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
2627 case Token::LBRACK: {
2628 Consume(Token::LBRACK);
2629 int pos = position();
2630 ExpressionT index = ParseExpression(true, CHECK_OK);
2631 result = factory()->NewProperty(result, index, pos);
2632 Expect(Token::RBRACK, CHECK_OK);
2636 case Token::LPAREN: {
2638 if (scanner()->current_token() == Token::IDENTIFIER) {
2639 // For call of an identifier we want to report position of
2640 // the identifier as position of the call in the stack trace.
2643 // For other kinds of calls we record position of the parenthesis as
2644 // position of the call. Note that this is extremely important for
2645 // expressions of the form function(){...}() for which call position
2646 // should not point to the closing brace otherwise it will intersect
2647 // with positions recorded for function literal and confuse debugger.
2648 pos = peek_position();
2649 // Also the trailing parenthesis are a hint that the function will
2650 // be called immediately. If we happen to have parsed a preceding
2651 // function literal eagerly, we can also compile it eagerly.
2652 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2653 result->AsFunctionLiteral()->set_parenthesized();
2656 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK);
2658 // Keep track of eval() calls since they disable all local variable
2660 // The calls that need special treatment are the
2661 // direct eval calls. These calls are all of the form eval(...), with
2662 // no explicit receiver.
2663 // These calls are marked as potentially direct eval calls. Whether
2664 // they are actually direct calls to eval is determined at run time.
2665 this->CheckPossibleEvalCall(result, scope_);
2666 result = factory()->NewCall(result, args, pos);
2667 if (fni_ != NULL) fni_->RemoveLastFunction();
2671 case Token::PERIOD: {
2672 Consume(Token::PERIOD);
2673 int pos = position();
2674 IdentifierT name = ParseIdentifierName(CHECK_OK);
2675 result = factory()->NewProperty(
2676 result, factory()->NewStringLiteral(name, pos), pos);
2677 if (fni_ != NULL) this->PushLiteralName(fni_, name);
2688 template <class Traits>
2689 typename ParserBase<Traits>::ExpressionT
2690 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
2692 // ('new')+ MemberExpression
2694 // The grammar for new expressions is pretty warped. We can have several 'new'
2695 // keywords following each other, and then a MemberExpression. When we see '('
2696 // after the MemberExpression, it's associated with the rightmost unassociated
2697 // 'new' to create a NewExpression with arguments. However, a NewExpression
2698 // can also occur without arguments.
2700 // Examples of new expression:
2701 // new foo.bar().baz means (new (foo.bar)()).baz
2702 // new foo()() means (new foo())()
2703 // new new foo()() means (new (new foo())())
2704 // new new foo means new (new foo)
2705 // new new foo() means new (new foo())
2706 // new new foo().bar().baz means (new (new foo()).bar()).baz
2708 if (peek() == Token::NEW) {
2709 Consume(Token::NEW);
2710 int new_pos = position();
2711 ExpressionT result = this->EmptyExpression();
2712 if (peek() == Token::SUPER) {
2713 const bool is_new = true;
2714 result = ParseSuperExpression(is_new, CHECK_OK);
2716 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
2718 if (peek() == Token::LPAREN) {
2719 // NewExpression with arguments.
2720 typename Traits::Type::ExpressionList args =
2721 this->ParseArguments(CHECK_OK);
2722 result = factory()->NewCallNew(result, args, new_pos);
2723 // The expression can still continue with . or [ after the arguments.
2724 result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
2727 // NewExpression without arguments.
2728 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2731 // No 'new' or 'super' keyword.
2732 return this->ParseMemberExpression(ok);
2736 template <class Traits>
2737 typename ParserBase<Traits>::ExpressionT
2738 ParserBase<Traits>::ParseMemberExpression(bool* ok) {
2739 // MemberExpression ::
2740 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
2741 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
2743 // The '[' Expression ']' and '.' Identifier parts are parsed by
2744 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2747 // Parse the initial primary or function expression.
2748 ExpressionT result = this->EmptyExpression();
2749 if (peek() == Token::FUNCTION) {
2750 Consume(Token::FUNCTION);
2751 int function_token_position = position();
2752 bool is_generator = Check(Token::MUL);
2753 IdentifierT name = this->EmptyIdentifier();
2754 bool is_strict_reserved_name = false;
2755 Scanner::Location function_name_location = Scanner::Location::invalid();
2756 FunctionLiteral::FunctionType function_type =
2757 FunctionLiteral::ANONYMOUS_EXPRESSION;
2758 if (peek_any_identifier()) {
2759 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2761 function_name_location = scanner()->location();
2762 function_type = FunctionLiteral::NAMED_EXPRESSION;
2764 result = this->ParseFunctionLiteral(
2765 name, function_name_location, is_strict_reserved_name,
2766 is_generator ? FunctionKind::kGeneratorFunction
2767 : FunctionKind::kNormalFunction,
2768 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
2770 } else if (peek() == Token::SUPER) {
2771 const bool is_new = false;
2772 result = ParseSuperExpression(is_new, CHECK_OK);
2774 result = ParsePrimaryExpression(CHECK_OK);
2777 result = ParseMemberExpressionContinuation(result, CHECK_OK);
2782 template <class Traits>
2783 typename ParserBase<Traits>::ExpressionT
2784 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
2785 Expect(Token::SUPER, CHECK_OK);
2787 FunctionState* function_state = function_state_;
2788 while (IsArrowFunction(function_state->kind())) {
2789 function_state = function_state->outer();
2791 // TODO(arv): Handle eval scopes similarly.
2793 FunctionKind kind = function_state->kind();
2794 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
2795 i::IsConstructor(kind)) {
2796 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
2797 scope_->RecordSuperPropertyUsage();
2798 return this->SuperReference(scope_, factory());
2800 // new super() is never allowed.
2801 // super() is only allowed in derived constructor
2802 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
2803 if (is_strong(language_mode())) {
2804 if (function_state->super_call_location().IsValid()) {
2805 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate");
2807 return this->EmptyExpression();
2808 } else if (function_state->return_location().IsValid()) {
2809 ReportMessageAt(function_state->return_location(),
2810 "strong_constructor_return_misplaced");
2812 return this->EmptyExpression();
2815 function_state->set_super_call_location(scanner()->location());
2816 return this->SuperReference(scope_, factory());
2820 ReportMessageAt(scanner()->location(), "unexpected_super");
2822 return this->EmptyExpression();
2826 template <class Traits>
2827 typename ParserBase<Traits>::ExpressionT
2828 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
2830 // Parses this part of MemberExpression:
2831 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
2834 case Token::LBRACK: {
2835 Consume(Token::LBRACK);
2836 int pos = position();
2837 ExpressionT index = this->ParseExpression(true, CHECK_OK);
2838 expression = factory()->NewProperty(expression, index, pos);
2840 this->PushPropertyName(fni_, index);
2842 Expect(Token::RBRACK, CHECK_OK);
2845 case Token::PERIOD: {
2846 Consume(Token::PERIOD);
2847 int pos = position();
2848 IdentifierT name = ParseIdentifierName(CHECK_OK);
2849 expression = factory()->NewProperty(
2850 expression, factory()->NewStringLiteral(name, pos), pos);
2852 this->PushLiteralName(fni_, name);
2856 case Token::TEMPLATE_SPAN:
2857 case Token::TEMPLATE_TAIL: {
2859 if (scanner()->current_token() == Token::IDENTIFIER) {
2862 pos = peek_position();
2863 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2864 // If the tag function looks like an IIFE, set_parenthesized() to
2865 // force eager compilation.
2866 expression->AsFunctionLiteral()->set_parenthesized();
2869 expression = ParseTemplateLiteral(expression, pos, CHECK_OK);
2877 return this->EmptyExpression();
2881 template <class Traits>
2882 typename ParserBase<Traits>::ExpressionT
2883 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
2884 ExpressionT params_ast,
2886 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
2887 // ASI inserts `;` after arrow parameters if a line terminator is found.
2888 // `=> ...` is never a valid expression, so report as syntax error.
2889 // If next token is not `=>`, it's a syntax error anyways.
2890 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
2892 return this->EmptyExpression();
2895 Scope* scope = this->NewScope(scope_, ARROW_SCOPE);
2896 typename Traits::Type::StatementList body;
2897 int num_parameters = -1;
2898 int materialized_literal_count = -1;
2899 int expected_property_count = -1;
2900 int handler_count = 0;
2901 Scanner::Location super_loc;
2904 typename Traits::Type::Factory function_factory(ast_value_factory());
2905 FunctionState function_state(&function_state_, &scope_, scope,
2906 kArrowFunction, &function_factory);
2907 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2908 // TODO(arv): Pass in eval_args_error_loc and reserved_loc here.
2909 num_parameters = Traits::DeclareArrowParametersFromExpression(
2910 params_ast, scope_, &dupe_error_loc, ok);
2913 Scanner::Location(start_pos, scanner()->location().beg_pos),
2914 "malformed_arrow_function_parameter_list");
2915 return this->EmptyExpression();
2918 if (num_parameters > Code::kMaxArguments) {
2919 ReportMessageAt(Scanner::Location(params_ast->position(), position()),
2920 "too_many_parameters");
2922 return this->EmptyExpression();
2925 Expect(Token::ARROW, CHECK_OK);
2927 if (peek() == Token::LBRACE) {
2928 // Multiple statemente body
2929 Consume(Token::LBRACE);
2930 bool is_lazily_parsed =
2931 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
2932 if (is_lazily_parsed) {
2933 body = this->NewStatementList(0, zone());
2934 this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2935 &materialized_literal_count,
2936 &expected_property_count, CHECK_OK);
2938 body = this->ParseEagerFunctionBody(
2939 this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL,
2940 Token::INIT_VAR, kArrowFunction, CHECK_OK);
2941 materialized_literal_count =
2942 function_state.materialized_literal_count();
2943 expected_property_count = function_state.expected_property_count();
2944 handler_count = function_state.handler_count();
2947 // Single-expression body
2948 int pos = position();
2949 parenthesized_function_ = false;
2950 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2951 body = this->NewStatementList(1, zone());
2952 body->Add(factory()->NewReturnStatement(expression, pos), zone());
2953 materialized_literal_count = function_state.materialized_literal_count();
2954 expected_property_count = function_state.expected_property_count();
2955 handler_count = function_state.handler_count();
2957 super_loc = function_state.super_call_location();
2959 scope->set_start_position(start_pos);
2960 scope->set_end_position(scanner()->location().end_pos);
2962 // Arrow function *parameter lists* are always checked as in strict mode.
2963 // TODO(arv): eval_args_error_loc and reserved_loc needs to be set by
2964 // DeclareArrowParametersFromExpression.
2965 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2966 Scanner::Location reserved_loc = Scanner::Location::invalid();
2967 const bool use_strict_params = true;
2968 this->CheckFunctionParameterNames(language_mode(), use_strict_params,
2969 eval_args_error_loc, dupe_error_loc, reserved_loc, CHECK_OK);
2971 // Validate strict mode.
2972 if (is_strict(language_mode())) {
2973 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos,
2975 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2979 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
2980 this->EmptyIdentifierString(), ast_value_factory(), scope, body,
2981 materialized_literal_count, expected_property_count, handler_count,
2982 num_parameters, FunctionLiteral::kNoDuplicateParameters,
2983 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
2984 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction,
2987 function_literal->set_function_token_position(start_pos);
2988 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc);
2990 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
2992 return function_literal;
2996 template <typename Traits>
2997 typename ParserBase<Traits>::ExpressionT
2998 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) {
2999 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3000 // text followed by a substitution expression), finalized by a single
3003 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3004 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3005 // NoSubstitutionTemplate.
3007 // When parsing a TemplateLiteral, we must have scanned either an initial
3008 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
3009 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
3011 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
3012 // In this case we may simply consume the token and build a template with a
3013 // single TEMPLATE_SPAN and no expressions.
3014 if (peek() == Token::TEMPLATE_TAIL) {
3015 Consume(Token::TEMPLATE_TAIL);
3016 int pos = position();
3017 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3018 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3019 Traits::AddTemplateSpan(&ts, true);
3020 return Traits::CloseTemplateLiteral(&ts, start, tag);
3023 Consume(Token::TEMPLATE_SPAN);
3024 int pos = position();
3025 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3026 Traits::AddTemplateSpan(&ts, false);
3029 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
3030 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
3031 // case, representing a TemplateMiddle).
3034 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3036 if (next == Token::EOS) {
3037 ReportMessageAt(Scanner::Location(start, peek_position()),
3038 "unterminated_template");
3040 return Traits::EmptyExpression();
3041 } else if (next == Token::ILLEGAL) {
3042 Traits::ReportMessageAt(
3043 Scanner::Location(position() + 1, peek_position()),
3044 "unexpected_token", "ILLEGAL", kSyntaxError);
3046 return Traits::EmptyExpression();
3049 int expr_pos = peek_position();
3050 ExpressionT expression = this->ParseExpression(true, CHECK_OK);
3051 Traits::AddTemplateExpression(&ts, expression);
3053 if (peek() != Token::RBRACE) {
3054 ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
3055 "unterminated_template_expr");
3057 return Traits::EmptyExpression();
3060 // If we didn't die parsing that expression, our next token should be a
3061 // TEMPLATE_SPAN or TEMPLATE_TAIL.
3062 next = scanner()->ScanTemplateContinuation();
3066 if (next == Token::EOS) {
3067 ReportMessageAt(Scanner::Location(start, pos), "unterminated_template");
3069 return Traits::EmptyExpression();
3070 } else if (next == Token::ILLEGAL) {
3071 Traits::ReportMessageAt(
3072 Scanner::Location(position() + 1, peek_position()),
3073 "unexpected_token", "ILLEGAL", kSyntaxError);
3075 return Traits::EmptyExpression();
3078 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
3079 } while (next == Token::TEMPLATE_SPAN);
3081 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
3082 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3083 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3084 return Traits::CloseTemplateLiteral(&ts, start, tag);
3088 template <typename Traits>
3089 typename ParserBase<Traits>::ExpressionT ParserBase<
3090 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression,
3091 Scanner::Location location,
3092 const char* message, bool* ok) {
3093 if (is_strict(language_mode()) && this->IsIdentifier(expression) &&
3094 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3095 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError);
3097 return this->EmptyExpression();
3098 } else if (expression->IsValidReferenceExpression()) {
3100 } else if (expression->IsCall()) {
3101 // If it is a call, make it a runtime error for legacy web compatibility.
3102 // Rewrite `expr' to `expr[throw ReferenceError]'.
3103 int pos = location.beg_pos;
3104 ExpressionT error = this->NewThrowReferenceError(message, pos);
3105 return factory()->NewProperty(expression, error, pos);
3107 this->ReportMessageAt(location, message, kReferenceError);
3109 return this->EmptyExpression();
3115 #undef CHECK_OK_CUSTOM
3118 template <typename Traits>
3119 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
3120 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3123 DCHECK(!is_generator || type == kMethodProperty);
3125 if (property == Token::SMI || property == Token::NUMBER) return;
3127 if (type == kValueProperty && IsProto()) {
3128 if (has_seen_proto_) {
3129 this->parser()->ReportMessage("duplicate_proto");
3133 has_seen_proto_ = true;
3139 template <typename Traits>
3140 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
3141 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3143 DCHECK(type == kMethodProperty || type == kAccessorProperty);
3145 if (property == Token::SMI || property == Token::NUMBER) return;
3148 if (IsPrototype()) {
3149 this->parser()->ReportMessage("static_prototype");
3153 } else if (IsConstructor()) {
3154 if (is_generator || type == kAccessorProperty) {
3156 is_generator ? "constructor_is_generator" : "constructor_is_accessor";
3157 this->parser()->ReportMessage(msg);
3161 if (has_seen_constructor_) {
3162 this->parser()->ReportMessage("duplicate_constructor");
3166 has_seen_constructor_ = true;
3172 #endif // V8_PREPARSER_H