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_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H
7 
8 #include "src/ast/scopes.h"
9 #include "src/bailout-reason.h"
10 #include "src/hashmap.h"
11 #include "src/messages.h"
12 #include "src/parsing/expression-classifier.h"
13 #include "src/parsing/func-name-inferrer.h"
14 #include "src/parsing/scanner.h"
15 #include "src/parsing/token.h"
16 
17 namespace v8 {
18 namespace internal {
19 
20 
21 enum FunctionNameValidity {
22   kFunctionNameIsStrictReserved,
23   kSkipFunctionNameCheck,
24   kFunctionNameValidityUnknown
25 };
26 
27 
28 struct FormalParametersBase {
FormalParametersBaseFormalParametersBase29   explicit FormalParametersBase(Scope* scope) : scope(scope) {}
30   Scope* scope;
31   bool has_rest = false;
32   bool is_simple = true;
33   int materialized_literals_count = 0;
34 };
35 
36 
37 // Common base class shared between parser and pre-parser. Traits encapsulate
38 // the differences between Parser and PreParser:
39 
40 // - Return types: For example, Parser functions return Expression* and
41 // PreParser functions return PreParserExpression.
42 
43 // - Creating parse tree nodes: Parser generates an AST during the recursive
44 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
45 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
46 // just enough data for the upper layer functions. PreParserFactory is
47 // responsible for creating these dummy objects. It provides a similar kind of
48 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
49 // used.
50 
51 // - Miscellaneous other tasks interleaved with the recursive descent. For
52 // example, Parser keeps track of which function literals should be marked as
53 // pretenured, and PreParser doesn't care.
54 
55 // The traits are expected to contain the following typedefs:
56 // struct Traits {
57 //   // In particular...
58 //   struct Type {
59 //     // Used by FunctionState and BlockState.
60 //     typedef Scope;
61 //     typedef GeneratorVariable;
62 //     // Return types for traversing functions.
63 //     typedef Identifier;
64 //     typedef Expression;
65 //     typedef FunctionLiteral;
66 //     typedef ClassLiteral;
67 //     typedef ObjectLiteralProperty;
68 //     typedef Literal;
69 //     typedef ExpressionList;
70 //     typedef PropertyList;
71 //     typedef FormalParameter;
72 //     typedef FormalParameters;
73 //     // For constructing objects returned by the traversing functions.
74 //     typedef Factory;
75 //   };
76 //   // ...
77 // };
78 
79 template <typename Traits>
80 class ParserBase : public Traits {
81  public:
82   // Shorten type names defined by Traits.
83   typedef typename Traits::Type::Expression ExpressionT;
84   typedef typename Traits::Type::Identifier IdentifierT;
85   typedef typename Traits::Type::FormalParameter FormalParameterT;
86   typedef typename Traits::Type::FormalParameters FormalParametersT;
87   typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
88   typedef typename Traits::Type::Literal LiteralT;
89   typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
90   typedef typename Traits::Type::StatementList StatementListT;
91 
ParserBase(Zone * zone,Scanner * scanner,uintptr_t stack_limit,v8::Extension * extension,AstValueFactory * ast_value_factory,ParserRecorder * log,typename Traits::Type::Parser this_object)92   ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
93              v8::Extension* extension, AstValueFactory* ast_value_factory,
94              ParserRecorder* log, typename Traits::Type::Parser this_object)
95       : Traits(this_object),
96         parenthesized_function_(false),
97         scope_(NULL),
98         function_state_(NULL),
99         extension_(extension),
100         fni_(NULL),
101         ast_value_factory_(ast_value_factory),
102         log_(log),
103         mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
104         stack_limit_(stack_limit),
105         zone_(zone),
106         scanner_(scanner),
107         stack_overflow_(false),
108         allow_lazy_(false),
109         allow_natives_(false),
110         allow_harmony_sloppy_(false),
111         allow_harmony_sloppy_function_(false),
112         allow_harmony_sloppy_let_(false),
113         allow_harmony_default_parameters_(false),
114         allow_harmony_destructuring_bind_(false),
115         allow_harmony_destructuring_assignment_(false),
116         allow_strong_mode_(false),
117         allow_legacy_const_(true),
118         allow_harmony_do_expressions_(false),
119         allow_harmony_function_name_(false) {}
120 
121 #define ALLOW_ACCESSORS(name)                           \
122   bool allow_##name() const { return allow_##name##_; } \
123   void set_allow_##name(bool allow) { allow_##name##_ = allow; }
124 
125   ALLOW_ACCESSORS(lazy);
126   ALLOW_ACCESSORS(natives);
127   ALLOW_ACCESSORS(harmony_sloppy);
128   ALLOW_ACCESSORS(harmony_sloppy_function);
129   ALLOW_ACCESSORS(harmony_sloppy_let);
130   ALLOW_ACCESSORS(harmony_default_parameters);
131   ALLOW_ACCESSORS(harmony_destructuring_bind);
132   ALLOW_ACCESSORS(harmony_destructuring_assignment);
133   ALLOW_ACCESSORS(strong_mode);
134   ALLOW_ACCESSORS(legacy_const);
135   ALLOW_ACCESSORS(harmony_do_expressions);
136   ALLOW_ACCESSORS(harmony_function_name);
137 #undef ALLOW_ACCESSORS
138 
stack_limit()139   uintptr_t stack_limit() const { return stack_limit_; }
140 
141  protected:
142   enum AllowRestrictedIdentifiers {
143     kAllowRestrictedIdentifiers,
144     kDontAllowRestrictedIdentifiers
145   };
146 
147   enum Mode {
148     PARSE_LAZILY,
149     PARSE_EAGERLY
150   };
151 
152   enum VariableDeclarationContext {
153     kStatementListItem,
154     kStatement,
155     kForStatement
156   };
157 
158   class Checkpoint;
159   class ObjectLiteralCheckerBase;
160 
161   // ---------------------------------------------------------------------------
162   // FunctionState and BlockState together implement the parser's scope stack.
163   // The parser's current scope is in scope_. BlockState and FunctionState
164   // constructors push on the scope stack and the destructors pop. They are also
165   // used to hold the parser's per-function and per-block state.
166   class BlockState BASE_EMBEDDED {
167    public:
BlockState(Scope ** scope_stack,Scope * scope)168     BlockState(Scope** scope_stack, Scope* scope)
169         : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
170       *scope_stack_ = scope;
171     }
~BlockState()172     ~BlockState() { *scope_stack_ = outer_scope_; }
173 
174    private:
175     Scope** scope_stack_;
176     Scope* outer_scope_;
177   };
178 
179   struct DestructuringAssignment {
180    public:
DestructuringAssignmentDestructuringAssignment181     DestructuringAssignment(ExpressionT expression, Scope* scope)
182         : assignment(expression), scope(scope) {}
183 
184     ExpressionT assignment;
185     Scope* scope;
186   };
187 
188   class FunctionState BASE_EMBEDDED {
189    public:
190     FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
191                   Scope* scope, FunctionKind kind,
192                   typename Traits::Type::Factory* factory);
193     ~FunctionState();
194 
NextMaterializedLiteralIndex()195     int NextMaterializedLiteralIndex() {
196       return next_materialized_literal_index_++;
197     }
materialized_literal_count()198     int materialized_literal_count() {
199       return next_materialized_literal_index_;
200     }
201 
SkipMaterializedLiterals(int count)202     void SkipMaterializedLiterals(int count) {
203       next_materialized_literal_index_ += count;
204     }
205 
AddProperty()206     void AddProperty() { expected_property_count_++; }
expected_property_count()207     int expected_property_count() { return expected_property_count_; }
208 
this_location()209     Scanner::Location this_location() const { return this_location_; }
super_location()210     Scanner::Location super_location() const { return super_location_; }
return_location()211     Scanner::Location return_location() const { return return_location_; }
set_this_location(Scanner::Location location)212     void set_this_location(Scanner::Location location) {
213       this_location_ = location;
214     }
set_super_location(Scanner::Location location)215     void set_super_location(Scanner::Location location) {
216       super_location_ = location;
217     }
set_return_location(Scanner::Location location)218     void set_return_location(Scanner::Location location) {
219       return_location_ = location;
220     }
221 
is_generator()222     bool is_generator() const { return IsGeneratorFunction(kind_); }
223 
kind()224     FunctionKind kind() const { return kind_; }
outer()225     FunctionState* outer() const { return outer_function_state_; }
226 
set_generator_object_variable(typename Traits::Type::GeneratorVariable * variable)227     void set_generator_object_variable(
228         typename Traits::Type::GeneratorVariable* variable) {
229       DCHECK(variable != NULL);
230       DCHECK(is_generator());
231       generator_object_variable_ = variable;
232     }
generator_object_variable()233     typename Traits::Type::GeneratorVariable* generator_object_variable()
234         const {
235       return generator_object_variable_;
236     }
237 
factory()238     typename Traits::Type::Factory* factory() { return factory_; }
239 
destructuring_assignments_to_rewrite()240     const List<DestructuringAssignment>& destructuring_assignments_to_rewrite()
241         const {
242       return destructuring_assignments_to_rewrite_;
243     }
244 
AddDestructuringAssignment(DestructuringAssignment pair)245     void AddDestructuringAssignment(DestructuringAssignment pair) {
246       destructuring_assignments_to_rewrite_.Add(pair);
247     }
248 
249    private:
250     // Used to assign an index to each literal that needs materialization in
251     // the function.  Includes regexp literals, and boilerplate for object and
252     // array literals.
253     int next_materialized_literal_index_;
254 
255     // Properties count estimation.
256     int expected_property_count_;
257 
258     // Location of most recent use of 'this' (invalid if none).
259     Scanner::Location this_location_;
260 
261     // Location of most recent 'return' statement (invalid if none).
262     Scanner::Location return_location_;
263 
264     // Location of call to the "super" constructor (invalid if none).
265     Scanner::Location super_location_;
266 
267     FunctionKind kind_;
268     // For generators, this variable may hold the generator object. It variable
269     // is used by yield expressions and return statements. It is not necessary
270     // for generator functions to have this variable set.
271     Variable* generator_object_variable_;
272 
273     FunctionState** function_state_stack_;
274     FunctionState* outer_function_state_;
275     Scope** scope_stack_;
276     Scope* outer_scope_;
277 
278     List<DestructuringAssignment> destructuring_assignments_to_rewrite_;
279 
280     void RewriteDestructuringAssignments();
281 
282     typename Traits::Type::Factory* factory_;
283 
284     friend class ParserTraits;
285     friend class Checkpoint;
286   };
287 
288   // Annoyingly, arrow functions first parse as comma expressions, then when we
289   // see the => we have to go back and reinterpret the arguments as being formal
290   // parameters.  To do so we need to reset some of the parser state back to
291   // what it was before the arguments were first seen.
292   class Checkpoint BASE_EMBEDDED {
293    public:
Checkpoint(ParserBase * parser)294     explicit Checkpoint(ParserBase* parser) {
295       function_state_ = parser->function_state_;
296       next_materialized_literal_index_ =
297           function_state_->next_materialized_literal_index_;
298       expected_property_count_ = function_state_->expected_property_count_;
299     }
300 
Restore(int * materialized_literal_index_delta)301     void Restore(int* materialized_literal_index_delta) {
302       *materialized_literal_index_delta =
303           function_state_->next_materialized_literal_index_ -
304           next_materialized_literal_index_;
305       function_state_->next_materialized_literal_index_ =
306           next_materialized_literal_index_;
307       function_state_->expected_property_count_ = expected_property_count_;
308     }
309 
310    private:
311     FunctionState* function_state_;
312     int next_materialized_literal_index_;
313     int expected_property_count_;
314   };
315 
316   class ParsingModeScope BASE_EMBEDDED {
317    public:
ParsingModeScope(ParserBase * parser,Mode mode)318     ParsingModeScope(ParserBase* parser, Mode mode)
319         : parser_(parser),
320           old_mode_(parser->mode()) {
321       parser_->mode_ = mode;
322     }
~ParsingModeScope()323     ~ParsingModeScope() {
324       parser_->mode_ = old_mode_;
325     }
326 
327    private:
328     ParserBase* parser_;
329     Mode old_mode_;
330   };
331 
NewScope(Scope * parent,ScopeType scope_type)332   Scope* NewScope(Scope* parent, ScopeType scope_type) {
333     // Must always pass the function kind for FUNCTION_SCOPE.
334     DCHECK(scope_type != FUNCTION_SCOPE);
335     return NewScope(parent, scope_type, kNormalFunction);
336   }
337 
NewScope(Scope * parent,ScopeType scope_type,FunctionKind kind)338   Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
339     DCHECK(ast_value_factory());
340     DCHECK(scope_type != MODULE_SCOPE || FLAG_harmony_modules);
341     Scope* result = new (zone())
342         Scope(zone(), parent, scope_type, ast_value_factory(), kind);
343     result->Initialize();
344     return result;
345   }
346 
scanner()347   Scanner* scanner() const { return scanner_; }
ast_value_factory()348   AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
position()349   int position() { return scanner_->location().beg_pos; }
peek_position()350   int peek_position() { return scanner_->peek_location().beg_pos; }
stack_overflow()351   bool stack_overflow() const { return stack_overflow_; }
set_stack_overflow()352   void set_stack_overflow() { stack_overflow_ = true; }
mode()353   Mode mode() const { return mode_; }
zone()354   Zone* zone() const { return zone_; }
355 
INLINE(Token::Value peek ())356   INLINE(Token::Value peek()) {
357     if (stack_overflow_) return Token::ILLEGAL;
358     return scanner()->peek();
359   }
360 
INLINE(Token::Value PeekAhead ())361   INLINE(Token::Value PeekAhead()) {
362     if (stack_overflow_) return Token::ILLEGAL;
363     return scanner()->PeekAhead();
364   }
365 
INLINE(Token::Value Next ())366   INLINE(Token::Value Next()) {
367     if (stack_overflow_) return Token::ILLEGAL;
368     {
369       if (GetCurrentStackPosition() < stack_limit_) {
370         // Any further calls to Next or peek will return the illegal token.
371         // The current call must return the next token, which might already
372         // have been peek'ed.
373         stack_overflow_ = true;
374       }
375     }
376     return scanner()->Next();
377   }
378 
Consume(Token::Value token)379   void Consume(Token::Value token) {
380     Token::Value next = Next();
381     USE(next);
382     USE(token);
383     DCHECK(next == token);
384   }
385 
Check(Token::Value token)386   bool Check(Token::Value token) {
387     Token::Value next = peek();
388     if (next == token) {
389       Consume(next);
390       return true;
391     }
392     return false;
393   }
394 
Expect(Token::Value token,bool * ok)395   void Expect(Token::Value token, bool* ok) {
396     Token::Value next = Next();
397     if (next != token) {
398       ReportUnexpectedToken(next);
399       *ok = false;
400     }
401   }
402 
ExpectSemicolon(bool * ok)403   void ExpectSemicolon(bool* ok) {
404     // Check for automatic semicolon insertion according to
405     // the rules given in ECMA-262, section 7.9, page 21.
406     Token::Value tok = peek();
407     if (tok == Token::SEMICOLON) {
408       Next();
409       return;
410     }
411     if (scanner()->HasAnyLineTerminatorBeforeNext() ||
412         tok == Token::RBRACE ||
413         tok == Token::EOS) {
414       return;
415     }
416     Expect(Token::SEMICOLON, ok);
417   }
418 
peek_any_identifier()419   bool peek_any_identifier() {
420     Token::Value next = peek();
421     return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
422            next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
423            next == Token::STATIC || next == Token::YIELD;
424   }
425 
CheckContextualKeyword(Vector<const char> keyword)426   bool CheckContextualKeyword(Vector<const char> keyword) {
427     if (PeekContextualKeyword(keyword)) {
428       Consume(Token::IDENTIFIER);
429       return true;
430     }
431     return false;
432   }
433 
PeekContextualKeyword(Vector<const char> keyword)434   bool PeekContextualKeyword(Vector<const char> keyword) {
435     return peek() == Token::IDENTIFIER &&
436            scanner()->is_next_contextual_keyword(keyword);
437   }
438 
ExpectContextualKeyword(Vector<const char> keyword,bool * ok)439   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
440     Expect(Token::IDENTIFIER, ok);
441     if (!*ok) return;
442     if (!scanner()->is_literal_contextual_keyword(keyword)) {
443       ReportUnexpectedToken(scanner()->current_token());
444       *ok = false;
445     }
446   }
447 
CheckInOrOf(ForEachStatement::VisitMode * visit_mode,bool * ok)448   bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
449     if (Check(Token::IN)) {
450       if (is_strong(language_mode())) {
451         ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn);
452         *ok = false;
453       } else {
454         *visit_mode = ForEachStatement::ENUMERATE;
455       }
456       return true;
457     } else if (CheckContextualKeyword(CStrVector("of"))) {
458       *visit_mode = ForEachStatement::ITERATE;
459       return true;
460     }
461     return false;
462   }
463 
464   // Checks whether an octal literal was last seen between beg_pos and end_pos.
465   // If so, reports an error. Only called for strict mode and template strings.
CheckOctalLiteral(int beg_pos,int end_pos,MessageTemplate::Template message,bool * ok)466   void CheckOctalLiteral(int beg_pos, int end_pos,
467                          MessageTemplate::Template message, bool* ok) {
468     Scanner::Location octal = scanner()->octal_position();
469     if (octal.IsValid() && beg_pos <= octal.beg_pos &&
470         octal.end_pos <= end_pos) {
471       ReportMessageAt(octal, message);
472       scanner()->clear_octal_position();
473       *ok = false;
474     }
475   }
476 
CheckStrictOctalLiteral(int beg_pos,int end_pos,bool * ok)477   inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
478     CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
479                       ok);
480   }
481 
CheckTemplateOctalLiteral(int beg_pos,int end_pos,bool * ok)482   inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
483     CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
484                       ok);
485   }
486 
487   void CheckDestructuringElement(ExpressionT element,
488                                  ExpressionClassifier* classifier, int beg_pos,
489                                  int end_pos);
490 
491   // Checking the name of a function literal. This has to be done after parsing
492   // the function, since the function can declare itself strict.
CheckFunctionName(LanguageMode language_mode,IdentifierT function_name,FunctionNameValidity function_name_validity,const Scanner::Location & function_name_loc,bool * ok)493   void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
494                          FunctionNameValidity function_name_validity,
495                          const Scanner::Location& function_name_loc, bool* ok) {
496     if (function_name_validity == kSkipFunctionNameCheck) return;
497     // The function name needs to be checked in strict mode.
498     if (is_sloppy(language_mode)) return;
499 
500     if (this->IsEvalOrArguments(function_name)) {
501       Traits::ReportMessageAt(function_name_loc,
502                               MessageTemplate::kStrictEvalArguments);
503       *ok = false;
504       return;
505     }
506     if (function_name_validity == kFunctionNameIsStrictReserved) {
507       Traits::ReportMessageAt(function_name_loc,
508                               MessageTemplate::kUnexpectedStrictReserved);
509       *ok = false;
510       return;
511     }
512     if (is_strong(language_mode) && this->IsUndefined(function_name)) {
513       Traits::ReportMessageAt(function_name_loc,
514                               MessageTemplate::kStrongUndefined);
515       *ok = false;
516       return;
517     }
518   }
519 
520   // Determine precedence of given token.
Precedence(Token::Value token,bool accept_IN)521   static int Precedence(Token::Value token, bool accept_IN) {
522     if (token == Token::IN && !accept_IN)
523       return 0;  // 0 precedence will terminate binary expression parsing
524     return Token::Precedence(token);
525   }
526 
factory()527   typename Traits::Type::Factory* factory() {
528     return function_state_->factory();
529   }
530 
language_mode()531   LanguageMode language_mode() { return scope_->language_mode(); }
is_generator()532   bool is_generator() const { return function_state_->is_generator(); }
533 
allow_const()534   bool allow_const() {
535     return is_strict(language_mode()) || allow_harmony_sloppy() ||
536            allow_legacy_const();
537   }
538 
allow_let()539   bool allow_let() {
540     return is_strict(language_mode()) || allow_harmony_sloppy_let();
541   }
542 
543   // Report syntax errors.
544   void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
545                      ParseErrorType error_type = kSyntaxError) {
546     Scanner::Location source_location = scanner()->location();
547     Traits::ReportMessageAt(source_location, message, arg, error_type);
548   }
549 
550   void ReportMessageAt(Scanner::Location location,
551                        MessageTemplate::Template message,
552                        ParseErrorType error_type = kSyntaxError) {
553     Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
554                             error_type);
555   }
556 
557   void GetUnexpectedTokenMessage(
558       Token::Value token, MessageTemplate::Template* message, const char** arg,
559       MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
560 
561   void ReportUnexpectedToken(Token::Value token);
562   void ReportUnexpectedTokenAt(
563       Scanner::Location location, Token::Value token,
564       MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
565 
566 
ReportClassifierError(const ExpressionClassifier::Error & error)567   void ReportClassifierError(const ExpressionClassifier::Error& error) {
568     Traits::ReportMessageAt(error.location, error.message, error.arg,
569                             error.type);
570   }
571 
ValidateExpression(const ExpressionClassifier * classifier,bool * ok)572   void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
573     if (!classifier->is_valid_expression() ||
574         classifier->has_cover_initialized_name()) {
575       const Scanner::Location& a = classifier->expression_error().location;
576       const Scanner::Location& b =
577           classifier->cover_initialized_name_error().location;
578       if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
579         ReportClassifierError(classifier->cover_initialized_name_error());
580       } else {
581         ReportClassifierError(classifier->expression_error());
582       }
583       *ok = false;
584     }
585   }
586 
ValidateFormalParameterInitializer(const ExpressionClassifier * classifier,bool * ok)587   void ValidateFormalParameterInitializer(
588       const ExpressionClassifier* classifier, bool* ok) {
589     if (!classifier->is_valid_formal_parameter_initializer()) {
590       ReportClassifierError(classifier->formal_parameter_initializer_error());
591       *ok = false;
592     }
593   }
594 
ValidateBindingPattern(const ExpressionClassifier * classifier,bool * ok)595   void ValidateBindingPattern(const ExpressionClassifier* classifier,
596                               bool* ok) {
597     if (!classifier->is_valid_binding_pattern()) {
598       ReportClassifierError(classifier->binding_pattern_error());
599       *ok = false;
600     }
601   }
602 
ValidateAssignmentPattern(const ExpressionClassifier * classifier,bool * ok)603   void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
604                                  bool* ok) {
605     if (!classifier->is_valid_assignment_pattern()) {
606       ReportClassifierError(classifier->assignment_pattern_error());
607       *ok = false;
608     }
609   }
610 
ValidateFormalParameters(const ExpressionClassifier * classifier,LanguageMode language_mode,bool allow_duplicates,bool * ok)611   void ValidateFormalParameters(const ExpressionClassifier* classifier,
612                                 LanguageMode language_mode,
613                                 bool allow_duplicates, bool* ok) {
614     if (!allow_duplicates &&
615         !classifier->is_valid_formal_parameter_list_without_duplicates()) {
616       ReportClassifierError(classifier->duplicate_formal_parameter_error());
617       *ok = false;
618     } else if (is_strict(language_mode) &&
619                !classifier->is_valid_strict_mode_formal_parameters()) {
620       ReportClassifierError(classifier->strict_mode_formal_parameter_error());
621       *ok = false;
622     } else if (is_strong(language_mode) &&
623                !classifier->is_valid_strong_mode_formal_parameters()) {
624       ReportClassifierError(classifier->strong_mode_formal_parameter_error());
625       *ok = false;
626     }
627   }
628 
ValidateArrowFormalParameters(const ExpressionClassifier * classifier,ExpressionT expr,bool parenthesized_formals,bool * ok)629   void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
630                                      ExpressionT expr,
631                                      bool parenthesized_formals, bool* ok) {
632     if (classifier->is_valid_binding_pattern()) {
633       // A simple arrow formal parameter: IDENTIFIER => BODY.
634       if (!this->IsIdentifier(expr)) {
635         Traits::ReportMessageAt(scanner()->location(),
636                                 MessageTemplate::kUnexpectedToken,
637                                 Token::String(scanner()->current_token()));
638         *ok = false;
639       }
640     } else if (!classifier->is_valid_arrow_formal_parameters()) {
641       // If after parsing the expr, we see an error but the expression is
642       // neither a valid binding pattern nor a valid parenthesized formal
643       // parameter list, show the "arrow formal parameters" error if the formals
644       // started with a parenthesis, and the binding pattern error otherwise.
645       const ExpressionClassifier::Error& error =
646           parenthesized_formals ? classifier->arrow_formal_parameters_error()
647                                 : classifier->binding_pattern_error();
648       ReportClassifierError(error);
649       *ok = false;
650     }
651   }
652 
ValidateLetPattern(const ExpressionClassifier * classifier,bool * ok)653   void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) {
654     if (!classifier->is_valid_let_pattern()) {
655       ReportClassifierError(classifier->let_pattern_error());
656       *ok = false;
657     }
658   }
659 
ExpressionUnexpectedToken(ExpressionClassifier * classifier)660   void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
661     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
662     const char* arg;
663     GetUnexpectedTokenMessage(peek(), &message, &arg);
664     classifier->RecordExpressionError(scanner()->peek_location(), message, arg);
665   }
666 
BindingPatternUnexpectedToken(ExpressionClassifier * classifier)667   void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
668     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
669     const char* arg;
670     GetUnexpectedTokenMessage(peek(), &message, &arg);
671     classifier->RecordBindingPatternError(scanner()->peek_location(), message,
672                                           arg);
673   }
674 
ArrowFormalParametersUnexpectedToken(ExpressionClassifier * classifier)675   void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
676     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
677     const char* arg;
678     GetUnexpectedTokenMessage(peek(), &message, &arg);
679     classifier->RecordArrowFormalParametersError(scanner()->peek_location(),
680                                                  message, arg);
681   }
682 
FormalParameterInitializerUnexpectedToken(ExpressionClassifier * classifier)683   void FormalParameterInitializerUnexpectedToken(
684       ExpressionClassifier* classifier) {
685     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
686     const char* arg;
687     GetUnexpectedTokenMessage(peek(), &message, &arg);
688     classifier->RecordFormalParameterInitializerError(
689         scanner()->peek_location(), message, arg);
690   }
691 
692   // Recursive descent functions:
693 
694   // Parses an identifier that is valid for the current scope, in particular it
695   // fails on strict mode future reserved keywords in a strict scope. If
696   // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
697   // "arguments" as identifier even in strict mode (this is needed in cases like
698   // "var foo = eval;").
699   IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
700   IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
701                                          bool* ok);
702   // Parses an identifier or a strict mode future reserved word, and indicate
703   // whether it is strict mode future reserved. Allows passing in is_generator
704   // for the case of parsing the identifier in a function expression, where the
705   // relevant "is_generator" bit is of the function being parsed, not the
706   // containing
707   // function.
708   IdentifierT ParseIdentifierOrStrictReservedWord(bool is_generator,
709                                                   bool* is_strict_reserved,
710                                                   bool* ok);
ParseIdentifierOrStrictReservedWord(bool * is_strict_reserved,bool * ok)711   IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
712                                                   bool* ok) {
713     return ParseIdentifierOrStrictReservedWord(this->is_generator(),
714                                                is_strict_reserved, ok);
715   }
716 
717   IdentifierT ParseIdentifierName(bool* ok);
718   // Parses an identifier and determines whether or not it is 'get' or 'set'.
719   IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
720                                             bool* ok);
721 
722 
723   ExpressionT ParseRegExpLiteral(bool seen_equal,
724                                  ExpressionClassifier* classifier, bool* ok);
725 
726   ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
727                                      bool* ok);
728   ExpressionT ParseExpression(bool accept_IN, bool* ok);
729   ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
730                               bool* ok);
731   ExpressionT ParseExpression(bool accept_IN, int flags,
732                               ExpressionClassifier* classifier, bool* ok);
733   ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
734   ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
735                                 bool* is_static, bool* is_computed_name,
736                                 bool* is_identifier, bool* is_escaped_keyword,
737                                 ExpressionClassifier* classifier, bool* ok);
738   ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
739   ObjectLiteralPropertyT ParsePropertyDefinition(
740       ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
741       bool is_static, bool* is_computed_name, bool* has_seen_constructor,
742       ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
743   typename Traits::Type::ExpressionList ParseArguments(
744       Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
745       bool* ok);
746 
747   enum AssignmentExpressionFlags {
748     kIsNormalAssignment = 0,
749     kIsPossiblePatternElement = 1 << 0,
750     kIsPossibleArrowFormals = 1 << 1
751   };
752 
753   ExpressionT ParseAssignmentExpression(bool accept_IN, int flags,
754                                         ExpressionClassifier* classifier,
755                                         bool* ok);
ParseAssignmentExpression(bool accept_IN,ExpressionClassifier * classifier,bool * ok)756   ExpressionT ParseAssignmentExpression(bool accept_IN,
757                                         ExpressionClassifier* classifier,
758                                         bool* ok) {
759     return ParseAssignmentExpression(accept_IN, kIsNormalAssignment, classifier,
760                                      ok);
761   }
762   ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
763   ExpressionT ParseConditionalExpression(bool accept_IN,
764                                          ExpressionClassifier* classifier,
765                                          bool* ok);
766   ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
767                                     ExpressionClassifier* classifier, bool* ok);
768   ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
769   ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
770                                      bool* ok);
771   ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
772                                           bool* ok);
773   ExpressionT ParseMemberWithNewPrefixesExpression(
774       ExpressionClassifier* classifier, bool* ok);
775   ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
776   ExpressionT ParseMemberExpressionContinuation(
777       ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
778   ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
779                                         const FormalParametersT& parameters,
780                                         const ExpressionClassifier& classifier,
781                                         bool* ok);
782   ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
783                                    ExpressionClassifier* classifier, bool* ok);
784   void AddTemplateExpression(ExpressionT);
785   ExpressionT ParseSuperExpression(bool is_new,
786                                    ExpressionClassifier* classifier, bool* ok);
787   ExpressionT ParseNewTargetExpression(bool* ok);
788   ExpressionT ParseStrongInitializationExpression(
789       ExpressionClassifier* classifier, bool* ok);
790   ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
791                                              bool* ok);
792 
793   void ParseFormalParameter(FormalParametersT* parameters,
794                             ExpressionClassifier* classifier, bool* ok);
795   void ParseFormalParameterList(FormalParametersT* parameters,
796                                 ExpressionClassifier* classifier, bool* ok);
797   void CheckArityRestrictions(
798       int param_count, FunctionLiteral::ArityRestriction arity_restriction,
799       bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
800 
801   bool IsNextLetKeyword();
802 
803   // Checks if the expression is a valid reference expression (e.g., on the
804   // left-hand side of assignments). Although ruled out by ECMA as early errors,
805   // we allow calls for web compatibility and rewrite them to a runtime throw.
806   ExpressionT CheckAndRewriteReferenceExpression(
807       ExpressionT expression, int beg_pos, int end_pos,
808       MessageTemplate::Template message, bool* ok);
809   ExpressionT ClassifyAndRewriteReferenceExpression(
810       ExpressionClassifier* classifier, ExpressionT expression, int beg_pos,
811       int end_pos, MessageTemplate::Template message,
812       ParseErrorType type = kSyntaxError);
813   ExpressionT CheckAndRewriteReferenceExpression(
814       ExpressionT expression, int beg_pos, int end_pos,
815       MessageTemplate::Template message, ParseErrorType type, bool* ok);
816 
817   bool IsValidReferenceExpression(ExpressionT expression);
818 
IsAssignableIdentifier(ExpressionT expression)819   bool IsAssignableIdentifier(ExpressionT expression) {
820     if (!Traits::IsIdentifier(expression)) return false;
821     if (is_strict(language_mode()) &&
822         Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
823       return false;
824     }
825     if (is_strong(language_mode()) &&
826         Traits::IsUndefined(Traits::AsIdentifier(expression))) {
827       return false;
828     }
829     return true;
830   }
831 
832   // Keep track of eval() calls since they disable all local variable
833   // optimizations. This checks if expression is an eval call, and if yes,
834   // forwards the information to scope.
CheckPossibleEvalCall(ExpressionT expression,Scope * scope)835   void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) {
836     if (Traits::IsIdentifier(expression) &&
837         Traits::IsEval(Traits::AsIdentifier(expression))) {
838       scope->DeclarationScope()->RecordEvalCall();
839       scope->RecordEvalCall();
840     }
841   }
842 
843   // Used to validate property names in object literals and class literals
844   enum PropertyKind {
845     kAccessorProperty,
846     kValueProperty,
847     kMethodProperty
848   };
849 
850   class ObjectLiteralCheckerBase {
851    public:
ObjectLiteralCheckerBase(ParserBase * parser)852     explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
853 
854     virtual void CheckProperty(Token::Value property, PropertyKind type,
855                                bool is_static, bool is_generator, bool* ok) = 0;
856 
~ObjectLiteralCheckerBase()857     virtual ~ObjectLiteralCheckerBase() {}
858 
859    protected:
parser()860     ParserBase* parser() const { return parser_; }
scanner()861     Scanner* scanner() const { return parser_->scanner(); }
862 
863    private:
864     ParserBase* parser_;
865   };
866 
867   // Validation per ES6 object literals.
868   class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
869    public:
ObjectLiteralChecker(ParserBase * parser)870     explicit ObjectLiteralChecker(ParserBase* parser)
871         : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
872 
873     void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
874                        bool is_generator, bool* ok) override;
875 
876    private:
IsProto()877     bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
878 
879     bool has_seen_proto_;
880   };
881 
882   // Validation per ES6 class literals.
883   class ClassLiteralChecker : public ObjectLiteralCheckerBase {
884    public:
ClassLiteralChecker(ParserBase * parser)885     explicit ClassLiteralChecker(ParserBase* parser)
886         : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
887 
888     void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
889                        bool is_generator, bool* ok) override;
890 
891    private:
IsConstructor()892     bool IsConstructor() {
893       return this->scanner()->LiteralMatches("constructor", 11);
894     }
IsPrototype()895     bool IsPrototype() {
896       return this->scanner()->LiteralMatches("prototype", 9);
897     }
898 
899     bool has_seen_constructor_;
900   };
901 
902   // If true, the next (and immediately following) function literal is
903   // preceded by a parenthesis.
904   // Heuristically that means that the function will be called immediately,
905   // so never lazily compile it.
906   bool parenthesized_function_;
907 
908   Scope* scope_;                   // Scope stack.
909   FunctionState* function_state_;  // Function state stack.
910   v8::Extension* extension_;
911   FuncNameInferrer* fni_;
912   AstValueFactory* ast_value_factory_;  // Not owned.
913   ParserRecorder* log_;
914   Mode mode_;
915   uintptr_t stack_limit_;
916 
917  private:
918   Zone* zone_;
919 
920   Scanner* scanner_;
921   bool stack_overflow_;
922 
923   bool allow_lazy_;
924   bool allow_natives_;
925   bool allow_harmony_sloppy_;
926   bool allow_harmony_sloppy_function_;
927   bool allow_harmony_sloppy_let_;
928   bool allow_harmony_default_parameters_;
929   bool allow_harmony_destructuring_bind_;
930   bool allow_harmony_destructuring_assignment_;
931   bool allow_strong_mode_;
932   bool allow_legacy_const_;
933   bool allow_harmony_do_expressions_;
934   bool allow_harmony_function_name_;
935 };
936 
937 
938 template <class Traits>
FunctionState(FunctionState ** function_state_stack,Scope ** scope_stack,Scope * scope,FunctionKind kind,typename Traits::Type::Factory * factory)939 ParserBase<Traits>::FunctionState::FunctionState(
940     FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
941     FunctionKind kind, typename Traits::Type::Factory* factory)
942     : next_materialized_literal_index_(0),
943       expected_property_count_(0),
944       this_location_(Scanner::Location::invalid()),
945       return_location_(Scanner::Location::invalid()),
946       super_location_(Scanner::Location::invalid()),
947       kind_(kind),
948       generator_object_variable_(NULL),
949       function_state_stack_(function_state_stack),
950       outer_function_state_(*function_state_stack),
951       scope_stack_(scope_stack),
952       outer_scope_(*scope_stack),
953       factory_(factory) {
954   *scope_stack_ = scope;
955   *function_state_stack = this;
956 }
957 
958 
959 template <class Traits>
~FunctionState()960 ParserBase<Traits>::FunctionState::~FunctionState() {
961   *scope_stack_ = outer_scope_;
962   *function_state_stack_ = outer_function_state_;
963 }
964 
965 
966 template <class Traits>
GetUnexpectedTokenMessage(Token::Value token,MessageTemplate::Template * message,const char ** arg,MessageTemplate::Template default_)967 void ParserBase<Traits>::GetUnexpectedTokenMessage(
968     Token::Value token, MessageTemplate::Template* message, const char** arg,
969     MessageTemplate::Template default_) {
970   // Four of the tokens are treated specially
971   switch (token) {
972     case Token::EOS:
973       *message = MessageTemplate::kUnexpectedEOS;
974       *arg = nullptr;
975       break;
976     case Token::SMI:
977     case Token::NUMBER:
978       *message = MessageTemplate::kUnexpectedTokenNumber;
979       *arg = nullptr;
980       break;
981     case Token::STRING:
982       *message = MessageTemplate::kUnexpectedTokenString;
983       *arg = nullptr;
984       break;
985     case Token::IDENTIFIER:
986       *message = MessageTemplate::kUnexpectedTokenIdentifier;
987       *arg = nullptr;
988       break;
989     case Token::FUTURE_RESERVED_WORD:
990       *message = MessageTemplate::kUnexpectedReserved;
991       *arg = nullptr;
992       break;
993     case Token::LET:
994     case Token::STATIC:
995     case Token::YIELD:
996     case Token::FUTURE_STRICT_RESERVED_WORD:
997       *message = is_strict(language_mode())
998                      ? MessageTemplate::kUnexpectedStrictReserved
999                      : MessageTemplate::kUnexpectedTokenIdentifier;
1000       *arg = nullptr;
1001       break;
1002     case Token::TEMPLATE_SPAN:
1003     case Token::TEMPLATE_TAIL:
1004       *message = MessageTemplate::kUnexpectedTemplateString;
1005       *arg = nullptr;
1006       break;
1007     case Token::ESCAPED_STRICT_RESERVED_WORD:
1008     case Token::ESCAPED_KEYWORD:
1009       *message = MessageTemplate::kInvalidEscapedReservedWord;
1010       *arg = nullptr;
1011       break;
1012     default:
1013       const char* name = Token::String(token);
1014       DCHECK(name != NULL);
1015       *arg = name;
1016       break;
1017   }
1018 }
1019 
1020 
1021 template <class Traits>
ReportUnexpectedToken(Token::Value token)1022 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1023   return ReportUnexpectedTokenAt(scanner_->location(), token);
1024 }
1025 
1026 
1027 template <class Traits>
ReportUnexpectedTokenAt(Scanner::Location source_location,Token::Value token,MessageTemplate::Template message)1028 void ParserBase<Traits>::ReportUnexpectedTokenAt(
1029     Scanner::Location source_location, Token::Value token,
1030     MessageTemplate::Template message) {
1031   const char* arg;
1032   GetUnexpectedTokenMessage(token, &message, &arg);
1033   Traits::ReportMessageAt(source_location, message, arg);
1034 }
1035 
1036 
1037 template <class Traits>
ParseIdentifier(AllowRestrictedIdentifiers allow_restricted_identifiers,bool * ok)1038 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1039     AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1040   ExpressionClassifier classifier;
1041   auto result = ParseAndClassifyIdentifier(&classifier, ok);
1042   if (!*ok) return Traits::EmptyIdentifier();
1043 
1044   if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1045     ValidateAssignmentPattern(&classifier, ok);
1046     if (!*ok) return Traits::EmptyIdentifier();
1047     ValidateBindingPattern(&classifier, ok);
1048     if (!*ok) return Traits::EmptyIdentifier();
1049   }
1050 
1051   return result;
1052 }
1053 
1054 
1055 template <class Traits>
1056 typename ParserBase<Traits>::IdentifierT
ParseAndClassifyIdentifier(ExpressionClassifier * classifier,bool * ok)1057 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1058                                                bool* ok) {
1059   Token::Value next = Next();
1060   if (next == Token::IDENTIFIER) {
1061     IdentifierT name = this->GetSymbol(scanner());
1062     // When this function is used to read a formal parameter, we don't always
1063     // know whether the function is going to be strict or sloppy.  Indeed for
1064     // arrow functions we don't always know that the identifier we are reading
1065     // is actually a formal parameter.  Therefore besides the errors that we
1066     // must detect because we know we're in strict mode, we also record any
1067     // error that we might make in the future once we know the language mode.
1068     if (this->IsEval(name)) {
1069       classifier->RecordStrictModeFormalParameterError(
1070           scanner()->location(), MessageTemplate::kStrictEvalArguments);
1071       if (is_strict(language_mode())) {
1072         classifier->RecordBindingPatternError(
1073             scanner()->location(), MessageTemplate::kStrictEvalArguments);
1074       }
1075     }
1076     if (this->IsArguments(name)) {
1077       scope_->RecordArgumentsUsage();
1078       classifier->RecordStrictModeFormalParameterError(
1079           scanner()->location(), MessageTemplate::kStrictEvalArguments);
1080       if (is_strict(language_mode())) {
1081         classifier->RecordBindingPatternError(
1082             scanner()->location(), MessageTemplate::kStrictEvalArguments);
1083       }
1084       if (is_strong(language_mode())) {
1085         classifier->RecordExpressionError(scanner()->location(),
1086                                           MessageTemplate::kStrongArguments);
1087       }
1088     }
1089     if (this->IsUndefined(name)) {
1090       classifier->RecordStrongModeFormalParameterError(
1091           scanner()->location(), MessageTemplate::kStrongUndefined);
1092       if (is_strong(language_mode())) {
1093         // TODO(dslomov): allow 'undefined' in nested patterns.
1094         classifier->RecordBindingPatternError(
1095             scanner()->location(), MessageTemplate::kStrongUndefined);
1096         classifier->RecordAssignmentPatternError(
1097             scanner()->location(), MessageTemplate::kStrongUndefined);
1098       }
1099     }
1100 
1101     if (classifier->duplicate_finder() != nullptr &&
1102         scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1103       classifier->RecordDuplicateFormalParameterError(scanner()->location());
1104     }
1105     return name;
1106   } else if (is_sloppy(language_mode()) &&
1107              (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1108               next == Token::ESCAPED_STRICT_RESERVED_WORD ||
1109               next == Token::LET || next == Token::STATIC ||
1110               (next == Token::YIELD && !is_generator()))) {
1111     classifier->RecordStrictModeFormalParameterError(
1112         scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1113     if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1114         is_strict(language_mode())) {
1115       ReportUnexpectedToken(next);
1116       *ok = false;
1117       return Traits::EmptyIdentifier();
1118     }
1119     if (next == Token::LET) {
1120       classifier->RecordLetPatternError(scanner()->location(),
1121                                         MessageTemplate::kLetInLexicalBinding);
1122     }
1123     return this->GetSymbol(scanner());
1124   } else {
1125     this->ReportUnexpectedToken(next);
1126     *ok = false;
1127     return Traits::EmptyIdentifier();
1128   }
1129 }
1130 
1131 
1132 template <class Traits>
1133 typename ParserBase<Traits>::IdentifierT
ParseIdentifierOrStrictReservedWord(bool is_generator,bool * is_strict_reserved,bool * ok)1134 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
1135     bool is_generator, bool* is_strict_reserved, bool* ok) {
1136   Token::Value next = Next();
1137   if (next == Token::IDENTIFIER) {
1138     *is_strict_reserved = false;
1139   } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1140              next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
1141     *is_strict_reserved = true;
1142   } else {
1143     ReportUnexpectedToken(next);
1144     *ok = false;
1145     return Traits::EmptyIdentifier();
1146   }
1147 
1148   IdentifierT name = this->GetSymbol(scanner());
1149   if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1150   return name;
1151 }
1152 
1153 
1154 template <class Traits>
1155 typename ParserBase<Traits>::IdentifierT
ParseIdentifierName(bool * ok)1156 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1157   Token::Value next = Next();
1158   if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
1159       next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
1160       next != Token::FUTURE_STRICT_RESERVED_WORD &&
1161       next != Token::ESCAPED_KEYWORD &&
1162       next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1163     this->ReportUnexpectedToken(next);
1164     *ok = false;
1165     return Traits::EmptyIdentifier();
1166   }
1167 
1168   IdentifierT name = this->GetSymbol(scanner());
1169   if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1170   return name;
1171 }
1172 
1173 
1174 template <class Traits>
1175 typename ParserBase<Traits>::IdentifierT
ParseIdentifierNameOrGetOrSet(bool * is_get,bool * is_set,bool * ok)1176 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
1177                                                   bool* is_set,
1178                                                   bool* ok) {
1179   IdentifierT result = ParseIdentifierName(ok);
1180   if (!*ok) return Traits::EmptyIdentifier();
1181   scanner()->IsGetOrSet(is_get, is_set);
1182   return result;
1183 }
1184 
1185 
1186 template <class Traits>
ParseRegExpLiteral(bool seen_equal,ExpressionClassifier * classifier,bool * ok)1187 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1188     bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
1189   int pos = peek_position();
1190   if (!scanner()->ScanRegExpPattern(seen_equal)) {
1191     Next();
1192     ReportMessage(MessageTemplate::kUnterminatedRegExp);
1193     *ok = false;
1194     return Traits::EmptyExpression();
1195   }
1196 
1197   int literal_index = function_state_->NextMaterializedLiteralIndex();
1198 
1199   IdentifierT js_pattern = this->GetNextSymbol(scanner());
1200   Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
1201   if (flags.IsNothing()) {
1202     Next();
1203     ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1204     *ok = false;
1205     return Traits::EmptyExpression();
1206   }
1207   int js_flags = flags.FromJust();
1208   Next();
1209   return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index,
1210                                      is_strong(language_mode()), pos);
1211 }
1212 
1213 
1214 #define CHECK_OK  ok); \
1215   if (!*ok) return this->EmptyExpression(); \
1216   ((void)0
1217 #define DUMMY )  // to make indentation work
1218 #undef DUMMY
1219 
1220 // Used in functions where the return type is not ExpressionT.
1221 #define CHECK_OK_CUSTOM(x) ok); \
1222   if (!*ok) return this->x(); \
1223   ((void)0
1224 #define DUMMY )  // to make indentation work
1225 #undef DUMMY
1226 
1227 
1228 template <class Traits>
1229 typename ParserBase<Traits>::ExpressionT
ParsePrimaryExpression(ExpressionClassifier * classifier,bool * ok)1230 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
1231                                            bool* ok) {
1232   // PrimaryExpression ::
1233   //   'this'
1234   //   'null'
1235   //   'true'
1236   //   'false'
1237   //   Identifier
1238   //   Number
1239   //   String
1240   //   ArrayLiteral
1241   //   ObjectLiteral
1242   //   RegExpLiteral
1243   //   ClassLiteral
1244   //   '(' Expression ')'
1245   //   TemplateLiteral
1246   //   do Block
1247 
1248   int beg_pos = peek_position();
1249   switch (peek()) {
1250     case Token::THIS: {
1251       BindingPatternUnexpectedToken(classifier);
1252       Consume(Token::THIS);
1253       if (FLAG_strong_this && is_strong(language_mode())) {
1254         // Constructors' usages of 'this' in strong mode are parsed separately.
1255         // TODO(rossberg): this does not work with arrow functions yet.
1256         if (IsClassConstructor(function_state_->kind())) {
1257           ReportMessage(MessageTemplate::kStrongConstructorThis);
1258           *ok = false;
1259           return this->EmptyExpression();
1260         }
1261       }
1262       return this->ThisExpression(scope_, factory(), beg_pos);
1263     }
1264 
1265     case Token::NULL_LITERAL:
1266     case Token::TRUE_LITERAL:
1267     case Token::FALSE_LITERAL:
1268       BindingPatternUnexpectedToken(classifier);
1269       return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1270     case Token::SMI:
1271     case Token::NUMBER:
1272       classifier->RecordBindingPatternError(
1273           scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
1274       return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1275 
1276     case Token::IDENTIFIER:
1277     case Token::LET:
1278     case Token::STATIC:
1279     case Token::YIELD:
1280     case Token::ESCAPED_STRICT_RESERVED_WORD:
1281     case Token::FUTURE_STRICT_RESERVED_WORD: {
1282       // Using eval or arguments in this context is OK even in strict mode.
1283       IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
1284       return this->ExpressionFromIdentifier(
1285           name, beg_pos, scanner()->location().end_pos, scope_, factory());
1286     }
1287 
1288     case Token::STRING: {
1289       classifier->RecordBindingPatternError(
1290           scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString);
1291       Consume(Token::STRING);
1292       return this->ExpressionFromString(beg_pos, scanner(), factory());
1293     }
1294 
1295     case Token::ASSIGN_DIV:
1296       classifier->RecordBindingPatternError(
1297           scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1298       return this->ParseRegExpLiteral(true, classifier, ok);
1299 
1300     case Token::DIV:
1301       classifier->RecordBindingPatternError(
1302           scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1303       return this->ParseRegExpLiteral(false, classifier, ok);
1304 
1305     case Token::LBRACK:
1306       if (!allow_harmony_destructuring_bind()) {
1307         BindingPatternUnexpectedToken(classifier);
1308       }
1309       return this->ParseArrayLiteral(classifier, ok);
1310 
1311     case Token::LBRACE:
1312       if (!allow_harmony_destructuring_bind()) {
1313         BindingPatternUnexpectedToken(classifier);
1314       }
1315       return this->ParseObjectLiteral(classifier, ok);
1316 
1317     case Token::LPAREN: {
1318       // Arrow function formal parameters are either a single identifier or a
1319       // list of BindingPattern productions enclosed in parentheses.
1320       // Parentheses are not valid on the LHS of a BindingPattern, so we use the
1321       // is_valid_binding_pattern() check to detect multiple levels of
1322       // parenthesization.
1323       if (!classifier->is_valid_binding_pattern()) {
1324         ArrowFormalParametersUnexpectedToken(classifier);
1325       }
1326       BindingPatternUnexpectedToken(classifier);
1327       Consume(Token::LPAREN);
1328       if (Check(Token::RPAREN)) {
1329         // ()=>x.  The continuation that looks for the => is in
1330         // ParseAssignmentExpression.
1331         classifier->RecordExpressionError(scanner()->location(),
1332                                           MessageTemplate::kUnexpectedToken,
1333                                           Token::String(Token::RPAREN));
1334         classifier->RecordBindingPatternError(scanner()->location(),
1335                                               MessageTemplate::kUnexpectedToken,
1336                                               Token::String(Token::RPAREN));
1337         return factory()->NewEmptyParentheses(beg_pos);
1338       } else if (Check(Token::ELLIPSIS)) {
1339         // (...x)=>x.  The continuation that looks for the => is in
1340         // ParseAssignmentExpression.
1341         int ellipsis_pos = position();
1342         classifier->RecordExpressionError(scanner()->location(),
1343                                           MessageTemplate::kUnexpectedToken,
1344                                           Token::String(Token::ELLIPSIS));
1345         classifier->RecordNonSimpleParameter();
1346         ExpressionT expr =
1347             this->ParseAssignmentExpression(true, classifier, CHECK_OK);
1348         if (peek() == Token::COMMA) {
1349           ReportMessageAt(scanner()->peek_location(),
1350                           MessageTemplate::kParamAfterRest);
1351           *ok = false;
1352           return this->EmptyExpression();
1353         }
1354         Expect(Token::RPAREN, CHECK_OK);
1355         return factory()->NewSpread(expr, ellipsis_pos);
1356       }
1357       // Heuristically try to detect immediately called functions before
1358       // seeing the call parentheses.
1359       parenthesized_function_ = (peek() == Token::FUNCTION);
1360       ExpressionT expr = this->ParseExpression(true, kIsPossibleArrowFormals,
1361                                                classifier, CHECK_OK);
1362       Expect(Token::RPAREN, CHECK_OK);
1363       if (peek() != Token::ARROW) {
1364         expr->set_is_parenthesized();
1365       }
1366       return expr;
1367     }
1368 
1369     case Token::CLASS: {
1370       BindingPatternUnexpectedToken(classifier);
1371       Consume(Token::CLASS);
1372       if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
1373         ReportMessage(MessageTemplate::kSloppyLexical);
1374         *ok = false;
1375         return this->EmptyExpression();
1376       }
1377       int class_token_position = position();
1378       IdentifierT name = this->EmptyIdentifier();
1379       bool is_strict_reserved_name = false;
1380       Scanner::Location class_name_location = Scanner::Location::invalid();
1381       if (peek_any_identifier()) {
1382         name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1383                                                    CHECK_OK);
1384         class_name_location = scanner()->location();
1385       }
1386       return this->ParseClassLiteral(name, class_name_location,
1387                                      is_strict_reserved_name,
1388                                      class_token_position, ok);
1389     }
1390 
1391     case Token::TEMPLATE_SPAN:
1392     case Token::TEMPLATE_TAIL:
1393       classifier->RecordBindingPatternError(
1394           scanner()->peek_location(),
1395           MessageTemplate::kUnexpectedTemplateString);
1396       return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
1397                                         classifier, ok);
1398 
1399     case Token::MOD:
1400       if (allow_natives() || extension_ != NULL) {
1401         BindingPatternUnexpectedToken(classifier);
1402         return this->ParseV8Intrinsic(ok);
1403       }
1404       break;
1405 
1406     case Token::DO:
1407       if (allow_harmony_do_expressions()) {
1408         BindingPatternUnexpectedToken(classifier);
1409         return Traits::ParseDoExpression(ok);
1410       }
1411       break;
1412 
1413     default:
1414       break;
1415   }
1416 
1417   ReportUnexpectedToken(Next());
1418   *ok = false;
1419   return this->EmptyExpression();
1420 }
1421 
1422 
1423 template <class Traits>
ParseExpression(bool accept_IN,bool * ok)1424 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1425     bool accept_IN, bool* ok) {
1426   ExpressionClassifier classifier;
1427   ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
1428   result = Traits::RewriteNonPattern(result, &classifier, CHECK_OK);
1429   return result;
1430 }
1431 
1432 
1433 template <class Traits>
ParseExpression(bool accept_IN,ExpressionClassifier * classifier,bool * ok)1434 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1435     bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
1436   return ParseExpression(accept_IN, kIsNormalAssignment, classifier, ok);
1437 }
1438 
1439 
1440 template <class Traits>
ParseExpression(bool accept_IN,int flags,ExpressionClassifier * classifier,bool * ok)1441 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1442     bool accept_IN, int flags, ExpressionClassifier* classifier, bool* ok) {
1443   // Expression ::
1444   //   AssignmentExpression
1445   //   Expression ',' AssignmentExpression
1446 
1447   ExpressionClassifier binding_classifier;
1448   ExpressionT result = this->ParseAssignmentExpression(
1449       accept_IN, flags, &binding_classifier, CHECK_OK);
1450   classifier->Accumulate(binding_classifier,
1451                          ExpressionClassifier::AllProductions);
1452   bool is_simple_parameter_list = this->IsIdentifier(result);
1453   bool seen_rest = false;
1454   while (peek() == Token::COMMA) {
1455     if (seen_rest) {
1456       // At this point the production can't possibly be valid, but we don't know
1457       // which error to signal.
1458       classifier->RecordArrowFormalParametersError(
1459           scanner()->peek_location(), MessageTemplate::kParamAfterRest);
1460     }
1461     Consume(Token::COMMA);
1462     bool is_rest = false;
1463     if (peek() == Token::ELLIPSIS) {
1464       // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1465       // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1466       // valid expression or binding pattern.
1467       ExpressionUnexpectedToken(classifier);
1468       BindingPatternUnexpectedToken(classifier);
1469       Consume(Token::ELLIPSIS);
1470       seen_rest = is_rest = true;
1471     }
1472     int pos = position();
1473     ExpressionT right = this->ParseAssignmentExpression(
1474         accept_IN, flags, &binding_classifier, CHECK_OK);
1475     if (is_rest) right = factory()->NewSpread(right, pos);
1476     is_simple_parameter_list =
1477         is_simple_parameter_list && this->IsIdentifier(right);
1478     classifier->Accumulate(binding_classifier,
1479                            ExpressionClassifier::AllProductions);
1480     result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1481   }
1482   if (!is_simple_parameter_list || seen_rest) {
1483     classifier->RecordNonSimpleParameter();
1484   }
1485 
1486   return result;
1487 }
1488 
1489 
1490 template <class Traits>
ParseArrayLiteral(ExpressionClassifier * classifier,bool * ok)1491 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
1492     ExpressionClassifier* classifier, bool* ok) {
1493   // ArrayLiteral ::
1494   //   '[' Expression? (',' Expression?)* ']'
1495 
1496   int pos = peek_position();
1497   typename Traits::Type::ExpressionList values =
1498       this->NewExpressionList(4, zone_);
1499   int first_spread_index = -1;
1500   Expect(Token::LBRACK, CHECK_OK);
1501   while (peek() != Token::RBRACK) {
1502     ExpressionT elem = this->EmptyExpression();
1503     if (peek() == Token::COMMA) {
1504       if (is_strong(language_mode())) {
1505         ReportMessageAt(scanner()->peek_location(),
1506                         MessageTemplate::kStrongEllision);
1507         *ok = false;
1508         return this->EmptyExpression();
1509       }
1510       elem = this->GetLiteralTheHole(peek_position(), factory());
1511     } else if (peek() == Token::ELLIPSIS) {
1512       int start_pos = peek_position();
1513       Consume(Token::ELLIPSIS);
1514       ExpressionT argument =
1515           this->ParseAssignmentExpression(true, classifier, CHECK_OK);
1516       elem = factory()->NewSpread(argument, start_pos);
1517 
1518       if (first_spread_index < 0) {
1519         first_spread_index = values->length();
1520       }
1521 
1522       if (argument->IsAssignment()) {
1523         classifier->RecordPatternError(
1524             Scanner::Location(start_pos, scanner()->location().end_pos),
1525             MessageTemplate::kInvalidDestructuringTarget);
1526       } else {
1527         CheckDestructuringElement(argument, classifier, start_pos,
1528                                   scanner()->location().end_pos);
1529       }
1530 
1531       if (peek() == Token::COMMA) {
1532         classifier->RecordPatternError(
1533             Scanner::Location(start_pos, scanner()->location().end_pos),
1534             MessageTemplate::kElementAfterRest);
1535       }
1536     } else {
1537       elem = this->ParseAssignmentExpression(true, kIsPossiblePatternElement,
1538                                              classifier, CHECK_OK);
1539     }
1540     values->Add(elem, zone_);
1541     if (peek() != Token::RBRACK) {
1542       Expect(Token::COMMA, CHECK_OK);
1543     }
1544   }
1545   Expect(Token::RBRACK, CHECK_OK);
1546 
1547   // Update the scope information before the pre-parsing bailout.
1548   int literal_index = function_state_->NextMaterializedLiteralIndex();
1549 
1550   return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
1551                                     is_strong(language_mode()), pos);
1552 }
1553 
1554 
1555 template <class Traits>
ParsePropertyName(IdentifierT * name,bool * is_get,bool * is_set,bool * is_static,bool * is_computed_name,bool * is_identifier,bool * is_escaped_keyword,ExpressionClassifier * classifier,bool * ok)1556 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
1557     IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
1558     bool* is_computed_name, bool* is_identifier, bool* is_escaped_keyword,
1559     ExpressionClassifier* classifier, bool* ok) {
1560   Token::Value token = peek();
1561   int pos = peek_position();
1562 
1563   // For non computed property names we normalize the name a bit:
1564   //
1565   //   "12" -> 12
1566   //   12.3 -> "12.3"
1567   //   12.30 -> "12.3"
1568   //   identifier -> "identifier"
1569   //
1570   // This is important because we use the property name as a key in a hash
1571   // table when we compute constant properties.
1572   switch (token) {
1573     case Token::STRING:
1574       Consume(Token::STRING);
1575       *name = this->GetSymbol(scanner());
1576       break;
1577 
1578     case Token::SMI:
1579       Consume(Token::SMI);
1580       *name = this->GetNumberAsSymbol(scanner());
1581       break;
1582 
1583     case Token::NUMBER:
1584       Consume(Token::NUMBER);
1585       *name = this->GetNumberAsSymbol(scanner());
1586       break;
1587 
1588     case Token::LBRACK: {
1589       *is_computed_name = true;
1590       Consume(Token::LBRACK);
1591       ExpressionClassifier computed_name_classifier;
1592       ExpressionT expression =
1593           ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
1594       expression = Traits::RewriteNonPattern(
1595           expression, &computed_name_classifier, CHECK_OK);
1596       classifier->Accumulate(computed_name_classifier,
1597                              ExpressionClassifier::ExpressionProductions);
1598       Expect(Token::RBRACK, CHECK_OK);
1599       return expression;
1600     }
1601 
1602     case Token::ESCAPED_KEYWORD:
1603       *is_escaped_keyword = true;
1604       *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
1605       break;
1606 
1607     case Token::STATIC:
1608       *is_static = true;
1609 
1610     // Fall through.
1611     default:
1612       *is_identifier = true;
1613       *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
1614       break;
1615   }
1616 
1617   uint32_t index;
1618   return this->IsArrayIndex(*name, &index)
1619              ? factory()->NewNumberLiteral(index, pos)
1620              : factory()->NewStringLiteral(*name, pos);
1621 }
1622 
1623 
1624 template <class Traits>
1625 typename ParserBase<Traits>::ObjectLiteralPropertyT
ParsePropertyDefinition(ObjectLiteralCheckerBase * checker,bool in_class,bool has_extends,bool is_static,bool * is_computed_name,bool * has_seen_constructor,ExpressionClassifier * classifier,IdentifierT * name,bool * ok)1626 ParserBase<Traits>::ParsePropertyDefinition(
1627     ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
1628     bool is_static, bool* is_computed_name, bool* has_seen_constructor,
1629     ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
1630   DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
1631   ExpressionT value = this->EmptyExpression();
1632   bool is_get = false;
1633   bool is_set = false;
1634   bool name_is_static = false;
1635   bool is_generator = Check(Token::MUL);
1636 
1637   Token::Value name_token = peek();
1638   int next_beg_pos = scanner()->peek_location().beg_pos;
1639   int next_end_pos = scanner()->peek_location().end_pos;
1640   bool is_identifier = false;
1641   bool is_escaped_keyword = false;
1642   ExpressionT name_expression = ParsePropertyName(
1643       name, &is_get, &is_set, &name_is_static, is_computed_name, &is_identifier,
1644       &is_escaped_keyword, classifier,
1645       CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1646 
1647   if (fni_ != nullptr && !*is_computed_name) {
1648     this->PushLiteralName(fni_, *name);
1649   }
1650 
1651   bool escaped_static =
1652       is_escaped_keyword &&
1653       scanner()->is_literal_contextual_keyword(CStrVector("static"));
1654 
1655   if (!in_class && !is_generator) {
1656     DCHECK(!is_static);
1657 
1658     if (peek() == Token::COLON) {
1659       // PropertyDefinition
1660       //    PropertyName ':' AssignmentExpression
1661       if (!*is_computed_name) {
1662         checker->CheckProperty(name_token, kValueProperty, false, false,
1663                                CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1664       }
1665       Consume(Token::COLON);
1666       value = this->ParseAssignmentExpression(
1667           true, kIsPossiblePatternElement, classifier,
1668           CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1669 
1670       return factory()->NewObjectLiteralProperty(name_expression, value, false,
1671                                                  *is_computed_name);
1672     }
1673 
1674     if ((is_identifier || is_escaped_keyword) &&
1675         (peek() == Token::COMMA || peek() == Token::RBRACE ||
1676          peek() == Token::ASSIGN)) {
1677       // PropertyDefinition
1678       //    IdentifierReference
1679       //    CoverInitializedName
1680       //
1681       // CoverInitializedName
1682       //    IdentifierReference Initializer?
1683       if (!Token::IsIdentifier(name_token, language_mode(),
1684                                this->is_generator())) {
1685         if (!escaped_static) {
1686           ReportUnexpectedTokenAt(scanner()->location(), name_token);
1687           *ok = false;
1688           return this->EmptyObjectLiteralProperty();
1689         }
1690       }
1691       if (classifier->duplicate_finder() != nullptr &&
1692           scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1693         classifier->RecordDuplicateFormalParameterError(scanner()->location());
1694       }
1695       if (name_token == Token::LET) {
1696         classifier->RecordLetPatternError(
1697             scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1698       }
1699 
1700       ExpressionT lhs = this->ExpressionFromIdentifier(
1701           *name, next_beg_pos, next_end_pos, scope_, factory());
1702       CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos);
1703 
1704       if (peek() == Token::ASSIGN) {
1705         Consume(Token::ASSIGN);
1706         ExpressionClassifier rhs_classifier;
1707         ExpressionT rhs = this->ParseAssignmentExpression(
1708             true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1709         rhs = Traits::RewriteNonPattern(
1710             rhs, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1711         classifier->Accumulate(rhs_classifier,
1712                                ExpressionClassifier::ExpressionProductions);
1713         value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
1714                                          RelocInfo::kNoPosition);
1715         classifier->RecordCoverInitializedNameError(
1716             Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1717             MessageTemplate::kInvalidCoverInitializedName);
1718       } else {
1719         value = lhs;
1720       }
1721 
1722       return factory()->NewObjectLiteralProperty(
1723           name_expression, value, ObjectLiteralProperty::COMPUTED, false,
1724           false);
1725     }
1726   }
1727 
1728   if (in_class && escaped_static && !is_static) {
1729     ReportUnexpectedTokenAt(scanner()->location(), name_token);
1730     *ok = false;
1731     return this->EmptyObjectLiteralProperty();
1732   }
1733 
1734   // Method definitions are never valid in patterns.
1735   classifier->RecordPatternError(
1736       Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1737       MessageTemplate::kInvalidDestructuringTarget);
1738 
1739   if (is_generator || peek() == Token::LPAREN) {
1740     // MethodDefinition
1741     //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1742     //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1743     if (!*is_computed_name) {
1744       checker->CheckProperty(name_token, kMethodProperty, is_static,
1745                              is_generator,
1746                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1747     }
1748 
1749     FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
1750                                      : FunctionKind::kConciseMethod;
1751 
1752     if (in_class && !is_static && this->IsConstructor(*name)) {
1753       *has_seen_constructor = true;
1754       kind = has_extends ? FunctionKind::kSubclassConstructor
1755                          : FunctionKind::kBaseConstructor;
1756     }
1757 
1758     if (!in_class) kind = WithObjectLiteralBit(kind);
1759 
1760     value = this->ParseFunctionLiteral(
1761         *name, scanner()->location(), kSkipFunctionNameCheck, kind,
1762         RelocInfo::kNoPosition, FunctionLiteral::kAnonymousExpression,
1763         FunctionLiteral::kNormalArity, language_mode(),
1764         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1765 
1766     return factory()->NewObjectLiteralProperty(name_expression, value,
1767                                                ObjectLiteralProperty::COMPUTED,
1768                                                is_static, *is_computed_name);
1769   }
1770 
1771   if (in_class && name_is_static && !is_static) {
1772     // ClassElement (static)
1773     //    'static' MethodDefinition
1774     *name = this->EmptyIdentifier();
1775     ObjectLiteralPropertyT property = ParsePropertyDefinition(
1776         checker, true, has_extends, true, is_computed_name, nullptr, classifier,
1777         name, ok);
1778     property = Traits::RewriteNonPatternObjectLiteralProperty(property,
1779                                                               classifier, ok);
1780     return property;
1781   }
1782 
1783   if (is_get || is_set) {
1784     // MethodDefinition (Accessors)
1785     //    get PropertyName '(' ')' '{' FunctionBody '}'
1786     //    set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
1787     *name = this->EmptyIdentifier();
1788     bool dont_care = false;
1789     name_token = peek();
1790 
1791     name_expression = ParsePropertyName(
1792         name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care,
1793         &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1794 
1795     if (!*is_computed_name) {
1796       checker->CheckProperty(name_token, kAccessorProperty, is_static,
1797                              is_generator,
1798                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1799     }
1800 
1801     FunctionKind kind = FunctionKind::kAccessorFunction;
1802     if (!in_class) kind = WithObjectLiteralBit(kind);
1803     typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
1804         *name, scanner()->location(), kSkipFunctionNameCheck, kind,
1805         RelocInfo::kNoPosition, FunctionLiteral::kAnonymousExpression,
1806         is_get ? FunctionLiteral::kGetterArity : FunctionLiteral::kSetterArity,
1807         language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1808 
1809     // Make sure the name expression is a string since we need a Name for
1810     // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
1811     // statically we can skip the extra runtime check.
1812     if (!*is_computed_name) {
1813       name_expression =
1814           factory()->NewStringLiteral(*name, name_expression->position());
1815     }
1816 
1817     return factory()->NewObjectLiteralProperty(
1818         name_expression, value,
1819         is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
1820         is_static, *is_computed_name);
1821   }
1822 
1823   Token::Value next = Next();
1824   ReportUnexpectedToken(next);
1825   *ok = false;
1826   return this->EmptyObjectLiteralProperty();
1827 }
1828 
1829 
1830 template <class Traits>
ParseObjectLiteral(ExpressionClassifier * classifier,bool * ok)1831 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
1832     ExpressionClassifier* classifier, bool* ok) {
1833   // ObjectLiteral ::
1834   // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
1835 
1836   int pos = peek_position();
1837   typename Traits::Type::PropertyList properties =
1838       this->NewPropertyList(4, zone_);
1839   int number_of_boilerplate_properties = 0;
1840   bool has_function = false;
1841   bool has_computed_names = false;
1842   ObjectLiteralChecker checker(this);
1843 
1844   Expect(Token::LBRACE, CHECK_OK);
1845 
1846   while (peek() != Token::RBRACE) {
1847     FuncNameInferrer::State fni_state(fni_);
1848 
1849     const bool in_class = false;
1850     const bool is_static = false;
1851     const bool has_extends = false;
1852     bool is_computed_name = false;
1853     IdentifierT name = this->EmptyIdentifier();
1854     ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
1855         &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
1856         classifier, &name, CHECK_OK);
1857 
1858     if (is_computed_name) {
1859       has_computed_names = true;
1860     }
1861 
1862     // Mark top-level object literals that contain function literals and
1863     // pretenure the literal so it can be added as a constant function
1864     // property. (Parser only.)
1865     this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
1866                                                           &has_function);
1867 
1868     // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
1869     if (!has_computed_names && this->IsBoilerplateProperty(property)) {
1870       number_of_boilerplate_properties++;
1871     }
1872     properties->Add(property, zone());
1873 
1874     if (peek() != Token::RBRACE) {
1875       // Need {} because of the CHECK_OK macro.
1876       Expect(Token::COMMA, CHECK_OK);
1877     }
1878 
1879     if (fni_ != nullptr) fni_->Infer();
1880 
1881     if (allow_harmony_function_name()) {
1882       Traits::SetFunctionNameFromPropertyName(property, name);
1883     }
1884   }
1885   Expect(Token::RBRACE, CHECK_OK);
1886 
1887   // Computation of literal_index must happen before pre parse bailout.
1888   int literal_index = function_state_->NextMaterializedLiteralIndex();
1889 
1890   return factory()->NewObjectLiteral(properties,
1891                                      literal_index,
1892                                      number_of_boilerplate_properties,
1893                                      has_function,
1894                                      is_strong(language_mode()),
1895                                      pos);
1896 }
1897 
1898 
1899 template <class Traits>
ParseArguments(Scanner::Location * first_spread_arg_loc,ExpressionClassifier * classifier,bool * ok)1900 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
1901     Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier,
1902     bool* ok) {
1903   // Arguments ::
1904   //   '(' (AssignmentExpression)*[','] ')'
1905 
1906   Scanner::Location spread_arg = Scanner::Location::invalid();
1907   typename Traits::Type::ExpressionList result =
1908       this->NewExpressionList(4, zone_);
1909   Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1910   bool done = (peek() == Token::RPAREN);
1911   bool was_unspread = false;
1912   int unspread_sequences_count = 0;
1913   while (!done) {
1914     int start_pos = peek_position();
1915     bool is_spread = Check(Token::ELLIPSIS);
1916 
1917     ExpressionT argument = this->ParseAssignmentExpression(
1918         true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
1919     argument = Traits::RewriteNonPattern(argument, classifier,
1920                                          CHECK_OK_CUSTOM(NullExpressionList));
1921     if (is_spread) {
1922       if (!spread_arg.IsValid()) {
1923         spread_arg.beg_pos = start_pos;
1924         spread_arg.end_pos = peek_position();
1925       }
1926       argument = factory()->NewSpread(argument, start_pos);
1927     }
1928     result->Add(argument, zone_);
1929 
1930     // unspread_sequences_count is the number of sequences of parameters which
1931     // are not prefixed with a spread '...' operator.
1932     if (is_spread) {
1933       was_unspread = false;
1934     } else if (!was_unspread) {
1935       was_unspread = true;
1936       unspread_sequences_count++;
1937     }
1938 
1939     if (result->length() > Code::kMaxArguments) {
1940       ReportMessage(MessageTemplate::kTooManyArguments);
1941       *ok = false;
1942       return this->NullExpressionList();
1943     }
1944     done = (peek() != Token::COMMA);
1945     if (!done) {
1946       Next();
1947     }
1948   }
1949   Scanner::Location location = scanner_->location();
1950   if (Token::RPAREN != Next()) {
1951     ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
1952     *ok = false;
1953     return this->NullExpressionList();
1954   }
1955   *first_spread_arg_loc = spread_arg;
1956 
1957   if (spread_arg.IsValid()) {
1958     // Unspread parameter sequences are translated into array literals in the
1959     // parser. Ensure that the number of materialized literals matches between
1960     // the parser and preparser
1961     Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
1962   }
1963 
1964   return result;
1965 }
1966 
1967 // Precedence = 2
1968 template <class Traits>
1969 typename ParserBase<Traits>::ExpressionT
ParseAssignmentExpression(bool accept_IN,int flags,ExpressionClassifier * classifier,bool * ok)1970 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
1971                                               ExpressionClassifier* classifier,
1972                                               bool* ok) {
1973   // AssignmentExpression ::
1974   //   ConditionalExpression
1975   //   ArrowFunction
1976   //   YieldExpression
1977   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
1978   bool maybe_pattern_element = flags & kIsPossiblePatternElement;
1979   bool maybe_arrow_formals = flags & kIsPossibleArrowFormals;
1980   bool is_destructuring_assignment = false;
1981   int lhs_beg_pos = peek_position();
1982 
1983   if (peek() == Token::YIELD && is_generator()) {
1984     return this->ParseYieldExpression(classifier, ok);
1985   }
1986 
1987   FuncNameInferrer::State fni_state(fni_);
1988   ParserBase<Traits>::Checkpoint checkpoint(this);
1989   ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
1990   bool parenthesized_formals = peek() == Token::LPAREN;
1991   if (!parenthesized_formals) {
1992     ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
1993   }
1994   ExpressionT expression = this->ParseConditionalExpression(
1995       accept_IN, &arrow_formals_classifier, CHECK_OK);
1996   if (peek() == Token::ARROW) {
1997     BindingPatternUnexpectedToken(classifier);
1998     ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
1999                                   parenthesized_formals, CHECK_OK);
2000     Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2001     Scope* scope =
2002         this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
2003     // Because the arrow's parameters were parsed in the outer scope, any
2004     // usage flags that might have been triggered there need to be copied
2005     // to the arrow scope.
2006     scope_->PropagateUsageFlagsToScope(scope);
2007     FormalParametersT parameters(scope);
2008     if (!arrow_formals_classifier.is_simple_parameter_list()) {
2009       scope->SetHasNonSimpleParameters();
2010       parameters.is_simple = false;
2011     }
2012 
2013     checkpoint.Restore(&parameters.materialized_literals_count);
2014 
2015     scope->set_start_position(lhs_beg_pos);
2016     Scanner::Location duplicate_loc = Scanner::Location::invalid();
2017     this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2018                                                 &duplicate_loc, CHECK_OK);
2019     if (duplicate_loc.IsValid()) {
2020       arrow_formals_classifier.RecordDuplicateFormalParameterError(
2021           duplicate_loc);
2022     }
2023     expression = this->ParseArrowFunctionLiteral(
2024         accept_IN, parameters, arrow_formals_classifier, CHECK_OK);
2025     if (maybe_pattern_element) {
2026       classifier->RecordPatternError(
2027           Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
2028           MessageTemplate::kInvalidDestructuringTarget);
2029     }
2030 
2031     if (fni_ != nullptr) fni_->Infer();
2032 
2033     return expression;
2034   }
2035 
2036   if (this->IsValidReferenceExpression(expression)) {
2037     arrow_formals_classifier.ForgiveAssignmentPatternError();
2038   }
2039 
2040   // "expression" was not itself an arrow function parameter list, but it might
2041   // form part of one.  Propagate speculative formal parameter error locations.
2042   classifier->Accumulate(
2043       arrow_formals_classifier,
2044       ExpressionClassifier::StandardProductions |
2045           ExpressionClassifier::FormalParametersProductions |
2046           ExpressionClassifier::CoverInitializedNameProduction);
2047 
2048   bool maybe_pattern =
2049       (expression->IsObjectLiteral() || expression->IsArrayLiteral()) &&
2050       !expression->is_parenthesized();
2051 
2052   if (!Token::IsAssignmentOp(peek())) {
2053     // Parsed conditional expression only (no assignment).
2054     if (maybe_pattern_element) {
2055       CheckDestructuringElement(expression, classifier, lhs_beg_pos,
2056                                 scanner()->location().end_pos);
2057     }
2058     return expression;
2059   }
2060 
2061   if (!(allow_harmony_destructuring_bind() ||
2062         allow_harmony_default_parameters())) {
2063     BindingPatternUnexpectedToken(classifier);
2064   }
2065 
2066   if (allow_harmony_destructuring_assignment() && maybe_pattern &&
2067       peek() == Token::ASSIGN) {
2068     classifier->ForgiveCoverInitializedNameError();
2069     ValidateAssignmentPattern(classifier, CHECK_OK);
2070     is_destructuring_assignment = true;
2071   } else if (maybe_arrow_formals) {
2072     expression = this->ClassifyAndRewriteReferenceExpression(
2073         classifier, expression, lhs_beg_pos, scanner()->location().end_pos,
2074         MessageTemplate::kInvalidLhsInAssignment);
2075   } else {
2076     if (maybe_pattern_element) {
2077       CheckDestructuringElement(expression, classifier, lhs_beg_pos,
2078                                 scanner()->location().end_pos);
2079     }
2080     expression = this->CheckAndRewriteReferenceExpression(
2081         expression, lhs_beg_pos, scanner()->location().end_pos,
2082         MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2083   }
2084 
2085   expression = this->MarkExpressionAsAssigned(expression);
2086 
2087   Token::Value op = Next();  // Get assignment operator.
2088   if (op != Token::ASSIGN) {
2089     classifier->RecordBindingPatternError(scanner()->location(),
2090                                           MessageTemplate::kUnexpectedToken,
2091                                           Token::String(op));
2092   }
2093   int pos = position();
2094 
2095   ExpressionClassifier rhs_classifier;
2096 
2097   ExpressionT right =
2098       this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
2099   right = Traits::RewriteNonPattern(right, &rhs_classifier, CHECK_OK);
2100   classifier->Accumulate(
2101       rhs_classifier, ExpressionClassifier::ExpressionProductions |
2102                           ExpressionClassifier::CoverInitializedNameProduction);
2103 
2104   // TODO(1231235): We try to estimate the set of properties set by
2105   // constructors. We define a new property whenever there is an
2106   // assignment to a property of 'this'. We should probably only add
2107   // properties if we haven't seen them before. Otherwise we'll
2108   // probably overestimate the number of properties.
2109   if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2110     function_state_->AddProperty();
2111   }
2112 
2113   if (op != Token::ASSIGN && maybe_pattern_element) {
2114     classifier->RecordAssignmentPatternError(
2115         Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
2116         MessageTemplate::kInvalidDestructuringTarget);
2117   }
2118 
2119   this->CheckAssigningFunctionLiteralToProperty(expression, right);
2120 
2121   if (fni_ != NULL) {
2122     // Check if the right hand side is a call to avoid inferring a
2123     // name if we're dealing with "a = function(){...}();"-like
2124     // expression.
2125     if ((op == Token::INIT || op == Token::ASSIGN) &&
2126         (!right->IsCall() && !right->IsCallNew())) {
2127       fni_->Infer();
2128     } else {
2129       fni_->RemoveLastFunction();
2130     }
2131   }
2132 
2133   if (op == Token::ASSIGN && allow_harmony_function_name()) {
2134     Traits::SetFunctionNameFromIdentifierRef(right, expression);
2135   }
2136 
2137   ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2138 
2139   if (is_destructuring_assignment) {
2140     result = factory()->NewRewritableAssignmentExpression(result);
2141     Traits::QueueDestructuringAssignmentForRewriting(result);
2142   }
2143 
2144   return result;
2145 }
2146 
2147 template <class Traits>
2148 typename ParserBase<Traits>::ExpressionT
ParseYieldExpression(ExpressionClassifier * classifier,bool * ok)2149 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
2150                                          bool* ok) {
2151   // YieldExpression ::
2152   //   'yield' ([no line terminator] '*'? AssignmentExpression)?
2153   int pos = peek_position();
2154   classifier->RecordPatternError(scanner()->peek_location(),
2155                                  MessageTemplate::kInvalidDestructuringTarget);
2156   FormalParameterInitializerUnexpectedToken(classifier);
2157   Expect(Token::YIELD, CHECK_OK);
2158   ExpressionT generator_object =
2159       factory()->NewVariableProxy(function_state_->generator_object_variable());
2160   ExpressionT expression = Traits::EmptyExpression();
2161   Yield::Kind kind = Yield::kSuspend;
2162   if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2163     if (Check(Token::MUL)) kind = Yield::kDelegating;
2164     switch (peek()) {
2165       case Token::EOS:
2166       case Token::SEMICOLON:
2167       case Token::RBRACE:
2168       case Token::RBRACK:
2169       case Token::RPAREN:
2170       case Token::COLON:
2171       case Token::COMMA:
2172         // The above set of tokens is the complete set of tokens that can appear
2173         // after an AssignmentExpression, and none of them can start an
2174         // AssignmentExpression.  This allows us to avoid looking for an RHS for
2175         // a Yield::kSuspend operation, given only one look-ahead token.
2176         if (kind == Yield::kSuspend)
2177           break;
2178         DCHECK_EQ(Yield::kDelegating, kind);
2179         // Delegating yields require an RHS; fall through.
2180       default:
2181         expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
2182         expression =
2183             Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
2184         break;
2185     }
2186   }
2187   if (kind == Yield::kDelegating) {
2188     // var iterator = subject[Symbol.iterator]();
2189     // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2190     // TODO(verwaest): Come up with a better solution.
2191     expression = this->GetIterator(expression, factory(), pos + 1);
2192   }
2193   // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2194   // TODO(verwaest): Come up with a better solution.
2195   typename Traits::Type::YieldExpression yield =
2196       factory()->NewYield(generator_object, expression, kind, pos);
2197   return yield;
2198 }
2199 
2200 
2201 // Precedence = 3
2202 template <class Traits>
2203 typename ParserBase<Traits>::ExpressionT
ParseConditionalExpression(bool accept_IN,ExpressionClassifier * classifier,bool * ok)2204 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
2205                                                ExpressionClassifier* classifier,
2206                                                bool* ok) {
2207   // ConditionalExpression ::
2208   //   LogicalOrExpression
2209   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2210 
2211   int pos = peek_position();
2212   // We start using the binary expression parser for prec >= 4 only!
2213   ExpressionT expression =
2214       this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2215   if (peek() != Token::CONDITIONAL) return expression;
2216   expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
2217   ArrowFormalParametersUnexpectedToken(classifier);
2218   BindingPatternUnexpectedToken(classifier);
2219   Consume(Token::CONDITIONAL);
2220   // In parsing the first assignment expression in conditional
2221   // expressions we always accept the 'in' keyword; see ECMA-262,
2222   // section 11.12, page 58.
2223   ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
2224   left = Traits::RewriteNonPattern(left, classifier, CHECK_OK);
2225   Expect(Token::COLON, CHECK_OK);
2226   ExpressionT right =
2227       ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
2228   right = Traits::RewriteNonPattern(right, classifier, CHECK_OK);
2229   return factory()->NewConditional(expression, left, right, pos);
2230 }
2231 
2232 
2233 // Precedence >= 4
2234 template <class Traits>
2235 typename ParserBase<Traits>::ExpressionT
ParseBinaryExpression(int prec,bool accept_IN,ExpressionClassifier * classifier,bool * ok)2236 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
2237                                           ExpressionClassifier* classifier,
2238                                           bool* ok) {
2239   DCHECK(prec >= 4);
2240   ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2241   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2242     // prec1 >= 4
2243     while (Precedence(peek(), accept_IN) == prec1) {
2244       x = Traits::RewriteNonPattern(x, classifier, CHECK_OK);
2245       BindingPatternUnexpectedToken(classifier);
2246       ArrowFormalParametersUnexpectedToken(classifier);
2247       Token::Value op = Next();
2248       Scanner::Location op_location = scanner()->location();
2249       int pos = position();
2250       ExpressionT y =
2251           ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
2252       y = Traits::RewriteNonPattern(y, classifier, CHECK_OK);
2253 
2254       if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2255                                                        factory())) {
2256         continue;
2257       }
2258 
2259       // For now we distinguish between comparisons and other binary
2260       // operations.  (We could combine the two and get rid of this
2261       // code and AST node eventually.)
2262       if (Token::IsCompareOp(op)) {
2263         // We have a comparison.
2264         Token::Value cmp = op;
2265         switch (op) {
2266           case Token::NE: cmp = Token::EQ; break;
2267           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2268           default: break;
2269         }
2270         if (cmp == Token::EQ && is_strong(language_mode())) {
2271           ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
2272           *ok = false;
2273           return this->EmptyExpression();
2274         }
2275         x = factory()->NewCompareOperation(cmp, x, y, pos);
2276         if (cmp != op) {
2277           // The comparison was negated - add a NOT.
2278           x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2279         }
2280 
2281       } else {
2282         // We have a "normal" binary operation.
2283         x = factory()->NewBinaryOperation(op, x, y, pos);
2284       }
2285     }
2286   }
2287   return x;
2288 }
2289 
2290 
2291 template <class Traits>
2292 typename ParserBase<Traits>::ExpressionT
ParseUnaryExpression(ExpressionClassifier * classifier,bool * ok)2293 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
2294                                          bool* ok) {
2295   // UnaryExpression ::
2296   //   PostfixExpression
2297   //   'delete' UnaryExpression
2298   //   'void' UnaryExpression
2299   //   'typeof' UnaryExpression
2300   //   '++' UnaryExpression
2301   //   '--' UnaryExpression
2302   //   '+' UnaryExpression
2303   //   '-' UnaryExpression
2304   //   '~' UnaryExpression
2305   //   '!' UnaryExpression
2306 
2307   Token::Value op = peek();
2308   if (Token::IsUnaryOp(op)) {
2309     BindingPatternUnexpectedToken(classifier);
2310     ArrowFormalParametersUnexpectedToken(classifier);
2311 
2312     op = Next();
2313     int pos = position();
2314     ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
2315     expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
2316 
2317     if (op == Token::DELETE && is_strict(language_mode())) {
2318       if (is_strong(language_mode())) {
2319         ReportMessage(MessageTemplate::kStrongDelete);
2320         *ok = false;
2321         return this->EmptyExpression();
2322       } else if (this->IsIdentifier(expression)) {
2323         // "delete identifier" is a syntax error in strict mode.
2324         ReportMessage(MessageTemplate::kStrictDelete);
2325         *ok = false;
2326         return this->EmptyExpression();
2327       }
2328     }
2329 
2330     // Allow Traits do rewrite the expression.
2331     return this->BuildUnaryExpression(expression, op, pos, factory());
2332   } else if (Token::IsCountOp(op)) {
2333     BindingPatternUnexpectedToken(classifier);
2334     ArrowFormalParametersUnexpectedToken(classifier);
2335     op = Next();
2336     int beg_pos = peek_position();
2337     ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
2338     expression = this->CheckAndRewriteReferenceExpression(
2339         expression, beg_pos, scanner()->location().end_pos,
2340         MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
2341     this->MarkExpressionAsAssigned(expression);
2342     expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
2343 
2344     return factory()->NewCountOperation(op,
2345                                         true /* prefix */,
2346                                         expression,
2347                                         position());
2348 
2349   } else {
2350     return this->ParsePostfixExpression(classifier, ok);
2351   }
2352 }
2353 
2354 
2355 template <class Traits>
2356 typename ParserBase<Traits>::ExpressionT
ParsePostfixExpression(ExpressionClassifier * classifier,bool * ok)2357 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
2358                                            bool* ok) {
2359   // PostfixExpression ::
2360   //   LeftHandSideExpression ('++' | '--')?
2361 
2362   int lhs_beg_pos = peek_position();
2363   ExpressionT expression =
2364       this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2365   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2366       Token::IsCountOp(peek())) {
2367     BindingPatternUnexpectedToken(classifier);
2368     ArrowFormalParametersUnexpectedToken(classifier);
2369 
2370     expression = this->CheckAndRewriteReferenceExpression(
2371         expression, lhs_beg_pos, scanner()->location().end_pos,
2372         MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
2373     expression = this->MarkExpressionAsAssigned(expression);
2374     expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
2375 
2376     Token::Value next = Next();
2377     expression =
2378         factory()->NewCountOperation(next,
2379                                      false /* postfix */,
2380                                      expression,
2381                                      position());
2382   }
2383   return expression;
2384 }
2385 
2386 
2387 template <class Traits>
2388 typename ParserBase<Traits>::ExpressionT
ParseLeftHandSideExpression(ExpressionClassifier * classifier,bool * ok)2389 ParserBase<Traits>::ParseLeftHandSideExpression(
2390     ExpressionClassifier* classifier, bool* ok) {
2391   // LeftHandSideExpression ::
2392   //   (NewExpression | MemberExpression) ...
2393 
2394   ExpressionT result =
2395       this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
2396 
2397   while (true) {
2398     switch (peek()) {
2399       case Token::LBRACK: {
2400         BindingPatternUnexpectedToken(classifier);
2401         ArrowFormalParametersUnexpectedToken(classifier);
2402         Consume(Token::LBRACK);
2403         int pos = position();
2404         ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
2405         index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
2406         result = factory()->NewProperty(result, index, pos);
2407         Expect(Token::RBRACK, CHECK_OK);
2408         break;
2409       }
2410 
2411       case Token::LPAREN: {
2412         result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
2413         BindingPatternUnexpectedToken(classifier);
2414         ArrowFormalParametersUnexpectedToken(classifier);
2415 
2416         if (is_strong(language_mode()) && this->IsIdentifier(result) &&
2417             this->IsEval(this->AsIdentifier(result))) {
2418           ReportMessage(MessageTemplate::kStrongDirectEval);
2419           *ok = false;
2420           return this->EmptyExpression();
2421         }
2422         int pos;
2423         if (scanner()->current_token() == Token::IDENTIFIER ||
2424             scanner()->current_token() == Token::SUPER) {
2425           // For call of an identifier we want to report position of
2426           // the identifier as position of the call in the stack trace.
2427           pos = position();
2428         } else {
2429           // For other kinds of calls we record position of the parenthesis as
2430           // position of the call. Note that this is extremely important for
2431           // expressions of the form function(){...}() for which call position
2432           // should not point to the closing brace otherwise it will intersect
2433           // with positions recorded for function literal and confuse debugger.
2434           pos = peek_position();
2435           // Also the trailing parenthesis are a hint that the function will
2436           // be called immediately. If we happen to have parsed a preceding
2437           // function literal eagerly, we can also compile it eagerly.
2438           if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2439             result->AsFunctionLiteral()->set_should_eager_compile();
2440           }
2441         }
2442         Scanner::Location spread_pos;
2443         typename Traits::Type::ExpressionList args =
2444             ParseArguments(&spread_pos, classifier, CHECK_OK);
2445 
2446         // Keep track of eval() calls since they disable all local variable
2447         // optimizations.
2448         // The calls that need special treatment are the
2449         // direct eval calls. These calls are all of the form eval(...), with
2450         // no explicit receiver.
2451         // These calls are marked as potentially direct eval calls. Whether
2452         // they are actually direct calls to eval is determined at run time.
2453         this->CheckPossibleEvalCall(result, scope_);
2454 
2455         bool is_super_call = result->IsSuperCallReference();
2456         if (spread_pos.IsValid()) {
2457           args = Traits::PrepareSpreadArguments(args);
2458           result = Traits::SpreadCall(result, args, pos);
2459         } else {
2460           result = factory()->NewCall(result, args, pos);
2461         }
2462 
2463         // Explicit calls to the super constructor using super() perform an
2464         // implicit binding assignment to the 'this' variable.
2465         if (is_super_call) {
2466           ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2467           result =
2468               factory()->NewAssignment(Token::INIT, this_expr, result, pos);
2469         }
2470 
2471         if (fni_ != NULL) fni_->RemoveLastFunction();
2472         break;
2473       }
2474 
2475       case Token::PERIOD: {
2476         BindingPatternUnexpectedToken(classifier);
2477         ArrowFormalParametersUnexpectedToken(classifier);
2478         Consume(Token::PERIOD);
2479         int pos = position();
2480         IdentifierT name = ParseIdentifierName(CHECK_OK);
2481         result = factory()->NewProperty(
2482             result, factory()->NewStringLiteral(name, pos), pos);
2483         if (fni_ != NULL) this->PushLiteralName(fni_, name);
2484         break;
2485       }
2486 
2487       case Token::TEMPLATE_SPAN:
2488       case Token::TEMPLATE_TAIL: {
2489         BindingPatternUnexpectedToken(classifier);
2490         ArrowFormalParametersUnexpectedToken(classifier);
2491         result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
2492         break;
2493       }
2494 
2495       default:
2496         return result;
2497     }
2498   }
2499 }
2500 
2501 
2502 template <class Traits>
2503 typename ParserBase<Traits>::ExpressionT
ParseMemberWithNewPrefixesExpression(ExpressionClassifier * classifier,bool * ok)2504 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
2505     ExpressionClassifier* classifier, bool* ok) {
2506   // NewExpression ::
2507   //   ('new')+ MemberExpression
2508   //
2509   // NewTarget ::
2510   //   'new' '.' 'target'
2511 
2512   // The grammar for new expressions is pretty warped. We can have several 'new'
2513   // keywords following each other, and then a MemberExpression. When we see '('
2514   // after the MemberExpression, it's associated with the rightmost unassociated
2515   // 'new' to create a NewExpression with arguments. However, a NewExpression
2516   // can also occur without arguments.
2517 
2518   // Examples of new expression:
2519   // new foo.bar().baz means (new (foo.bar)()).baz
2520   // new foo()() means (new foo())()
2521   // new new foo()() means (new (new foo())())
2522   // new new foo means new (new foo)
2523   // new new foo() means new (new foo())
2524   // new new foo().bar().baz means (new (new foo()).bar()).baz
2525 
2526   if (peek() == Token::NEW) {
2527     BindingPatternUnexpectedToken(classifier);
2528     ArrowFormalParametersUnexpectedToken(classifier);
2529     Consume(Token::NEW);
2530     int new_pos = position();
2531     ExpressionT result = this->EmptyExpression();
2532     if (peek() == Token::SUPER) {
2533       const bool is_new = true;
2534       result = ParseSuperExpression(is_new, classifier, CHECK_OK);
2535     } else if (peek() == Token::PERIOD) {
2536       return ParseNewTargetExpression(CHECK_OK);
2537     } else {
2538       result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
2539     }
2540     result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
2541     if (peek() == Token::LPAREN) {
2542       // NewExpression with arguments.
2543       Scanner::Location spread_pos;
2544       typename Traits::Type::ExpressionList args =
2545           this->ParseArguments(&spread_pos, classifier, CHECK_OK);
2546 
2547       if (spread_pos.IsValid()) {
2548         args = Traits::PrepareSpreadArguments(args);
2549         result = Traits::SpreadCallNew(result, args, new_pos);
2550       } else {
2551         result = factory()->NewCallNew(result, args, new_pos);
2552       }
2553       // The expression can still continue with . or [ after the arguments.
2554       result =
2555           this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
2556       return result;
2557     }
2558     // NewExpression without arguments.
2559     return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2560                                  new_pos);
2561   }
2562   // No 'new' or 'super' keyword.
2563   return this->ParseMemberExpression(classifier, ok);
2564 }
2565 
2566 
2567 template <class Traits>
2568 typename ParserBase<Traits>::ExpressionT
ParseMemberExpression(ExpressionClassifier * classifier,bool * ok)2569 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
2570                                           bool* ok) {
2571   // MemberExpression ::
2572   //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
2573   //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
2574 
2575   // The '[' Expression ']' and '.' Identifier parts are parsed by
2576   // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2577   // caller.
2578 
2579   // Parse the initial primary or function expression.
2580   ExpressionT result = this->EmptyExpression();
2581   if (peek() == Token::FUNCTION) {
2582     BindingPatternUnexpectedToken(classifier);
2583     ArrowFormalParametersUnexpectedToken(classifier);
2584 
2585     Consume(Token::FUNCTION);
2586     int function_token_position = position();
2587     bool is_generator = Check(Token::MUL);
2588     IdentifierT name = this->EmptyIdentifier();
2589     bool is_strict_reserved_name = false;
2590     Scanner::Location function_name_location = Scanner::Location::invalid();
2591     FunctionLiteral::FunctionType function_type =
2592         FunctionLiteral::kAnonymousExpression;
2593     if (peek_any_identifier()) {
2594       name = ParseIdentifierOrStrictReservedWord(
2595           is_generator, &is_strict_reserved_name, CHECK_OK);
2596       function_name_location = scanner()->location();
2597       function_type = FunctionLiteral::kNamedExpression;
2598     }
2599     result = this->ParseFunctionLiteral(
2600         name, function_name_location,
2601         is_strict_reserved_name ? kFunctionNameIsStrictReserved
2602                                 : kFunctionNameValidityUnknown,
2603         is_generator ? FunctionKind::kGeneratorFunction
2604                      : FunctionKind::kNormalFunction,
2605         function_token_position, function_type, FunctionLiteral::kNormalArity,
2606         language_mode(), CHECK_OK);
2607   } else if (peek() == Token::SUPER) {
2608     const bool is_new = false;
2609     result = ParseSuperExpression(is_new, classifier, CHECK_OK);
2610   } else {
2611     result = ParsePrimaryExpression(classifier, CHECK_OK);
2612   }
2613 
2614   result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
2615   return result;
2616 }
2617 
2618 
2619 template <class Traits>
2620 typename ParserBase<Traits>::ExpressionT
ParseStrongInitializationExpression(ExpressionClassifier * classifier,bool * ok)2621 ParserBase<Traits>::ParseStrongInitializationExpression(
2622     ExpressionClassifier* classifier, bool* ok) {
2623   // InitializationExpression ::  (strong mode)
2624   //  'this' '.' IdentifierName '=' AssignmentExpression
2625   //  'this' '[' Expression ']' '=' AssignmentExpression
2626 
2627   FuncNameInferrer::State fni_state(fni_);
2628 
2629   Consume(Token::THIS);
2630   int pos = position();
2631   function_state_->set_this_location(scanner()->location());
2632   ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2633 
2634   ExpressionT left = this->EmptyExpression();
2635   switch (peek()) {
2636     case Token::LBRACK: {
2637       Consume(Token::LBRACK);
2638       int pos = position();
2639       ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
2640       index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
2641       left = factory()->NewProperty(this_expr, index, pos);
2642       if (fni_ != NULL) {
2643         this->PushPropertyName(fni_, index);
2644       }
2645       Expect(Token::RBRACK, CHECK_OK);
2646       break;
2647     }
2648     case Token::PERIOD: {
2649       Consume(Token::PERIOD);
2650       int pos = position();
2651       IdentifierT name = ParseIdentifierName(CHECK_OK);
2652       left = factory()->NewProperty(
2653           this_expr, factory()->NewStringLiteral(name, pos), pos);
2654       if (fni_ != NULL) {
2655         this->PushLiteralName(fni_, name);
2656       }
2657       break;
2658     }
2659     default:
2660       ReportMessage(MessageTemplate::kStrongConstructorThis);
2661       *ok = false;
2662       return this->EmptyExpression();
2663   }
2664 
2665   if (peek() != Token::ASSIGN) {
2666     ReportMessageAt(function_state_->this_location(),
2667                     MessageTemplate::kStrongConstructorThis);
2668     *ok = false;
2669     return this->EmptyExpression();
2670   }
2671   Consume(Token::ASSIGN);
2672   left = this->MarkExpressionAsAssigned(left);
2673 
2674   ExpressionT right =
2675       this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2676   right = Traits::RewriteNonPattern(right, classifier, CHECK_OK);
2677   this->CheckAssigningFunctionLiteralToProperty(left, right);
2678   function_state_->AddProperty();
2679   if (fni_ != NULL) {
2680     // Check if the right hand side is a call to avoid inferring a
2681     // name if we're dealing with "this.a = function(){...}();"-like
2682     // expression.
2683     if (!right->IsCall() && !right->IsCallNew()) {
2684       fni_->Infer();
2685     } else {
2686       fni_->RemoveLastFunction();
2687     }
2688   }
2689 
2690   if (function_state_->return_location().IsValid()) {
2691     ReportMessageAt(function_state_->return_location(),
2692                     MessageTemplate::kStrongConstructorReturnMisplaced);
2693     *ok = false;
2694     return this->EmptyExpression();
2695   }
2696 
2697   return factory()->NewAssignment(Token::ASSIGN, left, right, pos);
2698 }
2699 
2700 
2701 template <class Traits>
2702 typename ParserBase<Traits>::ExpressionT
ParseStrongSuperCallExpression(ExpressionClassifier * classifier,bool * ok)2703 ParserBase<Traits>::ParseStrongSuperCallExpression(
2704     ExpressionClassifier* classifier, bool* ok) {
2705   // SuperCallExpression ::  (strong mode)
2706   //  'super' '(' ExpressionList ')'
2707   BindingPatternUnexpectedToken(classifier);
2708 
2709   Consume(Token::SUPER);
2710   int pos = position();
2711   Scanner::Location super_loc = scanner()->location();
2712   ExpressionT expr = this->SuperCallReference(scope_, factory(), pos);
2713 
2714   if (peek() != Token::LPAREN) {
2715     ReportMessage(MessageTemplate::kStrongConstructorSuper);
2716     *ok = false;
2717     return this->EmptyExpression();
2718   }
2719 
2720   Scanner::Location spread_pos;
2721   typename Traits::Type::ExpressionList args =
2722       ParseArguments(&spread_pos, classifier, CHECK_OK);
2723 
2724   // TODO(rossberg): This doesn't work with arrow functions yet.
2725   if (!IsSubclassConstructor(function_state_->kind())) {
2726     ReportMessage(MessageTemplate::kUnexpectedSuper);
2727     *ok = false;
2728     return this->EmptyExpression();
2729   } else if (function_state_->super_location().IsValid()) {
2730     ReportMessageAt(scanner()->location(),
2731                     MessageTemplate::kStrongSuperCallDuplicate);
2732     *ok = false;
2733     return this->EmptyExpression();
2734   } else if (function_state_->this_location().IsValid()) {
2735     ReportMessageAt(scanner()->location(),
2736                     MessageTemplate::kStrongSuperCallMisplaced);
2737     *ok = false;
2738     return this->EmptyExpression();
2739   } else if (function_state_->return_location().IsValid()) {
2740     ReportMessageAt(function_state_->return_location(),
2741                     MessageTemplate::kStrongConstructorReturnMisplaced);
2742     *ok = false;
2743     return this->EmptyExpression();
2744   }
2745 
2746   function_state_->set_super_location(super_loc);
2747   if (spread_pos.IsValid()) {
2748     args = Traits::PrepareSpreadArguments(args);
2749     expr = Traits::SpreadCall(expr, args, pos);
2750   } else {
2751     expr = factory()->NewCall(expr, args, pos);
2752   }
2753 
2754   // Explicit calls to the super constructor using super() perform an implicit
2755   // binding assignment to the 'this' variable.
2756   ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2757   return factory()->NewAssignment(Token::INIT, this_expr, expr, pos);
2758 }
2759 
2760 
2761 template <class Traits>
2762 typename ParserBase<Traits>::ExpressionT
ParseSuperExpression(bool is_new,ExpressionClassifier * classifier,bool * ok)2763 ParserBase<Traits>::ParseSuperExpression(bool is_new,
2764                                          ExpressionClassifier* classifier,
2765                                          bool* ok) {
2766   Expect(Token::SUPER, CHECK_OK);
2767   int pos = position();
2768 
2769   Scope* scope = scope_->ReceiverScope();
2770   FunctionKind kind = scope->function_kind();
2771   if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
2772       IsClassConstructor(kind)) {
2773     if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
2774       scope->RecordSuperPropertyUsage();
2775       return this->SuperPropertyReference(scope_, factory(), pos);
2776     }
2777     // new super() is never allowed.
2778     // super() is only allowed in derived constructor
2779     if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
2780       if (is_strong(language_mode())) {
2781         // Super calls in strong mode are parsed separately.
2782         ReportMessageAt(scanner()->location(),
2783                         MessageTemplate::kStrongConstructorSuper);
2784         *ok = false;
2785         return this->EmptyExpression();
2786       }
2787       // TODO(rossberg): This might not be the correct FunctionState for the
2788       // method here.
2789       function_state_->set_super_location(scanner()->location());
2790       return this->SuperCallReference(scope_, factory(), pos);
2791     }
2792   }
2793 
2794   ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
2795   *ok = false;
2796   return this->EmptyExpression();
2797 }
2798 
2799 
2800 template <class Traits>
2801 typename ParserBase<Traits>::ExpressionT
ParseNewTargetExpression(bool * ok)2802 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
2803   int pos = position();
2804   Consume(Token::PERIOD);
2805   ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
2806 
2807   if (!scope_->ReceiverScope()->is_function_scope()) {
2808     ReportMessageAt(scanner()->location(),
2809                     MessageTemplate::kUnexpectedNewTarget);
2810     *ok = false;
2811     return this->EmptyExpression();
2812   }
2813 
2814   return this->NewTargetExpression(scope_, factory(), pos);
2815 }
2816 
2817 
2818 template <class Traits>
2819 typename ParserBase<Traits>::ExpressionT
ParseMemberExpressionContinuation(ExpressionT expression,ExpressionClassifier * classifier,bool * ok)2820 ParserBase<Traits>::ParseMemberExpressionContinuation(
2821     ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
2822   // Parses this part of MemberExpression:
2823   // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
2824   while (true) {
2825     switch (peek()) {
2826       case Token::LBRACK: {
2827         BindingPatternUnexpectedToken(classifier);
2828         ArrowFormalParametersUnexpectedToken(classifier);
2829 
2830         Consume(Token::LBRACK);
2831         int pos = position();
2832         ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
2833         index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
2834         expression = factory()->NewProperty(expression, index, pos);
2835         if (fni_ != NULL) {
2836           this->PushPropertyName(fni_, index);
2837         }
2838         Expect(Token::RBRACK, CHECK_OK);
2839         break;
2840       }
2841       case Token::PERIOD: {
2842         BindingPatternUnexpectedToken(classifier);
2843         ArrowFormalParametersUnexpectedToken(classifier);
2844 
2845         Consume(Token::PERIOD);
2846         int pos = position();
2847         IdentifierT name = ParseIdentifierName(CHECK_OK);
2848         expression = factory()->NewProperty(
2849             expression, factory()->NewStringLiteral(name, pos), pos);
2850         if (fni_ != NULL) {
2851           this->PushLiteralName(fni_, name);
2852         }
2853         break;
2854       }
2855       case Token::TEMPLATE_SPAN:
2856       case Token::TEMPLATE_TAIL: {
2857         BindingPatternUnexpectedToken(classifier);
2858         ArrowFormalParametersUnexpectedToken(classifier);
2859         int pos;
2860         if (scanner()->current_token() == Token::IDENTIFIER) {
2861           pos = position();
2862         } else {
2863           pos = peek_position();
2864           if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2865             // If the tag function looks like an IIFE, set_parenthesized() to
2866             // force eager compilation.
2867             expression->AsFunctionLiteral()->set_should_eager_compile();
2868           }
2869         }
2870         expression =
2871             ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
2872         break;
2873       }
2874       default:
2875         return expression;
2876     }
2877   }
2878   DCHECK(false);
2879   return this->EmptyExpression();
2880 }
2881 
2882 
2883 template <class Traits>
ParseFormalParameter(FormalParametersT * parameters,ExpressionClassifier * classifier,bool * ok)2884 void ParserBase<Traits>::ParseFormalParameter(
2885     FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
2886   // FormalParameter[Yield,GeneratorParameter] :
2887   //   BindingElement[?Yield, ?GeneratorParameter]
2888   bool is_rest = parameters->has_rest;
2889 
2890   Token::Value next = peek();
2891   ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
2892   if (!*ok) return;
2893 
2894   ValidateBindingPattern(classifier, ok);
2895   if (!*ok) return;
2896 
2897   if (!Traits::IsIdentifier(pattern)) {
2898     if (!allow_harmony_destructuring_bind()) {
2899       ReportUnexpectedToken(next);
2900       *ok = false;
2901       return;
2902     }
2903     parameters->is_simple = false;
2904     ValidateFormalParameterInitializer(classifier, ok);
2905     if (!*ok) return;
2906     classifier->RecordNonSimpleParameter();
2907   }
2908 
2909   ExpressionT initializer = Traits::EmptyExpression();
2910   if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
2911     ExpressionClassifier init_classifier;
2912     initializer = ParseAssignmentExpression(true, &init_classifier, ok);
2913     if (!*ok) return;
2914     initializer = Traits::RewriteNonPattern(initializer, &init_classifier, ok);
2915     ValidateFormalParameterInitializer(&init_classifier, ok);
2916     if (!*ok) return;
2917     parameters->is_simple = false;
2918     classifier->RecordNonSimpleParameter();
2919   }
2920 
2921   Traits::AddFormalParameter(parameters, pattern, initializer,
2922                              scanner()->location().end_pos, is_rest);
2923 }
2924 
2925 
2926 template <class Traits>
ParseFormalParameterList(FormalParametersT * parameters,ExpressionClassifier * classifier,bool * ok)2927 void ParserBase<Traits>::ParseFormalParameterList(
2928     FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
2929   // FormalParameters[Yield,GeneratorParameter] :
2930   //   [empty]
2931   //   FormalParameterList[?Yield, ?GeneratorParameter]
2932   //
2933   // FormalParameterList[Yield,GeneratorParameter] :
2934   //   FunctionRestParameter[?Yield]
2935   //   FormalsList[?Yield, ?GeneratorParameter]
2936   //   FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
2937   //
2938   // FormalsList[Yield,GeneratorParameter] :
2939   //   FormalParameter[?Yield, ?GeneratorParameter]
2940   //   FormalsList[?Yield, ?GeneratorParameter] ,
2941   //     FormalParameter[?Yield,?GeneratorParameter]
2942 
2943   DCHECK_EQ(0, parameters->Arity());
2944 
2945   if (peek() != Token::RPAREN) {
2946     do {
2947       if (parameters->Arity() > Code::kMaxArguments) {
2948         ReportMessage(MessageTemplate::kTooManyParameters);
2949         *ok = false;
2950         return;
2951       }
2952       parameters->has_rest = Check(Token::ELLIPSIS);
2953       ParseFormalParameter(parameters, classifier, ok);
2954       if (!*ok) return;
2955     } while (!parameters->has_rest && Check(Token::COMMA));
2956 
2957     if (parameters->has_rest) {
2958       parameters->is_simple = false;
2959       classifier->RecordNonSimpleParameter();
2960       if (peek() == Token::COMMA) {
2961         ReportMessageAt(scanner()->peek_location(),
2962                       MessageTemplate::kParamAfterRest);
2963         *ok = false;
2964         return;
2965       }
2966     }
2967   }
2968 
2969   for (int i = 0; i < parameters->Arity(); ++i) {
2970     auto parameter = parameters->at(i);
2971     Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
2972   }
2973 }
2974 
2975 
2976 template <class Traits>
CheckArityRestrictions(int param_count,FunctionLiteral::ArityRestriction arity_restriction,bool has_rest,int formals_start_pos,int formals_end_pos,bool * ok)2977 void ParserBase<Traits>::CheckArityRestrictions(
2978     int param_count, FunctionLiteral::ArityRestriction arity_restriction,
2979     bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
2980   switch (arity_restriction) {
2981     case FunctionLiteral::kGetterArity:
2982       if (param_count != 0) {
2983         ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
2984                         MessageTemplate::kBadGetterArity);
2985         *ok = false;
2986       }
2987       break;
2988     case FunctionLiteral::kSetterArity:
2989       if (param_count != 1) {
2990         ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
2991                         MessageTemplate::kBadSetterArity);
2992         *ok = false;
2993       }
2994       if (has_rest) {
2995         ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
2996                         MessageTemplate::kBadSetterRestParameter);
2997         *ok = false;
2998       }
2999       break;
3000     default:
3001       break;
3002   }
3003 }
3004 
3005 
3006 template <class Traits>
IsNextLetKeyword()3007 bool ParserBase<Traits>::IsNextLetKeyword() {
3008   DCHECK(peek() == Token::LET);
3009   if (!allow_let()) {
3010     return false;
3011   }
3012   Token::Value next_next = PeekAhead();
3013   switch (next_next) {
3014     case Token::LBRACE:
3015     case Token::LBRACK:
3016     case Token::IDENTIFIER:
3017     case Token::STATIC:
3018     case Token::LET:  // Yes, you can do let let = ... in sloppy mode
3019     case Token::YIELD:
3020       return true;
3021     default:
3022       return false;
3023   }
3024 }
3025 
3026 
3027 template <class Traits>
3028 typename ParserBase<Traits>::ExpressionT
ParseArrowFunctionLiteral(bool accept_IN,const FormalParametersT & formal_parameters,const ExpressionClassifier & formals_classifier,bool * ok)3029 ParserBase<Traits>::ParseArrowFunctionLiteral(
3030     bool accept_IN, const FormalParametersT& formal_parameters,
3031     const ExpressionClassifier& formals_classifier, bool* ok) {
3032   if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3033     // ASI inserts `;` after arrow parameters if a line terminator is found.
3034     // `=> ...` is never a valid expression, so report as syntax error.
3035     // If next token is not `=>`, it's a syntax error anyways.
3036     ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3037     *ok = false;
3038     return this->EmptyExpression();
3039   }
3040 
3041   typename Traits::Type::StatementList body;
3042   int num_parameters = formal_parameters.scope->num_parameters();
3043   int materialized_literal_count = -1;
3044   int expected_property_count = -1;
3045   Scanner::Location super_loc;
3046 
3047   {
3048     typename Traits::Type::Factory function_factory(ast_value_factory());
3049     FunctionState function_state(&function_state_, &scope_,
3050                                  formal_parameters.scope, kArrowFunction,
3051                                  &function_factory);
3052 
3053     function_state.SkipMaterializedLiterals(
3054         formal_parameters.materialized_literals_count);
3055 
3056     this->ReindexLiterals(formal_parameters);
3057 
3058     Expect(Token::ARROW, CHECK_OK);
3059 
3060     if (peek() == Token::LBRACE) {
3061       // Multiple statement body
3062       Consume(Token::LBRACE);
3063       bool is_lazily_parsed =
3064           (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing());
3065       if (is_lazily_parsed) {
3066         body = this->NewStatementList(0, zone());
3067         this->SkipLazyFunctionBody(&materialized_literal_count,
3068                                    &expected_property_count, CHECK_OK);
3069         if (formal_parameters.materialized_literals_count > 0) {
3070           materialized_literal_count +=
3071               formal_parameters.materialized_literals_count;
3072         }
3073       } else {
3074         body = this->ParseEagerFunctionBody(
3075             this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
3076             kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK);
3077         materialized_literal_count =
3078             function_state.materialized_literal_count();
3079         expected_property_count = function_state.expected_property_count();
3080       }
3081     } else {
3082       // Single-expression body
3083       int pos = position();
3084       parenthesized_function_ = false;
3085       ExpressionClassifier classifier;
3086       ExpressionT expression =
3087           ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
3088       expression = Traits::RewriteNonPattern(expression, &classifier, CHECK_OK);
3089       body = this->NewStatementList(1, zone());
3090       this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
3091       body->Add(factory()->NewReturnStatement(expression, pos), zone());
3092       materialized_literal_count = function_state.materialized_literal_count();
3093       expected_property_count = function_state.expected_property_count();
3094     }
3095     super_loc = function_state.super_location();
3096 
3097     formal_parameters.scope->set_end_position(scanner()->location().end_pos);
3098 
3099     // Arrow function formal parameters are parsed as StrictFormalParameterList,
3100     // which is not the same as "parameters of a strict function"; it only means
3101     // that duplicates are not allowed.  Of course, the arrow function may
3102     // itself be strict as well.
3103     const bool allow_duplicate_parameters = false;
3104     this->ValidateFormalParameters(&formals_classifier, language_mode(),
3105                                    allow_duplicate_parameters, CHECK_OK);
3106 
3107     // Validate strict mode.
3108     if (is_strict(language_mode())) {
3109       CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
3110                               scanner()->location().end_pos, CHECK_OK);
3111     }
3112     if (is_strict(language_mode()) || allow_harmony_sloppy()) {
3113       this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
3114     }
3115 
3116     Traits::RewriteDestructuringAssignments();
3117   }
3118 
3119   FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
3120       this->EmptyIdentifierString(), formal_parameters.scope, body,
3121       materialized_literal_count, expected_property_count, num_parameters,
3122       FunctionLiteral::kNoDuplicateParameters,
3123       FunctionLiteral::kAnonymousExpression,
3124       FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
3125       formal_parameters.scope->start_position());
3126 
3127   function_literal->set_function_token_position(
3128       formal_parameters.scope->start_position());
3129   if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
3130 
3131   if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
3132 
3133   return function_literal;
3134 }
3135 
3136 
3137 template <typename Traits>
3138 typename ParserBase<Traits>::ExpressionT
ParseTemplateLiteral(ExpressionT tag,int start,ExpressionClassifier * classifier,bool * ok)3139 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
3140                                          ExpressionClassifier* classifier,
3141                                          bool* ok) {
3142   // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3143   // text followed by a substitution expression), finalized by a single
3144   // TEMPLATE_TAIL.
3145   //
3146   // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3147   // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3148   // NoSubstitutionTemplate.
3149   //
3150   // When parsing a TemplateLiteral, we must have scanned either an initial
3151   // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
3152   CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
3153 
3154   // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
3155   // In this case we may simply consume the token and build a template with a
3156   // single TEMPLATE_SPAN and no expressions.
3157   if (peek() == Token::TEMPLATE_TAIL) {
3158     Consume(Token::TEMPLATE_TAIL);
3159     int pos = position();
3160     CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3161     typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3162     Traits::AddTemplateSpan(&ts, true);
3163     return Traits::CloseTemplateLiteral(&ts, start, tag);
3164   }
3165 
3166   Consume(Token::TEMPLATE_SPAN);
3167   int pos = position();
3168   typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3169   Traits::AddTemplateSpan(&ts, false);
3170   Token::Value next;
3171 
3172   // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
3173   // and repeat if the following token is a TEMPLATE_SPAN as well (in this
3174   // case, representing a TemplateMiddle).
3175 
3176   do {
3177     CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3178     next = peek();
3179     if (next == Token::EOS) {
3180       ReportMessageAt(Scanner::Location(start, peek_position()),
3181                       MessageTemplate::kUnterminatedTemplate);
3182       *ok = false;
3183       return Traits::EmptyExpression();
3184     } else if (next == Token::ILLEGAL) {
3185       Traits::ReportMessageAt(
3186           Scanner::Location(position() + 1, peek_position()),
3187           MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3188       *ok = false;
3189       return Traits::EmptyExpression();
3190     }
3191 
3192     int expr_pos = peek_position();
3193     ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
3194     expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
3195     Traits::AddTemplateExpression(&ts, expression);
3196 
3197     if (peek() != Token::RBRACE) {
3198       ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
3199                       MessageTemplate::kUnterminatedTemplateExpr);
3200       *ok = false;
3201       return Traits::EmptyExpression();
3202     }
3203 
3204     // If we didn't die parsing that expression, our next token should be a
3205     // TEMPLATE_SPAN or TEMPLATE_TAIL.
3206     next = scanner()->ScanTemplateContinuation();
3207     Next();
3208     pos = position();
3209 
3210     if (next == Token::EOS) {
3211       ReportMessageAt(Scanner::Location(start, pos),
3212                       MessageTemplate::kUnterminatedTemplate);
3213       *ok = false;
3214       return Traits::EmptyExpression();
3215     } else if (next == Token::ILLEGAL) {
3216       Traits::ReportMessageAt(
3217           Scanner::Location(position() + 1, peek_position()),
3218           MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3219       *ok = false;
3220       return Traits::EmptyExpression();
3221     }
3222 
3223     Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
3224   } while (next == Token::TEMPLATE_SPAN);
3225 
3226   DCHECK_EQ(next, Token::TEMPLATE_TAIL);
3227   CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3228   // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3229   return Traits::CloseTemplateLiteral(&ts, start, tag);
3230 }
3231 
3232 
3233 template <typename Traits>
3234 typename ParserBase<Traits>::ExpressionT
CheckAndRewriteReferenceExpression(ExpressionT expression,int beg_pos,int end_pos,MessageTemplate::Template message,bool * ok)3235 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3236     ExpressionT expression, int beg_pos, int end_pos,
3237     MessageTemplate::Template message, bool* ok) {
3238   return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
3239                                                   message, kReferenceError, ok);
3240 }
3241 
3242 
3243 template <typename Traits>
3244 typename ParserBase<Traits>::ExpressionT
CheckAndRewriteReferenceExpression(ExpressionT expression,int beg_pos,int end_pos,MessageTemplate::Template message,ParseErrorType type,bool * ok)3245 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3246     ExpressionT expression, int beg_pos, int end_pos,
3247     MessageTemplate::Template message, ParseErrorType type, bool* ok) {
3248   ExpressionClassifier classifier;
3249   ExpressionT result = ClassifyAndRewriteReferenceExpression(
3250       &classifier, expression, beg_pos, end_pos, message, type);
3251   ValidateExpression(&classifier, ok);
3252   if (!*ok) return this->EmptyExpression();
3253   return result;
3254 }
3255 
3256 
3257 template <typename Traits>
3258 typename ParserBase<Traits>::ExpressionT
ClassifyAndRewriteReferenceExpression(ExpressionClassifier * classifier,ExpressionT expression,int beg_pos,int end_pos,MessageTemplate::Template message,ParseErrorType type)3259 ParserBase<Traits>::ClassifyAndRewriteReferenceExpression(
3260     ExpressionClassifier* classifier, ExpressionT expression, int beg_pos,
3261     int end_pos, MessageTemplate::Template message, ParseErrorType type) {
3262   Scanner::Location location(beg_pos, end_pos);
3263   if (this->IsIdentifier(expression)) {
3264     if (is_strict(language_mode()) &&
3265         this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3266       classifier->RecordExpressionError(
3267           location, MessageTemplate::kStrictEvalArguments, kSyntaxError);
3268       return expression;
3269     }
3270     if (is_strong(language_mode()) &&
3271         this->IsUndefined(this->AsIdentifier(expression))) {
3272       classifier->RecordExpressionError(
3273           location, MessageTemplate::kStrongUndefined, kSyntaxError);
3274       return expression;
3275     }
3276   }
3277   if (expression->IsValidReferenceExpression()) {
3278     return expression;
3279   } else if (expression->IsCall()) {
3280     // If it is a call, make it a runtime error for legacy web compatibility.
3281     // Rewrite `expr' to `expr[throw ReferenceError]'.
3282     int pos = location.beg_pos;
3283     ExpressionT error = this->NewThrowReferenceError(message, pos);
3284     return factory()->NewProperty(expression, error, pos);
3285   } else {
3286     classifier->RecordExpressionError(location, message, type);
3287     return expression;
3288   }
3289 }
3290 
3291 
3292 template <typename Traits>
IsValidReferenceExpression(ExpressionT expression)3293 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) {
3294   return this->IsAssignableIdentifier(expression) || expression->IsProperty();
3295 }
3296 
3297 
3298 template <typename Traits>
CheckDestructuringElement(ExpressionT expression,ExpressionClassifier * classifier,int begin,int end)3299 void ParserBase<Traits>::CheckDestructuringElement(
3300     ExpressionT expression, ExpressionClassifier* classifier, int begin,
3301     int end) {
3302   static const MessageTemplate::Template message =
3303       MessageTemplate::kInvalidDestructuringTarget;
3304   const Scanner::Location location(begin, end);
3305   if (expression->IsArrayLiteral() || expression->IsObjectLiteral() ||
3306       expression->IsAssignment()) {
3307     if (expression->is_parenthesized()) {
3308       classifier->RecordPatternError(location, message);
3309     }
3310     return;
3311   }
3312 
3313   if (expression->IsProperty()) {
3314     classifier->RecordBindingPatternError(location, message);
3315   } else if (!this->IsAssignableIdentifier(expression)) {
3316     classifier->RecordPatternError(location, message);
3317   }
3318 }
3319 
3320 
3321 #undef CHECK_OK
3322 #undef CHECK_OK_CUSTOM
3323 
3324 
3325 template <typename Traits>
CheckProperty(Token::Value property,PropertyKind type,bool is_static,bool is_generator,bool * ok)3326 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
3327     Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3328     bool* ok) {
3329   DCHECK(!is_static);
3330   DCHECK(!is_generator || type == kMethodProperty);
3331 
3332   if (property == Token::SMI || property == Token::NUMBER) return;
3333 
3334   if (type == kValueProperty && IsProto()) {
3335     if (has_seen_proto_) {
3336       this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
3337       *ok = false;
3338       return;
3339     }
3340     has_seen_proto_ = true;
3341     return;
3342   }
3343 }
3344 
3345 
3346 template <typename Traits>
CheckProperty(Token::Value property,PropertyKind type,bool is_static,bool is_generator,bool * ok)3347 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
3348     Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3349     bool* ok) {
3350   DCHECK(type == kMethodProperty || type == kAccessorProperty);
3351 
3352   if (property == Token::SMI || property == Token::NUMBER) return;
3353 
3354   if (is_static) {
3355     if (IsPrototype()) {
3356       this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
3357       *ok = false;
3358       return;
3359     }
3360   } else if (IsConstructor()) {
3361     if (is_generator || type == kAccessorProperty) {
3362       MessageTemplate::Template msg =
3363           is_generator ? MessageTemplate::kConstructorIsGenerator
3364                        : MessageTemplate::kConstructorIsAccessor;
3365       this->parser()->ReportMessage(msg);
3366       *ok = false;
3367       return;
3368     }
3369     if (has_seen_constructor_) {
3370       this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
3371       *ok = false;
3372       return;
3373     }
3374     has_seen_constructor_ = true;
3375     return;
3376   }
3377 }
3378 }  // namespace internal
3379 }  // namespace v8
3380 
3381 #endif  // V8_PARSING_PARSER_BASE_H
3382