deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / 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/v8.h"
9
10 #include "src/bailout-reason.h"
11 #include "src/func-name-inferrer.h"
12 #include "src/hashmap.h"
13 #include "src/scanner.h"
14 #include "src/scopes.h"
15 #include "src/token.h"
16
17 namespace v8 {
18 namespace internal {
19
20 // Common base class shared between parser and pre-parser. Traits encapsulate
21 // the differences between Parser and PreParser:
22
23 // - Return types: For example, Parser functions return Expression* and
24 // PreParser functions return PreParserExpression.
25
26 // - Creating parse tree nodes: Parser generates an AST during the recursive
27 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
28 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
29 // just enough data for the upper layer functions. PreParserFactory is
30 // responsible for creating these dummy objects. It provides a similar kind of
31 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
32 // used.
33
34 // - Miscellaneous other tasks interleaved with the recursive descent. For
35 // example, Parser keeps track of which function literals should be marked as
36 // pretenured, and PreParser doesn't care.
37
38 // The traits are expected to contain the following typedefs:
39 // struct Traits {
40 //   // In particular...
41 //   struct Type {
42 //     // Used by FunctionState and BlockState.
43 //     typedef Scope;
44 //     typedef GeneratorVariable;
45 //     // Return types for traversing functions.
46 //     typedef Identifier;
47 //     typedef Expression;
48 //     typedef FunctionLiteral;
49 //     typedef ClassLiteral;
50 //     typedef ObjectLiteralProperty;
51 //     typedef Literal;
52 //     typedef ExpressionList;
53 //     typedef PropertyList;
54 //     // For constructing objects returned by the traversing functions.
55 //     typedef Factory;
56 //   };
57 //   // ...
58 // };
59
60 template <typename Traits>
61 class ParserBase : public Traits {
62  public:
63   // Shorten type names defined by Traits.
64   typedef typename Traits::Type::Expression ExpressionT;
65   typedef typename Traits::Type::Identifier IdentifierT;
66   typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
67   typedef typename Traits::Type::Literal LiteralT;
68   typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
69
70   ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
71              v8::Extension* extension, AstValueFactory* ast_value_factory,
72              ParserRecorder* log, typename Traits::Type::Parser this_object)
73       : Traits(this_object),
74         parenthesized_function_(false),
75         scope_(NULL),
76         function_state_(NULL),
77         extension_(extension),
78         fni_(NULL),
79         ast_value_factory_(ast_value_factory),
80         log_(log),
81         mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
82         stack_limit_(stack_limit),
83         zone_(zone),
84         scanner_(scanner),
85         stack_overflow_(false),
86         allow_lazy_(false),
87         allow_natives_(false),
88         allow_harmony_arrow_functions_(false),
89         allow_harmony_object_literals_(false),
90         allow_harmony_sloppy_(false),
91         allow_harmony_computed_property_names_(false),
92         allow_harmony_rest_params_(false),
93         allow_strong_mode_(false) {}
94
95   // Getters that indicate whether certain syntactical constructs are
96   // allowed to be parsed by this instance of the parser.
97   bool allow_lazy() const { return allow_lazy_; }
98   bool allow_natives() const { return allow_natives_; }
99   bool allow_harmony_arrow_functions() const {
100     return allow_harmony_arrow_functions_;
101   }
102   bool allow_harmony_modules() const { return scanner()->HarmonyModules(); }
103   bool allow_harmony_numeric_literals() const {
104     return scanner()->HarmonyNumericLiterals();
105   }
106   bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); }
107   bool allow_harmony_object_literals() const {
108     return allow_harmony_object_literals_;
109   }
110   bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; }
111   bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
112   bool allow_harmony_computed_property_names() const {
113     return allow_harmony_computed_property_names_;
114   }
115   bool allow_harmony_rest_params() const {
116     return allow_harmony_rest_params_;
117   }
118
119   bool allow_strong_mode() const { return allow_strong_mode_; }
120
121   // Setters that determine whether certain syntactical constructs are
122   // allowed to be parsed by this instance of the parser.
123   void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
124   void set_allow_natives(bool allow) { allow_natives_ = allow; }
125   void set_allow_harmony_arrow_functions(bool allow) {
126     allow_harmony_arrow_functions_ = allow;
127   }
128   void set_allow_harmony_modules(bool allow) {
129     scanner()->SetHarmonyModules(allow);
130   }
131   void set_allow_harmony_numeric_literals(bool allow) {
132     scanner()->SetHarmonyNumericLiterals(allow);
133   }
134   void set_allow_harmony_classes(bool allow) {
135     scanner()->SetHarmonyClasses(allow);
136   }
137   void set_allow_harmony_object_literals(bool allow) {
138     allow_harmony_object_literals_ = allow;
139   }
140   void set_allow_harmony_sloppy(bool allow) {
141     allow_harmony_sloppy_ = allow;
142   }
143   void set_allow_harmony_unicode(bool allow) {
144     scanner()->SetHarmonyUnicode(allow);
145   }
146   void set_allow_harmony_computed_property_names(bool allow) {
147     allow_harmony_computed_property_names_ = allow;
148   }
149   void set_allow_harmony_rest_params(bool allow) {
150     allow_harmony_rest_params_ = allow;
151   }
152   void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
153
154  protected:
155   enum AllowEvalOrArgumentsAsIdentifier {
156     kAllowEvalOrArguments,
157     kDontAllowEvalOrArguments
158   };
159
160   enum Mode {
161     PARSE_LAZILY,
162     PARSE_EAGERLY
163   };
164
165   enum VariableDeclarationContext {
166     kStatementListItem,
167     kStatement,
168     kForStatement
169   };
170
171   // If a list of variable declarations includes any initializers.
172   enum VariableDeclarationProperties { kHasInitializers, kHasNoInitializers };
173
174   class Checkpoint;
175   class ObjectLiteralCheckerBase;
176
177   // ---------------------------------------------------------------------------
178   // FunctionState and BlockState together implement the parser's scope stack.
179   // The parser's current scope is in scope_. BlockState and FunctionState
180   // constructors push on the scope stack and the destructors pop. They are also
181   // used to hold the parser's per-function and per-block state.
182   class BlockState BASE_EMBEDDED {
183    public:
184     BlockState(Scope** scope_stack, Scope* scope)
185         : scope_stack_(scope_stack), outer_scope_(*scope_stack), scope_(scope) {
186       *scope_stack_ = scope_;
187     }
188     ~BlockState() { *scope_stack_ = outer_scope_; }
189
190    private:
191     Scope** scope_stack_;
192     Scope* outer_scope_;
193     Scope* scope_;
194   };
195
196   class FunctionState BASE_EMBEDDED {
197    public:
198     FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
199                   Scope* scope, FunctionKind kind,
200                   typename Traits::Type::Factory* factory);
201     ~FunctionState();
202
203     int NextMaterializedLiteralIndex() {
204       return next_materialized_literal_index_++;
205     }
206     int materialized_literal_count() {
207       return next_materialized_literal_index_;
208     }
209
210     int NextHandlerIndex() { return next_handler_index_++; }
211     int handler_count() { return next_handler_index_; }
212
213     void AddProperty() { expected_property_count_++; }
214     int expected_property_count() { return expected_property_count_; }
215
216     Scanner::Location return_location() const { return return_location_; }
217     Scanner::Location super_call_location() const {
218       return super_call_location_;
219     }
220     void set_return_location(Scanner::Location location) {
221       return_location_ = location;
222     }
223     void set_super_call_location(Scanner::Location location) {
224       super_call_location_ = location;
225     }
226
227     bool is_generator() const { return IsGeneratorFunction(kind_); }
228
229     FunctionKind kind() const { return kind_; }
230     FunctionState* outer() const { return outer_function_state_; }
231
232     void set_generator_object_variable(
233         typename Traits::Type::GeneratorVariable* variable) {
234       DCHECK(variable != NULL);
235       DCHECK(is_generator());
236       generator_object_variable_ = variable;
237     }
238     typename Traits::Type::GeneratorVariable* generator_object_variable()
239         const {
240       return generator_object_variable_;
241     }
242
243     typename Traits::Type::Factory* factory() { return factory_; }
244
245    private:
246     // Used to assign an index to each literal that needs materialization in
247     // the function.  Includes regexp literals, and boilerplate for object and
248     // array literals.
249     int next_materialized_literal_index_;
250
251     // Used to assign a per-function index to try and catch handlers.
252     int next_handler_index_;
253
254     // Properties count estimation.
255     int expected_property_count_;
256
257     // Location of most recent 'return' statement (invalid if none).
258     Scanner::Location return_location_;
259
260     // Location of call to the "super" constructor (invalid if none).
261     Scanner::Location super_call_location_;
262
263     FunctionKind kind_;
264     // For generators, this variable may hold the generator object. It variable
265     // is used by yield expressions and return statements. It is not necessary
266     // for generator functions to have this variable set.
267     Variable* generator_object_variable_;
268
269     FunctionState** function_state_stack_;
270     FunctionState* outer_function_state_;
271     Scope** scope_stack_;
272     Scope* outer_scope_;
273     typename Traits::Type::Factory* factory_;
274
275     friend class ParserTraits;
276     friend class Checkpoint;
277   };
278
279   // Annoyingly, arrow functions first parse as comma expressions, then when we
280   // see the => we have to go back and reinterpret the arguments as being formal
281   // parameters.  To do so we need to reset some of the parser state back to
282   // what it was before the arguments were first seen.
283   class Checkpoint BASE_EMBEDDED {
284    public:
285     explicit Checkpoint(ParserBase* parser) {
286       function_state_ = parser->function_state_;
287       next_materialized_literal_index_ =
288           function_state_->next_materialized_literal_index_;
289       next_handler_index_ = function_state_->next_handler_index_;
290       expected_property_count_ = function_state_->expected_property_count_;
291     }
292
293     void Restore() {
294       function_state_->next_materialized_literal_index_ =
295           next_materialized_literal_index_;
296       function_state_->next_handler_index_ = next_handler_index_;
297       function_state_->expected_property_count_ = expected_property_count_;
298     }
299
300    private:
301     FunctionState* function_state_;
302     int next_materialized_literal_index_;
303     int next_handler_index_;
304     int expected_property_count_;
305   };
306
307   class ParsingModeScope BASE_EMBEDDED {
308    public:
309     ParsingModeScope(ParserBase* parser, Mode mode)
310         : parser_(parser),
311           old_mode_(parser->mode()) {
312       parser_->mode_ = mode;
313     }
314     ~ParsingModeScope() {
315       parser_->mode_ = old_mode_;
316     }
317
318    private:
319     ParserBase* parser_;
320     Mode old_mode_;
321   };
322
323   Scope* NewScope(Scope* parent, ScopeType scope_type,
324                   FunctionKind kind = kNormalFunction) {
325     DCHECK(ast_value_factory());
326     DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules());
327     DCHECK((scope_type == FUNCTION_SCOPE && IsValidFunctionKind(kind)) ||
328            kind == kNormalFunction);
329     Scope* result = new (zone())
330         Scope(zone(), parent, scope_type, ast_value_factory(), kind);
331     result->Initialize();
332     return result;
333   }
334
335   Scanner* scanner() const { return scanner_; }
336   AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
337   int position() { return scanner_->location().beg_pos; }
338   int peek_position() { return scanner_->peek_location().beg_pos; }
339   bool stack_overflow() const { return stack_overflow_; }
340   void set_stack_overflow() { stack_overflow_ = true; }
341   Mode mode() const { return mode_; }
342   Zone* zone() const { return zone_; }
343
344   INLINE(Token::Value peek()) {
345     if (stack_overflow_) return Token::ILLEGAL;
346     return scanner()->peek();
347   }
348
349   INLINE(Token::Value Next()) {
350     if (stack_overflow_) return Token::ILLEGAL;
351     {
352       if (GetCurrentStackPosition() < stack_limit_) {
353         // Any further calls to Next or peek will return the illegal token.
354         // The current call must return the next token, which might already
355         // have been peek'ed.
356         stack_overflow_ = true;
357       }
358     }
359     return scanner()->Next();
360   }
361
362   void Consume(Token::Value token) {
363     Token::Value next = Next();
364     USE(next);
365     USE(token);
366     DCHECK(next == token);
367   }
368
369   bool Check(Token::Value token) {
370     Token::Value next = peek();
371     if (next == token) {
372       Consume(next);
373       return true;
374     }
375     return false;
376   }
377
378   void Expect(Token::Value token, bool* ok) {
379     Token::Value next = Next();
380     if (next != token) {
381       ReportUnexpectedToken(next);
382       *ok = false;
383     }
384   }
385
386   void ExpectSemicolon(bool* ok) {
387     // Check for automatic semicolon insertion according to
388     // the rules given in ECMA-262, section 7.9, page 21.
389     Token::Value tok = peek();
390     if (tok == Token::SEMICOLON) {
391       Next();
392       return;
393     }
394     if (scanner()->HasAnyLineTerminatorBeforeNext() ||
395         tok == Token::RBRACE ||
396         tok == Token::EOS) {
397       return;
398     }
399     Expect(Token::SEMICOLON, ok);
400   }
401
402   bool peek_any_identifier() {
403     Token::Value next = peek();
404     return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
405            next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
406            next == Token::STATIC || next == Token::YIELD;
407   }
408
409   bool CheckContextualKeyword(Vector<const char> keyword) {
410     if (PeekContextualKeyword(keyword)) {
411       Consume(Token::IDENTIFIER);
412       return true;
413     }
414     return false;
415   }
416
417   bool PeekContextualKeyword(Vector<const char> keyword) {
418     return peek() == Token::IDENTIFIER &&
419            scanner()->is_next_contextual_keyword(keyword);
420   }
421
422   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
423     Expect(Token::IDENTIFIER, ok);
424     if (!*ok) return;
425     if (!scanner()->is_literal_contextual_keyword(keyword)) {
426       ReportUnexpectedToken(scanner()->current_token());
427       *ok = false;
428     }
429   }
430
431   bool CheckInOrOf(
432       bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) {
433     if (Check(Token::IN)) {
434       if (is_strong(language_mode())) {
435         ReportMessageAt(scanner()->location(), "strong_for_in");
436         *ok = false;
437       } else {
438         *visit_mode = ForEachStatement::ENUMERATE;
439       }
440       return true;
441     } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
442       *visit_mode = ForEachStatement::ITERATE;
443       return true;
444     }
445     return false;
446   }
447
448   // Checks whether an octal literal was last seen between beg_pos and end_pos.
449   // If so, reports an error. Only called for strict mode and template strings.
450   void CheckOctalLiteral(int beg_pos, int end_pos, const char* error,
451                          bool* ok) {
452     Scanner::Location octal = scanner()->octal_position();
453     if (octal.IsValid() && beg_pos <= octal.beg_pos &&
454         octal.end_pos <= end_pos) {
455       ReportMessageAt(octal, error);
456       scanner()->clear_octal_position();
457       *ok = false;
458     }
459   }
460
461   inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
462     CheckOctalLiteral(beg_pos, end_pos, "strict_octal_literal", ok);
463   }
464
465   inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
466     CheckOctalLiteral(beg_pos, end_pos, "template_octal_literal", 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, FunctionKind kind,
472                          IdentifierT function_name,
473                          bool function_name_is_strict_reserved,
474                          const Scanner::Location& function_name_loc,
475                          bool* ok) {
476     // Property names are never checked.
477     if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return;
478     // The function name needs to be checked in strict mode.
479     if (is_sloppy(language_mode)) return;
480
481     if (this->IsEvalOrArguments(function_name)) {
482       Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments");
483       *ok = false;
484       return;
485     }
486     if (function_name_is_strict_reserved) {
487       Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved");
488       *ok = false;
489       return;
490     }
491   }
492
493   // Checking the parameter names of a function literal. This has to be done
494   // after parsing the function, since the function can declare itself strict.
495   void CheckFunctionParameterNames(LanguageMode language_mode,
496                                    bool strict_params,
497                                    const Scanner::Location& eval_args_error_loc,
498                                    const Scanner::Location& dupe_error_loc,
499                                    const Scanner::Location& reserved_loc,
500                                    bool* ok) {
501     if (is_sloppy(language_mode) && !strict_params) return;
502
503     if (is_strict(language_mode) && eval_args_error_loc.IsValid()) {
504       Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
505       *ok = false;
506       return;
507     }
508     // TODO(arv): When we add support for destructuring in setters we also need
509     // to check for duplicate names.
510     if (dupe_error_loc.IsValid()) {
511       Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe");
512       *ok = false;
513       return;
514     }
515     if (reserved_loc.IsValid()) {
516       Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
517       *ok = false;
518       return;
519     }
520   }
521
522   // Determine precedence of given token.
523   static int Precedence(Token::Value token, bool accept_IN) {
524     if (token == Token::IN && !accept_IN)
525       return 0;  // 0 precedence will terminate binary expression parsing
526     return Token::Precedence(token);
527   }
528
529   typename Traits::Type::Factory* factory() {
530     return function_state_->factory();
531   }
532
533   LanguageMode language_mode() { return scope_->language_mode(); }
534   bool is_generator() const { return function_state_->is_generator(); }
535
536   // Report syntax errors.
537   void ReportMessage(const char* message, const char* arg = NULL,
538                      ParseErrorType error_type = kSyntaxError) {
539     Scanner::Location source_location = scanner()->location();
540     Traits::ReportMessageAt(source_location, message, arg, error_type);
541   }
542
543   void ReportMessageAt(Scanner::Location location, const char* message,
544                        ParseErrorType error_type = kSyntaxError) {
545     Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
546                             error_type);
547   }
548
549   void ReportUnexpectedToken(Token::Value token);
550   void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token);
551
552   // Recursive descent functions:
553
554   // Parses an identifier that is valid for the current scope, in particular it
555   // fails on strict mode future reserved keywords in a strict scope. If
556   // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
557   // "arguments" as identifier even in strict mode (this is needed in cases like
558   // "var foo = eval;").
559   IdentifierT ParseIdentifier(
560       AllowEvalOrArgumentsAsIdentifier,
561       bool* ok);
562   // Parses an identifier or a strict mode future reserved word, and indicate
563   // whether it is strict mode future reserved.
564   IdentifierT ParseIdentifierOrStrictReservedWord(
565       bool* is_strict_reserved,
566       bool* ok);
567   IdentifierT ParseIdentifierName(bool* ok);
568   // Parses an identifier and determines whether or not it is 'get' or 'set'.
569   IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
570                                             bool* is_set,
571                                             bool* ok);
572
573   ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
574
575   ExpressionT ParsePrimaryExpression(bool* ok);
576   ExpressionT ParseExpression(bool accept_IN, bool* ok);
577   ExpressionT ParseArrayLiteral(bool* ok);
578   ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
579                                 bool* is_static, bool* is_computed_name,
580                                 bool* ok);
581   ExpressionT ParseObjectLiteral(bool* ok);
582   ObjectLiteralPropertyT ParsePropertyDefinition(
583       ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
584       bool is_static, bool* is_computed_name, bool* has_seen_constructor,
585       bool* ok);
586   typename Traits::Type::ExpressionList ParseArguments(bool* ok);
587   ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
588   ExpressionT ParseYieldExpression(bool* ok);
589   ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
590   ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
591   ExpressionT ParseUnaryExpression(bool* ok);
592   ExpressionT ParsePostfixExpression(bool* ok);
593   ExpressionT ParseLeftHandSideExpression(bool* ok);
594   ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
595   ExpressionT ParseMemberExpression(bool* ok);
596   ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
597                                                 bool* ok);
598   ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
599                                         bool* ok);
600   ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
601   void AddTemplateExpression(ExpressionT);
602   ExpressionT ParseSuperExpression(bool is_new, bool* ok);
603
604   // Checks if the expression is a valid reference expression (e.g., on the
605   // left-hand side of assignments). Although ruled out by ECMA as early errors,
606   // we allow calls for web compatibility and rewrite them to a runtime throw.
607   ExpressionT CheckAndRewriteReferenceExpression(
608       ExpressionT expression,
609       Scanner::Location location, const char* message, bool* ok);
610
611   // Used to validate property names in object literals and class literals
612   enum PropertyKind {
613     kAccessorProperty,
614     kValueProperty,
615     kMethodProperty
616   };
617
618   class ObjectLiteralCheckerBase {
619    public:
620     explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
621
622     virtual void CheckProperty(Token::Value property, PropertyKind type,
623                                bool is_static, bool is_generator, bool* ok) = 0;
624
625     virtual ~ObjectLiteralCheckerBase() {}
626
627    protected:
628     ParserBase* parser() const { return parser_; }
629     Scanner* scanner() const { return parser_->scanner(); }
630
631    private:
632     ParserBase* parser_;
633   };
634
635   // Validation per ES6 object literals.
636   class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
637    public:
638     explicit ObjectLiteralChecker(ParserBase* parser)
639         : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
640
641     void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
642                        bool is_generator, bool* ok) OVERRIDE;
643
644    private:
645     bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
646
647     bool has_seen_proto_;
648   };
649
650   // Validation per ES6 class literals.
651   class ClassLiteralChecker : public ObjectLiteralCheckerBase {
652    public:
653     explicit ClassLiteralChecker(ParserBase* parser)
654         : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
655
656     void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
657                        bool is_generator, bool* ok) OVERRIDE;
658
659    private:
660     bool IsConstructor() {
661       return this->scanner()->LiteralMatches("constructor", 11);
662     }
663     bool IsPrototype() {
664       return this->scanner()->LiteralMatches("prototype", 9);
665     }
666
667     bool has_seen_constructor_;
668   };
669
670   // If true, the next (and immediately following) function literal is
671   // preceded by a parenthesis.
672   // Heuristically that means that the function will be called immediately,
673   // so never lazily compile it.
674   bool parenthesized_function_;
675
676   Scope* scope_;                   // Scope stack.
677   FunctionState* function_state_;  // Function state stack.
678   v8::Extension* extension_;
679   FuncNameInferrer* fni_;
680   AstValueFactory* ast_value_factory_;  // Not owned.
681   ParserRecorder* log_;
682   Mode mode_;
683   uintptr_t stack_limit_;
684
685  private:
686   Zone* zone_;
687
688   Scanner* scanner_;
689   bool stack_overflow_;
690
691   bool allow_lazy_;
692   bool allow_natives_;
693   bool allow_harmony_arrow_functions_;
694   bool allow_harmony_object_literals_;
695   bool allow_harmony_sloppy_;
696   bool allow_harmony_computed_property_names_;
697   bool allow_harmony_rest_params_;
698   bool allow_strong_mode_;
699 };
700
701
702 class PreParserIdentifier {
703  public:
704   PreParserIdentifier() : type_(kUnknownIdentifier) {}
705   static PreParserIdentifier Default() {
706     return PreParserIdentifier(kUnknownIdentifier);
707   }
708   static PreParserIdentifier Eval() {
709     return PreParserIdentifier(kEvalIdentifier);
710   }
711   static PreParserIdentifier Arguments() {
712     return PreParserIdentifier(kArgumentsIdentifier);
713   }
714   static PreParserIdentifier FutureReserved() {
715     return PreParserIdentifier(kFutureReservedIdentifier);
716   }
717   static PreParserIdentifier FutureStrictReserved() {
718     return PreParserIdentifier(kFutureStrictReservedIdentifier);
719   }
720   static PreParserIdentifier Let() {
721     return PreParserIdentifier(kLetIdentifier);
722   }
723   static PreParserIdentifier Static() {
724     return PreParserIdentifier(kStaticIdentifier);
725   }
726   static PreParserIdentifier Yield() {
727     return PreParserIdentifier(kYieldIdentifier);
728   }
729   static PreParserIdentifier Prototype() {
730     return PreParserIdentifier(kPrototypeIdentifier);
731   }
732   static PreParserIdentifier Constructor() {
733     return PreParserIdentifier(kConstructorIdentifier);
734   }
735   bool IsEval() const { return type_ == kEvalIdentifier; }
736   bool IsArguments() const { return type_ == kArgumentsIdentifier; }
737   bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
738   bool IsLet() const { return type_ == kLetIdentifier; }
739   bool IsStatic() const { return type_ == kStaticIdentifier; }
740   bool IsYield() const { return type_ == kYieldIdentifier; }
741   bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
742   bool IsConstructor() const { return type_ == kConstructorIdentifier; }
743   bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
744   bool IsFutureStrictReserved() const {
745     return type_ == kFutureStrictReservedIdentifier ||
746            type_ == kLetIdentifier || type_ == kStaticIdentifier ||
747            type_ == kYieldIdentifier;
748   }
749   bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; }
750   V8_INLINE bool IsValidArrowParam() const {
751     // A valid identifier can be an arrow function parameter
752     // except for eval, arguments, yield, and reserved keywords.
753     return !(IsEval() || IsArguments() || IsFutureStrictReserved());
754   }
755
756   // Allow identifier->name()[->length()] to work. The preparser
757   // does not need the actual positions/lengths of the identifiers.
758   const PreParserIdentifier* operator->() const { return this; }
759   const PreParserIdentifier raw_name() const { return *this; }
760
761   int position() const { return 0; }
762   int length() const { return 0; }
763
764  private:
765   enum Type {
766     kUnknownIdentifier,
767     kFutureReservedIdentifier,
768     kFutureStrictReservedIdentifier,
769     kLetIdentifier,
770     kStaticIdentifier,
771     kYieldIdentifier,
772     kEvalIdentifier,
773     kArgumentsIdentifier,
774     kPrototypeIdentifier,
775     kConstructorIdentifier
776   };
777   explicit PreParserIdentifier(Type type) : type_(type) {}
778   Type type_;
779
780   friend class PreParserExpression;
781 };
782
783
784 class PreParserExpression {
785  public:
786   static PreParserExpression Default() {
787     return PreParserExpression(TypeField::encode(kExpression));
788   }
789
790   static PreParserExpression FromIdentifier(PreParserIdentifier id) {
791     return PreParserExpression(TypeField::encode(kIdentifierExpression) |
792                                IdentifierTypeField::encode(id.type_));
793   }
794
795   static PreParserExpression BinaryOperation(PreParserExpression left,
796                                              Token::Value op,
797                                              PreParserExpression right) {
798     bool valid_arrow_param_list =
799         op == Token::COMMA && !left.is_parenthesized() &&
800         !right.is_parenthesized() && left.IsValidArrowParams() &&
801         right.IsValidArrowParams();
802     return PreParserExpression(
803         TypeField::encode(kBinaryOperationExpression) |
804         IsValidArrowParamListField::encode(valid_arrow_param_list));
805   }
806
807   static PreParserExpression EmptyArrowParamList() {
808     // Any expression for which IsValidArrowParamList() returns true
809     // will work here.
810     return FromIdentifier(PreParserIdentifier::Default());
811   }
812
813   static PreParserExpression StringLiteral() {
814     return PreParserExpression(TypeField::encode(kStringLiteralExpression));
815   }
816
817   static PreParserExpression UseStrictStringLiteral() {
818     return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
819                                IsUseStrictField::encode(true));
820   }
821
822   static PreParserExpression UseStrongStringLiteral() {
823     return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
824                                IsUseStrongField::encode(true));
825   }
826
827   static PreParserExpression This() {
828     return PreParserExpression(TypeField::encode(kExpression) |
829                                ExpressionTypeField::encode(kThisExpression));
830   }
831
832   static PreParserExpression ThisProperty() {
833     return PreParserExpression(
834         TypeField::encode(kExpression) |
835         ExpressionTypeField::encode(kThisPropertyExpression));
836   }
837
838   static PreParserExpression Property() {
839     return PreParserExpression(
840         TypeField::encode(kExpression) |
841         ExpressionTypeField::encode(kPropertyExpression));
842   }
843
844   static PreParserExpression Call() {
845     return PreParserExpression(TypeField::encode(kExpression) |
846                                ExpressionTypeField::encode(kCallExpression));
847   }
848
849   static PreParserExpression NoTemplateTag() {
850     return PreParserExpression(TypeField::encode(kExpression) |
851                                ExpressionTypeField::encode(
852                                   kNoTemplateTagExpression));
853   }
854
855   bool IsIdentifier() const {
856     return TypeField::decode(code_) == kIdentifierExpression;
857   }
858
859   PreParserIdentifier AsIdentifier() const {
860     DCHECK(IsIdentifier());
861     return PreParserIdentifier(IdentifierTypeField::decode(code_));
862   }
863
864   bool IsStringLiteral() const {
865     return TypeField::decode(code_) == kStringLiteralExpression;
866   }
867
868   bool IsUseStrictLiteral() const {
869     return TypeField::decode(code_) == kStringLiteralExpression &&
870            IsUseStrictField::decode(code_);
871   }
872
873   bool IsUseStrongLiteral() const {
874     return TypeField::decode(code_) == kStringLiteralExpression &&
875            IsUseStrongField::decode(code_);
876   }
877
878   bool IsThis() const {
879     return TypeField::decode(code_) == kExpression &&
880            ExpressionTypeField::decode(code_) == kThisExpression;
881   }
882
883   bool IsThisProperty() const {
884     return TypeField::decode(code_) == kExpression &&
885            ExpressionTypeField::decode(code_) == kThisPropertyExpression;
886   }
887
888   bool IsProperty() const {
889     return TypeField::decode(code_) == kExpression &&
890            (ExpressionTypeField::decode(code_) == kPropertyExpression ||
891             ExpressionTypeField::decode(code_) == kThisPropertyExpression);
892   }
893
894   bool IsCall() const {
895     return TypeField::decode(code_) == kExpression &&
896            ExpressionTypeField::decode(code_) == kCallExpression;
897   }
898
899   bool IsValidReferenceExpression() const {
900     return IsIdentifier() || IsProperty();
901   }
902
903   bool IsValidArrowParamList() const {
904     return IsValidArrowParams() &&
905            ParenthesizationField::decode(code_) !=
906                kMultiParenthesizedExpression;
907   }
908
909   // At the moment PreParser doesn't track these expression types.
910   bool IsFunctionLiteral() const { return false; }
911   bool IsCallNew() const { return false; }
912
913   bool IsNoTemplateTag() const {
914     return TypeField::decode(code_) == kExpression &&
915            ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
916   }
917
918   PreParserExpression AsFunctionLiteral() { return *this; }
919
920   bool IsBinaryOperation() const {
921     return TypeField::decode(code_) == kBinaryOperationExpression;
922   }
923
924   bool is_parenthesized() const {
925     return ParenthesizationField::decode(code_) != kNotParenthesized;
926   }
927
928   void increase_parenthesization_level() {
929     code_ = ParenthesizationField::update(
930         code_, is_parenthesized() ? kMultiParenthesizedExpression
931                                   : kParanthesizedExpression);
932   }
933
934   // Dummy implementation for making expression->somefunc() work in both Parser
935   // and PreParser.
936   PreParserExpression* operator->() { return this; }
937
938   // More dummy implementations of things PreParser doesn't need to track:
939   void set_index(int index) {}  // For YieldExpressions
940   void set_parenthesized() {}
941
942   int position() const { return RelocInfo::kNoPosition; }
943   void set_function_token_position(int position) {}
944
945  private:
946   enum Type {
947     kExpression,
948     kIdentifierExpression,
949     kStringLiteralExpression,
950     kBinaryOperationExpression
951   };
952
953   enum Parenthesization {
954     kNotParenthesized,
955     kParanthesizedExpression,
956     kMultiParenthesizedExpression
957   };
958
959   enum ExpressionType {
960     kThisExpression,
961     kThisPropertyExpression,
962     kPropertyExpression,
963     kCallExpression,
964     kNoTemplateTagExpression
965   };
966
967   explicit PreParserExpression(uint32_t expression_code)
968       : code_(expression_code) {}
969
970   V8_INLINE bool IsValidArrowParams() const {
971     return IsBinaryOperation()
972                ? IsValidArrowParamListField::decode(code_)
973                : (IsIdentifier() && AsIdentifier().IsValidArrowParam());
974   }
975
976   // The first four bits are for the Type and Parenthesization.
977   typedef BitField<Type, 0, 2> TypeField;
978   typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField;
979
980   // The rest of the bits are interpreted depending on the value
981   // of the Type field, so they can share the storage.
982   typedef BitField<ExpressionType, ParenthesizationField::kNext, 3>
983       ExpressionTypeField;
984   typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField;
985   typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
986   typedef BitField<bool, ParenthesizationField::kNext, 1>
987       IsValidArrowParamListField;
988   typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10>
989       IdentifierTypeField;
990
991   uint32_t code_;
992 };
993
994
995 // PreParserExpressionList doesn't actually store the expressions because
996 // PreParser doesn't need to.
997 class PreParserExpressionList {
998  public:
999   // These functions make list->Add(some_expression) work (and do nothing).
1000   PreParserExpressionList() : length_(0) {}
1001   PreParserExpressionList* operator->() { return this; }
1002   void Add(PreParserExpression, void*) { ++length_; }
1003   int length() const { return length_; }
1004  private:
1005   int length_;
1006 };
1007
1008
1009 class PreParserStatement {
1010  public:
1011   static PreParserStatement Default() {
1012     return PreParserStatement(kUnknownStatement);
1013   }
1014
1015   static PreParserStatement FunctionDeclaration() {
1016     return PreParserStatement(kFunctionDeclaration);
1017   }
1018
1019   // Creates expression statement from expression.
1020   // Preserves being an unparenthesized string literal, possibly
1021   // "use strict".
1022   static PreParserStatement ExpressionStatement(
1023       PreParserExpression expression) {
1024     if (expression.IsUseStrictLiteral()) {
1025       return PreParserStatement(kUseStrictExpressionStatement);
1026     }
1027     if (expression.IsUseStrongLiteral()) {
1028       return PreParserStatement(kUseStrongExpressionStatement);
1029     }
1030     if (expression.IsStringLiteral()) {
1031       return PreParserStatement(kStringLiteralExpressionStatement);
1032     }
1033     return Default();
1034   }
1035
1036   bool IsStringLiteral() {
1037     return code_ == kStringLiteralExpressionStatement;
1038   }
1039
1040   bool IsUseStrictLiteral() {
1041     return code_ == kUseStrictExpressionStatement;
1042   }
1043
1044   bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
1045
1046   bool IsFunctionDeclaration() {
1047     return code_ == kFunctionDeclaration;
1048   }
1049
1050  private:
1051   enum Type {
1052     kUnknownStatement,
1053     kStringLiteralExpressionStatement,
1054     kUseStrictExpressionStatement,
1055     kUseStrongExpressionStatement,
1056     kFunctionDeclaration
1057   };
1058
1059   explicit PreParserStatement(Type code) : code_(code) {}
1060   Type code_;
1061 };
1062
1063
1064
1065 // PreParserStatementList doesn't actually store the statements because
1066 // the PreParser does not need them.
1067 class PreParserStatementList {
1068  public:
1069   // These functions make list->Add(some_expression) work as no-ops.
1070   PreParserStatementList() {}
1071   PreParserStatementList* operator->() { return this; }
1072   void Add(PreParserStatement, void*) {}
1073 };
1074
1075
1076 class PreParserFactory {
1077  public:
1078   explicit PreParserFactory(void* unused_value_factory) {}
1079   PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
1080                                        int pos) {
1081     return PreParserExpression::Default();
1082   }
1083   PreParserExpression NewNumberLiteral(double number,
1084                                        int pos) {
1085     return PreParserExpression::Default();
1086   }
1087   PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
1088                                        PreParserIdentifier js_flags,
1089                                        int literal_index,
1090                                        int pos) {
1091     return PreParserExpression::Default();
1092   }
1093   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1094                                       int literal_index,
1095                                       int pos) {
1096     return PreParserExpression::Default();
1097   }
1098   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1099                                                PreParserExpression value,
1100                                                ObjectLiteralProperty::Kind kind,
1101                                                bool is_static,
1102                                                bool is_computed_name) {
1103     return PreParserExpression::Default();
1104   }
1105   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1106                                                PreParserExpression value,
1107                                                bool is_static,
1108                                                bool is_computed_name) {
1109     return PreParserExpression::Default();
1110   }
1111   PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
1112                                        int literal_index,
1113                                        int boilerplate_properties,
1114                                        bool has_function,
1115                                        int pos) {
1116     return PreParserExpression::Default();
1117   }
1118   PreParserExpression NewVariableProxy(void* variable) {
1119     return PreParserExpression::Default();
1120   }
1121   PreParserExpression NewProperty(PreParserExpression obj,
1122                                   PreParserExpression key,
1123                                   int pos) {
1124     if (obj.IsThis()) {
1125       return PreParserExpression::ThisProperty();
1126     }
1127     return PreParserExpression::Property();
1128   }
1129   PreParserExpression NewUnaryOperation(Token::Value op,
1130                                         PreParserExpression expression,
1131                                         int pos) {
1132     return PreParserExpression::Default();
1133   }
1134   PreParserExpression NewBinaryOperation(Token::Value op,
1135                                          PreParserExpression left,
1136                                          PreParserExpression right, int pos) {
1137     return PreParserExpression::BinaryOperation(left, op, right);
1138   }
1139   PreParserExpression NewCompareOperation(Token::Value op,
1140                                           PreParserExpression left,
1141                                           PreParserExpression right, int pos) {
1142     return PreParserExpression::Default();
1143   }
1144   PreParserExpression NewAssignment(Token::Value op,
1145                                     PreParserExpression left,
1146                                     PreParserExpression right,
1147                                     int pos) {
1148     return PreParserExpression::Default();
1149   }
1150   PreParserExpression NewYield(PreParserExpression generator_object,
1151                                PreParserExpression expression,
1152                                Yield::Kind yield_kind,
1153                                int pos) {
1154     return PreParserExpression::Default();
1155   }
1156   PreParserExpression NewConditional(PreParserExpression condition,
1157                                      PreParserExpression then_expression,
1158                                      PreParserExpression else_expression,
1159                                      int pos) {
1160     return PreParserExpression::Default();
1161   }
1162   PreParserExpression NewCountOperation(Token::Value op,
1163                                         bool is_prefix,
1164                                         PreParserExpression expression,
1165                                         int pos) {
1166     return PreParserExpression::Default();
1167   }
1168   PreParserExpression NewCall(PreParserExpression expression,
1169                               PreParserExpressionList arguments,
1170                               int pos) {
1171     return PreParserExpression::Call();
1172   }
1173   PreParserExpression NewCallNew(PreParserExpression expression,
1174                                  PreParserExpressionList arguments,
1175                                  int pos) {
1176     return PreParserExpression::Default();
1177   }
1178   PreParserStatement NewReturnStatement(PreParserExpression expression,
1179                                         int pos) {
1180     return PreParserStatement::Default();
1181   }
1182   PreParserExpression NewFunctionLiteral(
1183       PreParserIdentifier name, AstValueFactory* ast_value_factory,
1184       Scope* scope, PreParserStatementList body, int materialized_literal_count,
1185       int expected_property_count, int handler_count, int parameter_count,
1186       FunctionLiteral::ParameterFlag has_duplicate_parameters,
1187       FunctionLiteral::FunctionType function_type,
1188       FunctionLiteral::IsFunctionFlag is_function,
1189       FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
1190       int position) {
1191     return PreParserExpression::Default();
1192   }
1193
1194   // Return the object itself as AstVisitor and implement the needed
1195   // dummy method right in this class.
1196   PreParserFactory* visitor() { return this; }
1197   int* ast_properties() {
1198     static int dummy = 42;
1199     return &dummy;
1200   }
1201 };
1202
1203
1204 class PreParser;
1205
1206 class PreParserTraits {
1207  public:
1208   struct Type {
1209     // TODO(marja): To be removed. The Traits object should contain all the data
1210     // it needs.
1211     typedef PreParser* Parser;
1212
1213     // PreParser doesn't need to store generator variables.
1214     typedef void GeneratorVariable;
1215
1216     typedef int AstProperties;
1217
1218     // Return types for traversing functions.
1219     typedef PreParserIdentifier Identifier;
1220     typedef PreParserExpression Expression;
1221     typedef PreParserExpression YieldExpression;
1222     typedef PreParserExpression FunctionLiteral;
1223     typedef PreParserExpression ClassLiteral;
1224     typedef PreParserExpression ObjectLiteralProperty;
1225     typedef PreParserExpression Literal;
1226     typedef PreParserExpressionList ExpressionList;
1227     typedef PreParserExpressionList PropertyList;
1228     typedef PreParserStatementList StatementList;
1229
1230     // For constructing objects returned by the traversing functions.
1231     typedef PreParserFactory Factory;
1232   };
1233
1234   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
1235
1236   // Helper functions for recursive descent.
1237   static bool IsEval(PreParserIdentifier identifier) {
1238     return identifier.IsEval();
1239   }
1240
1241   static bool IsArguments(PreParserIdentifier identifier) {
1242     return identifier.IsArguments();
1243   }
1244
1245   static bool IsEvalOrArguments(PreParserIdentifier identifier) {
1246     return identifier.IsEvalOrArguments();
1247   }
1248
1249   static bool IsPrototype(PreParserIdentifier identifier) {
1250     return identifier.IsPrototype();
1251   }
1252
1253   static bool IsConstructor(PreParserIdentifier identifier) {
1254     return identifier.IsConstructor();
1255   }
1256
1257   // Returns true if the expression is of type "this.foo".
1258   static bool IsThisProperty(PreParserExpression expression) {
1259     return expression.IsThisProperty();
1260   }
1261
1262   static bool IsIdentifier(PreParserExpression expression) {
1263     return expression.IsIdentifier();
1264   }
1265
1266   static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
1267     return expression.AsIdentifier();
1268   }
1269
1270   static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1271     return identifier.IsFutureStrictReserved();
1272   }
1273
1274   static bool IsBoilerplateProperty(PreParserExpression property) {
1275     // PreParser doesn't count boilerplate properties.
1276     return false;
1277   }
1278
1279   static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
1280     return false;
1281   }
1282
1283   static PreParserExpression GetPropertyValue(PreParserExpression property) {
1284     return PreParserExpression::Default();
1285   }
1286
1287   // Functions for encapsulating the differences between parsing and preparsing;
1288   // operations interleaved with the recursive descent.
1289   static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1290     // PreParser should not use FuncNameInferrer.
1291     UNREACHABLE();
1292   }
1293
1294   static void PushPropertyName(FuncNameInferrer* fni,
1295                                PreParserExpression expression) {
1296     // PreParser should not use FuncNameInferrer.
1297     UNREACHABLE();
1298   }
1299
1300   static void InferFunctionName(FuncNameInferrer* fni,
1301                                 PreParserExpression expression) {
1302     // PreParser should not use FuncNameInferrer.
1303     UNREACHABLE();
1304   }
1305
1306   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
1307       Scope* scope, PreParserExpression property, bool* has_function) {}
1308
1309   static void CheckAssigningFunctionLiteralToProperty(
1310       PreParserExpression left, PreParserExpression right) {}
1311
1312   // PreParser doesn't need to keep track of eval calls.
1313   static void CheckPossibleEvalCall(PreParserExpression expression,
1314                                     Scope* scope) {}
1315
1316   static PreParserExpression MarkExpressionAsAssigned(
1317       PreParserExpression expression) {
1318     // TODO(marja): To be able to produce the same errors, the preparser needs
1319     // to start tracking which expressions are variables and which are assigned.
1320     return expression;
1321   }
1322
1323   bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
1324                                               PreParserExpression y,
1325                                               Token::Value op,
1326                                               int pos,
1327                                               PreParserFactory* factory) {
1328     return false;
1329   }
1330
1331   PreParserExpression BuildUnaryExpression(PreParserExpression expression,
1332                                            Token::Value op, int pos,
1333                                            PreParserFactory* factory) {
1334     return PreParserExpression::Default();
1335   }
1336
1337   PreParserExpression NewThrowReferenceError(const char* type, int pos) {
1338     return PreParserExpression::Default();
1339   }
1340   PreParserExpression NewThrowSyntaxError(
1341       const char* type, Handle<Object> arg, int pos) {
1342     return PreParserExpression::Default();
1343   }
1344   PreParserExpression NewThrowTypeError(
1345       const char* type, Handle<Object> arg, int pos) {
1346     return PreParserExpression::Default();
1347   }
1348
1349   // Reporting errors.
1350   void ReportMessageAt(Scanner::Location location, const char* message,
1351                        const char* arg = NULL,
1352                        ParseErrorType error_type = kSyntaxError);
1353   void ReportMessageAt(int start_pos, int end_pos, const char* message,
1354                        const char* arg = NULL,
1355                        ParseErrorType error_type = kSyntaxError);
1356
1357   // "null" return type creators.
1358   static PreParserIdentifier EmptyIdentifier() {
1359     return PreParserIdentifier::Default();
1360   }
1361   static PreParserIdentifier EmptyIdentifierString() {
1362     return PreParserIdentifier::Default();
1363   }
1364   static PreParserExpression EmptyExpression() {
1365     return PreParserExpression::Default();
1366   }
1367   static PreParserExpression EmptyArrowParamList() {
1368     return PreParserExpression::EmptyArrowParamList();
1369   }
1370   static PreParserExpression EmptyLiteral() {
1371     return PreParserExpression::Default();
1372   }
1373   static PreParserExpression EmptyObjectLiteralProperty() {
1374     return PreParserExpression::Default();
1375   }
1376   static PreParserExpression EmptyFunctionLiteral() {
1377     return PreParserExpression::Default();
1378   }
1379   static PreParserExpressionList NullExpressionList() {
1380     return PreParserExpressionList();
1381   }
1382
1383   // Odd-ball literal creators.
1384   static PreParserExpression GetLiteralTheHole(int position,
1385                                                PreParserFactory* factory) {
1386     return PreParserExpression::Default();
1387   }
1388
1389   // Producing data during the recursive descent.
1390   PreParserIdentifier GetSymbol(Scanner* scanner);
1391   PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
1392
1393   static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1394     return PreParserIdentifier::Default();
1395   }
1396
1397   static PreParserExpression ThisExpression(Scope* scope,
1398                                             PreParserFactory* factory,
1399                                             int pos) {
1400     return PreParserExpression::This();
1401   }
1402
1403   static PreParserExpression SuperReference(Scope* scope,
1404                                             PreParserFactory* factory) {
1405     return PreParserExpression::Default();
1406   }
1407
1408   static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
1409                                                 int pos, int end_pos) {
1410     return PreParserExpression::Default();
1411   }
1412
1413   static PreParserExpression ExpressionFromLiteral(
1414       Token::Value token, int pos, Scanner* scanner,
1415       PreParserFactory* factory) {
1416     return PreParserExpression::Default();
1417   }
1418
1419   static PreParserExpression ExpressionFromIdentifier(
1420       PreParserIdentifier name, int start_position, int end_position,
1421       Scope* scope, PreParserFactory* factory) {
1422     return PreParserExpression::FromIdentifier(name);
1423   }
1424
1425   PreParserExpression ExpressionFromString(int pos,
1426                                            Scanner* scanner,
1427                                            PreParserFactory* factory = NULL);
1428
1429   PreParserExpression GetIterator(PreParserExpression iterable,
1430                                   PreParserFactory* factory) {
1431     return PreParserExpression::Default();
1432   }
1433
1434   static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
1435     return PreParserExpressionList();
1436   }
1437
1438   static PreParserStatementList NewStatementList(int size, Zone* zone) {
1439     return PreParserStatementList();
1440   }
1441
1442   static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
1443     return PreParserExpressionList();
1444   }
1445
1446   V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
1447                                       int* materialized_literal_count,
1448                                       int* expected_property_count, bool* ok) {
1449     UNREACHABLE();
1450   }
1451
1452   V8_INLINE PreParserStatementList
1453   ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
1454                          Variable* fvar, Token::Value fvar_init_op,
1455                          FunctionKind kind, bool* ok);
1456
1457   // Utility functions
1458   int DeclareArrowParametersFromExpression(PreParserExpression expression,
1459                                            Scope* scope,
1460                                            Scanner::Location* dupe_loc,
1461                                            bool* ok) {
1462     // TODO(aperez): Detect duplicated identifiers in paramlists.
1463     *ok = expression.IsValidArrowParamList();
1464     return 0;
1465   }
1466
1467   struct TemplateLiteralState {};
1468
1469   TemplateLiteralState OpenTemplateLiteral(int pos) {
1470     return TemplateLiteralState();
1471   }
1472   void AddTemplateSpan(TemplateLiteralState*, bool) {}
1473   void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
1474   PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
1475                                            PreParserExpression tag) {
1476     if (IsTaggedTemplate(tag)) {
1477       // Emulate generation of array literals for tag callsite
1478       // 1st is array of cooked strings, second is array of raw strings
1479       MaterializeTemplateCallsiteLiterals();
1480     }
1481     return EmptyExpression();
1482   }
1483   inline void MaterializeTemplateCallsiteLiterals();
1484   PreParserExpression NoTemplateTag() {
1485     return PreParserExpression::NoTemplateTag();
1486   }
1487   static bool IsTaggedTemplate(const PreParserExpression tag) {
1488     return !tag.IsNoTemplateTag();
1489   }
1490
1491   void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
1492
1493   // Temporary glue; these functions will move to ParserBase.
1494   PreParserExpression ParseV8Intrinsic(bool* ok);
1495   PreParserExpression ParseFunctionLiteral(
1496       PreParserIdentifier name, Scanner::Location function_name_location,
1497       bool name_is_strict_reserved, FunctionKind kind,
1498       int function_token_position, FunctionLiteral::FunctionType type,
1499       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
1500
1501   PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1502                                         Scanner::Location class_name_location,
1503                                         bool name_is_strict_reserved, int pos,
1504                                         bool* ok);
1505
1506  private:
1507   PreParser* pre_parser_;
1508 };
1509
1510
1511 // Preparsing checks a JavaScript program and emits preparse-data that helps
1512 // a later parsing to be faster.
1513 // See preparse-data-format.h for the data format.
1514
1515 // The PreParser checks that the syntax follows the grammar for JavaScript,
1516 // and collects some information about the program along the way.
1517 // The grammar check is only performed in order to understand the program
1518 // sufficiently to deduce some information about it, that can be used
1519 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
1520 // rather it is to speed up properly written and correct programs.
1521 // That means that contextual checks (like a label being declared where
1522 // it is used) are generally omitted.
1523 class PreParser : public ParserBase<PreParserTraits> {
1524  public:
1525   typedef PreParserIdentifier Identifier;
1526   typedef PreParserExpression Expression;
1527   typedef PreParserStatement Statement;
1528
1529   enum PreParseResult {
1530     kPreParseStackOverflow,
1531     kPreParseSuccess
1532   };
1533
1534   PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
1535             ParserRecorder* log, uintptr_t stack_limit)
1536       : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
1537                                     ast_value_factory, log, this) {}
1538
1539   // Pre-parse the program from the character stream; returns true on
1540   // success (even if parsing failed, the pre-parse data successfully
1541   // captured the syntax error), and false if a stack-overflow happened
1542   // during parsing.
1543   PreParseResult PreParseProgram(int* materialized_literals = 0) {
1544     Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1545     PreParserFactory factory(NULL);
1546     FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
1547                             &factory);
1548     bool ok = true;
1549     int start_position = scanner()->peek_location().beg_pos;
1550     ParseStatementList(Token::EOS, &ok);
1551     if (stack_overflow()) return kPreParseStackOverflow;
1552     if (!ok) {
1553       ReportUnexpectedToken(scanner()->current_token());
1554     } else if (is_strict(scope_->language_mode())) {
1555       CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
1556                               &ok);
1557     }
1558     if (materialized_literals) {
1559       *materialized_literals = function_state_->materialized_literal_count();
1560     }
1561     return kPreParseSuccess;
1562   }
1563
1564   // Parses a single function literal, from the opening parentheses before
1565   // parameters to the closing brace after the body.
1566   // Returns a FunctionEntry describing the body of the function in enough
1567   // detail that it can be lazily compiled.
1568   // The scanner is expected to have matched the "function" or "function*"
1569   // keyword and parameters, and have consumed the initial '{'.
1570   // At return, unless an error occurred, the scanner is positioned before the
1571   // the final '}'.
1572   PreParseResult PreParseLazyFunction(LanguageMode language_mode,
1573                                       FunctionKind kind, ParserRecorder* log);
1574
1575  private:
1576   friend class PreParserTraits;
1577
1578   // These types form an algebra over syntactic categories that is just
1579   // rich enough to let us recognize and propagate the constructs that
1580   // are either being counted in the preparser data, or is important
1581   // to throw the correct syntax error exceptions.
1582
1583   // All ParseXXX functions take as the last argument an *ok parameter
1584   // which is set to false if parsing failed; it is unchanged otherwise.
1585   // By making the 'exception handling' explicit, we are forced to check
1586   // for failure at the call sites.
1587   Statement ParseStatementListItem(bool* ok);
1588   void ParseStatementList(int end_token, bool* ok);
1589   Statement ParseStatement(bool* ok);
1590   Statement ParseSubStatement(bool* ok);
1591   Statement ParseFunctionDeclaration(bool* ok);
1592   Statement ParseClassDeclaration(bool* ok);
1593   Statement ParseBlock(bool* ok);
1594   Statement ParseVariableStatement(VariableDeclarationContext var_context,
1595                                    bool* ok);
1596   Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1597                                       VariableDeclarationProperties* decl_props,
1598                                       int* num_decl,
1599                                       bool* ok);
1600   Statement ParseExpressionOrLabelledStatement(bool* ok);
1601   Statement ParseIfStatement(bool* ok);
1602   Statement ParseContinueStatement(bool* ok);
1603   Statement ParseBreakStatement(bool* ok);
1604   Statement ParseReturnStatement(bool* ok);
1605   Statement ParseWithStatement(bool* ok);
1606   Statement ParseSwitchStatement(bool* ok);
1607   Statement ParseDoWhileStatement(bool* ok);
1608   Statement ParseWhileStatement(bool* ok);
1609   Statement ParseForStatement(bool* ok);
1610   Statement ParseThrowStatement(bool* ok);
1611   Statement ParseTryStatement(bool* ok);
1612   Statement ParseDebuggerStatement(bool* ok);
1613   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1614   Expression ParseObjectLiteral(bool* ok);
1615   Expression ParseV8Intrinsic(bool* ok);
1616
1617   V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
1618                                       int* materialized_literal_count,
1619                                       int* expected_property_count, bool* ok);
1620   V8_INLINE PreParserStatementList
1621   ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
1622                          Variable* fvar, Token::Value fvar_init_op,
1623                          FunctionKind kind, bool* ok);
1624
1625   Expression ParseFunctionLiteral(
1626       Identifier name, Scanner::Location function_name_location,
1627       bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
1628       FunctionLiteral::FunctionType function_type,
1629       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
1630   void ParseLazyFunctionLiteralBody(bool* ok);
1631
1632   PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1633                                         Scanner::Location class_name_location,
1634                                         bool name_is_strict_reserved, int pos,
1635                                         bool* ok);
1636 };
1637
1638
1639 void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1640   pre_parser_->function_state_->NextMaterializedLiteralIndex();
1641   pre_parser_->function_state_->NextMaterializedLiteralIndex();
1642 }
1643
1644
1645 PreParserStatementList PreParser::ParseEagerFunctionBody(
1646     PreParserIdentifier function_name, int pos, Variable* fvar,
1647     Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
1648   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1649
1650   ParseStatementList(Token::RBRACE, ok);
1651   if (!*ok) return PreParserStatementList();
1652
1653   Expect(Token::RBRACE, ok);
1654   return PreParserStatementList();
1655 }
1656
1657
1658 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1659     PreParserIdentifier function_name, int pos, Variable* fvar,
1660     Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
1661   return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar,
1662                                              fvar_init_op, kind, ok);
1663 }
1664
1665
1666 template <class Traits>
1667 ParserBase<Traits>::FunctionState::FunctionState(
1668     FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1669     FunctionKind kind, typename Traits::Type::Factory* factory)
1670     : next_materialized_literal_index_(0),
1671       next_handler_index_(0),
1672       expected_property_count_(0),
1673       return_location_(Scanner::Location::invalid()),
1674       super_call_location_(Scanner::Location::invalid()),
1675       kind_(kind),
1676       generator_object_variable_(NULL),
1677       function_state_stack_(function_state_stack),
1678       outer_function_state_(*function_state_stack),
1679       scope_stack_(scope_stack),
1680       outer_scope_(*scope_stack),
1681       factory_(factory) {
1682   *scope_stack_ = scope;
1683   *function_state_stack = this;
1684 }
1685
1686
1687 template <class Traits>
1688 ParserBase<Traits>::FunctionState::~FunctionState() {
1689   *scope_stack_ = outer_scope_;
1690   *function_state_stack_ = outer_function_state_;
1691 }
1692
1693
1694 template<class Traits>
1695 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1696   return ReportUnexpectedTokenAt(scanner_->location(), token);
1697 }
1698
1699
1700 template<class Traits>
1701 void ParserBase<Traits>::ReportUnexpectedTokenAt(
1702     Scanner::Location source_location, Token::Value token) {
1703
1704   // Four of the tokens are treated specially
1705   switch (token) {
1706     case Token::EOS:
1707       return ReportMessageAt(source_location, "unexpected_eos");
1708     case Token::SMI:
1709     case Token::NUMBER:
1710       return ReportMessageAt(source_location, "unexpected_token_number");
1711     case Token::STRING:
1712       return ReportMessageAt(source_location, "unexpected_token_string");
1713     case Token::IDENTIFIER:
1714       return ReportMessageAt(source_location, "unexpected_token_identifier");
1715     case Token::FUTURE_RESERVED_WORD:
1716       return ReportMessageAt(source_location, "unexpected_reserved");
1717     case Token::LET:
1718     case Token::STATIC:
1719     case Token::YIELD:
1720     case Token::FUTURE_STRICT_RESERVED_WORD:
1721       return ReportMessageAt(source_location,
1722                              is_strict(language_mode())
1723                                  ? "unexpected_strict_reserved"
1724                                  : "unexpected_token_identifier");
1725     case Token::TEMPLATE_SPAN:
1726     case Token::TEMPLATE_TAIL:
1727       return Traits::ReportMessageAt(source_location,
1728           "unexpected_template_string");
1729     default:
1730       const char* name = Token::String(token);
1731       DCHECK(name != NULL);
1732       Traits::ReportMessageAt(source_location, "unexpected_token", name);
1733   }
1734 }
1735
1736
1737 template<class Traits>
1738 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1739     AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1740     bool* ok) {
1741   Token::Value next = Next();
1742   if (next == Token::IDENTIFIER) {
1743     IdentifierT name = this->GetSymbol(scanner());
1744     if (allow_eval_or_arguments == kDontAllowEvalOrArguments) {
1745       if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) {
1746         ReportMessage("strict_eval_arguments");
1747         *ok = false;
1748       }
1749     } else {
1750       if (is_strong(language_mode()) && this->IsArguments(name)) {
1751         ReportMessage("strong_arguments");
1752         *ok = false;
1753       }
1754     }
1755     if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1756     return name;
1757   } else if (is_sloppy(language_mode()) &&
1758              (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1759               next == Token::LET || next == Token::STATIC ||
1760               (next == Token::YIELD && !is_generator()))) {
1761     return this->GetSymbol(scanner());
1762   } else {
1763     this->ReportUnexpectedToken(next);
1764     *ok = false;
1765     return Traits::EmptyIdentifier();
1766   }
1767 }
1768
1769
1770 template <class Traits>
1771 typename ParserBase<Traits>::IdentifierT ParserBase<
1772     Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1773                                                  bool* ok) {
1774   Token::Value next = Next();
1775   if (next == Token::IDENTIFIER) {
1776     *is_strict_reserved = false;
1777   } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1778              next == Token::STATIC ||
1779              (next == Token::YIELD && !this->is_generator())) {
1780     *is_strict_reserved = true;
1781   } else {
1782     ReportUnexpectedToken(next);
1783     *ok = false;
1784     return Traits::EmptyIdentifier();
1785   }
1786
1787   IdentifierT name = this->GetSymbol(scanner());
1788   if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1789   return name;
1790 }
1791
1792
1793 template <class Traits>
1794 typename ParserBase<Traits>::IdentifierT
1795 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1796   Token::Value next = Next();
1797   if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
1798       next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
1799       next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1800     this->ReportUnexpectedToken(next);
1801     *ok = false;
1802     return Traits::EmptyIdentifier();
1803   }
1804
1805   IdentifierT name = this->GetSymbol(scanner());
1806   if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1807   return name;
1808 }
1809
1810
1811 template <class Traits>
1812 typename ParserBase<Traits>::IdentifierT
1813 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
1814                                                   bool* is_set,
1815                                                   bool* ok) {
1816   IdentifierT result = ParseIdentifierName(ok);
1817   if (!*ok) return Traits::EmptyIdentifier();
1818   scanner()->IsGetOrSet(is_get, is_set);
1819   return result;
1820 }
1821
1822
1823 template <class Traits>
1824 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1825     bool seen_equal, bool* ok) {
1826   int pos = peek_position();
1827   if (!scanner()->ScanRegExpPattern(seen_equal)) {
1828     Next();
1829     ReportMessage("unterminated_regexp");
1830     *ok = false;
1831     return Traits::EmptyExpression();
1832   }
1833
1834   int literal_index = function_state_->NextMaterializedLiteralIndex();
1835
1836   IdentifierT js_pattern = this->GetNextSymbol(scanner());
1837   if (!scanner()->ScanRegExpFlags()) {
1838     Next();
1839     ReportMessage("malformed_regexp_flags");
1840     *ok = false;
1841     return Traits::EmptyExpression();
1842   }
1843   IdentifierT js_flags = this->GetNextSymbol(scanner());
1844   Next();
1845   return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1846 }
1847
1848
1849 #define CHECK_OK  ok); \
1850   if (!*ok) return this->EmptyExpression(); \
1851   ((void)0
1852 #define DUMMY )  // to make indentation work
1853 #undef DUMMY
1854
1855 // Used in functions where the return type is not ExpressionT.
1856 #define CHECK_OK_CUSTOM(x) ok); \
1857   if (!*ok) return this->x(); \
1858   ((void)0
1859 #define DUMMY )  // to make indentation work
1860 #undef DUMMY
1861
1862 template <class Traits>
1863 typename ParserBase<Traits>::ExpressionT
1864 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
1865   // PrimaryExpression ::
1866   //   'this'
1867   //   'null'
1868   //   'true'
1869   //   'false'
1870   //   Identifier
1871   //   Number
1872   //   String
1873   //   ArrayLiteral
1874   //   ObjectLiteral
1875   //   RegExpLiteral
1876   //   ClassLiteral
1877   //   '(' Expression ')'
1878   //   TemplateLiteral
1879
1880   int beg_pos = scanner()->peek_location().beg_pos;
1881   int end_pos = scanner()->peek_location().end_pos;
1882   ExpressionT result = this->EmptyExpression();
1883   Token::Value token = peek();
1884   switch (token) {
1885     case Token::THIS: {
1886       Consume(Token::THIS);
1887       scope_->RecordThisUsage();
1888       result = this->ThisExpression(scope_, factory(), beg_pos);
1889       break;
1890     }
1891
1892     case Token::NULL_LITERAL:
1893     case Token::TRUE_LITERAL:
1894     case Token::FALSE_LITERAL:
1895     case Token::SMI:
1896     case Token::NUMBER:
1897       Next();
1898       result =
1899           this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
1900       break;
1901
1902     case Token::IDENTIFIER:
1903     case Token::LET:
1904     case Token::STATIC:
1905     case Token::YIELD:
1906     case Token::FUTURE_STRICT_RESERVED_WORD: {
1907       // Using eval or arguments in this context is OK even in strict mode.
1908       IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1909       result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
1910                                               factory());
1911       break;
1912     }
1913
1914     case Token::STRING: {
1915       Consume(Token::STRING);
1916       result = this->ExpressionFromString(beg_pos, scanner(), factory());
1917       break;
1918     }
1919
1920     case Token::ASSIGN_DIV:
1921       result = this->ParseRegExpLiteral(true, CHECK_OK);
1922       break;
1923
1924     case Token::DIV:
1925       result = this->ParseRegExpLiteral(false, CHECK_OK);
1926       break;
1927
1928     case Token::LBRACK:
1929       result = this->ParseArrayLiteral(CHECK_OK);
1930       break;
1931
1932     case Token::LBRACE:
1933       result = this->ParseObjectLiteral(CHECK_OK);
1934       break;
1935
1936     case Token::LPAREN:
1937       Consume(Token::LPAREN);
1938       if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) {
1939         // Arrow functions are the only expression type constructions
1940         // for which an empty parameter list "()" is valid input.
1941         Consume(Token::RPAREN);
1942         result = this->ParseArrowFunctionLiteral(
1943             beg_pos, this->EmptyArrowParamList(), CHECK_OK);
1944       } else {
1945         // Heuristically try to detect immediately called functions before
1946         // seeing the call parentheses.
1947         parenthesized_function_ = (peek() == Token::FUNCTION);
1948         result = this->ParseExpression(true, CHECK_OK);
1949         result->increase_parenthesization_level();
1950         Expect(Token::RPAREN, CHECK_OK);
1951       }
1952       break;
1953
1954     case Token::CLASS: {
1955       Consume(Token::CLASS);
1956       if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
1957         ReportMessage("sloppy_lexical", NULL);
1958         *ok = false;
1959         break;
1960       }
1961       int class_token_position = position();
1962       IdentifierT name = this->EmptyIdentifier();
1963       bool is_strict_reserved_name = false;
1964       Scanner::Location class_name_location = Scanner::Location::invalid();
1965       if (peek_any_identifier()) {
1966         name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1967                                                    CHECK_OK);
1968         class_name_location = scanner()->location();
1969       }
1970       result = this->ParseClassLiteral(name, class_name_location,
1971                                        is_strict_reserved_name,
1972                                        class_token_position, CHECK_OK);
1973       break;
1974     }
1975
1976     case Token::TEMPLATE_SPAN:
1977     case Token::TEMPLATE_TAIL:
1978       result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
1979                                           CHECK_OK);
1980       break;
1981
1982     case Token::MOD:
1983       if (allow_natives() || extension_ != NULL) {
1984         result = this->ParseV8Intrinsic(CHECK_OK);
1985         break;
1986       }
1987       // If we're not allowing special syntax we fall-through to the
1988       // default case.
1989
1990     default: {
1991       Next();
1992       ReportUnexpectedToken(token);
1993       *ok = false;
1994     }
1995   }
1996
1997   return result;
1998 }
1999
2000 // Precedence = 1
2001 template <class Traits>
2002 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2003     bool accept_IN, bool* ok) {
2004   // Expression ::
2005   //   AssignmentExpression
2006   //   Expression ',' AssignmentExpression
2007
2008   ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
2009   while (peek() == Token::COMMA) {
2010     Expect(Token::COMMA, CHECK_OK);
2011     int pos = position();
2012     ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
2013     result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2014   }
2015   return result;
2016 }
2017
2018
2019 template <class Traits>
2020 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2021     bool* ok) {
2022   // ArrayLiteral ::
2023   //   '[' Expression? (',' Expression?)* ']'
2024
2025   int pos = peek_position();
2026   typename Traits::Type::ExpressionList values =
2027       this->NewExpressionList(4, zone_);
2028   Expect(Token::LBRACK, CHECK_OK);
2029   while (peek() != Token::RBRACK) {
2030     ExpressionT elem = this->EmptyExpression();
2031     if (peek() == Token::COMMA) {
2032       if (is_strong(language_mode())) {
2033         ReportMessageAt(scanner()->peek_location(), "strong_ellision");
2034         *ok = false;
2035         return this->EmptyExpression();
2036       }
2037       elem = this->GetLiteralTheHole(peek_position(), factory());
2038     } else {
2039       elem = this->ParseAssignmentExpression(true, CHECK_OK);
2040     }
2041     values->Add(elem, zone_);
2042     if (peek() != Token::RBRACK) {
2043       Expect(Token::COMMA, CHECK_OK);
2044     }
2045   }
2046   Expect(Token::RBRACK, CHECK_OK);
2047
2048   // Update the scope information before the pre-parsing bailout.
2049   int literal_index = function_state_->NextMaterializedLiteralIndex();
2050
2051   return factory()->NewArrayLiteral(values, literal_index, pos);
2052 }
2053
2054
2055 template <class Traits>
2056 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2057     IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2058     bool* is_computed_name, bool* ok) {
2059   Token::Value token = peek();
2060   int pos = peek_position();
2061
2062   // For non computed property names we normalize the name a bit:
2063   //
2064   //   "12" -> 12
2065   //   12.3 -> "12.3"
2066   //   12.30 -> "12.3"
2067   //   identifier -> "identifier"
2068   //
2069   // This is important because we use the property name as a key in a hash
2070   // table when we compute constant properties.
2071   switch (token) {
2072     case Token::STRING:
2073       Consume(Token::STRING);
2074       *name = this->GetSymbol(scanner());
2075       break;
2076
2077     case Token::SMI:
2078       Consume(Token::SMI);
2079       *name = this->GetNumberAsSymbol(scanner());
2080       break;
2081
2082     case Token::NUMBER:
2083       Consume(Token::NUMBER);
2084       *name = this->GetNumberAsSymbol(scanner());
2085       break;
2086
2087     case Token::LBRACK:
2088       if (allow_harmony_computed_property_names_) {
2089         *is_computed_name = true;
2090         Consume(Token::LBRACK);
2091         ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2092         Expect(Token::RBRACK, CHECK_OK);
2093         return expression;
2094       }
2095
2096     // Fall through.
2097     case Token::STATIC:
2098       *is_static = true;
2099
2100     // Fall through.
2101     default:
2102       *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2103       break;
2104   }
2105
2106   uint32_t index;
2107   return this->IsArrayIndex(*name, &index)
2108              ? factory()->NewNumberLiteral(index, pos)
2109              : factory()->NewStringLiteral(*name, pos);
2110 }
2111
2112
2113 template <class Traits>
2114 typename ParserBase<Traits>::ObjectLiteralPropertyT
2115 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
2116                                             bool in_class, bool has_extends,
2117                                             bool is_static,
2118                                             bool* is_computed_name,
2119                                             bool* has_seen_constructor,
2120                                             bool* ok) {
2121   DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2122   ExpressionT value = this->EmptyExpression();
2123   IdentifierT name = this->EmptyIdentifier();
2124   bool is_get = false;
2125   bool is_set = false;
2126   bool name_is_static = false;
2127   bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
2128
2129   Token::Value name_token = peek();
2130   int next_beg_pos = scanner()->peek_location().beg_pos;
2131   int next_end_pos = scanner()->peek_location().end_pos;
2132   ExpressionT name_expression = ParsePropertyName(
2133       &name, &is_get, &is_set, &name_is_static, is_computed_name,
2134       CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2135
2136   if (fni_ != nullptr && !*is_computed_name) {
2137     this->PushLiteralName(fni_, name);
2138   }
2139
2140   if (!in_class && !is_generator && peek() == Token::COLON) {
2141     // PropertyDefinition : PropertyName ':' AssignmentExpression
2142     if (!*is_computed_name) {
2143       checker->CheckProperty(name_token, kValueProperty, is_static,
2144                              is_generator,
2145                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2146     }
2147     Consume(Token::COLON);
2148     value = this->ParseAssignmentExpression(
2149         true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2150
2151   } else if (is_generator ||
2152              (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
2153     // Concise Method
2154     if (!*is_computed_name) {
2155       checker->CheckProperty(name_token, kMethodProperty, is_static,
2156                              is_generator,
2157                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2158     }
2159
2160     FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2161                                      : FunctionKind::kConciseMethod;
2162
2163     if (in_class && !is_static && this->IsConstructor(name)) {
2164       *has_seen_constructor = true;
2165       kind = has_extends ? FunctionKind::kSubclassConstructor
2166                          : FunctionKind::kBaseConstructor;
2167     }
2168
2169     if (!in_class) kind = WithObjectLiteralBit(kind);
2170
2171     value = this->ParseFunctionLiteral(
2172         name, scanner()->location(),
2173         false,  // reserved words are allowed here
2174         kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2175         FunctionLiteral::NORMAL_ARITY,
2176         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2177
2178     return factory()->NewObjectLiteralProperty(name_expression, value,
2179                                                ObjectLiteralProperty::COMPUTED,
2180                                                is_static, *is_computed_name);
2181
2182   } else if (in_class && name_is_static && !is_static) {
2183     // static MethodDefinition
2184     return ParsePropertyDefinition(checker, true, has_extends, true,
2185                                    is_computed_name, nullptr, ok);
2186   } else if (is_get || is_set) {
2187     // Accessor
2188     name = this->EmptyIdentifier();
2189     bool dont_care = false;
2190     name_token = peek();
2191
2192     name_expression = ParsePropertyName(
2193         &name, &dont_care, &dont_care, &dont_care, is_computed_name,
2194         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2195
2196     if (!*is_computed_name) {
2197       checker->CheckProperty(name_token, kAccessorProperty, is_static,
2198                              is_generator,
2199                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2200     }
2201
2202     FunctionKind kind = FunctionKind::kAccessorFunction;
2203     if (!in_class) kind = WithObjectLiteralBit(kind);
2204     typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2205         name, scanner()->location(),
2206         false,  // reserved words are allowed here
2207         kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2208         is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2209         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2210
2211     // Make sure the name expression is a string since we need a Name for
2212     // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2213     // statically we can skip the extra runtime check.
2214     if (!*is_computed_name) {
2215       name_expression =
2216           factory()->NewStringLiteral(name, name_expression->position());
2217     }
2218
2219     return factory()->NewObjectLiteralProperty(
2220         name_expression, value,
2221         is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2222         is_static, *is_computed_name);
2223
2224   } else if (!in_class && allow_harmony_object_literals_ &&
2225              Token::IsIdentifier(name_token, language_mode(),
2226                                  this->is_generator())) {
2227     DCHECK(!*is_computed_name);
2228     DCHECK(!is_static);
2229     value = this->ExpressionFromIdentifier(name, next_beg_pos, next_end_pos,
2230                                            scope_, factory());
2231     return factory()->NewObjectLiteralProperty(
2232         name_expression, value, ObjectLiteralProperty::COMPUTED, false, false);
2233
2234   } else {
2235     Token::Value next = Next();
2236     ReportUnexpectedToken(next);
2237     *ok = false;
2238     return this->EmptyObjectLiteralProperty();
2239   }
2240
2241   return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
2242                                              *is_computed_name);
2243 }
2244
2245
2246 template <class Traits>
2247 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2248     bool* ok) {
2249   // ObjectLiteral ::
2250   // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2251
2252   int pos = peek_position();
2253   typename Traits::Type::PropertyList properties =
2254       this->NewPropertyList(4, zone_);
2255   int number_of_boilerplate_properties = 0;
2256   bool has_function = false;
2257   bool has_computed_names = false;
2258   ObjectLiteralChecker checker(this);
2259
2260   Expect(Token::LBRACE, CHECK_OK);
2261
2262   while (peek() != Token::RBRACE) {
2263     if (fni_ != nullptr) fni_->Enter();
2264
2265     const bool in_class = false;
2266     const bool is_static = false;
2267     const bool has_extends = false;
2268     bool is_computed_name = false;
2269     ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2270         &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
2271         CHECK_OK);
2272
2273     if (is_computed_name) {
2274       has_computed_names = true;
2275     }
2276
2277     // Mark top-level object literals that contain function literals and
2278     // pretenure the literal so it can be added as a constant function
2279     // property. (Parser only.)
2280     this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2281                                                           &has_function);
2282
2283     // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2284     if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2285       number_of_boilerplate_properties++;
2286     }
2287     properties->Add(property, zone());
2288
2289     if (peek() != Token::RBRACE) {
2290       // Need {} because of the CHECK_OK macro.
2291       Expect(Token::COMMA, CHECK_OK);
2292     }
2293
2294     if (fni_ != nullptr) {
2295       fni_->Infer();
2296       fni_->Leave();
2297     }
2298   }
2299   Expect(Token::RBRACE, CHECK_OK);
2300
2301   // Computation of literal_index must happen before pre parse bailout.
2302   int literal_index = function_state_->NextMaterializedLiteralIndex();
2303
2304   return factory()->NewObjectLiteral(properties,
2305                                      literal_index,
2306                                      number_of_boilerplate_properties,
2307                                      has_function,
2308                                      pos);
2309 }
2310
2311
2312 template <class Traits>
2313 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
2314     bool* ok) {
2315   // Arguments ::
2316   //   '(' (AssignmentExpression)*[','] ')'
2317
2318   typename Traits::Type::ExpressionList result =
2319       this->NewExpressionList(4, zone_);
2320   Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2321   bool done = (peek() == Token::RPAREN);
2322   while (!done) {
2323     ExpressionT argument = this->ParseAssignmentExpression(
2324         true, CHECK_OK_CUSTOM(NullExpressionList));
2325     result->Add(argument, zone_);
2326     if (result->length() > Code::kMaxArguments) {
2327       ReportMessage("too_many_arguments");
2328       *ok = false;
2329       return this->NullExpressionList();
2330     }
2331     done = (peek() != Token::COMMA);
2332     if (!done) {
2333       Next();
2334     }
2335   }
2336   Scanner::Location location = scanner_->location();
2337   if (Token::RPAREN != Next()) {
2338     ReportMessageAt(location, "unterminated_arg_list");
2339     *ok = false;
2340     return this->NullExpressionList();
2341   }
2342   return result;
2343 }
2344
2345 // Precedence = 2
2346 template <class Traits>
2347 typename ParserBase<Traits>::ExpressionT
2348 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2349   // AssignmentExpression ::
2350   //   ConditionalExpression
2351   //   ArrowFunction
2352   //   YieldExpression
2353   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
2354
2355   Scanner::Location lhs_location = scanner()->peek_location();
2356
2357   if (peek() == Token::YIELD && is_generator()) {
2358     return this->ParseYieldExpression(ok);
2359   }
2360
2361   if (fni_ != NULL) fni_->Enter();
2362   ParserBase<Traits>::Checkpoint checkpoint(this);
2363   ExpressionT expression =
2364       this->ParseConditionalExpression(accept_IN, CHECK_OK);
2365
2366   if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2367     checkpoint.Restore();
2368     expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2369                                                  expression, CHECK_OK);
2370     return expression;
2371   }
2372
2373   if (!Token::IsAssignmentOp(peek())) {
2374     if (fni_ != NULL) fni_->Leave();
2375     // Parsed conditional expression only (no assignment).
2376     return expression;
2377   }
2378
2379   expression = this->CheckAndRewriteReferenceExpression(
2380       expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
2381   expression = this->MarkExpressionAsAssigned(expression);
2382
2383   Token::Value op = Next();  // Get assignment operator.
2384   int pos = position();
2385   ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
2386
2387   // TODO(1231235): We try to estimate the set of properties set by
2388   // constructors. We define a new property whenever there is an
2389   // assignment to a property of 'this'. We should probably only add
2390   // properties if we haven't seen them before. Otherwise we'll
2391   // probably overestimate the number of properties.
2392   if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2393     function_state_->AddProperty();
2394   }
2395
2396   this->CheckAssigningFunctionLiteralToProperty(expression, right);
2397
2398   if (fni_ != NULL) {
2399     // Check if the right hand side is a call to avoid inferring a
2400     // name if we're dealing with "a = function(){...}();"-like
2401     // expression.
2402     if ((op == Token::INIT_VAR
2403          || op == Token::INIT_CONST_LEGACY
2404          || op == Token::ASSIGN)
2405         && (!right->IsCall() && !right->IsCallNew())) {
2406       fni_->Infer();
2407     } else {
2408       fni_->RemoveLastFunction();
2409     }
2410     fni_->Leave();
2411   }
2412
2413   return factory()->NewAssignment(op, expression, right, pos);
2414 }
2415
2416 template <class Traits>
2417 typename ParserBase<Traits>::ExpressionT
2418 ParserBase<Traits>::ParseYieldExpression(bool* ok) {
2419   // YieldExpression ::
2420   //   'yield' ([no line terminator] '*'? AssignmentExpression)?
2421   int pos = peek_position();
2422   Expect(Token::YIELD, CHECK_OK);
2423   ExpressionT generator_object =
2424       factory()->NewVariableProxy(function_state_->generator_object_variable());
2425   ExpressionT expression = Traits::EmptyExpression();
2426   Yield::Kind kind = Yield::kSuspend;
2427   if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2428     if (Check(Token::MUL)) kind = Yield::kDelegating;
2429     switch (peek()) {
2430       case Token::EOS:
2431       case Token::SEMICOLON:
2432       case Token::RBRACE:
2433       case Token::RBRACK:
2434       case Token::RPAREN:
2435       case Token::COLON:
2436       case Token::COMMA:
2437         // The above set of tokens is the complete set of tokens that can appear
2438         // after an AssignmentExpression, and none of them can start an
2439         // AssignmentExpression.  This allows us to avoid looking for an RHS for
2440         // a Yield::kSuspend operation, given only one look-ahead token.
2441         if (kind == Yield::kSuspend)
2442           break;
2443         DCHECK_EQ(Yield::kDelegating, kind);
2444         // Delegating yields require an RHS; fall through.
2445       default:
2446         expression = ParseAssignmentExpression(false, CHECK_OK);
2447         break;
2448     }
2449   }
2450   if (kind == Yield::kDelegating) {
2451     // var iterator = subject[Symbol.iterator]();
2452     expression = this->GetIterator(expression, factory());
2453   }
2454   typename Traits::Type::YieldExpression yield =
2455       factory()->NewYield(generator_object, expression, kind, pos);
2456   if (kind == Yield::kDelegating) {
2457     yield->set_index(function_state_->NextHandlerIndex());
2458   }
2459   return yield;
2460 }
2461
2462
2463 // Precedence = 3
2464 template <class Traits>
2465 typename ParserBase<Traits>::ExpressionT
2466 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) {
2467   // ConditionalExpression ::
2468   //   LogicalOrExpression
2469   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2470
2471   int pos = peek_position();
2472   // We start using the binary expression parser for prec >= 4 only!
2473   ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK);
2474   if (peek() != Token::CONDITIONAL) return expression;
2475   Consume(Token::CONDITIONAL);
2476   // In parsing the first assignment expression in conditional
2477   // expressions we always accept the 'in' keyword; see ECMA-262,
2478   // section 11.12, page 58.
2479   ExpressionT left = ParseAssignmentExpression(true, CHECK_OK);
2480   Expect(Token::COLON, CHECK_OK);
2481   ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2482   return factory()->NewConditional(expression, left, right, pos);
2483 }
2484
2485
2486 // Precedence >= 4
2487 template <class Traits>
2488 typename ParserBase<Traits>::ExpressionT
2489 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
2490   DCHECK(prec >= 4);
2491   ExpressionT x = this->ParseUnaryExpression(CHECK_OK);
2492   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2493     // prec1 >= 4
2494     while (Precedence(peek(), accept_IN) == prec1) {
2495       Token::Value op = Next();
2496       Scanner::Location op_location = scanner()->location();
2497       int pos = position();
2498       ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
2499
2500       if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2501                                                        factory())) {
2502         continue;
2503       }
2504
2505       // For now we distinguish between comparisons and other binary
2506       // operations.  (We could combine the two and get rid of this
2507       // code and AST node eventually.)
2508       if (Token::IsCompareOp(op)) {
2509         // We have a comparison.
2510         Token::Value cmp = op;
2511         switch (op) {
2512           case Token::NE: cmp = Token::EQ; break;
2513           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2514           default: break;
2515         }
2516         if (cmp == Token::EQ && is_strong(language_mode())) {
2517           ReportMessageAt(op_location, "strong_equal");
2518           *ok = false;
2519           return this->EmptyExpression();
2520         }
2521         x = factory()->NewCompareOperation(cmp, x, y, pos);
2522         if (cmp != op) {
2523           // The comparison was negated - add a NOT.
2524           x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2525         }
2526
2527       } else {
2528         // We have a "normal" binary operation.
2529         x = factory()->NewBinaryOperation(op, x, y, pos);
2530       }
2531     }
2532   }
2533   return x;
2534 }
2535
2536
2537 template <class Traits>
2538 typename ParserBase<Traits>::ExpressionT
2539 ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
2540   // UnaryExpression ::
2541   //   PostfixExpression
2542   //   'delete' UnaryExpression
2543   //   'void' UnaryExpression
2544   //   'typeof' UnaryExpression
2545   //   '++' UnaryExpression
2546   //   '--' UnaryExpression
2547   //   '+' UnaryExpression
2548   //   '-' UnaryExpression
2549   //   '~' UnaryExpression
2550   //   '!' UnaryExpression
2551
2552   Token::Value op = peek();
2553   if (Token::IsUnaryOp(op)) {
2554     op = Next();
2555     int pos = position();
2556     ExpressionT expression = ParseUnaryExpression(CHECK_OK);
2557
2558     if (op == Token::DELETE && is_strict(language_mode())) {
2559       if (is_strong(language_mode())) {
2560         ReportMessage("strong_delete");
2561         *ok = false;
2562         return this->EmptyExpression();
2563       } else if (this->IsIdentifier(expression)) {
2564         // "delete identifier" is a syntax error in strict mode.
2565         ReportMessage("strict_delete");
2566         *ok = false;
2567         return this->EmptyExpression();
2568       }
2569     }
2570
2571     // Allow Traits do rewrite the expression.
2572     return this->BuildUnaryExpression(expression, op, pos, factory());
2573   } else if (Token::IsCountOp(op)) {
2574     op = Next();
2575     Scanner::Location lhs_location = scanner()->peek_location();
2576     ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
2577     expression = this->CheckAndRewriteReferenceExpression(
2578         expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
2579     this->MarkExpressionAsAssigned(expression);
2580
2581     return factory()->NewCountOperation(op,
2582                                         true /* prefix */,
2583                                         expression,
2584                                         position());
2585
2586   } else {
2587     return this->ParsePostfixExpression(ok);
2588   }
2589 }
2590
2591
2592 template <class Traits>
2593 typename ParserBase<Traits>::ExpressionT
2594 ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
2595   // PostfixExpression ::
2596   //   LeftHandSideExpression ('++' | '--')?
2597
2598   Scanner::Location lhs_location = scanner()->peek_location();
2599   ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK);
2600   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2601       Token::IsCountOp(peek())) {
2602     expression = this->CheckAndRewriteReferenceExpression(
2603         expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
2604     expression = this->MarkExpressionAsAssigned(expression);
2605
2606     Token::Value next = Next();
2607     expression =
2608         factory()->NewCountOperation(next,
2609                                      false /* postfix */,
2610                                      expression,
2611                                      position());
2612   }
2613   return expression;
2614 }
2615
2616
2617 template <class Traits>
2618 typename ParserBase<Traits>::ExpressionT
2619 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
2620   // LeftHandSideExpression ::
2621   //   (NewExpression | MemberExpression) ...
2622
2623   ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
2624
2625   while (true) {
2626     switch (peek()) {
2627       case Token::LBRACK: {
2628         Consume(Token::LBRACK);
2629         int pos = position();
2630         ExpressionT index = ParseExpression(true, CHECK_OK);
2631         result = factory()->NewProperty(result, index, pos);
2632         Expect(Token::RBRACK, CHECK_OK);
2633         break;
2634       }
2635
2636       case Token::LPAREN: {
2637         int pos;
2638         if (scanner()->current_token() == Token::IDENTIFIER) {
2639           // For call of an identifier we want to report position of
2640           // the identifier as position of the call in the stack trace.
2641           pos = position();
2642         } else {
2643           // For other kinds of calls we record position of the parenthesis as
2644           // position of the call. Note that this is extremely important for
2645           // expressions of the form function(){...}() for which call position
2646           // should not point to the closing brace otherwise it will intersect
2647           // with positions recorded for function literal and confuse debugger.
2648           pos = peek_position();
2649           // Also the trailing parenthesis are a hint that the function will
2650           // be called immediately. If we happen to have parsed a preceding
2651           // function literal eagerly, we can also compile it eagerly.
2652           if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2653             result->AsFunctionLiteral()->set_parenthesized();
2654           }
2655         }
2656         typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK);
2657
2658         // Keep track of eval() calls since they disable all local variable
2659         // optimizations.
2660         // The calls that need special treatment are the
2661         // direct eval calls. These calls are all of the form eval(...), with
2662         // no explicit receiver.
2663         // These calls are marked as potentially direct eval calls. Whether
2664         // they are actually direct calls to eval is determined at run time.
2665         this->CheckPossibleEvalCall(result, scope_);
2666         result = factory()->NewCall(result, args, pos);
2667         if (fni_ != NULL) fni_->RemoveLastFunction();
2668         break;
2669       }
2670
2671       case Token::PERIOD: {
2672         Consume(Token::PERIOD);
2673         int pos = position();
2674         IdentifierT name = ParseIdentifierName(CHECK_OK);
2675         result = factory()->NewProperty(
2676             result, factory()->NewStringLiteral(name, pos), pos);
2677         if (fni_ != NULL) this->PushLiteralName(fni_, name);
2678         break;
2679       }
2680
2681       default:
2682         return result;
2683     }
2684   }
2685 }
2686
2687
2688 template <class Traits>
2689 typename ParserBase<Traits>::ExpressionT
2690 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
2691   // NewExpression ::
2692   //   ('new')+ MemberExpression
2693
2694   // The grammar for new expressions is pretty warped. We can have several 'new'
2695   // keywords following each other, and then a MemberExpression. When we see '('
2696   // after the MemberExpression, it's associated with the rightmost unassociated
2697   // 'new' to create a NewExpression with arguments. However, a NewExpression
2698   // can also occur without arguments.
2699
2700   // Examples of new expression:
2701   // new foo.bar().baz means (new (foo.bar)()).baz
2702   // new foo()() means (new foo())()
2703   // new new foo()() means (new (new foo())())
2704   // new new foo means new (new foo)
2705   // new new foo() means new (new foo())
2706   // new new foo().bar().baz means (new (new foo()).bar()).baz
2707
2708   if (peek() == Token::NEW) {
2709     Consume(Token::NEW);
2710     int new_pos = position();
2711     ExpressionT result = this->EmptyExpression();
2712     if (peek() == Token::SUPER) {
2713       const bool is_new = true;
2714       result = ParseSuperExpression(is_new, CHECK_OK);
2715     } else {
2716       result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
2717     }
2718     if (peek() == Token::LPAREN) {
2719       // NewExpression with arguments.
2720       typename Traits::Type::ExpressionList args =
2721           this->ParseArguments(CHECK_OK);
2722       result = factory()->NewCallNew(result, args, new_pos);
2723       // The expression can still continue with . or [ after the arguments.
2724       result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
2725       return result;
2726     }
2727     // NewExpression without arguments.
2728     return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2729                                  new_pos);
2730   }
2731   // No 'new' or 'super' keyword.
2732   return this->ParseMemberExpression(ok);
2733 }
2734
2735
2736 template <class Traits>
2737 typename ParserBase<Traits>::ExpressionT
2738 ParserBase<Traits>::ParseMemberExpression(bool* ok) {
2739   // MemberExpression ::
2740   //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
2741   //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
2742
2743   // The '[' Expression ']' and '.' Identifier parts are parsed by
2744   // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2745   // caller.
2746
2747   // Parse the initial primary or function expression.
2748   ExpressionT result = this->EmptyExpression();
2749   if (peek() == Token::FUNCTION) {
2750     Consume(Token::FUNCTION);
2751     int function_token_position = position();
2752     bool is_generator = Check(Token::MUL);
2753     IdentifierT name = this->EmptyIdentifier();
2754     bool is_strict_reserved_name = false;
2755     Scanner::Location function_name_location = Scanner::Location::invalid();
2756     FunctionLiteral::FunctionType function_type =
2757         FunctionLiteral::ANONYMOUS_EXPRESSION;
2758     if (peek_any_identifier()) {
2759       name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2760                                                  CHECK_OK);
2761       function_name_location = scanner()->location();
2762       function_type = FunctionLiteral::NAMED_EXPRESSION;
2763     }
2764     result = this->ParseFunctionLiteral(
2765         name, function_name_location, is_strict_reserved_name,
2766         is_generator ? FunctionKind::kGeneratorFunction
2767                      : FunctionKind::kNormalFunction,
2768         function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
2769         CHECK_OK);
2770   } else if (peek() == Token::SUPER) {
2771     const bool is_new = false;
2772     result = ParseSuperExpression(is_new, CHECK_OK);
2773   } else {
2774     result = ParsePrimaryExpression(CHECK_OK);
2775   }
2776
2777   result = ParseMemberExpressionContinuation(result, CHECK_OK);
2778   return result;
2779 }
2780
2781
2782 template <class Traits>
2783 typename ParserBase<Traits>::ExpressionT
2784 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
2785   Expect(Token::SUPER, CHECK_OK);
2786
2787   FunctionState* function_state = function_state_;
2788   while (IsArrowFunction(function_state->kind())) {
2789     function_state = function_state->outer();
2790   }
2791   // TODO(arv): Handle eval scopes similarly.
2792
2793   FunctionKind kind = function_state->kind();
2794   if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
2795       i::IsConstructor(kind)) {
2796     if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
2797       scope_->RecordSuperPropertyUsage();
2798       return this->SuperReference(scope_, factory());
2799     }
2800     // new super() is never allowed.
2801     // super() is only allowed in derived constructor
2802     if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
2803       if (is_strong(language_mode())) {
2804         if (function_state->super_call_location().IsValid()) {
2805           ReportMessageAt(scanner()->location(), "strong_super_call_duplicate");
2806           *ok = false;
2807           return this->EmptyExpression();
2808         } else if (function_state->return_location().IsValid()) {
2809           ReportMessageAt(function_state->return_location(),
2810                           "strong_constructor_return_misplaced");
2811           *ok = false;
2812           return this->EmptyExpression();
2813         }
2814       }
2815       function_state->set_super_call_location(scanner()->location());
2816       return this->SuperReference(scope_, factory());
2817     }
2818   }
2819
2820   ReportMessageAt(scanner()->location(), "unexpected_super");
2821   *ok = false;
2822   return this->EmptyExpression();
2823 }
2824
2825
2826 template <class Traits>
2827 typename ParserBase<Traits>::ExpressionT
2828 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
2829                                                       bool* ok) {
2830   // Parses this part of MemberExpression:
2831   // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
2832   while (true) {
2833     switch (peek()) {
2834       case Token::LBRACK: {
2835         Consume(Token::LBRACK);
2836         int pos = position();
2837         ExpressionT index = this->ParseExpression(true, CHECK_OK);
2838         expression = factory()->NewProperty(expression, index, pos);
2839         if (fni_ != NULL) {
2840           this->PushPropertyName(fni_, index);
2841         }
2842         Expect(Token::RBRACK, CHECK_OK);
2843         break;
2844       }
2845       case Token::PERIOD: {
2846         Consume(Token::PERIOD);
2847         int pos = position();
2848         IdentifierT name = ParseIdentifierName(CHECK_OK);
2849         expression = factory()->NewProperty(
2850             expression, factory()->NewStringLiteral(name, pos), pos);
2851         if (fni_ != NULL) {
2852           this->PushLiteralName(fni_, name);
2853         }
2854         break;
2855       }
2856       case Token::TEMPLATE_SPAN:
2857       case Token::TEMPLATE_TAIL: {
2858         int pos;
2859         if (scanner()->current_token() == Token::IDENTIFIER) {
2860           pos = position();
2861         } else {
2862           pos = peek_position();
2863           if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2864             // If the tag function looks like an IIFE, set_parenthesized() to
2865             // force eager compilation.
2866             expression->AsFunctionLiteral()->set_parenthesized();
2867           }
2868         }
2869         expression = ParseTemplateLiteral(expression, pos, CHECK_OK);
2870         break;
2871       }
2872       default:
2873         return expression;
2874     }
2875   }
2876   DCHECK(false);
2877   return this->EmptyExpression();
2878 }
2879
2880
2881 template <class Traits>
2882 typename ParserBase<Traits>::ExpressionT
2883 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
2884                                               ExpressionT params_ast,
2885                                               bool* ok) {
2886   if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
2887     // ASI inserts `;` after arrow parameters if a line terminator is found.
2888     // `=> ...` is never a valid expression, so report as syntax error.
2889     // If next token is not `=>`, it's a syntax error anyways.
2890     ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
2891     *ok = false;
2892     return this->EmptyExpression();
2893   }
2894
2895   Scope* scope = this->NewScope(scope_, ARROW_SCOPE);
2896   typename Traits::Type::StatementList body;
2897   int num_parameters = -1;
2898   int materialized_literal_count = -1;
2899   int expected_property_count = -1;
2900   int handler_count = 0;
2901   Scanner::Location super_loc;
2902
2903   {
2904     typename Traits::Type::Factory function_factory(ast_value_factory());
2905     FunctionState function_state(&function_state_, &scope_, scope,
2906                                  kArrowFunction, &function_factory);
2907     Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2908     // TODO(arv): Pass in eval_args_error_loc and reserved_loc here.
2909     num_parameters = Traits::DeclareArrowParametersFromExpression(
2910         params_ast, scope_, &dupe_error_loc, ok);
2911     if (!*ok) {
2912       ReportMessageAt(
2913           Scanner::Location(start_pos, scanner()->location().beg_pos),
2914           "malformed_arrow_function_parameter_list");
2915       return this->EmptyExpression();
2916     }
2917
2918     if (num_parameters > Code::kMaxArguments) {
2919       ReportMessageAt(Scanner::Location(params_ast->position(), position()),
2920                       "too_many_parameters");
2921       *ok = false;
2922       return this->EmptyExpression();
2923     }
2924
2925     Expect(Token::ARROW, CHECK_OK);
2926
2927     if (peek() == Token::LBRACE) {
2928       // Multiple statemente body
2929       Consume(Token::LBRACE);
2930       bool is_lazily_parsed =
2931           (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
2932       if (is_lazily_parsed) {
2933         body = this->NewStatementList(0, zone());
2934         this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2935                                    &materialized_literal_count,
2936                                    &expected_property_count, CHECK_OK);
2937       } else {
2938         body = this->ParseEagerFunctionBody(
2939             this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL,
2940             Token::INIT_VAR, kArrowFunction, CHECK_OK);
2941         materialized_literal_count =
2942             function_state.materialized_literal_count();
2943         expected_property_count = function_state.expected_property_count();
2944         handler_count = function_state.handler_count();
2945       }
2946     } else {
2947       // Single-expression body
2948       int pos = position();
2949       parenthesized_function_ = false;
2950       ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2951       body = this->NewStatementList(1, zone());
2952       body->Add(factory()->NewReturnStatement(expression, pos), zone());
2953       materialized_literal_count = function_state.materialized_literal_count();
2954       expected_property_count = function_state.expected_property_count();
2955       handler_count = function_state.handler_count();
2956     }
2957     super_loc = function_state.super_call_location();
2958
2959     scope->set_start_position(start_pos);
2960     scope->set_end_position(scanner()->location().end_pos);
2961
2962     // Arrow function *parameter lists* are always checked as in strict mode.
2963     // TODO(arv): eval_args_error_loc and reserved_loc needs to be set by
2964     // DeclareArrowParametersFromExpression.
2965     Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2966     Scanner::Location reserved_loc = Scanner::Location::invalid();
2967     const bool use_strict_params = true;
2968     this->CheckFunctionParameterNames(language_mode(), use_strict_params,
2969         eval_args_error_loc, dupe_error_loc, reserved_loc, CHECK_OK);
2970
2971     // Validate strict mode.
2972     if (is_strict(language_mode())) {
2973       CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos,
2974                               CHECK_OK);
2975       this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2976     }
2977   }
2978
2979   FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
2980       this->EmptyIdentifierString(), ast_value_factory(), scope, body,
2981       materialized_literal_count, expected_property_count, handler_count,
2982       num_parameters, FunctionLiteral::kNoDuplicateParameters,
2983       FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
2984       FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction,
2985       start_pos);
2986
2987   function_literal->set_function_token_position(start_pos);
2988   if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc);
2989
2990   if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
2991
2992   return function_literal;
2993 }
2994
2995
2996 template <typename Traits>
2997 typename ParserBase<Traits>::ExpressionT
2998 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) {
2999   // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3000   // text followed by a substitution expression), finalized by a single
3001   // TEMPLATE_TAIL.
3002   //
3003   // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3004   // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3005   // NoSubstitutionTemplate.
3006   //
3007   // When parsing a TemplateLiteral, we must have scanned either an initial
3008   // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
3009   CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
3010
3011   // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
3012   // In this case we may simply consume the token and build a template with a
3013   // single TEMPLATE_SPAN and no expressions.
3014   if (peek() == Token::TEMPLATE_TAIL) {
3015     Consume(Token::TEMPLATE_TAIL);
3016     int pos = position();
3017     CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3018     typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3019     Traits::AddTemplateSpan(&ts, true);
3020     return Traits::CloseTemplateLiteral(&ts, start, tag);
3021   }
3022
3023   Consume(Token::TEMPLATE_SPAN);
3024   int pos = position();
3025   typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3026   Traits::AddTemplateSpan(&ts, false);
3027   Token::Value next;
3028
3029   // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
3030   // and repeat if the following token is a TEMPLATE_SPAN as well (in this
3031   // case, representing a TemplateMiddle).
3032
3033   do {
3034     CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3035     next = peek();
3036     if (next == Token::EOS) {
3037       ReportMessageAt(Scanner::Location(start, peek_position()),
3038                       "unterminated_template");
3039       *ok = false;
3040       return Traits::EmptyExpression();
3041     } else if (next == Token::ILLEGAL) {
3042       Traits::ReportMessageAt(
3043           Scanner::Location(position() + 1, peek_position()),
3044           "unexpected_token", "ILLEGAL", kSyntaxError);
3045       *ok = false;
3046       return Traits::EmptyExpression();
3047     }
3048
3049     int expr_pos = peek_position();
3050     ExpressionT expression = this->ParseExpression(true, CHECK_OK);
3051     Traits::AddTemplateExpression(&ts, expression);
3052
3053     if (peek() != Token::RBRACE) {
3054       ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
3055                       "unterminated_template_expr");
3056       *ok = false;
3057       return Traits::EmptyExpression();
3058     }
3059
3060     // If we didn't die parsing that expression, our next token should be a
3061     // TEMPLATE_SPAN or TEMPLATE_TAIL.
3062     next = scanner()->ScanTemplateContinuation();
3063     Next();
3064     pos = position();
3065
3066     if (next == Token::EOS) {
3067       ReportMessageAt(Scanner::Location(start, pos), "unterminated_template");
3068       *ok = false;
3069       return Traits::EmptyExpression();
3070     } else if (next == Token::ILLEGAL) {
3071       Traits::ReportMessageAt(
3072           Scanner::Location(position() + 1, peek_position()),
3073           "unexpected_token", "ILLEGAL", kSyntaxError);
3074       *ok = false;
3075       return Traits::EmptyExpression();
3076     }
3077
3078     Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
3079   } while (next == Token::TEMPLATE_SPAN);
3080
3081   DCHECK_EQ(next, Token::TEMPLATE_TAIL);
3082   CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3083   // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3084   return Traits::CloseTemplateLiteral(&ts, start, tag);
3085 }
3086
3087
3088 template <typename Traits>
3089 typename ParserBase<Traits>::ExpressionT ParserBase<
3090     Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression,
3091                                                 Scanner::Location location,
3092                                                 const char* message, bool* ok) {
3093   if (is_strict(language_mode()) && this->IsIdentifier(expression) &&
3094       this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3095     this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError);
3096     *ok = false;
3097     return this->EmptyExpression();
3098   } else if (expression->IsValidReferenceExpression()) {
3099     return expression;
3100   } else if (expression->IsCall()) {
3101     // If it is a call, make it a runtime error for legacy web compatibility.
3102     // Rewrite `expr' to `expr[throw ReferenceError]'.
3103     int pos = location.beg_pos;
3104     ExpressionT error = this->NewThrowReferenceError(message, pos);
3105     return factory()->NewProperty(expression, error, pos);
3106   } else {
3107     this->ReportMessageAt(location, message, kReferenceError);
3108     *ok = false;
3109     return this->EmptyExpression();
3110   }
3111 }
3112
3113
3114 #undef CHECK_OK
3115 #undef CHECK_OK_CUSTOM
3116
3117
3118 template <typename Traits>
3119 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
3120     Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3121     bool* ok) {
3122   DCHECK(!is_static);
3123   DCHECK(!is_generator || type == kMethodProperty);
3124
3125   if (property == Token::SMI || property == Token::NUMBER) return;
3126
3127   if (type == kValueProperty && IsProto()) {
3128     if (has_seen_proto_) {
3129       this->parser()->ReportMessage("duplicate_proto");
3130       *ok = false;
3131       return;
3132     }
3133     has_seen_proto_ = true;
3134     return;
3135   }
3136 }
3137
3138
3139 template <typename Traits>
3140 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
3141     Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3142     bool* ok) {
3143   DCHECK(type == kMethodProperty || type == kAccessorProperty);
3144
3145   if (property == Token::SMI || property == Token::NUMBER) return;
3146
3147   if (is_static) {
3148     if (IsPrototype()) {
3149       this->parser()->ReportMessage("static_prototype");
3150       *ok = false;
3151       return;
3152     }
3153   } else if (IsConstructor()) {
3154     if (is_generator || type == kAccessorProperty) {
3155       const char* msg =
3156           is_generator ? "constructor_is_generator" : "constructor_is_accessor";
3157       this->parser()->ReportMessage(msg);
3158       *ok = false;
3159       return;
3160     }
3161     if (has_seen_constructor_) {
3162       this->parser()->ReportMessage("duplicate_constructor");
3163       *ok = false;
3164       return;
3165     }
3166     has_seen_constructor_ = true;
3167     return;
3168   }
3169 }
3170 } }  // v8::internal
3171
3172 #endif  // V8_PREPARSER_H