50dbcf1a46310b5bbed950705c2438dec70caae8
[platform/upstream/v8.git] / src / preparser.h
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.
4
5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H
7
8 #include "src/bailout-reason.h"
9 #include "src/expression-classifier.h"
10 #include "src/func-name-inferrer.h"
11 #include "src/hashmap.h"
12 #include "src/messages.h"
13 #include "src/scanner.h"
14 #include "src/scopes.h"
15 #include "src/token.h"
16
17 namespace v8 {
18 namespace internal {
19
20
21 enum FunctionNameValidity {
22   kFunctionNameIsStrictReserved,
23   kSkipFunctionNameCheck,
24   kFunctionNameValidityUnknown
25 };
26
27
28 struct FormalParametersBase {
29   explicit FormalParametersBase(Scope* scope) : scope(scope) {}
30   Scope* scope;
31   bool has_rest = false;
32   bool is_simple = true;
33   int materialized_literals_count = 0;
34   mutable int rest_array_literal_index = -1;
35 };
36
37
38 // Common base class shared between parser and pre-parser. Traits encapsulate
39 // the differences between Parser and PreParser:
40
41 // - Return types: For example, Parser functions return Expression* and
42 // PreParser functions return PreParserExpression.
43
44 // - Creating parse tree nodes: Parser generates an AST during the recursive
45 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
46 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
47 // just enough data for the upper layer functions. PreParserFactory is
48 // responsible for creating these dummy objects. It provides a similar kind of
49 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
50 // used.
51
52 // - Miscellaneous other tasks interleaved with the recursive descent. For
53 // example, Parser keeps track of which function literals should be marked as
54 // pretenured, and PreParser doesn't care.
55
56 // The traits are expected to contain the following typedefs:
57 // struct Traits {
58 //   // In particular...
59 //   struct Type {
60 //     // Used by FunctionState and BlockState.
61 //     typedef Scope;
62 //     typedef GeneratorVariable;
63 //     // Return types for traversing functions.
64 //     typedef Identifier;
65 //     typedef Expression;
66 //     typedef FunctionLiteral;
67 //     typedef ClassLiteral;
68 //     typedef ObjectLiteralProperty;
69 //     typedef Literal;
70 //     typedef ExpressionList;
71 //     typedef PropertyList;
72 //     typedef FormalParameter;
73 //     typedef FormalParameters;
74 //     // For constructing objects returned by the traversing functions.
75 //     typedef Factory;
76 //   };
77 //   // ...
78 // };
79
80 template <typename Traits>
81 class ParserBase : public Traits {
82  public:
83   // Shorten type names defined by Traits.
84   typedef typename Traits::Type::Expression ExpressionT;
85   typedef typename Traits::Type::Identifier IdentifierT;
86   typedef typename Traits::Type::FormalParameter FormalParameterT;
87   typedef typename Traits::Type::FormalParameters FormalParametersT;
88   typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
89   typedef typename Traits::Type::Literal LiteralT;
90   typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
91
92   ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
93              v8::Extension* extension, AstValueFactory* ast_value_factory,
94              ParserRecorder* log, typename Traits::Type::Parser this_object)
95       : Traits(this_object),
96         parenthesized_function_(false),
97         scope_(NULL),
98         function_state_(NULL),
99         extension_(extension),
100         fni_(NULL),
101         ast_value_factory_(ast_value_factory),
102         log_(log),
103         mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
104         stack_limit_(stack_limit),
105         zone_(zone),
106         scanner_(scanner),
107         stack_overflow_(false),
108         allow_lazy_(false),
109         allow_natives_(false),
110         allow_harmony_arrow_functions_(false),
111         allow_harmony_sloppy_(false),
112         allow_harmony_sloppy_function_(false),
113         allow_harmony_sloppy_let_(false),
114         allow_harmony_rest_parameters_(false),
115         allow_harmony_default_parameters_(false),
116         allow_harmony_spread_calls_(false),
117         allow_harmony_destructuring_(false),
118         allow_harmony_spread_arrays_(false),
119         allow_harmony_new_target_(false),
120         allow_strong_mode_(false),
121         allow_legacy_const_(true) {}
122
123 #define ALLOW_ACCESSORS(name)                           \
124   bool allow_##name() const { return allow_##name##_; } \
125   void set_allow_##name(bool allow) { allow_##name##_ = allow; }
126
127   ALLOW_ACCESSORS(lazy);
128   ALLOW_ACCESSORS(natives);
129   ALLOW_ACCESSORS(harmony_arrow_functions);
130   ALLOW_ACCESSORS(harmony_sloppy);
131   ALLOW_ACCESSORS(harmony_sloppy_function);
132   ALLOW_ACCESSORS(harmony_sloppy_let);
133   ALLOW_ACCESSORS(harmony_rest_parameters);
134   ALLOW_ACCESSORS(harmony_default_parameters);
135   ALLOW_ACCESSORS(harmony_spread_calls);
136   ALLOW_ACCESSORS(harmony_destructuring);
137   ALLOW_ACCESSORS(harmony_spread_arrays);
138   ALLOW_ACCESSORS(harmony_new_target);
139   ALLOW_ACCESSORS(strong_mode);
140   ALLOW_ACCESSORS(legacy_const);
141 #undef ALLOW_ACCESSORS
142
143  protected:
144   enum AllowRestrictedIdentifiers {
145     kAllowRestrictedIdentifiers,
146     kDontAllowRestrictedIdentifiers
147   };
148
149   enum Mode {
150     PARSE_LAZILY,
151     PARSE_EAGERLY
152   };
153
154   enum VariableDeclarationContext {
155     kStatementListItem,
156     kStatement,
157     kForStatement
158   };
159
160   class Checkpoint;
161   class ObjectLiteralCheckerBase;
162
163   // ---------------------------------------------------------------------------
164   // FunctionState and BlockState together implement the parser's scope stack.
165   // The parser's current scope is in scope_. BlockState and FunctionState
166   // constructors push on the scope stack and the destructors pop. They are also
167   // used to hold the parser's per-function and per-block state.
168   class BlockState BASE_EMBEDDED {
169    public:
170     BlockState(Scope** scope_stack, Scope* scope)
171         : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
172       *scope_stack_ = scope;
173     }
174     ~BlockState() { *scope_stack_ = outer_scope_; }
175
176    private:
177     Scope** scope_stack_;
178     Scope* outer_scope_;
179   };
180
181   class FunctionState BASE_EMBEDDED {
182    public:
183     FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
184                   Scope* scope, FunctionKind kind,
185                   typename Traits::Type::Factory* factory);
186     ~FunctionState();
187
188     int NextMaterializedLiteralIndex() {
189       return next_materialized_literal_index_++;
190     }
191     int materialized_literal_count() {
192       return next_materialized_literal_index_;
193     }
194
195     void SkipMaterializedLiterals(int count) {
196       next_materialized_literal_index_ += count;
197     }
198
199     void AddProperty() { expected_property_count_++; }
200     int expected_property_count() { return expected_property_count_; }
201
202     Scanner::Location this_location() const { return this_location_; }
203     Scanner::Location super_location() const { return super_location_; }
204     Scanner::Location return_location() const { return return_location_; }
205     void set_this_location(Scanner::Location location) {
206       this_location_ = location;
207     }
208     void set_super_location(Scanner::Location location) {
209       super_location_ = location;
210     }
211     void set_return_location(Scanner::Location location) {
212       return_location_ = location;
213     }
214
215     bool is_generator() const { return IsGeneratorFunction(kind_); }
216
217     FunctionKind kind() const { return kind_; }
218     FunctionState* outer() const { return outer_function_state_; }
219
220     void set_generator_object_variable(
221         typename Traits::Type::GeneratorVariable* variable) {
222       DCHECK(variable != NULL);
223       DCHECK(is_generator());
224       generator_object_variable_ = variable;
225     }
226     typename Traits::Type::GeneratorVariable* generator_object_variable()
227         const {
228       return generator_object_variable_;
229     }
230
231     typename Traits::Type::Factory* factory() { return factory_; }
232
233    private:
234     // Used to assign an index to each literal that needs materialization in
235     // the function.  Includes regexp literals, and boilerplate for object and
236     // array literals.
237     int next_materialized_literal_index_;
238
239     // Properties count estimation.
240     int expected_property_count_;
241
242     // Location of most recent use of 'this' (invalid if none).
243     Scanner::Location this_location_;
244
245     // Location of most recent 'return' statement (invalid if none).
246     Scanner::Location return_location_;
247
248     // Location of call to the "super" constructor (invalid if none).
249     Scanner::Location super_location_;
250
251     FunctionKind kind_;
252     // For generators, this variable may hold the generator object. It variable
253     // is used by yield expressions and return statements. It is not necessary
254     // for generator functions to have this variable set.
255     Variable* generator_object_variable_;
256
257     FunctionState** function_state_stack_;
258     FunctionState* outer_function_state_;
259     Scope** scope_stack_;
260     Scope* outer_scope_;
261     typename Traits::Type::Factory* factory_;
262
263     friend class ParserTraits;
264     friend class Checkpoint;
265   };
266
267   // Annoyingly, arrow functions first parse as comma expressions, then when we
268   // see the => we have to go back and reinterpret the arguments as being formal
269   // parameters.  To do so we need to reset some of the parser state back to
270   // what it was before the arguments were first seen.
271   class Checkpoint BASE_EMBEDDED {
272    public:
273     explicit Checkpoint(ParserBase* parser) {
274       function_state_ = parser->function_state_;
275       next_materialized_literal_index_ =
276           function_state_->next_materialized_literal_index_;
277       expected_property_count_ = function_state_->expected_property_count_;
278     }
279
280     void Restore(int* materialized_literal_index_delta) {
281       *materialized_literal_index_delta =
282           function_state_->next_materialized_literal_index_ -
283           next_materialized_literal_index_;
284       function_state_->next_materialized_literal_index_ =
285           next_materialized_literal_index_;
286       function_state_->expected_property_count_ = expected_property_count_;
287     }
288
289    private:
290     FunctionState* function_state_;
291     int next_materialized_literal_index_;
292     int expected_property_count_;
293   };
294
295   class ParsingModeScope BASE_EMBEDDED {
296    public:
297     ParsingModeScope(ParserBase* parser, Mode mode)
298         : parser_(parser),
299           old_mode_(parser->mode()) {
300       parser_->mode_ = mode;
301     }
302     ~ParsingModeScope() {
303       parser_->mode_ = old_mode_;
304     }
305
306    private:
307     ParserBase* parser_;
308     Mode old_mode_;
309   };
310
311   Scope* NewScope(Scope* parent, ScopeType scope_type) {
312     // Must always pass the function kind for FUNCTION_SCOPE and ARROW_SCOPE.
313     DCHECK(scope_type != FUNCTION_SCOPE);
314     DCHECK(scope_type != ARROW_SCOPE);
315     return NewScope(parent, scope_type, kNormalFunction);
316   }
317
318   Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
319     DCHECK(ast_value_factory());
320     DCHECK(scope_type != MODULE_SCOPE || FLAG_harmony_modules);
321     DCHECK(!IsArrowFunction(kind) || scope_type == ARROW_SCOPE);
322     Scope* result = new (zone())
323         Scope(zone(), parent, scope_type, ast_value_factory(), kind);
324     result->Initialize();
325     return result;
326   }
327
328   Scanner* scanner() const { return scanner_; }
329   AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
330   int position() { return scanner_->location().beg_pos; }
331   int peek_position() { return scanner_->peek_location().beg_pos; }
332   bool stack_overflow() const { return stack_overflow_; }
333   void set_stack_overflow() { stack_overflow_ = true; }
334   Mode mode() const { return mode_; }
335   Zone* zone() const { return zone_; }
336
337   INLINE(Token::Value peek()) {
338     if (stack_overflow_) return Token::ILLEGAL;
339     return scanner()->peek();
340   }
341
342   INLINE(Token::Value PeekAhead()) {
343     if (stack_overflow_) return Token::ILLEGAL;
344     return scanner()->PeekAhead();
345   }
346
347   INLINE(Token::Value Next()) {
348     if (stack_overflow_) return Token::ILLEGAL;
349     {
350       if (GetCurrentStackPosition() < stack_limit_) {
351         // Any further calls to Next or peek will return the illegal token.
352         // The current call must return the next token, which might already
353         // have been peek'ed.
354         stack_overflow_ = true;
355       }
356     }
357     return scanner()->Next();
358   }
359
360   void Consume(Token::Value token) {
361     Token::Value next = Next();
362     USE(next);
363     USE(token);
364     DCHECK(next == token);
365   }
366
367   bool Check(Token::Value token) {
368     Token::Value next = peek();
369     if (next == token) {
370       Consume(next);
371       return true;
372     }
373     return false;
374   }
375
376   void Expect(Token::Value token, bool* ok) {
377     Token::Value next = Next();
378     if (next != token) {
379       ReportUnexpectedToken(next);
380       *ok = false;
381     }
382   }
383
384   void ExpectSemicolon(bool* ok) {
385     // Check for automatic semicolon insertion according to
386     // the rules given in ECMA-262, section 7.9, page 21.
387     Token::Value tok = peek();
388     if (tok == Token::SEMICOLON) {
389       Next();
390       return;
391     }
392     if (scanner()->HasAnyLineTerminatorBeforeNext() ||
393         tok == Token::RBRACE ||
394         tok == Token::EOS) {
395       return;
396     }
397     Expect(Token::SEMICOLON, ok);
398   }
399
400   bool peek_any_identifier() {
401     Token::Value next = peek();
402     return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
403            next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
404            next == Token::STATIC || next == Token::YIELD;
405   }
406
407   bool CheckContextualKeyword(Vector<const char> keyword) {
408     if (PeekContextualKeyword(keyword)) {
409       Consume(Token::IDENTIFIER);
410       return true;
411     }
412     return false;
413   }
414
415   bool PeekContextualKeyword(Vector<const char> keyword) {
416     return peek() == Token::IDENTIFIER &&
417            scanner()->is_next_contextual_keyword(keyword);
418   }
419
420   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
421     Expect(Token::IDENTIFIER, ok);
422     if (!*ok) return;
423     if (!scanner()->is_literal_contextual_keyword(keyword)) {
424       ReportUnexpectedToken(scanner()->current_token());
425       *ok = false;
426     }
427   }
428
429   bool CheckInOrOf(
430       bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) {
431     if (Check(Token::IN)) {
432       if (is_strong(language_mode())) {
433         ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn);
434         *ok = false;
435       } else {
436         *visit_mode = ForEachStatement::ENUMERATE;
437       }
438       return true;
439     } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
440       *visit_mode = ForEachStatement::ITERATE;
441       return true;
442     }
443     return false;
444   }
445
446   // Checks whether an octal literal was last seen between beg_pos and end_pos.
447   // If so, reports an error. Only called for strict mode and template strings.
448   void CheckOctalLiteral(int beg_pos, int end_pos,
449                          MessageTemplate::Template message, bool* ok) {
450     Scanner::Location octal = scanner()->octal_position();
451     if (octal.IsValid() && beg_pos <= octal.beg_pos &&
452         octal.end_pos <= end_pos) {
453       ReportMessageAt(octal, message);
454       scanner()->clear_octal_position();
455       *ok = false;
456     }
457   }
458
459   inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
460     CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
461                       ok);
462   }
463
464   inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
465     CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
466                       ok);
467   }
468
469   // Checking the name of a function literal. This has to be done after parsing
470   // the function, since the function can declare itself strict.
471   void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
472                          FunctionNameValidity function_name_validity,
473                          const Scanner::Location& function_name_loc, bool* ok) {
474     if (function_name_validity == kSkipFunctionNameCheck) return;
475     // The function name needs to be checked in strict mode.
476     if (is_sloppy(language_mode)) return;
477
478     if (this->IsEvalOrArguments(function_name)) {
479       Traits::ReportMessageAt(function_name_loc,
480                               MessageTemplate::kStrictEvalArguments);
481       *ok = false;
482       return;
483     }
484     if (function_name_validity == kFunctionNameIsStrictReserved) {
485       Traits::ReportMessageAt(function_name_loc,
486                               MessageTemplate::kUnexpectedStrictReserved);
487       *ok = false;
488       return;
489     }
490     if (is_strong(language_mode) && this->IsUndefined(function_name)) {
491       Traits::ReportMessageAt(function_name_loc,
492                               MessageTemplate::kStrongUndefined);
493       *ok = false;
494       return;
495     }
496   }
497
498   // Determine precedence of given token.
499   static int Precedence(Token::Value token, bool accept_IN) {
500     if (token == Token::IN && !accept_IN)
501       return 0;  // 0 precedence will terminate binary expression parsing
502     return Token::Precedence(token);
503   }
504
505   typename Traits::Type::Factory* factory() {
506     return function_state_->factory();
507   }
508
509   LanguageMode language_mode() { return scope_->language_mode(); }
510   bool is_generator() const { return function_state_->is_generator(); }
511
512   bool allow_const() {
513     return is_strict(language_mode()) || allow_harmony_sloppy() ||
514            allow_legacy_const();
515   }
516
517   bool allow_let() {
518     return is_strict(language_mode()) || allow_harmony_sloppy_let();
519   }
520
521   // Report syntax errors.
522   void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
523                      ParseErrorType error_type = kSyntaxError) {
524     Scanner::Location source_location = scanner()->location();
525     Traits::ReportMessageAt(source_location, message, arg, error_type);
526   }
527
528   void ReportMessageAt(Scanner::Location location,
529                        MessageTemplate::Template message,
530                        ParseErrorType error_type = kSyntaxError) {
531     Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
532                             error_type);
533   }
534
535   void GetUnexpectedTokenMessage(
536       Token::Value token, MessageTemplate::Template* message, const char** arg,
537       MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
538
539   void ReportUnexpectedToken(Token::Value token);
540   void ReportUnexpectedTokenAt(
541       Scanner::Location location, Token::Value token,
542       MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
543
544
545   void ReportClassifierError(const ExpressionClassifier::Error& error) {
546     Traits::ReportMessageAt(error.location, error.message, error.arg,
547                             kSyntaxError);
548   }
549
550   void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
551     if (!classifier->is_valid_expression()) {
552       ReportClassifierError(classifier->expression_error());
553       *ok = false;
554     }
555   }
556
557   void ValidateFormalParameterInitializer(
558       const ExpressionClassifier* classifier, bool* ok) {
559     if (!classifier->is_valid_formal_parameter_initializer()) {
560       ReportClassifierError(classifier->formal_parameter_initializer_error());
561       *ok = false;
562     }
563   }
564
565   void ValidateBindingPattern(const ExpressionClassifier* classifier,
566                               bool* ok) {
567     if (!classifier->is_valid_binding_pattern()) {
568       ReportClassifierError(classifier->binding_pattern_error());
569       *ok = false;
570     }
571   }
572
573   void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
574                                  bool* ok) {
575     if (!classifier->is_valid_assignment_pattern()) {
576       ReportClassifierError(classifier->assignment_pattern_error());
577       *ok = false;
578     }
579   }
580
581   void ValidateFormalParameters(const ExpressionClassifier* classifier,
582                                 LanguageMode language_mode,
583                                 bool allow_duplicates, bool* ok) {
584     if (!allow_duplicates &&
585         !classifier->is_valid_formal_parameter_list_without_duplicates()) {
586       ReportClassifierError(classifier->duplicate_formal_parameter_error());
587       *ok = false;
588     } else if (is_strict(language_mode) &&
589                !classifier->is_valid_strict_mode_formal_parameters()) {
590       ReportClassifierError(classifier->strict_mode_formal_parameter_error());
591       *ok = false;
592     } else if (is_strong(language_mode) &&
593                !classifier->is_valid_strong_mode_formal_parameters()) {
594       ReportClassifierError(classifier->strong_mode_formal_parameter_error());
595       *ok = false;
596     }
597   }
598
599   void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
600                                      ExpressionT expr,
601                                      bool parenthesized_formals, bool* ok) {
602     if (classifier->is_valid_binding_pattern()) {
603       // A simple arrow formal parameter: IDENTIFIER => BODY.
604       if (!this->IsIdentifier(expr)) {
605         Traits::ReportMessageAt(scanner()->location(),
606                                 MessageTemplate::kUnexpectedToken,
607                                 Token::String(scanner()->current_token()));
608         *ok = false;
609       }
610     } else if (!classifier->is_valid_arrow_formal_parameters()) {
611       // If after parsing the expr, we see an error but the expression is
612       // neither a valid binding pattern nor a valid parenthesized formal
613       // parameter list, show the "arrow formal parameters" error if the formals
614       // started with a parenthesis, and the binding pattern error otherwise.
615       const ExpressionClassifier::Error& error =
616           parenthesized_formals ? classifier->arrow_formal_parameters_error()
617                                 : classifier->binding_pattern_error();
618       ReportClassifierError(error);
619       *ok = false;
620     }
621   }
622
623   void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
624     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
625     const char* arg;
626     GetUnexpectedTokenMessage(peek(), &message, &arg);
627     classifier->RecordExpressionError(scanner()->peek_location(), message, arg);
628   }
629
630   void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
631     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
632     const char* arg;
633     GetUnexpectedTokenMessage(peek(), &message, &arg);
634     classifier->RecordBindingPatternError(scanner()->peek_location(), message,
635                                           arg);
636   }
637
638   void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
639     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
640     const char* arg;
641     GetUnexpectedTokenMessage(peek(), &message, &arg);
642     classifier->RecordArrowFormalParametersError(scanner()->peek_location(),
643                                                  message, arg);
644   }
645
646   void FormalParameterInitializerUnexpectedToken(
647       ExpressionClassifier* classifier) {
648     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
649     const char* arg;
650     GetUnexpectedTokenMessage(peek(), &message, &arg);
651     classifier->RecordFormalParameterInitializerError(
652         scanner()->peek_location(), message, arg);
653   }
654
655   // Recursive descent functions:
656
657   // Parses an identifier that is valid for the current scope, in particular it
658   // fails on strict mode future reserved keywords in a strict scope. If
659   // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
660   // "arguments" as identifier even in strict mode (this is needed in cases like
661   // "var foo = eval;").
662   IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
663   IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
664                                          bool* ok);
665   // Parses an identifier or a strict mode future reserved word, and indicate
666   // whether it is strict mode future reserved.
667   IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
668                                                   bool* ok);
669   IdentifierT ParseIdentifierName(bool* ok);
670   // Parses an identifier and determines whether or not it is 'get' or 'set'.
671   IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
672                                             bool* ok);
673
674
675   ExpressionT ParseRegExpLiteral(bool seen_equal,
676                                  ExpressionClassifier* classifier, bool* ok);
677
678   ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
679                                      bool* ok);
680   ExpressionT ParseExpression(bool accept_IN, bool* ok);
681   ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
682                               bool* ok);
683   ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
684   ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
685                                 bool* is_static, bool* is_computed_name,
686                                 ExpressionClassifier* classifier, bool* ok);
687   ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
688   ObjectLiteralPropertyT ParsePropertyDefinition(
689       ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
690       bool is_static, bool* is_computed_name, bool* has_seen_constructor,
691       ExpressionClassifier* classifier, bool* ok);
692   typename Traits::Type::ExpressionList ParseArguments(
693       Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
694       bool* ok);
695   ExpressionT ParseAssignmentExpression(bool accept_IN,
696                                         ExpressionClassifier* classifier,
697                                         bool* ok);
698   ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
699   ExpressionT ParseConditionalExpression(bool accept_IN,
700                                          ExpressionClassifier* classifier,
701                                          bool* ok);
702   ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
703                                     ExpressionClassifier* classifier, bool* ok);
704   ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
705   ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
706                                      bool* ok);
707   ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
708                                           bool* ok);
709   ExpressionT ParseMemberWithNewPrefixesExpression(
710       ExpressionClassifier* classifier, bool* ok);
711   ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
712   ExpressionT ParseMemberExpressionContinuation(
713       ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
714   ExpressionT ParseArrowFunctionLiteral(
715       const FormalParametersT& parameters,
716       const ExpressionClassifier& classifier, bool* ok);
717   ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
718                                    ExpressionClassifier* classifier, bool* ok);
719   void AddTemplateExpression(ExpressionT);
720   ExpressionT ParseSuperExpression(bool is_new,
721                                    ExpressionClassifier* classifier, bool* ok);
722   ExpressionT ParseNewTargetExpression(bool* ok);
723   ExpressionT ParseStrongInitializationExpression(
724       ExpressionClassifier* classifier, bool* ok);
725   ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
726                                              bool* ok);
727
728   void ParseFormalParameter(FormalParametersT* parameters,
729                             ExpressionClassifier* classifier, bool* ok);
730   void ParseFormalParameterList(FormalParametersT* parameters,
731                                 ExpressionClassifier* classifier, bool* ok);
732   void CheckArityRestrictions(
733       int param_count, FunctionLiteral::ArityRestriction arity_restriction,
734       bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
735
736   bool IsNextLetKeyword();
737
738   // Checks if the expression is a valid reference expression (e.g., on the
739   // left-hand side of assignments). Although ruled out by ECMA as early errors,
740   // we allow calls for web compatibility and rewrite them to a runtime throw.
741   ExpressionT CheckAndRewriteReferenceExpression(
742       ExpressionT expression, int beg_pos, int end_pos,
743       MessageTemplate::Template message, bool* ok);
744   ExpressionT CheckAndRewriteReferenceExpression(
745       ExpressionT expression, int beg_pos, int end_pos,
746       MessageTemplate::Template message, ParseErrorType type, bool* ok);
747
748   // Used to validate property names in object literals and class literals
749   enum PropertyKind {
750     kAccessorProperty,
751     kValueProperty,
752     kMethodProperty
753   };
754
755   class ObjectLiteralCheckerBase {
756    public:
757     explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
758
759     virtual void CheckProperty(Token::Value property, PropertyKind type,
760                                bool is_static, bool is_generator, bool* ok) = 0;
761
762     virtual ~ObjectLiteralCheckerBase() {}
763
764    protected:
765     ParserBase* parser() const { return parser_; }
766     Scanner* scanner() const { return parser_->scanner(); }
767
768    private:
769     ParserBase* parser_;
770   };
771
772   // Validation per ES6 object literals.
773   class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
774    public:
775     explicit ObjectLiteralChecker(ParserBase* parser)
776         : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
777
778     void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
779                        bool is_generator, bool* ok) override;
780
781    private:
782     bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
783
784     bool has_seen_proto_;
785   };
786
787   // Validation per ES6 class literals.
788   class ClassLiteralChecker : public ObjectLiteralCheckerBase {
789    public:
790     explicit ClassLiteralChecker(ParserBase* parser)
791         : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
792
793     void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
794                        bool is_generator, bool* ok) override;
795
796    private:
797     bool IsConstructor() {
798       return this->scanner()->LiteralMatches("constructor", 11);
799     }
800     bool IsPrototype() {
801       return this->scanner()->LiteralMatches("prototype", 9);
802     }
803
804     bool has_seen_constructor_;
805   };
806
807   // If true, the next (and immediately following) function literal is
808   // preceded by a parenthesis.
809   // Heuristically that means that the function will be called immediately,
810   // so never lazily compile it.
811   bool parenthesized_function_;
812
813   Scope* scope_;                   // Scope stack.
814   FunctionState* function_state_;  // Function state stack.
815   v8::Extension* extension_;
816   FuncNameInferrer* fni_;
817   AstValueFactory* ast_value_factory_;  // Not owned.
818   ParserRecorder* log_;
819   Mode mode_;
820   uintptr_t stack_limit_;
821
822  private:
823   Zone* zone_;
824
825   Scanner* scanner_;
826   bool stack_overflow_;
827
828   bool allow_lazy_;
829   bool allow_natives_;
830   bool allow_harmony_arrow_functions_;
831   bool allow_harmony_sloppy_;
832   bool allow_harmony_sloppy_function_;
833   bool allow_harmony_sloppy_let_;
834   bool allow_harmony_rest_parameters_;
835   bool allow_harmony_default_parameters_;
836   bool allow_harmony_spread_calls_;
837   bool allow_harmony_destructuring_;
838   bool allow_harmony_spread_arrays_;
839   bool allow_harmony_new_target_;
840   bool allow_strong_mode_;
841   bool allow_legacy_const_;
842 };
843
844
845 class PreParserIdentifier {
846  public:
847   PreParserIdentifier() : type_(kUnknownIdentifier) {}
848   static PreParserIdentifier Default() {
849     return PreParserIdentifier(kUnknownIdentifier);
850   }
851   static PreParserIdentifier Eval() {
852     return PreParserIdentifier(kEvalIdentifier);
853   }
854   static PreParserIdentifier Arguments() {
855     return PreParserIdentifier(kArgumentsIdentifier);
856   }
857   static PreParserIdentifier Undefined() {
858     return PreParserIdentifier(kUndefinedIdentifier);
859   }
860   static PreParserIdentifier FutureReserved() {
861     return PreParserIdentifier(kFutureReservedIdentifier);
862   }
863   static PreParserIdentifier FutureStrictReserved() {
864     return PreParserIdentifier(kFutureStrictReservedIdentifier);
865   }
866   static PreParserIdentifier Let() {
867     return PreParserIdentifier(kLetIdentifier);
868   }
869   static PreParserIdentifier Static() {
870     return PreParserIdentifier(kStaticIdentifier);
871   }
872   static PreParserIdentifier Yield() {
873     return PreParserIdentifier(kYieldIdentifier);
874   }
875   static PreParserIdentifier Prototype() {
876     return PreParserIdentifier(kPrototypeIdentifier);
877   }
878   static PreParserIdentifier Constructor() {
879     return PreParserIdentifier(kConstructorIdentifier);
880   }
881   bool IsEval() const { return type_ == kEvalIdentifier; }
882   bool IsArguments() const { return type_ == kArgumentsIdentifier; }
883   bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
884   bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
885   bool IsLet() const { return type_ == kLetIdentifier; }
886   bool IsStatic() const { return type_ == kStaticIdentifier; }
887   bool IsYield() const { return type_ == kYieldIdentifier; }
888   bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
889   bool IsConstructor() const { return type_ == kConstructorIdentifier; }
890   bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
891   bool IsFutureStrictReserved() const {
892     return type_ == kFutureStrictReservedIdentifier ||
893            type_ == kLetIdentifier || type_ == kStaticIdentifier ||
894            type_ == kYieldIdentifier;
895   }
896
897   // Allow identifier->name()[->length()] to work. The preparser
898   // does not need the actual positions/lengths of the identifiers.
899   const PreParserIdentifier* operator->() const { return this; }
900   const PreParserIdentifier raw_name() const { return *this; }
901
902   int position() const { return 0; }
903   int length() const { return 0; }
904
905  private:
906   enum Type {
907     kUnknownIdentifier,
908     kFutureReservedIdentifier,
909     kFutureStrictReservedIdentifier,
910     kLetIdentifier,
911     kStaticIdentifier,
912     kYieldIdentifier,
913     kEvalIdentifier,
914     kArgumentsIdentifier,
915     kUndefinedIdentifier,
916     kPrototypeIdentifier,
917     kConstructorIdentifier
918   };
919
920   explicit PreParserIdentifier(Type type) : type_(type) {}
921   Type type_;
922
923   friend class PreParserExpression;
924 };
925
926
927 class PreParserExpression {
928  public:
929   static PreParserExpression Default() {
930     return PreParserExpression(TypeField::encode(kExpression));
931   }
932
933   static PreParserExpression Spread(PreParserExpression expression) {
934     return PreParserExpression(TypeField::encode(kSpreadExpression));
935   }
936
937   static PreParserExpression FromIdentifier(PreParserIdentifier id) {
938     return PreParserExpression(TypeField::encode(kIdentifierExpression) |
939                                IdentifierTypeField::encode(id.type_));
940   }
941
942   static PreParserExpression BinaryOperation(PreParserExpression left,
943                                              Token::Value op,
944                                              PreParserExpression right) {
945     return PreParserExpression(
946         TypeField::encode(kBinaryOperationExpression) |
947         HasRestField::encode(op == Token::COMMA &&
948                              right->IsSpreadExpression()));
949   }
950
951   static PreParserExpression StringLiteral() {
952     return PreParserExpression(TypeField::encode(kStringLiteralExpression));
953   }
954
955   static PreParserExpression UseStrictStringLiteral() {
956     return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
957                                IsUseStrictField::encode(true));
958   }
959
960   static PreParserExpression UseStrongStringLiteral() {
961     return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
962                                IsUseStrongField::encode(true));
963   }
964
965   static PreParserExpression This() {
966     return PreParserExpression(TypeField::encode(kExpression) |
967                                ExpressionTypeField::encode(kThisExpression));
968   }
969
970   static PreParserExpression ThisProperty() {
971     return PreParserExpression(
972         TypeField::encode(kExpression) |
973         ExpressionTypeField::encode(kThisPropertyExpression));
974   }
975
976   static PreParserExpression Property() {
977     return PreParserExpression(
978         TypeField::encode(kExpression) |
979         ExpressionTypeField::encode(kPropertyExpression));
980   }
981
982   static PreParserExpression Call() {
983     return PreParserExpression(TypeField::encode(kExpression) |
984                                ExpressionTypeField::encode(kCallExpression));
985   }
986
987   static PreParserExpression SuperCallReference() {
988     return PreParserExpression(
989         TypeField::encode(kExpression) |
990         ExpressionTypeField::encode(kSuperCallReference));
991   }
992
993   static PreParserExpression NoTemplateTag() {
994     return PreParserExpression(
995         TypeField::encode(kExpression) |
996         ExpressionTypeField::encode(kNoTemplateTagExpression));
997   }
998
999   bool IsIdentifier() const {
1000     return TypeField::decode(code_) == kIdentifierExpression;
1001   }
1002
1003   PreParserIdentifier AsIdentifier() const {
1004     DCHECK(IsIdentifier());
1005     return PreParserIdentifier(IdentifierTypeField::decode(code_));
1006   }
1007
1008   bool IsStringLiteral() const {
1009     return TypeField::decode(code_) == kStringLiteralExpression;
1010   }
1011
1012   bool IsUseStrictLiteral() const {
1013     return TypeField::decode(code_) == kStringLiteralExpression &&
1014            IsUseStrictField::decode(code_);
1015   }
1016
1017   bool IsUseStrongLiteral() const {
1018     return TypeField::decode(code_) == kStringLiteralExpression &&
1019            IsUseStrongField::decode(code_);
1020   }
1021
1022   bool IsThis() const {
1023     return TypeField::decode(code_) == kExpression &&
1024            ExpressionTypeField::decode(code_) == kThisExpression;
1025   }
1026
1027   bool IsThisProperty() const {
1028     return TypeField::decode(code_) == kExpression &&
1029            ExpressionTypeField::decode(code_) == kThisPropertyExpression;
1030   }
1031
1032   bool IsProperty() const {
1033     return TypeField::decode(code_) == kExpression &&
1034            (ExpressionTypeField::decode(code_) == kPropertyExpression ||
1035             ExpressionTypeField::decode(code_) == kThisPropertyExpression);
1036   }
1037
1038   bool IsCall() const {
1039     return TypeField::decode(code_) == kExpression &&
1040            ExpressionTypeField::decode(code_) == kCallExpression;
1041   }
1042
1043   bool IsSuperCallReference() const {
1044     return TypeField::decode(code_) == kExpression &&
1045            ExpressionTypeField::decode(code_) == kSuperCallReference;
1046   }
1047
1048   bool IsValidReferenceExpression() const {
1049     return IsIdentifier() || IsProperty();
1050   }
1051
1052   // At the moment PreParser doesn't track these expression types.
1053   bool IsFunctionLiteral() const { return false; }
1054   bool IsCallNew() const { return false; }
1055
1056   bool IsNoTemplateTag() const {
1057     return TypeField::decode(code_) == kExpression &&
1058            ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
1059   }
1060
1061   bool IsSpreadExpression() const {
1062     return TypeField::decode(code_) == kSpreadExpression;
1063   }
1064
1065   bool IsArrowFunctionFormalParametersWithRestParameter() const {
1066     // Iff the expression classifier has determined that this expression is a
1067     // valid arrow fformal parameter list, return true if the formal parameter
1068     // list ends with a rest parameter.
1069     return IsSpreadExpression() ||
1070            (IsBinaryOperation() && HasRestField::decode(code_));
1071   }
1072
1073   PreParserExpression AsFunctionLiteral() { return *this; }
1074
1075   bool IsBinaryOperation() const {
1076     return TypeField::decode(code_) == kBinaryOperationExpression;
1077   }
1078
1079   // Dummy implementation for making expression->somefunc() work in both Parser
1080   // and PreParser.
1081   PreParserExpression* operator->() { return this; }
1082
1083   // More dummy implementations of things PreParser doesn't need to track:
1084   void set_index(int index) {}  // For YieldExpressions
1085   void set_should_eager_compile() {}
1086
1087   int position() const { return RelocInfo::kNoPosition; }
1088   void set_function_token_position(int position) {}
1089
1090  private:
1091   enum Type {
1092     kExpression,
1093     kIdentifierExpression,
1094     kStringLiteralExpression,
1095     kBinaryOperationExpression,
1096     kSpreadExpression
1097   };
1098
1099   enum ExpressionType {
1100     kThisExpression,
1101     kThisPropertyExpression,
1102     kPropertyExpression,
1103     kCallExpression,
1104     kSuperCallReference,
1105     kNoTemplateTagExpression
1106   };
1107
1108   explicit PreParserExpression(uint32_t expression_code)
1109       : code_(expression_code) {}
1110
1111   // The first three bits are for the Type.
1112   typedef BitField<Type, 0, 3> TypeField;
1113
1114   // The rest of the bits are interpreted depending on the value
1115   // of the Type field, so they can share the storage.
1116   typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
1117   typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
1118   typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
1119   typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
1120       IdentifierTypeField;
1121   typedef BitField<bool, TypeField::kNext, 1> HasRestField;
1122
1123   uint32_t code_;
1124 };
1125
1126
1127 // The pre-parser doesn't need to build lists of expressions, identifiers, or
1128 // the like.
1129 template <typename T>
1130 class PreParserList {
1131  public:
1132   // These functions make list->Add(some_expression) work (and do nothing).
1133   PreParserList() : length_(0) {}
1134   PreParserList* operator->() { return this; }
1135   void Add(T, void*) { ++length_; }
1136   int length() const { return length_; }
1137  private:
1138   int length_;
1139 };
1140
1141
1142 typedef PreParserList<PreParserExpression> PreParserExpressionList;
1143
1144
1145 class PreParserStatement {
1146  public:
1147   static PreParserStatement Default() {
1148     return PreParserStatement(kUnknownStatement);
1149   }
1150
1151   static PreParserStatement Jump() {
1152     return PreParserStatement(kJumpStatement);
1153   }
1154
1155   static PreParserStatement FunctionDeclaration() {
1156     return PreParserStatement(kFunctionDeclaration);
1157   }
1158
1159   // Creates expression statement from expression.
1160   // Preserves being an unparenthesized string literal, possibly
1161   // "use strict".
1162   static PreParserStatement ExpressionStatement(
1163       PreParserExpression expression) {
1164     if (expression.IsUseStrictLiteral()) {
1165       return PreParserStatement(kUseStrictExpressionStatement);
1166     }
1167     if (expression.IsUseStrongLiteral()) {
1168       return PreParserStatement(kUseStrongExpressionStatement);
1169     }
1170     if (expression.IsStringLiteral()) {
1171       return PreParserStatement(kStringLiteralExpressionStatement);
1172     }
1173     return Default();
1174   }
1175
1176   bool IsStringLiteral() {
1177     return code_ == kStringLiteralExpressionStatement;
1178   }
1179
1180   bool IsUseStrictLiteral() {
1181     return code_ == kUseStrictExpressionStatement;
1182   }
1183
1184   bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
1185
1186   bool IsFunctionDeclaration() {
1187     return code_ == kFunctionDeclaration;
1188   }
1189
1190   bool IsJumpStatement() {
1191     return code_ == kJumpStatement;
1192   }
1193
1194  private:
1195   enum Type {
1196     kUnknownStatement,
1197     kJumpStatement,
1198     kStringLiteralExpressionStatement,
1199     kUseStrictExpressionStatement,
1200     kUseStrongExpressionStatement,
1201     kFunctionDeclaration
1202   };
1203
1204   explicit PreParserStatement(Type code) : code_(code) {}
1205   Type code_;
1206 };
1207
1208
1209 typedef PreParserList<PreParserStatement> PreParserStatementList;
1210
1211
1212 class PreParserFactory {
1213  public:
1214   explicit PreParserFactory(void* unused_value_factory) {}
1215   PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
1216                                        int pos) {
1217     return PreParserExpression::Default();
1218   }
1219   PreParserExpression NewNumberLiteral(double number,
1220                                        int pos) {
1221     return PreParserExpression::Default();
1222   }
1223   PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
1224                                        PreParserIdentifier js_flags,
1225                                        int literal_index,
1226                                        bool is_strong,
1227                                        int pos) {
1228     return PreParserExpression::Default();
1229   }
1230   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1231                                       int literal_index,
1232                                       bool is_strong,
1233                                       int pos) {
1234     return PreParserExpression::Default();
1235   }
1236   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1237                                       int first_spread_index, int literal_index,
1238                                       bool is_strong, int pos) {
1239     return PreParserExpression::Default();
1240   }
1241   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1242                                                PreParserExpression value,
1243                                                ObjectLiteralProperty::Kind kind,
1244                                                bool is_static,
1245                                                bool is_computed_name) {
1246     return PreParserExpression::Default();
1247   }
1248   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1249                                                PreParserExpression value,
1250                                                bool is_static,
1251                                                bool is_computed_name) {
1252     return PreParserExpression::Default();
1253   }
1254   PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
1255                                        int literal_index,
1256                                        int boilerplate_properties,
1257                                        bool has_function,
1258                                        bool is_strong,
1259                                        int pos) {
1260     return PreParserExpression::Default();
1261   }
1262   PreParserExpression NewVariableProxy(void* variable) {
1263     return PreParserExpression::Default();
1264   }
1265   PreParserExpression NewProperty(PreParserExpression obj,
1266                                   PreParserExpression key,
1267                                   int pos) {
1268     if (obj.IsThis()) {
1269       return PreParserExpression::ThisProperty();
1270     }
1271     return PreParserExpression::Property();
1272   }
1273   PreParserExpression NewUnaryOperation(Token::Value op,
1274                                         PreParserExpression expression,
1275                                         int pos) {
1276     return PreParserExpression::Default();
1277   }
1278   PreParserExpression NewBinaryOperation(Token::Value op,
1279                                          PreParserExpression left,
1280                                          PreParserExpression right, int pos) {
1281     return PreParserExpression::BinaryOperation(left, op, right);
1282   }
1283   PreParserExpression NewCompareOperation(Token::Value op,
1284                                           PreParserExpression left,
1285                                           PreParserExpression right, int pos) {
1286     return PreParserExpression::Default();
1287   }
1288   PreParserExpression NewAssignment(Token::Value op,
1289                                     PreParserExpression left,
1290                                     PreParserExpression right,
1291                                     int pos) {
1292     return PreParserExpression::Default();
1293   }
1294   PreParserExpression NewYield(PreParserExpression generator_object,
1295                                PreParserExpression expression,
1296                                Yield::Kind yield_kind,
1297                                int pos) {
1298     return PreParserExpression::Default();
1299   }
1300   PreParserExpression NewConditional(PreParserExpression condition,
1301                                      PreParserExpression then_expression,
1302                                      PreParserExpression else_expression,
1303                                      int pos) {
1304     return PreParserExpression::Default();
1305   }
1306   PreParserExpression NewCountOperation(Token::Value op,
1307                                         bool is_prefix,
1308                                         PreParserExpression expression,
1309                                         int pos) {
1310     return PreParserExpression::Default();
1311   }
1312   PreParserExpression NewCall(PreParserExpression expression,
1313                               PreParserExpressionList arguments,
1314                               int pos) {
1315     return PreParserExpression::Call();
1316   }
1317   PreParserExpression NewCallNew(PreParserExpression expression,
1318                                  PreParserExpressionList arguments,
1319                                  int pos) {
1320     return PreParserExpression::Default();
1321   }
1322   PreParserExpression NewCallRuntime(const AstRawString* name,
1323                                      const Runtime::Function* function,
1324                                      PreParserExpressionList arguments,
1325                                      int pos) {
1326     return PreParserExpression::Default();
1327   }
1328   PreParserStatement NewReturnStatement(PreParserExpression expression,
1329                                         int pos) {
1330     return PreParserStatement::Default();
1331   }
1332   PreParserExpression NewFunctionLiteral(
1333       PreParserIdentifier name, AstValueFactory* ast_value_factory,
1334       Scope* scope, PreParserStatementList body, int materialized_literal_count,
1335       int expected_property_count, int parameter_count,
1336       FunctionLiteral::ParameterFlag has_duplicate_parameters,
1337       FunctionLiteral::FunctionType function_type,
1338       FunctionLiteral::IsFunctionFlag is_function,
1339       FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
1340       int position) {
1341     return PreParserExpression::Default();
1342   }
1343
1344   PreParserExpression NewSpread(PreParserExpression expression, int pos) {
1345     return PreParserExpression::Spread(expression);
1346   }
1347
1348   PreParserExpression NewEmptyParentheses(int pos) {
1349     return PreParserExpression::Default();
1350   }
1351
1352   // Return the object itself as AstVisitor and implement the needed
1353   // dummy method right in this class.
1354   PreParserFactory* visitor() { return this; }
1355   int* ast_properties() {
1356     static int dummy = 42;
1357     return &dummy;
1358   }
1359 };
1360
1361
1362 struct PreParserFormalParameters : FormalParametersBase {
1363   explicit PreParserFormalParameters(Scope* scope)
1364       : FormalParametersBase(scope) {}
1365   int arity = 0;
1366
1367   int Arity() const { return arity; }
1368   PreParserIdentifier at(int i) { return PreParserIdentifier(); }  // Dummy
1369 };
1370
1371
1372 class PreParser;
1373
1374 class PreParserTraits {
1375  public:
1376   struct Type {
1377     // TODO(marja): To be removed. The Traits object should contain all the data
1378     // it needs.
1379     typedef PreParser* Parser;
1380
1381     // PreParser doesn't need to store generator variables.
1382     typedef void GeneratorVariable;
1383
1384     typedef int AstProperties;
1385
1386     // Return types for traversing functions.
1387     typedef PreParserIdentifier Identifier;
1388     typedef PreParserExpression Expression;
1389     typedef PreParserExpression YieldExpression;
1390     typedef PreParserExpression FunctionLiteral;
1391     typedef PreParserExpression ClassLiteral;
1392     typedef PreParserExpression ObjectLiteralProperty;
1393     typedef PreParserExpression Literal;
1394     typedef PreParserExpressionList ExpressionList;
1395     typedef PreParserExpressionList PropertyList;
1396     typedef PreParserIdentifier FormalParameter;
1397     typedef PreParserFormalParameters FormalParameters;
1398     typedef PreParserStatementList StatementList;
1399
1400     // For constructing objects returned by the traversing functions.
1401     typedef PreParserFactory Factory;
1402   };
1403
1404   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
1405
1406   // Helper functions for recursive descent.
1407   static bool IsEval(PreParserIdentifier identifier) {
1408     return identifier.IsEval();
1409   }
1410
1411   static bool IsArguments(PreParserIdentifier identifier) {
1412     return identifier.IsArguments();
1413   }
1414
1415   static bool IsEvalOrArguments(PreParserIdentifier identifier) {
1416     return identifier.IsEvalOrArguments();
1417   }
1418
1419   static bool IsUndefined(PreParserIdentifier identifier) {
1420     return identifier.IsUndefined();
1421   }
1422
1423   static bool IsPrototype(PreParserIdentifier identifier) {
1424     return identifier.IsPrototype();
1425   }
1426
1427   static bool IsConstructor(PreParserIdentifier identifier) {
1428     return identifier.IsConstructor();
1429   }
1430
1431   // Returns true if the expression is of type "this.foo".
1432   static bool IsThisProperty(PreParserExpression expression) {
1433     return expression.IsThisProperty();
1434   }
1435
1436   static bool IsIdentifier(PreParserExpression expression) {
1437     return expression.IsIdentifier();
1438   }
1439
1440   static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
1441     return expression.AsIdentifier();
1442   }
1443
1444   static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1445     return identifier.IsFutureStrictReserved();
1446   }
1447
1448   static bool IsBoilerplateProperty(PreParserExpression property) {
1449     // PreParser doesn't count boilerplate properties.
1450     return false;
1451   }
1452
1453   static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
1454     return false;
1455   }
1456
1457   static PreParserExpression GetPropertyValue(PreParserExpression property) {
1458     return PreParserExpression::Default();
1459   }
1460
1461   // Functions for encapsulating the differences between parsing and preparsing;
1462   // operations interleaved with the recursive descent.
1463   static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1464     // PreParser should not use FuncNameInferrer.
1465     UNREACHABLE();
1466   }
1467
1468   static void PushPropertyName(FuncNameInferrer* fni,
1469                                PreParserExpression expression) {
1470     // PreParser should not use FuncNameInferrer.
1471     UNREACHABLE();
1472   }
1473
1474   static void InferFunctionName(FuncNameInferrer* fni,
1475                                 PreParserExpression expression) {
1476     // PreParser should not use FuncNameInferrer.
1477     UNREACHABLE();
1478   }
1479
1480   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
1481       Scope* scope, PreParserExpression property, bool* has_function) {}
1482
1483   static void CheckAssigningFunctionLiteralToProperty(
1484       PreParserExpression left, PreParserExpression right) {}
1485
1486   static void CheckPossibleEvalCall(PreParserExpression expression,
1487                                     Scope* scope) {
1488     if (IsIdentifier(expression) && IsEval(AsIdentifier(expression))) {
1489       scope->DeclarationScope()->RecordEvalCall();
1490       scope->RecordEvalCall();
1491     }
1492   }
1493
1494   static PreParserExpression MarkExpressionAsAssigned(
1495       PreParserExpression expression) {
1496     // TODO(marja): To be able to produce the same errors, the preparser needs
1497     // to start tracking which expressions are variables and which are assigned.
1498     return expression;
1499   }
1500
1501   bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
1502                                               PreParserExpression y,
1503                                               Token::Value op,
1504                                               int pos,
1505                                               PreParserFactory* factory) {
1506     return false;
1507   }
1508
1509   PreParserExpression BuildUnaryExpression(PreParserExpression expression,
1510                                            Token::Value op, int pos,
1511                                            PreParserFactory* factory) {
1512     return PreParserExpression::Default();
1513   }
1514
1515   PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
1516                                              int pos) {
1517     return PreParserExpression::Default();
1518   }
1519   PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
1520                                           Handle<Object> arg, int pos) {
1521     return PreParserExpression::Default();
1522   }
1523   PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
1524                                         Handle<Object> arg, int pos) {
1525     return PreParserExpression::Default();
1526   }
1527
1528   // Reporting errors.
1529   void ReportMessageAt(Scanner::Location location,
1530                        MessageTemplate::Template message,
1531                        const char* arg = NULL,
1532                        ParseErrorType error_type = kSyntaxError);
1533   void ReportMessageAt(int start_pos, int end_pos,
1534                        MessageTemplate::Template message,
1535                        const char* arg = NULL,
1536                        ParseErrorType error_type = kSyntaxError);
1537
1538   // "null" return type creators.
1539   static PreParserIdentifier EmptyIdentifier() {
1540     return PreParserIdentifier::Default();
1541   }
1542   static PreParserIdentifier EmptyIdentifierString() {
1543     return PreParserIdentifier::Default();
1544   }
1545   static PreParserExpression EmptyExpression() {
1546     return PreParserExpression::Default();
1547   }
1548   static PreParserExpression EmptyLiteral() {
1549     return PreParserExpression::Default();
1550   }
1551   static PreParserExpression EmptyObjectLiteralProperty() {
1552     return PreParserExpression::Default();
1553   }
1554   static PreParserExpression EmptyFunctionLiteral() {
1555     return PreParserExpression::Default();
1556   }
1557   static PreParserExpressionList NullExpressionList() {
1558     return PreParserExpressionList();
1559   }
1560
1561   // Odd-ball literal creators.
1562   static PreParserExpression GetLiteralTheHole(int position,
1563                                                PreParserFactory* factory) {
1564     return PreParserExpression::Default();
1565   }
1566
1567   // Producing data during the recursive descent.
1568   PreParserIdentifier GetSymbol(Scanner* scanner);
1569   PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
1570
1571   static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1572     return PreParserIdentifier::Default();
1573   }
1574
1575   static PreParserExpression ThisExpression(Scope* scope,
1576                                             PreParserFactory* factory,
1577                                             int pos) {
1578     return PreParserExpression::This();
1579   }
1580
1581   static PreParserExpression SuperPropertyReference(Scope* scope,
1582                                                     PreParserFactory* factory,
1583                                                     int pos) {
1584     return PreParserExpression::Default();
1585   }
1586
1587   static PreParserExpression SuperCallReference(Scope* scope,
1588                                                 PreParserFactory* factory,
1589                                                 int pos) {
1590     return PreParserExpression::SuperCallReference();
1591   }
1592
1593   static PreParserExpression NewTargetExpression(Scope* scope,
1594                                                  PreParserFactory* factory,
1595                                                  int pos) {
1596     return PreParserExpression::Default();
1597   }
1598
1599   static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
1600                                                 int pos, int end_pos) {
1601     return PreParserExpression::Default();
1602   }
1603
1604   static PreParserExpression ExpressionFromLiteral(
1605       Token::Value token, int pos, Scanner* scanner,
1606       PreParserFactory* factory) {
1607     return PreParserExpression::Default();
1608   }
1609
1610   static PreParserExpression ExpressionFromIdentifier(
1611       PreParserIdentifier name, int start_position, int end_position,
1612       Scope* scope, PreParserFactory* factory) {
1613     return PreParserExpression::FromIdentifier(name);
1614   }
1615
1616   PreParserExpression ExpressionFromString(int pos,
1617                                            Scanner* scanner,
1618                                            PreParserFactory* factory = NULL);
1619
1620   PreParserExpression GetIterator(PreParserExpression iterable,
1621                                   PreParserFactory* factory) {
1622     return PreParserExpression::Default();
1623   }
1624
1625   static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
1626     return PreParserExpressionList();
1627   }
1628
1629   static PreParserStatementList NewStatementList(int size, Zone* zone) {
1630     return PreParserStatementList();
1631   }
1632
1633   static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
1634     return PreParserExpressionList();
1635   }
1636
1637   static void AddParameterInitializationBlock(
1638       const PreParserFormalParameters& parameters,
1639       PreParserStatementList list, bool* ok) {}
1640
1641   V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1642                                       int* expected_property_count, bool* ok) {
1643     UNREACHABLE();
1644   }
1645
1646   V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1647       PreParserIdentifier function_name, int pos,
1648       const PreParserFormalParameters& parameters, FunctionKind kind,
1649       FunctionLiteral::FunctionType function_type, bool* ok);
1650
1651   V8_INLINE void ParseArrowFunctionFormalParameterList(
1652       PreParserFormalParameters* parameters,
1653       PreParserExpression expression, const Scanner::Location& params_loc,
1654       Scanner::Location* duplicate_loc, bool* ok);
1655
1656   void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
1657
1658   struct TemplateLiteralState {};
1659
1660   TemplateLiteralState OpenTemplateLiteral(int pos) {
1661     return TemplateLiteralState();
1662   }
1663   void AddTemplateSpan(TemplateLiteralState*, bool) {}
1664   void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
1665   PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
1666                                            PreParserExpression tag) {
1667     if (IsTaggedTemplate(tag)) {
1668       // Emulate generation of array literals for tag callsite
1669       // 1st is array of cooked strings, second is array of raw strings
1670       MaterializeTemplateCallsiteLiterals();
1671     }
1672     return EmptyExpression();
1673   }
1674   inline void MaterializeTemplateCallsiteLiterals();
1675   PreParserExpression NoTemplateTag() {
1676     return PreParserExpression::NoTemplateTag();
1677   }
1678   static bool IsTaggedTemplate(const PreParserExpression tag) {
1679     return !tag.IsNoTemplateTag();
1680   }
1681
1682   void AddFormalParameter(
1683       PreParserFormalParameters* parameters, PreParserExpression pattern,
1684       PreParserExpression initializer, bool is_rest) {
1685     ++parameters->arity;
1686   }
1687   void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
1688                               ExpressionClassifier* classifier) {
1689     if (!classifier->is_simple_parameter_list()) {
1690       scope->SetHasNonSimpleParameters();
1691     }
1692   }
1693
1694   void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
1695
1696   // Temporary glue; these functions will move to ParserBase.
1697   PreParserExpression ParseV8Intrinsic(bool* ok);
1698   PreParserExpression ParseFunctionLiteral(
1699       PreParserIdentifier name, Scanner::Location function_name_location,
1700       FunctionNameValidity function_name_validity, FunctionKind kind,
1701       int function_token_position, FunctionLiteral::FunctionType type,
1702       FunctionLiteral::ArityRestriction arity_restriction,
1703       LanguageMode language_mode, bool* ok);
1704
1705   PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1706                                         Scanner::Location class_name_location,
1707                                         bool name_is_strict_reserved, int pos,
1708                                         bool* ok);
1709
1710   PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
1711     return list;
1712   }
1713
1714   inline void MaterializeUnspreadArgumentsLiterals(int count);
1715
1716   inline PreParserExpression SpreadCall(PreParserExpression function,
1717                                         PreParserExpressionList args, int pos);
1718
1719   inline PreParserExpression SpreadCallNew(PreParserExpression function,
1720                                            PreParserExpressionList args,
1721                                            int pos);
1722
1723  private:
1724   PreParser* pre_parser_;
1725 };
1726
1727
1728 // Preparsing checks a JavaScript program and emits preparse-data that helps
1729 // a later parsing to be faster.
1730 // See preparse-data-format.h for the data format.
1731
1732 // The PreParser checks that the syntax follows the grammar for JavaScript,
1733 // and collects some information about the program along the way.
1734 // The grammar check is only performed in order to understand the program
1735 // sufficiently to deduce some information about it, that can be used
1736 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
1737 // rather it is to speed up properly written and correct programs.
1738 // That means that contextual checks (like a label being declared where
1739 // it is used) are generally omitted.
1740 class PreParser : public ParserBase<PreParserTraits> {
1741  public:
1742   typedef PreParserIdentifier Identifier;
1743   typedef PreParserExpression Expression;
1744   typedef PreParserStatement Statement;
1745
1746   enum PreParseResult {
1747     kPreParseStackOverflow,
1748     kPreParseSuccess
1749   };
1750
1751   PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
1752             ParserRecorder* log, uintptr_t stack_limit)
1753       : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
1754                                     ast_value_factory, log, this) {}
1755
1756   // Pre-parse the program from the character stream; returns true on
1757   // success (even if parsing failed, the pre-parse data successfully
1758   // captured the syntax error), and false if a stack-overflow happened
1759   // during parsing.
1760   PreParseResult PreParseProgram(int* materialized_literals = 0) {
1761     Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1762     PreParserFactory factory(NULL);
1763     FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
1764                             &factory);
1765     bool ok = true;
1766     int start_position = scanner()->peek_location().beg_pos;
1767     ParseStatementList(Token::EOS, &ok);
1768     if (stack_overflow()) return kPreParseStackOverflow;
1769     if (!ok) {
1770       ReportUnexpectedToken(scanner()->current_token());
1771     } else if (is_strict(scope_->language_mode())) {
1772       CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
1773                               &ok);
1774     }
1775     if (materialized_literals) {
1776       *materialized_literals = function_state_->materialized_literal_count();
1777     }
1778     return kPreParseSuccess;
1779   }
1780
1781   // Parses a single function literal, from the opening parentheses before
1782   // parameters to the closing brace after the body.
1783   // Returns a FunctionEntry describing the body of the function in enough
1784   // detail that it can be lazily compiled.
1785   // The scanner is expected to have matched the "function" or "function*"
1786   // keyword and parameters, and have consumed the initial '{'.
1787   // At return, unless an error occurred, the scanner is positioned before the
1788   // the final '}'.
1789   PreParseResult PreParseLazyFunction(
1790       LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
1791       ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr);
1792
1793  private:
1794   friend class PreParserTraits;
1795
1796   static const int kLazyParseTrialLimit = 200;
1797
1798   // These types form an algebra over syntactic categories that is just
1799   // rich enough to let us recognize and propagate the constructs that
1800   // are either being counted in the preparser data, or is important
1801   // to throw the correct syntax error exceptions.
1802
1803   // All ParseXXX functions take as the last argument an *ok parameter
1804   // which is set to false if parsing failed; it is unchanged otherwise.
1805   // By making the 'exception handling' explicit, we are forced to check
1806   // for failure at the call sites.
1807   Statement ParseStatementListItem(bool* ok);
1808   void ParseStatementList(int end_token, bool* ok,
1809                           Scanner::BookmarkScope* bookmark = nullptr);
1810   Statement ParseStatement(bool* ok);
1811   Statement ParseSubStatement(bool* ok);
1812   Statement ParseFunctionDeclaration(bool* ok);
1813   Statement ParseClassDeclaration(bool* ok);
1814   Statement ParseBlock(bool* ok);
1815   Statement ParseVariableStatement(VariableDeclarationContext var_context,
1816                                    bool* ok);
1817   Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1818                                       int* num_decl,
1819                                       Scanner::Location* first_initializer_loc,
1820                                       Scanner::Location* bindings_loc,
1821                                       bool* ok);
1822   Statement ParseExpressionOrLabelledStatement(bool* ok);
1823   Statement ParseIfStatement(bool* ok);
1824   Statement ParseContinueStatement(bool* ok);
1825   Statement ParseBreakStatement(bool* ok);
1826   Statement ParseReturnStatement(bool* ok);
1827   Statement ParseWithStatement(bool* ok);
1828   Statement ParseSwitchStatement(bool* ok);
1829   Statement ParseDoWhileStatement(bool* ok);
1830   Statement ParseWhileStatement(bool* ok);
1831   Statement ParseForStatement(bool* ok);
1832   Statement ParseThrowStatement(bool* ok);
1833   Statement ParseTryStatement(bool* ok);
1834   Statement ParseDebuggerStatement(bool* ok);
1835   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1836   Expression ParseObjectLiteral(bool* ok);
1837   Expression ParseV8Intrinsic(bool* ok);
1838
1839   V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1840                                       int* expected_property_count, bool* ok);
1841   V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1842       PreParserIdentifier function_name, int pos,
1843       const PreParserFormalParameters& parameters, FunctionKind kind,
1844       FunctionLiteral::FunctionType function_type, bool* ok);
1845
1846   Expression ParseFunctionLiteral(
1847       Identifier name, Scanner::Location function_name_location,
1848       FunctionNameValidity function_name_validity, FunctionKind kind,
1849       int function_token_pos, FunctionLiteral::FunctionType function_type,
1850       FunctionLiteral::ArityRestriction arity_restriction,
1851       LanguageMode language_mode, bool* ok);
1852   void ParseLazyFunctionLiteralBody(bool* ok,
1853                                     Scanner::BookmarkScope* bookmark = nullptr);
1854
1855   PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1856                                         Scanner::Location class_name_location,
1857                                         bool name_is_strict_reserved, int pos,
1858                                         bool* ok);
1859 };
1860
1861
1862 void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1863   pre_parser_->function_state_->NextMaterializedLiteralIndex();
1864   pre_parser_->function_state_->NextMaterializedLiteralIndex();
1865 }
1866
1867
1868 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
1869   for (int i = 0; i < count; ++i) {
1870     pre_parser_->function_state_->NextMaterializedLiteralIndex();
1871   }
1872 }
1873
1874
1875 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
1876                                                 PreParserExpressionList args,
1877                                                 int pos) {
1878   return pre_parser_->factory()->NewCall(function, args, pos);
1879 }
1880
1881 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1882                                                    PreParserExpressionList args,
1883                                                    int pos) {
1884   return pre_parser_->factory()->NewCallNew(function, args, pos);
1885 }
1886
1887
1888 void PreParserTraits::ParseArrowFunctionFormalParameterList(
1889     PreParserFormalParameters* parameters,
1890     PreParserExpression params, const Scanner::Location& params_loc,
1891     Scanner::Location* duplicate_loc, bool* ok) {
1892   // TODO(wingo): Detect duplicated identifiers in paramlists.  Detect parameter
1893   // lists that are too long.
1894
1895   // Accomodate array literal for rest parameter.
1896   if (params.IsArrowFunctionFormalParametersWithRestParameter()) {
1897     ++parameters->materialized_literals_count;
1898     pre_parser_->function_state_->NextMaterializedLiteralIndex();
1899   }
1900 }
1901
1902
1903 PreParserStatementList PreParser::ParseEagerFunctionBody(
1904     PreParserIdentifier function_name, int pos,
1905     const PreParserFormalParameters& parameters, FunctionKind kind,
1906     FunctionLiteral::FunctionType function_type, bool* ok) {
1907   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1908
1909   ParseStatementList(Token::RBRACE, ok);
1910   if (!*ok) return PreParserStatementList();
1911
1912   Expect(Token::RBRACE, ok);
1913   return PreParserStatementList();
1914 }
1915
1916
1917 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1918     PreParserIdentifier function_name, int pos,
1919     const PreParserFormalParameters& parameters, FunctionKind kind,
1920     FunctionLiteral::FunctionType function_type, bool* ok) {
1921   return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
1922                                              kind, function_type, ok);
1923 }
1924
1925
1926 template <class Traits>
1927 ParserBase<Traits>::FunctionState::FunctionState(
1928     FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1929     FunctionKind kind, typename Traits::Type::Factory* factory)
1930     : next_materialized_literal_index_(0),
1931       expected_property_count_(0),
1932       this_location_(Scanner::Location::invalid()),
1933       return_location_(Scanner::Location::invalid()),
1934       super_location_(Scanner::Location::invalid()),
1935       kind_(kind),
1936       generator_object_variable_(NULL),
1937       function_state_stack_(function_state_stack),
1938       outer_function_state_(*function_state_stack),
1939       scope_stack_(scope_stack),
1940       outer_scope_(*scope_stack),
1941       factory_(factory) {
1942   *scope_stack_ = scope;
1943   *function_state_stack = this;
1944 }
1945
1946
1947 template <class Traits>
1948 ParserBase<Traits>::FunctionState::~FunctionState() {
1949   *scope_stack_ = outer_scope_;
1950   *function_state_stack_ = outer_function_state_;
1951 }
1952
1953
1954 template <class Traits>
1955 void ParserBase<Traits>::GetUnexpectedTokenMessage(
1956     Token::Value token, MessageTemplate::Template* message, const char** arg,
1957     MessageTemplate::Template default_) {
1958   // Four of the tokens are treated specially
1959   switch (token) {
1960     case Token::EOS:
1961       *message = MessageTemplate::kUnexpectedEOS;
1962       *arg = nullptr;
1963       break;
1964     case Token::SMI:
1965     case Token::NUMBER:
1966       *message = MessageTemplate::kUnexpectedTokenNumber;
1967       *arg = nullptr;
1968       break;
1969     case Token::STRING:
1970       *message = MessageTemplate::kUnexpectedTokenString;
1971       *arg = nullptr;
1972       break;
1973     case Token::IDENTIFIER:
1974       *message = MessageTemplate::kUnexpectedTokenIdentifier;
1975       *arg = nullptr;
1976       break;
1977     case Token::FUTURE_RESERVED_WORD:
1978       *message = MessageTemplate::kUnexpectedReserved;
1979       *arg = nullptr;
1980       break;
1981     case Token::LET:
1982     case Token::STATIC:
1983     case Token::YIELD:
1984     case Token::FUTURE_STRICT_RESERVED_WORD:
1985       *message = is_strict(language_mode())
1986                      ? MessageTemplate::kUnexpectedStrictReserved
1987                      : MessageTemplate::kUnexpectedTokenIdentifier;
1988       *arg = nullptr;
1989       break;
1990     case Token::TEMPLATE_SPAN:
1991     case Token::TEMPLATE_TAIL:
1992       *message = MessageTemplate::kUnexpectedTemplateString;
1993       *arg = nullptr;
1994       break;
1995     default:
1996       const char* name = Token::String(token);
1997       DCHECK(name != NULL);
1998       *arg = name;
1999       break;
2000   }
2001 }
2002
2003
2004 template <class Traits>
2005 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
2006   return ReportUnexpectedTokenAt(scanner_->location(), token);
2007 }
2008
2009
2010 template <class Traits>
2011 void ParserBase<Traits>::ReportUnexpectedTokenAt(
2012     Scanner::Location source_location, Token::Value token,
2013     MessageTemplate::Template message) {
2014   const char* arg;
2015   GetUnexpectedTokenMessage(token, &message, &arg);
2016   Traits::ReportMessageAt(source_location, message, arg);
2017 }
2018
2019
2020 template <class Traits>
2021 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
2022     AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
2023   ExpressionClassifier classifier;
2024   auto result = ParseAndClassifyIdentifier(&classifier, ok);
2025   if (!*ok) return Traits::EmptyIdentifier();
2026
2027   if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
2028     ValidateAssignmentPattern(&classifier, ok);
2029     if (!*ok) return Traits::EmptyIdentifier();
2030     ValidateBindingPattern(&classifier, ok);
2031     if (!*ok) return Traits::EmptyIdentifier();
2032   } else {
2033     ValidateExpression(&classifier, ok);
2034     if (!*ok) return Traits::EmptyIdentifier();
2035   }
2036
2037   return result;
2038 }
2039
2040
2041 template <class Traits>
2042 typename ParserBase<Traits>::IdentifierT
2043 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
2044                                                bool* ok) {
2045   Token::Value next = Next();
2046   if (next == Token::IDENTIFIER) {
2047     IdentifierT name = this->GetSymbol(scanner());
2048     // When this function is used to read a formal parameter, we don't always
2049     // know whether the function is going to be strict or sloppy.  Indeed for
2050     // arrow functions we don't always know that the identifier we are reading
2051     // is actually a formal parameter.  Therefore besides the errors that we
2052     // must detect because we know we're in strict mode, we also record any
2053     // error that we might make in the future once we know the language mode.
2054     if (this->IsEval(name)) {
2055       classifier->RecordStrictModeFormalParameterError(
2056           scanner()->location(), MessageTemplate::kStrictEvalArguments);
2057       if (is_strict(language_mode())) {
2058         classifier->RecordBindingPatternError(
2059             scanner()->location(), MessageTemplate::kStrictEvalArguments);
2060       }
2061     }
2062     if (this->IsArguments(name)) {
2063       scope_->RecordArgumentsUsage();
2064       classifier->RecordStrictModeFormalParameterError(
2065           scanner()->location(), MessageTemplate::kStrictEvalArguments);
2066       if (is_strict(language_mode())) {
2067         classifier->RecordBindingPatternError(
2068             scanner()->location(), MessageTemplate::kStrictEvalArguments);
2069       }
2070       if (is_strong(language_mode())) {
2071         classifier->RecordExpressionError(scanner()->location(),
2072                                           MessageTemplate::kStrongArguments);
2073       }
2074     }
2075     if (this->IsUndefined(name)) {
2076       classifier->RecordStrongModeFormalParameterError(
2077           scanner()->location(), MessageTemplate::kStrongUndefined);
2078       if (is_strong(language_mode())) {
2079         // TODO(dslomov): allow 'undefined' in nested patterns.
2080         classifier->RecordBindingPatternError(
2081             scanner()->location(), MessageTemplate::kStrongUndefined);
2082         classifier->RecordAssignmentPatternError(
2083             scanner()->location(), MessageTemplate::kStrongUndefined);
2084       }
2085     }
2086
2087     if (classifier->duplicate_finder() != nullptr &&
2088         scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2089       classifier->RecordDuplicateFormalParameterError(scanner()->location());
2090     }
2091     return name;
2092   } else if (is_sloppy(language_mode()) &&
2093              (next == Token::FUTURE_STRICT_RESERVED_WORD ||
2094               next == Token::LET || next == Token::STATIC ||
2095               (next == Token::YIELD && !is_generator()))) {
2096     classifier->RecordStrictModeFormalParameterError(
2097         scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
2098     return this->GetSymbol(scanner());
2099   } else {
2100     this->ReportUnexpectedToken(next);
2101     *ok = false;
2102     return Traits::EmptyIdentifier();
2103   }
2104 }
2105
2106
2107 template <class Traits>
2108 typename ParserBase<Traits>::IdentifierT ParserBase<
2109     Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
2110                                                  bool* ok) {
2111   Token::Value next = Next();
2112   if (next == Token::IDENTIFIER) {
2113     *is_strict_reserved = false;
2114   } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
2115              next == Token::STATIC ||
2116              (next == Token::YIELD && !this->is_generator())) {
2117     *is_strict_reserved = true;
2118   } else {
2119     ReportUnexpectedToken(next);
2120     *ok = false;
2121     return Traits::EmptyIdentifier();
2122   }
2123
2124   IdentifierT name = this->GetSymbol(scanner());
2125   if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
2126   return name;
2127 }
2128
2129
2130 template <class Traits>
2131 typename ParserBase<Traits>::IdentifierT
2132 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
2133   Token::Value next = Next();
2134   if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
2135       next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
2136       next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
2137     this->ReportUnexpectedToken(next);
2138     *ok = false;
2139     return Traits::EmptyIdentifier();
2140   }
2141
2142   IdentifierT name = this->GetSymbol(scanner());
2143   if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
2144   return name;
2145 }
2146
2147
2148 template <class Traits>
2149 typename ParserBase<Traits>::IdentifierT
2150 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
2151                                                   bool* is_set,
2152                                                   bool* ok) {
2153   IdentifierT result = ParseIdentifierName(ok);
2154   if (!*ok) return Traits::EmptyIdentifier();
2155   scanner()->IsGetOrSet(is_get, is_set);
2156   return result;
2157 }
2158
2159
2160 template <class Traits>
2161 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
2162     bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
2163   int pos = peek_position();
2164   if (!scanner()->ScanRegExpPattern(seen_equal)) {
2165     Next();
2166     ReportMessage(MessageTemplate::kUnterminatedRegExp);
2167     *ok = false;
2168     return Traits::EmptyExpression();
2169   }
2170
2171   int literal_index = function_state_->NextMaterializedLiteralIndex();
2172
2173   IdentifierT js_pattern = this->GetNextSymbol(scanner());
2174   if (!scanner()->ScanRegExpFlags()) {
2175     Next();
2176     ReportMessage(MessageTemplate::kMalformedRegExpFlags);
2177     *ok = false;
2178     return Traits::EmptyExpression();
2179   }
2180   IdentifierT js_flags = this->GetNextSymbol(scanner());
2181   Next();
2182   return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index,
2183                                      is_strong(language_mode()), pos);
2184 }
2185
2186
2187 #define CHECK_OK  ok); \
2188   if (!*ok) return this->EmptyExpression(); \
2189   ((void)0
2190 #define DUMMY )  // to make indentation work
2191 #undef DUMMY
2192
2193 // Used in functions where the return type is not ExpressionT.
2194 #define CHECK_OK_CUSTOM(x) ok); \
2195   if (!*ok) return this->x(); \
2196   ((void)0
2197 #define DUMMY )  // to make indentation work
2198 #undef DUMMY
2199
2200
2201 template <class Traits>
2202 typename ParserBase<Traits>::ExpressionT
2203 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
2204                                            bool* ok) {
2205   // PrimaryExpression ::
2206   //   'this'
2207   //   'null'
2208   //   'true'
2209   //   'false'
2210   //   Identifier
2211   //   Number
2212   //   String
2213   //   ArrayLiteral
2214   //   ObjectLiteral
2215   //   RegExpLiteral
2216   //   ClassLiteral
2217   //   '(' Expression ')'
2218   //   TemplateLiteral
2219
2220   int beg_pos = scanner()->peek_location().beg_pos;
2221   int end_pos = scanner()->peek_location().end_pos;
2222   ExpressionT result = this->EmptyExpression();
2223   Token::Value token = peek();
2224   switch (token) {
2225     case Token::THIS: {
2226       BindingPatternUnexpectedToken(classifier);
2227       Consume(Token::THIS);
2228       if (FLAG_strong_this && is_strong(language_mode())) {
2229         // Constructors' usages of 'this' in strong mode are parsed separately.
2230         // TODO(rossberg): this does not work with arrow functions yet.
2231         if (IsClassConstructor(function_state_->kind())) {
2232           ReportMessage(MessageTemplate::kStrongConstructorThis);
2233           *ok = false;
2234           break;
2235         }
2236       }
2237       result = this->ThisExpression(scope_, factory(), beg_pos);
2238       break;
2239     }
2240
2241     case Token::NULL_LITERAL:
2242     case Token::TRUE_LITERAL:
2243     case Token::FALSE_LITERAL:
2244       BindingPatternUnexpectedToken(classifier);
2245       Next();
2246       result =
2247           this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2248       break;
2249     case Token::SMI:
2250     case Token::NUMBER:
2251       classifier->RecordBindingPatternError(
2252           scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
2253       Next();
2254       result =
2255           this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2256       break;
2257
2258     case Token::IDENTIFIER:
2259     case Token::LET:
2260     case Token::STATIC:
2261     case Token::YIELD:
2262     case Token::FUTURE_STRICT_RESERVED_WORD: {
2263       // Using eval or arguments in this context is OK even in strict mode.
2264       IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
2265       result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
2266                                               factory());
2267       break;
2268     }
2269
2270     case Token::STRING: {
2271       classifier->RecordBindingPatternError(
2272           scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString);
2273       Consume(Token::STRING);
2274       result = this->ExpressionFromString(beg_pos, scanner(), factory());
2275       break;
2276     }
2277
2278     case Token::ASSIGN_DIV:
2279       classifier->RecordBindingPatternError(
2280           scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
2281       result = this->ParseRegExpLiteral(true, classifier, CHECK_OK);
2282       break;
2283
2284     case Token::DIV:
2285       classifier->RecordBindingPatternError(
2286           scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
2287       result = this->ParseRegExpLiteral(false, classifier, CHECK_OK);
2288       break;
2289
2290     case Token::LBRACK:
2291       if (!allow_harmony_destructuring()) {
2292         BindingPatternUnexpectedToken(classifier);
2293       }
2294       result = this->ParseArrayLiteral(classifier, CHECK_OK);
2295       break;
2296
2297     case Token::LBRACE:
2298       if (!allow_harmony_destructuring()) {
2299         BindingPatternUnexpectedToken(classifier);
2300       }
2301       result = this->ParseObjectLiteral(classifier, CHECK_OK);
2302       break;
2303
2304     case Token::LPAREN:
2305       // Arrow function formal parameters are either a single identifier or a
2306       // list of BindingPattern productions enclosed in parentheses.
2307       // Parentheses are not valid on the LHS of a BindingPattern, so we use the
2308       // is_valid_binding_pattern() check to detect multiple levels of
2309       // parenthesization.
2310       if (!classifier->is_valid_binding_pattern()) {
2311         ArrowFormalParametersUnexpectedToken(classifier);
2312       }
2313       BindingPatternUnexpectedToken(classifier);
2314       Consume(Token::LPAREN);
2315       if (Check(Token::RPAREN)) {
2316         // ()=>x.  The continuation that looks for the => is in
2317         // ParseAssignmentExpression.
2318         classifier->RecordExpressionError(scanner()->location(),
2319                                           MessageTemplate::kUnexpectedToken,
2320                                           Token::String(Token::RPAREN));
2321         classifier->RecordBindingPatternError(scanner()->location(),
2322                                               MessageTemplate::kUnexpectedToken,
2323                                               Token::String(Token::RPAREN));
2324         result = factory()->NewEmptyParentheses(beg_pos);
2325       } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
2326         // (...x)=>x.  The continuation that looks for the => is in
2327         // ParseAssignmentExpression.
2328         int ellipsis_pos = scanner()->location().beg_pos;
2329         classifier->RecordExpressionError(scanner()->location(),
2330                                           MessageTemplate::kUnexpectedToken,
2331                                           Token::String(Token::ELLIPSIS));
2332         classifier->RecordNonSimpleParameter();
2333         Scanner::Location expr_loc = scanner()->peek_location();
2334         Token::Value tok = peek();
2335         result = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2336         // Patterns are not allowed as rest parameters.  There is no way we can
2337         // succeed so go ahead and use the convenient ReportUnexpectedToken
2338         // interface.
2339         if (!Traits::IsIdentifier(result)) {
2340           ReportUnexpectedTokenAt(expr_loc, tok);
2341           *ok = false;
2342           return this->EmptyExpression();
2343         }
2344         result = factory()->NewSpread(result, ellipsis_pos);
2345
2346         if (peek() == Token::COMMA) {
2347           ReportMessageAt(scanner()->peek_location(),
2348                           MessageTemplate::kParamAfterRest);
2349           *ok = false;
2350           return this->EmptyExpression();
2351         }
2352         Expect(Token::RPAREN, CHECK_OK);
2353       } else {
2354         // Heuristically try to detect immediately called functions before
2355         // seeing the call parentheses.
2356         parenthesized_function_ = (peek() == Token::FUNCTION);
2357         result = this->ParseExpression(true, classifier, CHECK_OK);
2358         Expect(Token::RPAREN, CHECK_OK);
2359       }
2360       break;
2361
2362     case Token::CLASS: {
2363       BindingPatternUnexpectedToken(classifier);
2364       Consume(Token::CLASS);
2365       if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2366         ReportMessage(MessageTemplate::kSloppyLexical);
2367         *ok = false;
2368         break;
2369       }
2370       int class_token_position = position();
2371       IdentifierT name = this->EmptyIdentifier();
2372       bool is_strict_reserved_name = false;
2373       Scanner::Location class_name_location = Scanner::Location::invalid();
2374       if (peek_any_identifier()) {
2375         name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2376                                                    CHECK_OK);
2377         class_name_location = scanner()->location();
2378       }
2379       result = this->ParseClassLiteral(name, class_name_location,
2380                                        is_strict_reserved_name,
2381                                        class_token_position, CHECK_OK);
2382       break;
2383     }
2384
2385     case Token::TEMPLATE_SPAN:
2386     case Token::TEMPLATE_TAIL:
2387       classifier->RecordBindingPatternError(
2388           scanner()->peek_location(),
2389           MessageTemplate::kUnexpectedTemplateString);
2390       result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
2391                                           classifier, CHECK_OK);
2392       break;
2393
2394     case Token::MOD:
2395       if (allow_natives() || extension_ != NULL) {
2396         result = this->ParseV8Intrinsic(CHECK_OK);
2397         break;
2398       }
2399       // If we're not allowing special syntax we fall-through to the
2400       // default case.
2401
2402     default: {
2403       Next();
2404       ReportUnexpectedToken(token);
2405       *ok = false;
2406     }
2407   }
2408
2409   return result;
2410 }
2411
2412
2413 template <class Traits>
2414 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2415     bool accept_IN, bool* ok) {
2416   ExpressionClassifier classifier;
2417   ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
2418   ValidateExpression(&classifier, CHECK_OK);
2419   return result;
2420 }
2421
2422
2423 // Precedence = 1
2424 template <class Traits>
2425 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2426     bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2427   // Expression ::
2428   //   AssignmentExpression
2429   //   Expression ',' AssignmentExpression
2430
2431   ExpressionClassifier binding_classifier;
2432   ExpressionT result =
2433       this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
2434   classifier->Accumulate(binding_classifier,
2435                          ExpressionClassifier::AllProductions);
2436   bool is_simple_parameter_list = this->IsIdentifier(result);
2437   bool seen_rest = false;
2438   while (peek() == Token::COMMA) {
2439     if (seen_rest) {
2440       // At this point the production can't possibly be valid, but we don't know
2441       // which error to signal.
2442       classifier->RecordArrowFormalParametersError(
2443           scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2444     }
2445     Consume(Token::COMMA);
2446     bool is_rest = false;
2447     if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) {
2448       // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2449       // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2450       // valid expression or binding pattern.
2451       ExpressionUnexpectedToken(classifier);
2452       BindingPatternUnexpectedToken(classifier);
2453       Consume(Token::ELLIPSIS);
2454       seen_rest = is_rest = true;
2455     }
2456     int pos = position();
2457     ExpressionT right = this->ParseAssignmentExpression(
2458         accept_IN, &binding_classifier, CHECK_OK);
2459     if (is_rest) right = factory()->NewSpread(right, pos);
2460     is_simple_parameter_list =
2461         is_simple_parameter_list && this->IsIdentifier(right);
2462     classifier->Accumulate(binding_classifier,
2463                            ExpressionClassifier::AllProductions);
2464     result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2465   }
2466   if (!is_simple_parameter_list || seen_rest) {
2467     classifier->RecordNonSimpleParameter();
2468   }
2469   return result;
2470 }
2471
2472
2473 template <class Traits>
2474 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2475     ExpressionClassifier* classifier, bool* ok) {
2476   // ArrayLiteral ::
2477   //   '[' Expression? (',' Expression?)* ']'
2478
2479   int pos = peek_position();
2480   typename Traits::Type::ExpressionList values =
2481       this->NewExpressionList(4, zone_);
2482   int first_spread_index = -1;
2483   Expect(Token::LBRACK, CHECK_OK);
2484   while (peek() != Token::RBRACK) {
2485     bool seen_spread = false;
2486     ExpressionT elem = this->EmptyExpression();
2487     if (peek() == Token::COMMA) {
2488       if (is_strong(language_mode())) {
2489         ReportMessageAt(scanner()->peek_location(),
2490                         MessageTemplate::kStrongEllision);
2491         *ok = false;
2492         return this->EmptyExpression();
2493       }
2494       elem = this->GetLiteralTheHole(peek_position(), factory());
2495     } else if (peek() == Token::ELLIPSIS) {
2496       if (!allow_harmony_spread_arrays()) {
2497         ExpressionUnexpectedToken(classifier);
2498       }
2499       int start_pos = peek_position();
2500       Consume(Token::ELLIPSIS);
2501       ExpressionT argument =
2502           this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2503       elem = factory()->NewSpread(argument, start_pos);
2504       seen_spread = true;
2505       if (first_spread_index < 0) {
2506         first_spread_index = values->length();
2507       }
2508     } else {
2509       elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2510     }
2511     values->Add(elem, zone_);
2512     if (peek() != Token::RBRACK) {
2513       if (seen_spread) {
2514         BindingPatternUnexpectedToken(classifier);
2515       }
2516       Expect(Token::COMMA, CHECK_OK);
2517     }
2518   }
2519   Expect(Token::RBRACK, CHECK_OK);
2520
2521   // Update the scope information before the pre-parsing bailout.
2522   int literal_index = function_state_->NextMaterializedLiteralIndex();
2523
2524   return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
2525                                     is_strong(language_mode()), pos);
2526 }
2527
2528
2529 template <class Traits>
2530 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2531     IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2532     bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
2533   Token::Value token = peek();
2534   int pos = peek_position();
2535
2536   // For non computed property names we normalize the name a bit:
2537   //
2538   //   "12" -> 12
2539   //   12.3 -> "12.3"
2540   //   12.30 -> "12.3"
2541   //   identifier -> "identifier"
2542   //
2543   // This is important because we use the property name as a key in a hash
2544   // table when we compute constant properties.
2545   switch (token) {
2546     case Token::STRING:
2547       Consume(Token::STRING);
2548       *name = this->GetSymbol(scanner());
2549       break;
2550
2551     case Token::SMI:
2552       Consume(Token::SMI);
2553       *name = this->GetNumberAsSymbol(scanner());
2554       break;
2555
2556     case Token::NUMBER:
2557       Consume(Token::NUMBER);
2558       *name = this->GetNumberAsSymbol(scanner());
2559       break;
2560
2561     case Token::LBRACK: {
2562       *is_computed_name = true;
2563       Consume(Token::LBRACK);
2564       ExpressionClassifier computed_name_classifier;
2565       ExpressionT expression =
2566           ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
2567       classifier->Accumulate(computed_name_classifier,
2568                              ExpressionClassifier::ExpressionProductions);
2569       Expect(Token::RBRACK, CHECK_OK);
2570       return expression;
2571     }
2572
2573     case Token::STATIC:
2574       *is_static = true;
2575
2576     // Fall through.
2577     default:
2578       *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2579       break;
2580   }
2581
2582   uint32_t index;
2583   return this->IsArrayIndex(*name, &index)
2584              ? factory()->NewNumberLiteral(index, pos)
2585              : factory()->NewStringLiteral(*name, pos);
2586 }
2587
2588
2589 template <class Traits>
2590 typename ParserBase<Traits>::ObjectLiteralPropertyT
2591 ParserBase<Traits>::ParsePropertyDefinition(
2592     ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2593     bool is_static, bool* is_computed_name, bool* has_seen_constructor,
2594     ExpressionClassifier* classifier, bool* ok) {
2595   DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2596   ExpressionT value = this->EmptyExpression();
2597   IdentifierT name = this->EmptyIdentifier();
2598   bool is_get = false;
2599   bool is_set = false;
2600   bool name_is_static = false;
2601   bool is_generator = Check(Token::MUL);
2602
2603   Token::Value name_token = peek();
2604   int next_beg_pos = scanner()->peek_location().beg_pos;
2605   int next_end_pos = scanner()->peek_location().end_pos;
2606   ExpressionT name_expression = ParsePropertyName(
2607       &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier,
2608       CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2609
2610   if (fni_ != nullptr && !*is_computed_name) {
2611     this->PushLiteralName(fni_, name);
2612   }
2613
2614   if (!in_class && !is_generator) {
2615     DCHECK(!is_static);
2616
2617     if (peek() == Token::COLON) {
2618       // PropertyDefinition
2619       //    PropertyName ':' AssignmentExpression
2620       if (!*is_computed_name) {
2621         checker->CheckProperty(name_token, kValueProperty, false, false,
2622                                CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2623       }
2624       Consume(Token::COLON);
2625       value = this->ParseAssignmentExpression(
2626           true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2627       return factory()->NewObjectLiteralProperty(name_expression, value, false,
2628                                                  *is_computed_name);
2629     }
2630
2631     if (Token::IsIdentifier(name_token, language_mode(),
2632                             this->is_generator()) &&
2633         (peek() == Token::COMMA || peek() == Token::RBRACE ||
2634          peek() == Token::ASSIGN)) {
2635       // PropertyDefinition
2636       //    IdentifierReference
2637       //    CoverInitializedName
2638       //
2639       // CoverInitializedName
2640       //    IdentifierReference Initializer?
2641       if (classifier->duplicate_finder() != nullptr &&
2642           scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2643         classifier->RecordDuplicateFormalParameterError(scanner()->location());
2644       }
2645
2646       ExpressionT lhs = this->ExpressionFromIdentifier(
2647           name, next_beg_pos, next_end_pos, scope_, factory());
2648
2649       if (peek() == Token::ASSIGN) {
2650         this->ExpressionUnexpectedToken(classifier);
2651         Consume(Token::ASSIGN);
2652         ExpressionClassifier rhs_classifier;
2653         ExpressionT rhs = this->ParseAssignmentExpression(
2654             true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2655         classifier->Accumulate(rhs_classifier,
2656                                ExpressionClassifier::ExpressionProductions);
2657         value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2658                                          RelocInfo::kNoPosition);
2659       } else {
2660         value = lhs;
2661       }
2662
2663       return factory()->NewObjectLiteralProperty(
2664           name_expression, value, ObjectLiteralProperty::COMPUTED, false,
2665           false);
2666     }
2667   }
2668
2669
2670   if (is_generator || peek() == Token::LPAREN) {
2671     // MethodDefinition
2672     //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2673     //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2674     if (!*is_computed_name) {
2675       checker->CheckProperty(name_token, kMethodProperty, is_static,
2676                              is_generator,
2677                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2678     }
2679
2680     FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2681                                      : FunctionKind::kConciseMethod;
2682
2683     if (in_class && !is_static && this->IsConstructor(name)) {
2684       *has_seen_constructor = true;
2685       kind = has_extends ? FunctionKind::kSubclassConstructor
2686                          : FunctionKind::kBaseConstructor;
2687     }
2688
2689     if (!in_class) kind = WithObjectLiteralBit(kind);
2690
2691     value = this->ParseFunctionLiteral(
2692         name, scanner()->location(), kSkipFunctionNameCheck, kind,
2693         RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2694         FunctionLiteral::NORMAL_ARITY, language_mode(),
2695         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2696
2697     return factory()->NewObjectLiteralProperty(name_expression, value,
2698                                                ObjectLiteralProperty::COMPUTED,
2699                                                is_static, *is_computed_name);
2700   }
2701
2702   if (in_class && name_is_static && !is_static) {
2703     // ClassElement (static)
2704     //    'static' MethodDefinition
2705     return ParsePropertyDefinition(checker, true, has_extends, true,
2706                                    is_computed_name, nullptr, classifier, ok);
2707   }
2708
2709   if (is_get || is_set) {
2710     // MethodDefinition (Accessors)
2711     //    get PropertyName '(' ')' '{' FunctionBody '}'
2712     //    set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2713     name = this->EmptyIdentifier();
2714     bool dont_care = false;
2715     name_token = peek();
2716
2717     name_expression = ParsePropertyName(
2718         &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2719         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2720
2721     if (!*is_computed_name) {
2722       checker->CheckProperty(name_token, kAccessorProperty, is_static,
2723                              is_generator,
2724                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2725     }
2726
2727     FunctionKind kind = FunctionKind::kAccessorFunction;
2728     if (!in_class) kind = WithObjectLiteralBit(kind);
2729     typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2730         name, scanner()->location(), kSkipFunctionNameCheck, kind,
2731         RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2732         is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2733         language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2734
2735     // Make sure the name expression is a string since we need a Name for
2736     // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2737     // statically we can skip the extra runtime check.
2738     if (!*is_computed_name) {
2739       name_expression =
2740           factory()->NewStringLiteral(name, name_expression->position());
2741     }
2742
2743     return factory()->NewObjectLiteralProperty(
2744         name_expression, value,
2745         is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2746         is_static, *is_computed_name);
2747   }
2748
2749   Token::Value next = Next();
2750   ReportUnexpectedToken(next);
2751   *ok = false;
2752   return this->EmptyObjectLiteralProperty();
2753 }
2754
2755
2756 template <class Traits>
2757 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2758     ExpressionClassifier* classifier, bool* ok) {
2759   // ObjectLiteral ::
2760   // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2761
2762   int pos = peek_position();
2763   typename Traits::Type::PropertyList properties =
2764       this->NewPropertyList(4, zone_);
2765   int number_of_boilerplate_properties = 0;
2766   bool has_function = false;
2767   bool has_computed_names = false;
2768   ObjectLiteralChecker checker(this);
2769
2770   Expect(Token::LBRACE, CHECK_OK);
2771
2772   while (peek() != Token::RBRACE) {
2773     if (fni_ != nullptr) fni_->Enter();
2774
2775     const bool in_class = false;
2776     const bool is_static = false;
2777     const bool has_extends = false;
2778     bool is_computed_name = false;
2779     ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2780         &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
2781         classifier, CHECK_OK);
2782
2783     if (is_computed_name) {
2784       has_computed_names = true;
2785     }
2786
2787     // Mark top-level object literals that contain function literals and
2788     // pretenure the literal so it can be added as a constant function
2789     // property. (Parser only.)
2790     this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2791                                                           &has_function);
2792
2793     // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2794     if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2795       number_of_boilerplate_properties++;
2796     }
2797     properties->Add(property, zone());
2798
2799     if (peek() != Token::RBRACE) {
2800       // Need {} because of the CHECK_OK macro.
2801       Expect(Token::COMMA, CHECK_OK);
2802     }
2803
2804     if (fni_ != nullptr) {
2805       fni_->Infer();
2806       fni_->Leave();
2807     }
2808   }
2809   Expect(Token::RBRACE, CHECK_OK);
2810
2811   // Computation of literal_index must happen before pre parse bailout.
2812   int literal_index = function_state_->NextMaterializedLiteralIndex();
2813
2814   return factory()->NewObjectLiteral(properties,
2815                                      literal_index,
2816                                      number_of_boilerplate_properties,
2817                                      has_function,
2818                                      is_strong(language_mode()),
2819                                      pos);
2820 }
2821
2822
2823 template <class Traits>
2824 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
2825     Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier,
2826     bool* ok) {
2827   // Arguments ::
2828   //   '(' (AssignmentExpression)*[','] ')'
2829
2830   Scanner::Location spread_arg = Scanner::Location::invalid();
2831   typename Traits::Type::ExpressionList result =
2832       this->NewExpressionList(4, zone_);
2833   Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2834   bool done = (peek() == Token::RPAREN);
2835   bool was_unspread = false;
2836   int unspread_sequences_count = 0;
2837   while (!done) {
2838     bool is_spread =
2839         allow_harmony_spread_calls() && (peek() == Token::ELLIPSIS);
2840     int start_pos = peek_position();
2841     if (is_spread) Consume(Token::ELLIPSIS);
2842
2843     ExpressionT argument = this->ParseAssignmentExpression(
2844         true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
2845     if (is_spread) {
2846       if (!spread_arg.IsValid()) {
2847         spread_arg.beg_pos = start_pos;
2848         spread_arg.end_pos = peek_position();
2849       }
2850       argument = factory()->NewSpread(argument, start_pos);
2851     }
2852     result->Add(argument, zone_);
2853
2854     // unspread_sequences_count is the number of sequences of parameters which
2855     // are not prefixed with a spread '...' operator.
2856     if (is_spread) {
2857       was_unspread = false;
2858     } else if (!was_unspread) {
2859       was_unspread = true;
2860       unspread_sequences_count++;
2861     }
2862
2863     if (result->length() > Code::kMaxArguments) {
2864       ReportMessage(MessageTemplate::kTooManyArguments);
2865       *ok = false;
2866       return this->NullExpressionList();
2867     }
2868     done = (peek() != Token::COMMA);
2869     if (!done) {
2870       Next();
2871     }
2872   }
2873   Scanner::Location location = scanner_->location();
2874   if (Token::RPAREN != Next()) {
2875     ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2876     *ok = false;
2877     return this->NullExpressionList();
2878   }
2879   *first_spread_arg_loc = spread_arg;
2880
2881   if (spread_arg.IsValid()) {
2882     // Unspread parameter sequences are translated into array literals in the
2883     // parser. Ensure that the number of materialized literals matches between
2884     // the parser and preparser
2885     Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2886   }
2887
2888   return result;
2889 }
2890
2891 // Precedence = 2
2892 template <class Traits>
2893 typename ParserBase<Traits>::ExpressionT
2894 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
2895                                               ExpressionClassifier* classifier,
2896                                               bool* ok) {
2897   // AssignmentExpression ::
2898   //   ConditionalExpression
2899   //   ArrowFunction
2900   //   YieldExpression
2901   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
2902
2903   int lhs_beg_pos = peek_position();
2904
2905   if (peek() == Token::YIELD && is_generator()) {
2906     return this->ParseYieldExpression(classifier, ok);
2907   }
2908
2909   if (fni_ != NULL) fni_->Enter();
2910   ParserBase<Traits>::Checkpoint checkpoint(this);
2911   ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
2912   bool parenthesized_formals = peek() == Token::LPAREN;
2913   if (!parenthesized_formals) {
2914     ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2915   }
2916   ExpressionT expression = this->ParseConditionalExpression(
2917       accept_IN, &arrow_formals_classifier, CHECK_OK);
2918   if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2919     BindingPatternUnexpectedToken(classifier);
2920     ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2921                                   parenthesized_formals, CHECK_OK);
2922     Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2923     Scope* scope =
2924         this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2925     FormalParametersT parameters(scope);
2926     if (!arrow_formals_classifier.is_simple_parameter_list()) {
2927       scope->SetHasNonSimpleParameters();
2928       parameters.is_simple = false;
2929     }
2930
2931     Scanner::Location duplicate_loc = Scanner::Location::invalid();
2932     this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2933                                                 &duplicate_loc, CHECK_OK);
2934
2935     checkpoint.Restore(&parameters.materialized_literals_count);
2936
2937     scope->set_start_position(lhs_beg_pos);
2938     if (duplicate_loc.IsValid()) {
2939       arrow_formals_classifier.RecordDuplicateFormalParameterError(
2940           duplicate_loc);
2941     }
2942     expression = this->ParseArrowFunctionLiteral(
2943         parameters, arrow_formals_classifier, CHECK_OK);
2944     return expression;
2945   }
2946
2947   // "expression" was not itself an arrow function parameter list, but it might
2948   // form part of one.  Propagate speculative formal parameter error locations.
2949   classifier->Accumulate(arrow_formals_classifier,
2950                          ExpressionClassifier::StandardProductions |
2951                              ExpressionClassifier::FormalParametersProductions);
2952
2953   if (!Token::IsAssignmentOp(peek())) {
2954     if (fni_ != NULL) fni_->Leave();
2955     // Parsed conditional expression only (no assignment).
2956     return expression;
2957   }
2958
2959   if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) {
2960     BindingPatternUnexpectedToken(classifier);
2961   }
2962
2963   expression = this->CheckAndRewriteReferenceExpression(
2964       expression, lhs_beg_pos, scanner()->location().end_pos,
2965       MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2966   expression = this->MarkExpressionAsAssigned(expression);
2967
2968   Token::Value op = Next();  // Get assignment operator.
2969   if (op != Token::ASSIGN) {
2970     classifier->RecordBindingPatternError(scanner()->location(),
2971                                           MessageTemplate::kUnexpectedToken,
2972                                           Token::String(op));
2973   }
2974   int pos = position();
2975
2976   ExpressionClassifier rhs_classifier;
2977   ExpressionT right =
2978       this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
2979   classifier->Accumulate(rhs_classifier,
2980                          ExpressionClassifier::ExpressionProductions);
2981
2982   // TODO(1231235): We try to estimate the set of properties set by
2983   // constructors. We define a new property whenever there is an
2984   // assignment to a property of 'this'. We should probably only add
2985   // properties if we haven't seen them before. Otherwise we'll
2986   // probably overestimate the number of properties.
2987   if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2988     function_state_->AddProperty();
2989   }
2990
2991   this->CheckAssigningFunctionLiteralToProperty(expression, right);
2992
2993   if (fni_ != NULL) {
2994     // Check if the right hand side is a call to avoid inferring a
2995     // name if we're dealing with "a = function(){...}();"-like
2996     // expression.
2997     if ((op == Token::INIT_VAR
2998          || op == Token::INIT_CONST_LEGACY
2999          || op == Token::ASSIGN)
3000         && (!right->IsCall() && !right->IsCallNew())) {
3001       fni_->Infer();
3002     } else {
3003       fni_->RemoveLastFunction();
3004     }
3005     fni_->Leave();
3006   }
3007
3008   return factory()->NewAssignment(op, expression, right, pos);
3009 }
3010
3011 template <class Traits>
3012 typename ParserBase<Traits>::ExpressionT
3013 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
3014                                          bool* ok) {
3015   // YieldExpression ::
3016   //   'yield' ([no line terminator] '*'? AssignmentExpression)?
3017   int pos = peek_position();
3018   BindingPatternUnexpectedToken(classifier);
3019   FormalParameterInitializerUnexpectedToken(classifier);
3020   Expect(Token::YIELD, CHECK_OK);
3021   ExpressionT generator_object =
3022       factory()->NewVariableProxy(function_state_->generator_object_variable());
3023   ExpressionT expression = Traits::EmptyExpression();
3024   Yield::Kind kind = Yield::kSuspend;
3025   if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
3026     if (Check(Token::MUL)) kind = Yield::kDelegating;
3027     switch (peek()) {
3028       case Token::EOS:
3029       case Token::SEMICOLON:
3030       case Token::RBRACE:
3031       case Token::RBRACK:
3032       case Token::RPAREN:
3033       case Token::COLON:
3034       case Token::COMMA:
3035         // The above set of tokens is the complete set of tokens that can appear
3036         // after an AssignmentExpression, and none of them can start an
3037         // AssignmentExpression.  This allows us to avoid looking for an RHS for
3038         // a Yield::kSuspend operation, given only one look-ahead token.
3039         if (kind == Yield::kSuspend)
3040           break;
3041         DCHECK_EQ(Yield::kDelegating, kind);
3042         // Delegating yields require an RHS; fall through.
3043       default:
3044         expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
3045         break;
3046     }
3047   }
3048   if (kind == Yield::kDelegating) {
3049     // var iterator = subject[Symbol.iterator]();
3050     expression = this->GetIterator(expression, factory());
3051   }
3052   typename Traits::Type::YieldExpression yield =
3053       factory()->NewYield(generator_object, expression, kind, pos);
3054   return yield;
3055 }
3056
3057
3058 // Precedence = 3
3059 template <class Traits>
3060 typename ParserBase<Traits>::ExpressionT
3061 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
3062                                                ExpressionClassifier* classifier,
3063                                                bool* ok) {
3064   // ConditionalExpression ::
3065   //   LogicalOrExpression
3066   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3067
3068   int pos = peek_position();
3069   // We start using the binary expression parser for prec >= 4 only!
3070   ExpressionT expression =
3071       this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
3072   if (peek() != Token::CONDITIONAL) return expression;
3073   ArrowFormalParametersUnexpectedToken(classifier);
3074   BindingPatternUnexpectedToken(classifier);
3075   Consume(Token::CONDITIONAL);
3076   // In parsing the first assignment expression in conditional
3077   // expressions we always accept the 'in' keyword; see ECMA-262,
3078   // section 11.12, page 58.
3079   ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
3080   Expect(Token::COLON, CHECK_OK);
3081   ExpressionT right =
3082       ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
3083   return factory()->NewConditional(expression, left, right, pos);
3084 }
3085
3086
3087 // Precedence >= 4
3088 template <class Traits>
3089 typename ParserBase<Traits>::ExpressionT
3090 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
3091                                           ExpressionClassifier* classifier,
3092                                           bool* ok) {
3093   DCHECK(prec >= 4);
3094   ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
3095   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3096     // prec1 >= 4
3097     while (Precedence(peek(), accept_IN) == prec1) {
3098       BindingPatternUnexpectedToken(classifier);
3099       ArrowFormalParametersUnexpectedToken(classifier);
3100       Token::Value op = Next();
3101       Scanner::Location op_location = scanner()->location();
3102       int pos = position();
3103       ExpressionT y =
3104           ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
3105
3106       if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
3107                                                        factory())) {
3108         continue;
3109       }
3110
3111       // For now we distinguish between comparisons and other binary
3112       // operations.  (We could combine the two and get rid of this
3113       // code and AST node eventually.)
3114       if (Token::IsCompareOp(op)) {
3115         // We have a comparison.
3116         Token::Value cmp = op;
3117         switch (op) {
3118           case Token::NE: cmp = Token::EQ; break;
3119           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
3120           default: break;
3121         }
3122         if (cmp == Token::EQ && is_strong(language_mode())) {
3123           ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
3124           *ok = false;
3125           return this->EmptyExpression();
3126         }
3127         x = factory()->NewCompareOperation(cmp, x, y, pos);
3128         if (cmp != op) {
3129           // The comparison was negated - add a NOT.
3130           x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3131         }
3132
3133       } else {
3134         // We have a "normal" binary operation.
3135         x = factory()->NewBinaryOperation(op, x, y, pos);
3136       }
3137     }
3138   }
3139   return x;
3140 }
3141
3142
3143 template <class Traits>
3144 typename ParserBase<Traits>::ExpressionT
3145 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
3146                                          bool* ok) {
3147   // UnaryExpression ::
3148   //   PostfixExpression
3149   //   'delete' UnaryExpression
3150   //   'void' UnaryExpression
3151   //   'typeof' UnaryExpression
3152   //   '++' UnaryExpression
3153   //   '--' UnaryExpression
3154   //   '+' UnaryExpression
3155   //   '-' UnaryExpression
3156   //   '~' UnaryExpression
3157   //   '!' UnaryExpression
3158
3159   Token::Value op = peek();
3160   if (Token::IsUnaryOp(op)) {
3161     BindingPatternUnexpectedToken(classifier);
3162     ArrowFormalParametersUnexpectedToken(classifier);
3163
3164     op = Next();
3165     int pos = position();
3166     ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
3167
3168     if (op == Token::DELETE && is_strict(language_mode())) {
3169       if (is_strong(language_mode())) {
3170         ReportMessage(MessageTemplate::kStrongDelete);
3171         *ok = false;
3172         return this->EmptyExpression();
3173       } else if (this->IsIdentifier(expression)) {
3174         // "delete identifier" is a syntax error in strict mode.
3175         ReportMessage(MessageTemplate::kStrictDelete);
3176         *ok = false;
3177         return this->EmptyExpression();
3178       }
3179     }
3180
3181     // Allow Traits do rewrite the expression.
3182     return this->BuildUnaryExpression(expression, op, pos, factory());
3183   } else if (Token::IsCountOp(op)) {
3184     BindingPatternUnexpectedToken(classifier);
3185     ArrowFormalParametersUnexpectedToken(classifier);
3186     op = Next();
3187     int beg_pos = peek_position();
3188     ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
3189     expression = this->CheckAndRewriteReferenceExpression(
3190         expression, beg_pos, scanner()->location().end_pos,
3191         MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
3192     this->MarkExpressionAsAssigned(expression);
3193
3194     return factory()->NewCountOperation(op,
3195                                         true /* prefix */,
3196                                         expression,
3197                                         position());
3198
3199   } else {
3200     return this->ParsePostfixExpression(classifier, ok);
3201   }
3202 }
3203
3204
3205 template <class Traits>
3206 typename ParserBase<Traits>::ExpressionT
3207 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
3208                                            bool* ok) {
3209   // PostfixExpression ::
3210   //   LeftHandSideExpression ('++' | '--')?
3211
3212   int lhs_beg_pos = peek_position();
3213   ExpressionT expression =
3214       this->ParseLeftHandSideExpression(classifier, CHECK_OK);
3215   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
3216       Token::IsCountOp(peek())) {
3217     BindingPatternUnexpectedToken(classifier);
3218     ArrowFormalParametersUnexpectedToken(classifier);
3219
3220     expression = this->CheckAndRewriteReferenceExpression(
3221         expression, lhs_beg_pos, scanner()->location().end_pos,
3222         MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
3223     expression = this->MarkExpressionAsAssigned(expression);
3224
3225     Token::Value next = Next();
3226     expression =
3227         factory()->NewCountOperation(next,
3228                                      false /* postfix */,
3229                                      expression,
3230                                      position());
3231   }
3232   return expression;
3233 }
3234
3235
3236 template <class Traits>
3237 typename ParserBase<Traits>::ExpressionT
3238 ParserBase<Traits>::ParseLeftHandSideExpression(
3239     ExpressionClassifier* classifier, bool* ok) {
3240   // LeftHandSideExpression ::
3241   //   (NewExpression | MemberExpression) ...
3242
3243   ExpressionT result =
3244       this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3245
3246   while (true) {
3247     switch (peek()) {
3248       case Token::LBRACK: {
3249         BindingPatternUnexpectedToken(classifier);
3250         ArrowFormalParametersUnexpectedToken(classifier);
3251         Consume(Token::LBRACK);
3252         int pos = position();
3253         ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
3254         result = factory()->NewProperty(result, index, pos);
3255         Expect(Token::RBRACK, CHECK_OK);
3256         break;
3257       }
3258
3259       case Token::LPAREN: {
3260         BindingPatternUnexpectedToken(classifier);
3261         ArrowFormalParametersUnexpectedToken(classifier);
3262
3263         if (is_strong(language_mode()) && this->IsIdentifier(result) &&
3264             this->IsEval(this->AsIdentifier(result))) {
3265           ReportMessage(MessageTemplate::kStrongDirectEval);
3266           *ok = false;
3267           return this->EmptyExpression();
3268         }
3269         int pos;
3270         if (scanner()->current_token() == Token::IDENTIFIER) {
3271           // For call of an identifier we want to report position of
3272           // the identifier as position of the call in the stack trace.
3273           pos = position();
3274         } else {
3275           // For other kinds of calls we record position of the parenthesis as
3276           // position of the call. Note that this is extremely important for
3277           // expressions of the form function(){...}() for which call position
3278           // should not point to the closing brace otherwise it will intersect
3279           // with positions recorded for function literal and confuse debugger.
3280           pos = peek_position();
3281           // Also the trailing parenthesis are a hint that the function will
3282           // be called immediately. If we happen to have parsed a preceding
3283           // function literal eagerly, we can also compile it eagerly.
3284           if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3285             result->AsFunctionLiteral()->set_should_eager_compile();
3286           }
3287         }
3288         Scanner::Location spread_pos;
3289         typename Traits::Type::ExpressionList args =
3290             ParseArguments(&spread_pos, classifier, CHECK_OK);
3291
3292         // Keep track of eval() calls since they disable all local variable
3293         // optimizations.
3294         // The calls that need special treatment are the
3295         // direct eval calls. These calls are all of the form eval(...), with
3296         // no explicit receiver.
3297         // These calls are marked as potentially direct eval calls. Whether
3298         // they are actually direct calls to eval is determined at run time.
3299         this->CheckPossibleEvalCall(result, scope_);
3300
3301         bool is_super_call = result->IsSuperCallReference();
3302         if (spread_pos.IsValid()) {
3303           args = Traits::PrepareSpreadArguments(args);
3304           result = Traits::SpreadCall(result, args, pos);
3305         } else {
3306           result = factory()->NewCall(result, args, pos);
3307         }
3308
3309         // Explicit calls to the super constructor using super() perform an
3310         // implicit binding assignment to the 'this' variable.
3311         if (is_super_call) {
3312           ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3313           result = factory()->NewAssignment(Token::INIT_CONST, this_expr,
3314                                             result, pos);
3315         }
3316
3317         if (fni_ != NULL) fni_->RemoveLastFunction();
3318         break;
3319       }
3320
3321       case Token::PERIOD: {
3322         BindingPatternUnexpectedToken(classifier);
3323         ArrowFormalParametersUnexpectedToken(classifier);
3324         Consume(Token::PERIOD);
3325         int pos = position();
3326         IdentifierT name = ParseIdentifierName(CHECK_OK);
3327         result = factory()->NewProperty(
3328             result, factory()->NewStringLiteral(name, pos), pos);
3329         if (fni_ != NULL) this->PushLiteralName(fni_, name);
3330         break;
3331       }
3332
3333       case Token::TEMPLATE_SPAN:
3334       case Token::TEMPLATE_TAIL: {
3335         BindingPatternUnexpectedToken(classifier);
3336         ArrowFormalParametersUnexpectedToken(classifier);
3337         result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
3338         break;
3339       }
3340
3341       default:
3342         return result;
3343     }
3344   }
3345 }
3346
3347
3348 template <class Traits>
3349 typename ParserBase<Traits>::ExpressionT
3350 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
3351     ExpressionClassifier* classifier, bool* ok) {
3352   // NewExpression ::
3353   //   ('new')+ MemberExpression
3354   //
3355   // NewTarget ::
3356   //   'new' '.' 'target'
3357
3358   // The grammar for new expressions is pretty warped. We can have several 'new'
3359   // keywords following each other, and then a MemberExpression. When we see '('
3360   // after the MemberExpression, it's associated with the rightmost unassociated
3361   // 'new' to create a NewExpression with arguments. However, a NewExpression
3362   // can also occur without arguments.
3363
3364   // Examples of new expression:
3365   // new foo.bar().baz means (new (foo.bar)()).baz
3366   // new foo()() means (new foo())()
3367   // new new foo()() means (new (new foo())())
3368   // new new foo means new (new foo)
3369   // new new foo() means new (new foo())
3370   // new new foo().bar().baz means (new (new foo()).bar()).baz
3371
3372   if (peek() == Token::NEW) {
3373     BindingPatternUnexpectedToken(classifier);
3374     ArrowFormalParametersUnexpectedToken(classifier);
3375     Consume(Token::NEW);
3376     int new_pos = position();
3377     ExpressionT result = this->EmptyExpression();
3378     if (peek() == Token::SUPER) {
3379       const bool is_new = true;
3380       result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3381     } else if (allow_harmony_new_target() && peek() == Token::PERIOD) {
3382       return ParseNewTargetExpression(CHECK_OK);
3383     } else {
3384       result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3385     }
3386     if (peek() == Token::LPAREN) {
3387       // NewExpression with arguments.
3388       Scanner::Location spread_pos;
3389       typename Traits::Type::ExpressionList args =
3390           this->ParseArguments(&spread_pos, classifier, CHECK_OK);
3391
3392       if (spread_pos.IsValid()) {
3393         args = Traits::PrepareSpreadArguments(args);
3394         result = Traits::SpreadCallNew(result, args, new_pos);
3395       } else {
3396         result = factory()->NewCallNew(result, args, new_pos);
3397       }
3398       // The expression can still continue with . or [ after the arguments.
3399       result =
3400           this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
3401       return result;
3402     }
3403     // NewExpression without arguments.
3404     return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
3405                                  new_pos);
3406   }
3407   // No 'new' or 'super' keyword.
3408   return this->ParseMemberExpression(classifier, ok);
3409 }
3410
3411
3412 template <class Traits>
3413 typename ParserBase<Traits>::ExpressionT
3414 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
3415                                           bool* ok) {
3416   // MemberExpression ::
3417   //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
3418   //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3419
3420   // The '[' Expression ']' and '.' Identifier parts are parsed by
3421   // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3422   // caller.
3423
3424   // Parse the initial primary or function expression.
3425   ExpressionT result = this->EmptyExpression();
3426   if (peek() == Token::FUNCTION) {
3427     BindingPatternUnexpectedToken(classifier);
3428     ArrowFormalParametersUnexpectedToken(classifier);
3429
3430     Consume(Token::FUNCTION);
3431     int function_token_position = position();
3432     bool is_generator = Check(Token::MUL);
3433     IdentifierT name = this->EmptyIdentifier();
3434     bool is_strict_reserved_name = false;
3435     Scanner::Location function_name_location = Scanner::Location::invalid();
3436     FunctionLiteral::FunctionType function_type =
3437         FunctionLiteral::ANONYMOUS_EXPRESSION;
3438     if (peek_any_identifier()) {
3439       name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3440                                                  CHECK_OK);
3441       function_name_location = scanner()->location();
3442       function_type = FunctionLiteral::NAMED_EXPRESSION;
3443     }
3444     result = this->ParseFunctionLiteral(
3445         name, function_name_location,
3446         is_strict_reserved_name ? kFunctionNameIsStrictReserved
3447                                 : kFunctionNameValidityUnknown,
3448         is_generator ? FunctionKind::kGeneratorFunction
3449                      : FunctionKind::kNormalFunction,
3450         function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
3451         language_mode(), CHECK_OK);
3452   } else if (peek() == Token::SUPER) {
3453     const bool is_new = false;
3454     result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3455   } else {
3456     result = ParsePrimaryExpression(classifier, CHECK_OK);
3457   }
3458
3459   result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
3460   return result;
3461 }
3462
3463
3464 template <class Traits>
3465 typename ParserBase<Traits>::ExpressionT
3466 ParserBase<Traits>::ParseStrongInitializationExpression(
3467     ExpressionClassifier* classifier, bool* ok) {
3468   // InitializationExpression ::  (strong mode)
3469   //  'this' '.' IdentifierName '=' AssignmentExpression
3470   //  'this' '[' Expression ']' '=' AssignmentExpression
3471
3472   if (fni_ != NULL) fni_->Enter();
3473
3474   Consume(Token::THIS);
3475   int pos = position();
3476   function_state_->set_this_location(scanner()->location());
3477   ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3478
3479   ExpressionT left = this->EmptyExpression();
3480   switch (peek()) {
3481     case Token::LBRACK: {
3482       Consume(Token::LBRACK);
3483       int pos = position();
3484       ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3485       left = factory()->NewProperty(this_expr, index, pos);
3486       if (fni_ != NULL) {
3487         this->PushPropertyName(fni_, index);
3488       }
3489       Expect(Token::RBRACK, CHECK_OK);
3490       break;
3491     }
3492     case Token::PERIOD: {
3493       Consume(Token::PERIOD);
3494       int pos = position();
3495       IdentifierT name = ParseIdentifierName(CHECK_OK);
3496       left = factory()->NewProperty(
3497           this_expr, factory()->NewStringLiteral(name, pos), pos);
3498       if (fni_ != NULL) {
3499         this->PushLiteralName(fni_, name);
3500       }
3501       break;
3502     }
3503     default:
3504       ReportMessage(MessageTemplate::kStrongConstructorThis);
3505       *ok = false;
3506       return this->EmptyExpression();
3507   }
3508
3509   if (peek() != Token::ASSIGN) {
3510     ReportMessageAt(function_state_->this_location(),
3511                     MessageTemplate::kStrongConstructorThis);
3512     *ok = false;
3513     return this->EmptyExpression();
3514   }
3515   Consume(Token::ASSIGN);
3516   left = this->MarkExpressionAsAssigned(left);
3517
3518   ExpressionT right =
3519       this->ParseAssignmentExpression(true, classifier, CHECK_OK);
3520   this->CheckAssigningFunctionLiteralToProperty(left, right);
3521   function_state_->AddProperty();
3522   if (fni_ != NULL) {
3523     // Check if the right hand side is a call to avoid inferring a
3524     // name if we're dealing with "this.a = function(){...}();"-like
3525     // expression.
3526     if (!right->IsCall() && !right->IsCallNew()) {
3527       fni_->Infer();
3528     } else {
3529       fni_->RemoveLastFunction();
3530     }
3531     fni_->Leave();
3532   }
3533
3534   if (function_state_->return_location().IsValid()) {
3535     ReportMessageAt(function_state_->return_location(),
3536                     MessageTemplate::kStrongConstructorReturnMisplaced);
3537     *ok = false;
3538     return this->EmptyExpression();
3539   }
3540
3541   return factory()->NewAssignment(Token::ASSIGN, left, right, pos);
3542 }
3543
3544
3545 template <class Traits>
3546 typename ParserBase<Traits>::ExpressionT
3547 ParserBase<Traits>::ParseStrongSuperCallExpression(
3548     ExpressionClassifier* classifier, bool* ok) {
3549   // SuperCallExpression ::  (strong mode)
3550   //  'super' '(' ExpressionList ')'
3551   BindingPatternUnexpectedToken(classifier);
3552
3553   Consume(Token::SUPER);
3554   int pos = position();
3555   Scanner::Location super_loc = scanner()->location();
3556   ExpressionT expr = this->SuperCallReference(scope_, factory(), pos);
3557
3558   if (peek() != Token::LPAREN) {
3559     ReportMessage(MessageTemplate::kStrongConstructorSuper);
3560     *ok = false;
3561     return this->EmptyExpression();
3562   }
3563
3564   Scanner::Location spread_pos;
3565   typename Traits::Type::ExpressionList args =
3566       ParseArguments(&spread_pos, classifier, CHECK_OK);
3567
3568   // TODO(rossberg): This doesn't work with arrow functions yet.
3569   if (!IsSubclassConstructor(function_state_->kind())) {
3570     ReportMessage(MessageTemplate::kUnexpectedSuper);
3571     *ok = false;
3572     return this->EmptyExpression();
3573   } else if (function_state_->super_location().IsValid()) {
3574     ReportMessageAt(scanner()->location(),
3575                     MessageTemplate::kStrongSuperCallDuplicate);
3576     *ok = false;
3577     return this->EmptyExpression();
3578   } else if (function_state_->this_location().IsValid()) {
3579     ReportMessageAt(scanner()->location(),
3580                     MessageTemplate::kStrongSuperCallMisplaced);
3581     *ok = false;
3582     return this->EmptyExpression();
3583   } else if (function_state_->return_location().IsValid()) {
3584     ReportMessageAt(function_state_->return_location(),
3585                     MessageTemplate::kStrongConstructorReturnMisplaced);
3586     *ok = false;
3587     return this->EmptyExpression();
3588   }
3589
3590   function_state_->set_super_location(super_loc);
3591   if (spread_pos.IsValid()) {
3592     args = Traits::PrepareSpreadArguments(args);
3593     expr = Traits::SpreadCall(expr, args, pos);
3594   } else {
3595     expr = factory()->NewCall(expr, args, pos);
3596   }
3597
3598   // Explicit calls to the super constructor using super() perform an implicit
3599   // binding assignment to the 'this' variable.
3600   ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3601   return factory()->NewAssignment(Token::INIT_CONST, this_expr, expr, pos);
3602 }
3603
3604
3605 template <class Traits>
3606 typename ParserBase<Traits>::ExpressionT
3607 ParserBase<Traits>::ParseSuperExpression(bool is_new,
3608                                          ExpressionClassifier* classifier,
3609                                          bool* ok) {
3610   int pos = position();
3611   Expect(Token::SUPER, CHECK_OK);
3612
3613   Scope* scope = scope_->ReceiverScope();
3614   FunctionKind kind = scope->function_kind();
3615   if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3616       IsClassConstructor(kind)) {
3617     if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3618       scope->RecordSuperPropertyUsage();
3619       return this->SuperPropertyReference(scope_, factory(), pos);
3620     }
3621     // new super() is never allowed.
3622     // super() is only allowed in derived constructor
3623     if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
3624       if (is_strong(language_mode())) {
3625         // Super calls in strong mode are parsed separately.
3626         ReportMessageAt(scanner()->location(),
3627                         MessageTemplate::kStrongConstructorSuper);
3628         *ok = false;
3629         return this->EmptyExpression();
3630       }
3631       // TODO(rossberg): This might not be the correct FunctionState for the
3632       // method here.
3633       function_state_->set_super_location(scanner()->location());
3634       return this->SuperCallReference(scope_, factory(), pos);
3635     }
3636   }
3637
3638   ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
3639   *ok = false;
3640   return this->EmptyExpression();
3641 }
3642
3643
3644 template <class Traits>
3645 typename ParserBase<Traits>::ExpressionT
3646 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
3647   int pos = position();
3648   Consume(Token::PERIOD);
3649   ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
3650
3651   if (!scope_->ReceiverScope()->is_function_scope()) {
3652     ReportMessageAt(scanner()->location(),
3653                     MessageTemplate::kUnexpectedNewTarget);
3654     *ok = false;
3655     return this->EmptyExpression();
3656   }
3657
3658   return this->NewTargetExpression(scope_, factory(), pos);
3659 }
3660
3661
3662 template <class Traits>
3663 typename ParserBase<Traits>::ExpressionT
3664 ParserBase<Traits>::ParseMemberExpressionContinuation(
3665     ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
3666   // Parses this part of MemberExpression:
3667   // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3668   while (true) {
3669     switch (peek()) {
3670       case Token::LBRACK: {
3671         BindingPatternUnexpectedToken(classifier);
3672         ArrowFormalParametersUnexpectedToken(classifier);
3673
3674         Consume(Token::LBRACK);
3675         int pos = position();
3676         ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3677         expression = factory()->NewProperty(expression, index, pos);
3678         if (fni_ != NULL) {
3679           this->PushPropertyName(fni_, index);
3680         }
3681         Expect(Token::RBRACK, CHECK_OK);
3682         break;
3683       }
3684       case Token::PERIOD: {
3685         BindingPatternUnexpectedToken(classifier);
3686         ArrowFormalParametersUnexpectedToken(classifier);
3687
3688         Consume(Token::PERIOD);
3689         int pos = position();
3690         IdentifierT name = ParseIdentifierName(CHECK_OK);
3691         expression = factory()->NewProperty(
3692             expression, factory()->NewStringLiteral(name, pos), pos);
3693         if (fni_ != NULL) {
3694           this->PushLiteralName(fni_, name);
3695         }
3696         break;
3697       }
3698       case Token::TEMPLATE_SPAN:
3699       case Token::TEMPLATE_TAIL: {
3700         BindingPatternUnexpectedToken(classifier);
3701         ArrowFormalParametersUnexpectedToken(classifier);
3702         int pos;
3703         if (scanner()->current_token() == Token::IDENTIFIER) {
3704           pos = position();
3705         } else {
3706           pos = peek_position();
3707           if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3708             // If the tag function looks like an IIFE, set_parenthesized() to
3709             // force eager compilation.
3710             expression->AsFunctionLiteral()->set_should_eager_compile();
3711           }
3712         }
3713         expression =
3714             ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
3715         break;
3716       }
3717       default:
3718         return expression;
3719     }
3720   }
3721   DCHECK(false);
3722   return this->EmptyExpression();
3723 }
3724
3725
3726 template <class Traits>
3727 void ParserBase<Traits>::ParseFormalParameter(
3728     FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3729   // FormalParameter[Yield,GeneratorParameter] :
3730   //   BindingElement[?Yield, ?GeneratorParameter]
3731   bool is_rest = parameters->has_rest;
3732
3733   Token::Value next = peek();
3734   ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
3735   if (!*ok) return;
3736
3737   ValidateBindingPattern(classifier, ok);
3738   if (!*ok) return;
3739
3740   if (!Traits::IsIdentifier(pattern)) {
3741     if (is_rest || !allow_harmony_destructuring()) {
3742       ReportUnexpectedToken(next);
3743       *ok = false;
3744       return;
3745     }
3746     parameters->is_simple = false;
3747     ValidateFormalParameterInitializer(classifier, ok);
3748     if (!*ok) return;
3749     classifier->RecordNonSimpleParameter();
3750   }
3751
3752   if (is_rest) {
3753     parameters->rest_array_literal_index =
3754         function_state_->NextMaterializedLiteralIndex();
3755     ++parameters->materialized_literals_count;
3756   }
3757
3758   ExpressionT initializer = Traits::EmptyExpression();
3759   if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
3760     ExpressionClassifier init_classifier;
3761     initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3762     if (!*ok) return;
3763     ValidateExpression(&init_classifier, ok);
3764     ValidateFormalParameterInitializer(&init_classifier, ok);
3765     if (!*ok) return;
3766     parameters->is_simple = false;
3767     classifier->RecordNonSimpleParameter();
3768   }
3769
3770   Traits::AddFormalParameter(parameters, pattern, initializer, is_rest);
3771 }
3772
3773
3774 template <class Traits>
3775 void ParserBase<Traits>::ParseFormalParameterList(
3776     FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3777   // FormalParameters[Yield,GeneratorParameter] :
3778   //   [empty]
3779   //   FormalParameterList[?Yield, ?GeneratorParameter]
3780   //
3781   // FormalParameterList[Yield,GeneratorParameter] :
3782   //   FunctionRestParameter[?Yield]
3783   //   FormalsList[?Yield, ?GeneratorParameter]
3784   //   FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
3785   //
3786   // FormalsList[Yield,GeneratorParameter] :
3787   //   FormalParameter[?Yield, ?GeneratorParameter]
3788   //   FormalsList[?Yield, ?GeneratorParameter] ,
3789   //     FormalParameter[?Yield,?GeneratorParameter]
3790
3791   DCHECK_EQ(0, parameters->Arity());
3792
3793   if (peek() != Token::RPAREN) {
3794     do {
3795       if (parameters->Arity() > Code::kMaxArguments) {
3796         ReportMessage(MessageTemplate::kTooManyParameters);
3797         *ok = false;
3798         return;
3799       }
3800       parameters->has_rest =
3801           allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
3802       ParseFormalParameter(parameters, classifier, ok);
3803       if (!*ok) return;
3804     } while (!parameters->has_rest && Check(Token::COMMA));
3805
3806     if (parameters->has_rest) {
3807       parameters->is_simple = false;
3808       classifier->RecordNonSimpleParameter();
3809       if (peek() == Token::COMMA) {
3810         ReportMessageAt(scanner()->peek_location(),
3811                       MessageTemplate::kParamAfterRest);
3812         *ok = false;
3813         return;
3814       }
3815     }
3816   }
3817
3818   for (int i = 0; i < parameters->Arity(); ++i) {
3819     auto parameter = parameters->at(i);
3820     Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
3821   }
3822 }
3823
3824
3825 template <class Traits>
3826 void ParserBase<Traits>::CheckArityRestrictions(
3827     int param_count, FunctionLiteral::ArityRestriction arity_restriction,
3828     bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
3829   switch (arity_restriction) {
3830     case FunctionLiteral::GETTER_ARITY:
3831       if (param_count != 0) {
3832         ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3833                         MessageTemplate::kBadGetterArity);
3834         *ok = false;
3835       }
3836       break;
3837     case FunctionLiteral::SETTER_ARITY:
3838       if (param_count != 1) {
3839         ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3840                         MessageTemplate::kBadSetterArity);
3841         *ok = false;
3842       }
3843       if (has_rest) {
3844         ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3845                         MessageTemplate::kBadSetterRestParameter);
3846         *ok = false;
3847       }
3848       break;
3849     default:
3850       break;
3851   }
3852 }
3853
3854
3855 template <class Traits>
3856 bool ParserBase<Traits>::IsNextLetKeyword() {
3857   DCHECK(peek() == Token::LET);
3858   if (!allow_let()) {
3859     return false;
3860   }
3861   Token::Value next_next = PeekAhead();
3862   switch (next_next) {
3863     case Token::LBRACE:
3864     case Token::LBRACK:
3865     case Token::IDENTIFIER:
3866     case Token::STATIC:
3867     case Token::LET:  // Yes, you can do let let = ... in sloppy mode
3868     case Token::YIELD:
3869       return true;
3870     default:
3871       return false;
3872   }
3873 }
3874
3875
3876 template <class Traits>
3877 typename ParserBase<Traits>::ExpressionT
3878 ParserBase<Traits>::ParseArrowFunctionLiteral(
3879     const FormalParametersT& formal_parameters,
3880     const ExpressionClassifier& formals_classifier, bool* ok) {
3881   if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3882     // ASI inserts `;` after arrow parameters if a line terminator is found.
3883     // `=> ...` is never a valid expression, so report as syntax error.
3884     // If next token is not `=>`, it's a syntax error anyways.
3885     ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3886     *ok = false;
3887     return this->EmptyExpression();
3888   }
3889
3890   typename Traits::Type::StatementList body;
3891   int num_parameters = formal_parameters.scope->num_parameters();
3892   int materialized_literal_count = -1;
3893   int expected_property_count = -1;
3894   Scanner::Location super_loc;
3895
3896   {
3897     typename Traits::Type::Factory function_factory(ast_value_factory());
3898     FunctionState function_state(&function_state_, &scope_,
3899                                  formal_parameters.scope, kArrowFunction,
3900                                  &function_factory);
3901
3902     function_state.SkipMaterializedLiterals(
3903         formal_parameters.materialized_literals_count);
3904
3905     this->ReindexLiterals(formal_parameters);
3906
3907     Expect(Token::ARROW, CHECK_OK);
3908
3909     if (peek() == Token::LBRACE) {
3910       // Multiple statement body
3911       Consume(Token::LBRACE);
3912       bool is_lazily_parsed =
3913           (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
3914       if (is_lazily_parsed) {
3915         body = this->NewStatementList(0, zone());
3916         this->SkipLazyFunctionBody(&materialized_literal_count,
3917                                    &expected_property_count, CHECK_OK);
3918
3919         if (formal_parameters.materialized_literals_count > 0) {
3920           materialized_literal_count +=
3921               formal_parameters.materialized_literals_count;
3922         }
3923       } else {
3924         body = this->ParseEagerFunctionBody(
3925             this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
3926             kArrowFunction, FunctionLiteral::ANONYMOUS_EXPRESSION, CHECK_OK);
3927         materialized_literal_count =
3928             function_state.materialized_literal_count();
3929         expected_property_count = function_state.expected_property_count();
3930       }
3931     } else {
3932       // Single-expression body
3933       int pos = position();
3934       parenthesized_function_ = false;
3935       ExpressionClassifier classifier;
3936       ExpressionT expression =
3937           ParseAssignmentExpression(true, &classifier, CHECK_OK);
3938       ValidateExpression(&classifier, CHECK_OK);
3939       body = this->NewStatementList(1, zone());
3940       this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
3941       body->Add(factory()->NewReturnStatement(expression, pos), zone());
3942       materialized_literal_count = function_state.materialized_literal_count();
3943       expected_property_count = function_state.expected_property_count();
3944     }
3945     super_loc = function_state.super_location();
3946
3947     formal_parameters.scope->set_end_position(scanner()->location().end_pos);
3948
3949     // Arrow function formal parameters are parsed as StrictFormalParameterList,
3950     // which is not the same as "parameters of a strict function"; it only means
3951     // that duplicates are not allowed.  Of course, the arrow function may
3952     // itself be strict as well.
3953     const bool allow_duplicate_parameters = false;
3954     this->ValidateFormalParameters(&formals_classifier, language_mode(),
3955                                    allow_duplicate_parameters, CHECK_OK);
3956
3957     // Validate strict mode.
3958     if (is_strict(language_mode())) {
3959       CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
3960                               scanner()->location().end_pos, CHECK_OK);
3961     }
3962     if (is_strict(language_mode()) || allow_harmony_sloppy()) {
3963       this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
3964     }
3965   }
3966
3967   FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
3968       this->EmptyIdentifierString(), ast_value_factory(),
3969       formal_parameters.scope, body, materialized_literal_count,
3970       expected_property_count, num_parameters,
3971       FunctionLiteral::kNoDuplicateParameters,
3972       FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
3973       FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
3974       formal_parameters.scope->start_position());
3975
3976   function_literal->set_function_token_position(
3977       formal_parameters.scope->start_position());
3978   if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
3979
3980   if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
3981
3982   return function_literal;
3983 }
3984
3985
3986 template <typename Traits>
3987 typename ParserBase<Traits>::ExpressionT
3988 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
3989                                          ExpressionClassifier* classifier,
3990                                          bool* ok) {
3991   // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3992   // text followed by a substitution expression), finalized by a single
3993   // TEMPLATE_TAIL.
3994   //
3995   // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3996   // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3997   // NoSubstitutionTemplate.
3998   //
3999   // When parsing a TemplateLiteral, we must have scanned either an initial
4000   // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
4001   CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4002
4003   // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
4004   // In this case we may simply consume the token and build a template with a
4005   // single TEMPLATE_SPAN and no expressions.
4006   if (peek() == Token::TEMPLATE_TAIL) {
4007     Consume(Token::TEMPLATE_TAIL);
4008     int pos = position();
4009     CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4010     typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
4011     Traits::AddTemplateSpan(&ts, true);
4012     return Traits::CloseTemplateLiteral(&ts, start, tag);
4013   }
4014
4015   Consume(Token::TEMPLATE_SPAN);
4016   int pos = position();
4017   typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
4018   Traits::AddTemplateSpan(&ts, false);
4019   Token::Value next;
4020
4021   // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
4022   // and repeat if the following token is a TEMPLATE_SPAN as well (in this
4023   // case, representing a TemplateMiddle).
4024
4025   do {
4026     CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4027     next = peek();
4028     if (next == Token::EOS) {
4029       ReportMessageAt(Scanner::Location(start, peek_position()),
4030                       MessageTemplate::kUnterminatedTemplate);
4031       *ok = false;
4032       return Traits::EmptyExpression();
4033     } else if (next == Token::ILLEGAL) {
4034       Traits::ReportMessageAt(
4035           Scanner::Location(position() + 1, peek_position()),
4036           MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4037       *ok = false;
4038       return Traits::EmptyExpression();
4039     }
4040
4041     int expr_pos = peek_position();
4042     ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
4043     Traits::AddTemplateExpression(&ts, expression);
4044
4045     if (peek() != Token::RBRACE) {
4046       ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
4047                       MessageTemplate::kUnterminatedTemplateExpr);
4048       *ok = false;
4049       return Traits::EmptyExpression();
4050     }
4051
4052     // If we didn't die parsing that expression, our next token should be a
4053     // TEMPLATE_SPAN or TEMPLATE_TAIL.
4054     next = scanner()->ScanTemplateContinuation();
4055     Next();
4056     pos = position();
4057
4058     if (next == Token::EOS) {
4059       ReportMessageAt(Scanner::Location(start, pos),
4060                       MessageTemplate::kUnterminatedTemplate);
4061       *ok = false;
4062       return Traits::EmptyExpression();
4063     } else if (next == Token::ILLEGAL) {
4064       Traits::ReportMessageAt(
4065           Scanner::Location(position() + 1, peek_position()),
4066           MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4067       *ok = false;
4068       return Traits::EmptyExpression();
4069     }
4070
4071     Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
4072   } while (next == Token::TEMPLATE_SPAN);
4073
4074   DCHECK_EQ(next, Token::TEMPLATE_TAIL);
4075   CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4076   // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4077   return Traits::CloseTemplateLiteral(&ts, start, tag);
4078 }
4079
4080
4081 template <typename Traits>
4082 typename ParserBase<Traits>::ExpressionT
4083 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
4084     ExpressionT expression, int beg_pos, int end_pos,
4085     MessageTemplate::Template message, bool* ok) {
4086   return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
4087                                                   message, kReferenceError, ok);
4088 }
4089
4090
4091 template <typename Traits>
4092 typename ParserBase<Traits>::ExpressionT
4093 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
4094     ExpressionT expression, int beg_pos, int end_pos,
4095     MessageTemplate::Template message, ParseErrorType type, bool* ok) {
4096   Scanner::Location location(beg_pos, end_pos);
4097   if (this->IsIdentifier(expression)) {
4098     if (is_strict(language_mode()) &&
4099         this->IsEvalOrArguments(this->AsIdentifier(expression))) {
4100       this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments,
4101                             kSyntaxError);
4102       *ok = false;
4103       return this->EmptyExpression();
4104     }
4105     if (is_strong(language_mode()) &&
4106         this->IsUndefined(this->AsIdentifier(expression))) {
4107       this->ReportMessageAt(location, MessageTemplate::kStrongUndefined,
4108                             kSyntaxError);
4109       *ok = false;
4110       return this->EmptyExpression();
4111     }
4112   }
4113   if (expression->IsValidReferenceExpression()) {
4114     return expression;
4115   } else if (expression->IsCall()) {
4116     // If it is a call, make it a runtime error for legacy web compatibility.
4117     // Rewrite `expr' to `expr[throw ReferenceError]'.
4118     int pos = location.beg_pos;
4119     ExpressionT error = this->NewThrowReferenceError(message, pos);
4120     return factory()->NewProperty(expression, error, pos);
4121   } else {
4122     this->ReportMessageAt(location, message, type);
4123     *ok = false;
4124     return this->EmptyExpression();
4125   }
4126 }
4127
4128
4129 #undef CHECK_OK
4130 #undef CHECK_OK_CUSTOM
4131
4132
4133 template <typename Traits>
4134 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
4135     Token::Value property, PropertyKind type, bool is_static, bool is_generator,
4136     bool* ok) {
4137   DCHECK(!is_static);
4138   DCHECK(!is_generator || type == kMethodProperty);
4139
4140   if (property == Token::SMI || property == Token::NUMBER) return;
4141
4142   if (type == kValueProperty && IsProto()) {
4143     if (has_seen_proto_) {
4144       this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
4145       *ok = false;
4146       return;
4147     }
4148     has_seen_proto_ = true;
4149     return;
4150   }
4151 }
4152
4153
4154 template <typename Traits>
4155 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
4156     Token::Value property, PropertyKind type, bool is_static, bool is_generator,
4157     bool* ok) {
4158   DCHECK(type == kMethodProperty || type == kAccessorProperty);
4159
4160   if (property == Token::SMI || property == Token::NUMBER) return;
4161
4162   if (is_static) {
4163     if (IsPrototype()) {
4164       this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
4165       *ok = false;
4166       return;
4167     }
4168   } else if (IsConstructor()) {
4169     if (is_generator || type == kAccessorProperty) {
4170       MessageTemplate::Template msg =
4171           is_generator ? MessageTemplate::kConstructorIsGenerator
4172                        : MessageTemplate::kConstructorIsAccessor;
4173       this->parser()->ReportMessage(msg);
4174       *ok = false;
4175       return;
4176     }
4177     if (has_seen_constructor_) {
4178       this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
4179       *ok = false;
4180       return;
4181     }
4182     has_seen_constructor_ = true;
4183     return;
4184   }
4185 }
4186 } }  // v8::internal
4187
4188 #endif  // V8_PREPARSER_H