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