1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_PARSING_PARSER_BASE_H
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_PARSING_PARSER_BASE_H
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
8f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/ast.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopes.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/bailout-reason.h"
1113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/base/hashmap.h"
1262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/counters.h"
13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/globals.h"
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/messages.h"
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/expression-classifier.h"
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/func-name-inferrer.h"
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/scanner.h"
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/token.h"
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal {
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum FunctionNameValidity {
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kFunctionNameIsStrictReserved,
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kSkipFunctionNameCheck,
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kFunctionNameValidityUnknown
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochenum AllowLabelledFunctionStatement {
313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  kAllowLabelledFunctionStatement,
323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  kDisallowLabelledFunctionStatement,
333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch};
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
35bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochenum class ParseFunctionFlags {
36bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  kIsNormal = 0,
37bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  kIsGenerator = 1,
38bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  kIsAsync = 2,
39bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  kIsDefault = 4
40bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch};
41bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
42bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstatic inline ParseFunctionFlags operator|(ParseFunctionFlags lhs,
43bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                           ParseFunctionFlags rhs) {
44bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  typedef unsigned char T;
45bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) |
46bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                         static_cast<T>(rhs));
47bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
48bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
49bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstatic inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs,
50bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                             const ParseFunctionFlags& rhs) {
51bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  lhs = lhs | rhs;
52bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return lhs;
53bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
54bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
55bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstatic inline bool operator&(ParseFunctionFlags bitfield,
56bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             ParseFunctionFlags mask) {
57bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  typedef unsigned char T;
58bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return static_cast<T>(bitfield) & static_cast<T>(mask);
59bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
60bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct FormalParametersBase {
62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {}
63c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
64c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int num_parameters() const {
65c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // Don't include the rest parameter into the function's formal parameter
66c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
67c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // which says whether we need to create an arguments adaptor frame).
68c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return arity - has_rest;
69c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
70c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
71c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  void UpdateArityAndFunctionLength(bool is_optional, bool is_rest) {
72c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (!is_optional && !is_rest && function_length == arity) {
73c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      ++function_length;
74c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
75c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    ++arity;
76c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
77c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeclarationScope* scope;
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool has_rest = false;
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_simple = true;
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int materialized_literals_count = 0;
82c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int function_length = 0;
83c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int arity = 0;
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ----------------------------------------------------------------------------
88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// The CHECK_OK macro is a convenient macro to enforce error
89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// handling for functions that may fail (by returning !*ok).
90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// CAUTION: This macro appends extra statements after a call,
92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// thus it must never be used where only a single statement
93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// is correct (e.g. an if statement branch w/o braces)!
94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
95f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define CHECK_OK_CUSTOM(x, ...) ok);       \
96f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!*ok) return impl()->x(__VA_ARGS__); \
97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ((void)0
98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define DUMMY )  // to make indentation work
99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#undef DUMMY
100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Used in functions where the return type is ExpressionT.
102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression)
103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define CHECK_OK_VOID ok); \
10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!*ok) return;        \
10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ((void)0
10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define DUMMY )  // to make indentation work
10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef DUMMY
10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Common base class template shared between parser and pre-parser.
111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// The Impl parameter is the actual class of the parser/pre-parser,
112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// following the Curiously Recurring Template Pattern (CRTP).
113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// The structure of the parser objects is roughly the following:
114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   // A structure template containing type definitions, needed to
116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   // avoid a cyclic dependency.
117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   template <typename Impl>
118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   struct ParserTypes;
119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//
120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   // The parser base object, which should just implement pure
121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   // parser behavior.  The Impl parameter is the actual derived
122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   // class (according to CRTP), which implements impure parser
123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   // behavior.
124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   template <typename Impl>
125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   class ParserBase { ... };
126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   // And then, for each parser variant (e.g., parser, preparser, etc):
128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   class Parser;
129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   template <>
131f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   class ParserTypes<Parser> { ... };
132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   class Parser : public ParserBase<Parser> { ... };
134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
135f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// The parser base object implements pure parsing, according to the
136f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// language grammar.  Different parser implementations may exhibit
137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// different parser-driven behavior that is not considered as pure
138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// parsing, e.g., early error detection and reporting, AST generation, etc.
139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// The ParserTypes structure encapsulates the differences in the
141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// types used in parsing methods.  E.g., Parser methods use Expression*
142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// and PreParser methods use PreParserExpression.  For any given parser
143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// implementation class Impl, it is expected to contain the following typedefs:
144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//
145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// template <>
146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// struct ParserTypes<Impl> {
147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   // Synonyms for ParserBase<Impl> and Impl, respectively.
148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Base;
149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Impl;
150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   // TODO(nikolaos): this one will probably go away, as it is
151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   // not related to pure parsing.
152f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Variable;
153f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   // Return types for traversing functions.
154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Identifier;
155f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Expression;
156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef FunctionLiteral;
157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef ObjectLiteralProperty;
158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef ClassLiteralProperty;
159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef ExpressionList;
160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef ObjectPropertyList;
161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef ClassPropertyList;
162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef FormalParameters;
163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Statement;
164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef StatementList;
165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Block;
166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef BreakableStatement;
167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef IterationStatement;
168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   // For constructing objects returned by the traversing functions.
169f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Factory;
170f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   // For other implementation-specific tasks.
171f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef Target;
172f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch//   typedef TargetScope;
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// };
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
176f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstruct ParserTypes;
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
179f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass ParserBase {
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Shorten type names defined by ParserTypes<Impl>.
182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef ParserTypes<Impl> Types;
183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::Identifier IdentifierT;
184f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::Expression ExpressionT;
185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::FunctionLiteral FunctionLiteralT;
186f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT;
188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::ExpressionList ExpressionListT;
189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::FormalParameters FormalParametersT;
190f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::Statement StatementT;
191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::StatementList StatementListT;
192f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename Types::Block BlockT;
193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef typename v8::internal::ExpressionClassifier<Types>
194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionClassifier;
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // All implementation-specific methods must be called through this.
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Impl* impl() { return static_cast<Impl*>(this); }
198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Impl* impl() const { return static_cast<const Impl*>(this); }
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             v8::Extension* extension, AstValueFactory* ast_value_factory,
20262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             RuntimeCallStats* runtime_call_stats,
20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             bool parsing_on_main_thread = true)
20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      : scope_(nullptr),
205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        function_state_(nullptr),
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        extension_(extension),
207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        fni_(nullptr),
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ast_value_factory_(ast_value_factory),
209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ast_node_factory_(ast_value_factory),
210c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        runtime_call_stats_(runtime_call_stats),
21162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        parsing_on_main_thread_(parsing_on_main_thread),
212bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        parsing_module_(false),
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        stack_limit_(stack_limit),
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        zone_(zone),
215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier_(nullptr),
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        scanner_(scanner),
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        stack_overflow_(false),
218c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile),
21962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        function_literal_id_(0),
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        allow_natives_(false),
2213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        allow_tailcalls_(false),
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        allow_harmony_do_expressions_(false),
223bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        allow_harmony_function_sent_(false),
224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        allow_harmony_restrictive_generators_(false),
225f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        allow_harmony_trailing_commas_(false),
22662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        allow_harmony_class_fields_(false),
22762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        allow_harmony_object_rest_spread_(false),
22862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        allow_harmony_dynamic_import_(false),
22962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        allow_harmony_async_iteration_(false),
23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        allow_harmony_template_escapes_(false) {}
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOW_ACCESSORS(name)                           \
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool allow_##name() const { return allow_##name##_; } \
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_allow_##name(bool allow) { allow_##name##_ = allow; }
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ALLOW_ACCESSORS(natives);
2373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ALLOW_ACCESSORS(tailcalls);
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ALLOW_ACCESSORS(harmony_do_expressions);
239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ALLOW_ACCESSORS(harmony_function_sent);
24013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ALLOW_ACCESSORS(harmony_restrictive_generators);
241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ALLOW_ACCESSORS(harmony_trailing_commas);
242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ALLOW_ACCESSORS(harmony_class_fields);
24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ALLOW_ACCESSORS(harmony_object_rest_spread);
24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ALLOW_ACCESSORS(harmony_dynamic_import);
24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ALLOW_ACCESSORS(harmony_async_iteration);
24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ALLOW_ACCESSORS(harmony_template_escapes);
2473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef ALLOW_ACCESSORS
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uintptr_t stack_limit() const { return stack_limit_; }
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
254c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  void set_default_eager_compile_hint(
255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      FunctionLiteral::EagerCompileHint eager_compile_hint) {
256c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    default_eager_compile_hint_ = eager_compile_hint;
257c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
258c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
259c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  FunctionLiteral::EagerCompileHint default_eager_compile_hint() const {
260c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return default_eager_compile_hint_;
261c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
262c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int GetNextFunctionLiteralId() { return ++function_literal_id_; }
26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int GetLastFunctionLiteralId() const { return function_literal_id_; }
26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void SkipFunctionLiterals(int delta) { function_literal_id_ += delta; }
26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void ResetFunctionLiteralId() { function_literal_id_ = 0; }
26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Zone* zone() const { return zone_; }
271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected:
273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  friend class v8::internal::ExpressionClassifier<ParserTypes<Impl>>;
274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum AllowRestrictedIdentifiers {
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kAllowRestrictedIdentifiers,
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kDontAllowRestrictedIdentifiers
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
280c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  enum LazyParsingResult { kLazyParsingComplete, kLazyParsingAborted };
281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum VariableDeclarationContext {
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kStatementListItem,
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kStatement,
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kForStatement
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
288c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  enum class FunctionBodyType { kNormal, kSingleExpression };
289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class Checkpoint;
291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class ClassLiteralChecker;
292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class ObjectLiteralChecker;
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ---------------------------------------------------------------------------
29562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // BlockState and FunctionState implement the parser's scope stack.
29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The parser's current scope is in scope_. BlockState and FunctionState
29762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // constructors push on the scope stack and the destructors pop. They are also
29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // used to hold the parser's per-funcion state.
29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  class BlockState BASE_EMBEDDED {
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   public:
30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState(Scope** scope_stack, Scope* scope)
30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *scope_stack_ = scope;
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
30662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState(Zone* zone, Scope** scope_stack)
30762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        : BlockState(scope_stack,
30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                     new (zone) Scope(zone, *scope_stack, BLOCK_SCOPE)) {}
309f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
31062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ~BlockState() { *scope_stack_ = outer_scope_; }
311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
312f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch   private:
31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Scope** const scope_stack_;
31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Scope* const outer_scope_;
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct DestructuringAssignment {
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   public:
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DestructuringAssignment(ExpressionT expression, Scope* scope)
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        : assignment(expression), scope(scope) {}
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ExpressionT assignment;
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Scope* scope;
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
326bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  class TailCallExpressionList {
327bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch   public:
328bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    explicit TailCallExpressionList(Zone* zone)
329bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        : zone_(zone), expressions_(0, zone), has_explicit_tail_calls_(false) {}
330bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
331bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    const ZoneList<ExpressionT>& expressions() const { return expressions_; }
332bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    const Scanner::Location& location() const { return loc_; }
333bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
334bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    bool has_explicit_tail_calls() const { return has_explicit_tail_calls_; }
335bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
336bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    void Swap(TailCallExpressionList& other) {
337bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      expressions_.Swap(&other.expressions_);
338bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      std::swap(loc_, other.loc_);
339bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      std::swap(has_explicit_tail_calls_, other.has_explicit_tail_calls_);
340bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
341bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
342bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    void AddImplicitTailCall(ExpressionT expr) {
343bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      expressions_.Add(expr, zone_);
344bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
345bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
346bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    void Append(const TailCallExpressionList& other) {
347bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!has_explicit_tail_calls()) {
348bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        loc_ = other.loc_;
349bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        has_explicit_tail_calls_ = other.has_explicit_tail_calls_;
350bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
351bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      expressions_.AddAll(other.expressions_, zone_);
352bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
354bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch   private:
355bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Zone* zone_;
356bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ZoneList<ExpressionT> expressions_;
357bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Scanner::Location loc_;
358bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    bool has_explicit_tail_calls_;
359bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  };
360bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
361bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Defines whether tail call expressions are allowed or not.
362bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  enum class ReturnExprContext {
363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // We are inside return statement which is allowed to contain tail call
364bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // expressions. Tail call expressions are allowed.
365bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    kInsideValidReturnStatement,
366bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
367bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // We are inside a block in which tail call expressions are allowed but
368bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // not yet inside a return statement.
369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    kInsideValidBlock,
370bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
371bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // Tail call expressions are not allowed in the following blocks.
372bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    kInsideTryBlock,
373bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    kInsideForInOfBody,
374bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  };
375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
37662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  class FunctionState final : public BlockState {
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   public:
37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  DeclarationScope* scope);
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ~FunctionState();
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
38262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DeclarationScope* scope() const { return scope_->AsDeclarationScope(); }
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void AddProperty() { expected_property_count_++; }
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int expected_property_count() { return expected_property_count_; }
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
387f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    FunctionKind kind() const { return scope()->function_kind(); }
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FunctionState* outer() const { return outer_function_state_; }
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    typename Types::Variable* generator_object_variable() const {
39162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return scope()->generator_object_var();
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    typename Types::Variable* promise_variable() const {
39562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return scope()->promise_var();
39662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
39762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
39862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void RewindDestructuringAssignments(int pos) {
39962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      destructuring_assignments_to_rewrite_.Rewind(pos);
40062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
40162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
40262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void SetDestructuringAssignmentsScope(int pos, Scope* scope) {
40362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      for (int i = pos; i < destructuring_assignments_to_rewrite_.length();
40462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           ++i) {
40562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        destructuring_assignments_to_rewrite_[i].scope = scope;
40662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
40913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    const ZoneList<DestructuringAssignment>&
41013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        destructuring_assignments_to_rewrite() const {
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return destructuring_assignments_to_rewrite_;
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
414bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    TailCallExpressionList& tail_call_expressions() {
415bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return tail_call_expressions_;
416109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    void AddImplicitTailCallExpression(ExpressionT expression) {
418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (return_expr_context() ==
419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          ReturnExprContext::kInsideValidReturnStatement) {
420bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        tail_call_expressions_.AddImplicitTailCall(expression);
421bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
422bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
423109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
42413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() {
42513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return &reported_errors_;
42613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
42713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
428bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ReturnExprContext return_expr_context() const {
429bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return return_expr_context_;
430109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
431bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    void set_return_expr_context(ReturnExprContext context) {
432bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return_expr_context_ = context;
433109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
434109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
435109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    ZoneList<ExpressionT>* non_patterns_to_rewrite() {
436109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return &non_patterns_to_rewrite_;
437109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
438109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
43962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool next_function_is_likely_called() const {
44062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return next_function_is_likely_called_;
441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
44362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool previous_function_was_likely_called() const {
44462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return previous_function_was_likely_called_;
445bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
446bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
44762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void set_next_function_is_likely_called() {
44862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      next_function_is_likely_called_ = true;
449bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
450bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
451109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch   private:
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void AddDestructuringAssignment(DestructuringAssignment pair) {
45362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      destructuring_assignments_to_rewrite_.Add(pair, scope_->zone());
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
45613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    void AddNonPatternForRewriting(ExpressionT expr, bool* ok) {
45762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      non_patterns_to_rewrite_.Add(expr, scope_->zone());
45813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (non_patterns_to_rewrite_.length() >=
45913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          std::numeric_limits<uint16_t>::max())
46013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        *ok = false;
461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Used to assign an index to each literal that needs materialization in
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the function.  Includes regexp literals, and boilerplate for object and
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // array literals.
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int next_materialized_literal_index_;
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Properties count estimation.
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int expected_property_count_;
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FunctionState** function_state_stack_;
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FunctionState* outer_function_state_;
47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DeclarationScope* scope_;
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
47513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_;
476bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    TailCallExpressionList tail_call_expressions_;
477bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ReturnExprContext return_expr_context_;
478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    ZoneList<ExpressionT> non_patterns_to_rewrite_;
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
48013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    ZoneList<typename ExpressionClassifier::Error> reported_errors_;
48113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
48262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Record whether the next (=== immediately following) function literal is
48362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // preceded by a parenthesis / exclamation mark. Also record the previous
48462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // state.
48562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // These are managed by the FunctionState constructor; the caller may only
48662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // call set_next_function_is_likely_called.
48762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool next_function_is_likely_called_;
48862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool previous_function_was_likely_called_;
489bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    friend Impl;
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    friend class Checkpoint;
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
494bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // This scope sets current ReturnExprContext to given value.
495bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  class ReturnExprScope {
496bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch   public:
497bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    explicit ReturnExprScope(FunctionState* function_state,
498bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             ReturnExprContext return_expr_context)
499bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        : function_state_(function_state),
500bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          sav_return_expr_context_(function_state->return_expr_context()) {
501bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      // Don't update context if we are requested to enable tail call
502bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      // expressions but current block does not allow them.
503bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (return_expr_context !=
504bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              ReturnExprContext::kInsideValidReturnStatement ||
505bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) {
506bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        function_state->set_return_expr_context(return_expr_context);
507bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
508bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
509bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ~ReturnExprScope() {
510bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      function_state_->set_return_expr_context(sav_return_expr_context_);
511bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
512bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
513bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch   private:
514bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    FunctionState* function_state_;
515bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ReturnExprContext sav_return_expr_context_;
516bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  };
517bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
518bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Collects all return expressions at tail call position in this scope
519bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // to a separate list.
520bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  class CollectExpressionsInTailPositionToListScope {
521bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch   public:
522bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    CollectExpressionsInTailPositionToListScope(FunctionState* function_state,
523bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                                TailCallExpressionList* list)
524bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        : function_state_(function_state), list_(list) {
525bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      function_state->tail_call_expressions().Swap(*list_);
526bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
527bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ~CollectExpressionsInTailPositionToListScope() {
528bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      function_state_->tail_call_expressions().Swap(*list_);
529bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
530bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
531bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch   private:
532bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    FunctionState* function_state_;
533bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    TailCallExpressionList* list_;
534bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  };
535bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Annoyingly, arrow functions first parse as comma expressions, then when we
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // see the => we have to go back and reinterpret the arguments as being formal
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // parameters.  To do so we need to reset some of the parser state back to
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // what it was before the arguments were first seen.
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class Checkpoint BASE_EMBEDDED {
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   public:
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    explicit Checkpoint(ParserBase* parser) {
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function_state_ = parser->function_state_;
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      next_materialized_literal_index_ =
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          function_state_->next_materialized_literal_index_;
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      expected_property_count_ = function_state_->expected_property_count_;
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void Restore(int* materialized_literal_index_delta) {
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *materialized_literal_index_delta =
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          function_state_->next_materialized_literal_index_ -
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          next_materialized_literal_index_;
553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function_state_->next_materialized_literal_index_ =
554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          next_materialized_literal_index_;
555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function_state_->expected_property_count_ = expected_property_count_;
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   private:
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FunctionState* function_state_;
560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int next_materialized_literal_index_;
561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int expected_property_count_;
562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  struct DeclarationDescriptor {
565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    enum Kind { NORMAL, PARAMETER };
566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scope* scope;
567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    VariableMode mode;
568f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int declaration_pos;
569f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int initialization_pos;
570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Kind declaration_kind;
571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
572f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  struct DeclarationParsingResult {
574f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    struct Declaration {
575f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Declaration(ExpressionT pattern, int initializer_position,
576f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  ExpressionT initializer)
577f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          : pattern(pattern),
578f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            initializer_position(initializer_position),
579f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            initializer(initializer) {}
580f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT pattern;
582f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      int initializer_position;
583f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT initializer;
584f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    };
585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
586f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DeclarationParsingResult()
587f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        : declarations(4),
588f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          first_initializer_loc(Scanner::Location::invalid()),
589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          bindings_loc(Scanner::Location::invalid()) {}
590f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DeclarationDescriptor descriptor;
592f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    List<Declaration> declarations;
593f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scanner::Location first_initializer_loc;
594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scanner::Location bindings_loc;
595f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
596f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
597f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  struct CatchInfo {
598f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch   public:
599f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    explicit CatchInfo(ParserBase* parser)
600f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        : name(parser->impl()->EmptyIdentifier()),
601f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          variable(nullptr),
602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          pattern(parser->impl()->EmptyExpression()),
603f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          scope(nullptr),
604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          init_block(parser->impl()->NullBlock()),
605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          inner_block(parser->impl()->NullBlock()),
606f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          bound_names(1, parser->zone()),
607f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          tail_call_expressions(parser->zone()) {}
608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    IdentifierT name;
609f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Variable* variable;
610f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT pattern;
611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scope* scope;
612f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    BlockT init_block;
613f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    BlockT inner_block;
614f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*> bound_names;
615f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    TailCallExpressionList tail_call_expressions;
616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
618f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  struct ForInfo {
619f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch   public:
620f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    explicit ForInfo(ParserBase* parser)
621f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        : bound_names(1, parser->zone()),
622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          mode(ForEachStatement::ENUMERATE),
623c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          position(kNoSourcePosition),
624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          parsing_result() {}
625f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*> bound_names;
626f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ForEachStatement::VisitMode mode;
627c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int position;
628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DeclarationParsingResult parsing_result;
629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
630f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
631f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  struct ClassInfo {
632f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch   public:
633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    explicit ClassInfo(ParserBase* parser)
634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        : proxy(nullptr),
635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          extends(parser->impl()->EmptyExpression()),
636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          properties(parser->impl()->NewClassPropertyList(4)),
637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          constructor(parser->impl()->EmptyFunctionLiteral()),
638f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          has_seen_constructor(false),
63962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          has_name_static_property(false),
64062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          has_static_computed_names(false) {}
641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    VariableProxy* proxy;
642f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT extends;
643f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    typename Types::ClassPropertyList properties;
644f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    FunctionLiteralT constructor;
645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool has_seen_constructor;
64662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool has_name_static_property;
64762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool has_static_computed_names;
648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeclarationScope* NewScriptScope() const {
651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return new (zone()) DeclarationScope(zone(), ast_value_factory());
652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeclarationScope* NewVarblockScope() const {
655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE);
656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ModuleScope* NewModuleScope(DeclarationScope* parent) const {
659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return new (zone()) ModuleScope(parent, ast_value_factory());
660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeclarationScope* NewEvalScope(Scope* parent) const {
663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE);
664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Scope* NewScope(ScopeType scope_type) const {
667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return NewScopeWithParent(scope(), scope_type);
668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // This constructor should only be used when absolutely necessary. Most scopes
671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // should automatically use scope() as parent, and be fine with
672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // NewScope(ScopeType) above.
673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Scope* NewScopeWithParent(Scope* parent, ScopeType scope_type) const {
674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Must always use the specific constructors for the blacklisted scope
675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // types.
676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_NE(FUNCTION_SCOPE, scope_type);
677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_NE(SCRIPT_SCOPE, scope_type);
678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_NE(MODULE_SCOPE, scope_type);
679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_NOT_NULL(parent);
680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone()) Scope(zone(), parent, scope_type);
681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
68362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Creates a function scope that always allocates in zone(). The function
68462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // scope itself is either allocated in zone() or in target_zone if one is
68562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // passed in.
68662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeclarationScope* NewFunctionScope(FunctionKind kind,
68762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     Zone* target_zone = nullptr) const {
688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(ast_value_factory());
68962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (target_zone == nullptr) target_zone = zone();
69062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DeclarationScope* result = new (target_zone)
69162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind);
692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // TODO(verwaest): Move into the DeclarationScope constructor.
693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (!IsArrowFunction(kind)) {
694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      result->DeclareDefaultFunctionVariables(ast_value_factory());
695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return result;
697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_INLINE DeclarationScope* GetDeclarationScope() const {
700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return scope()->GetDeclarationScope();
701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_INLINE DeclarationScope* GetClosureScope() const {
703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return scope()->GetClosureScope();
704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scanner* scanner() const { return scanner_; }
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int position() const { return scanner_->location().beg_pos; }
709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int peek_position() const { return scanner_->peek_location().beg_pos; }
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool stack_overflow() const { return stack_overflow_; }
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_stack_overflow() { stack_overflow_ = true; }
712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(Token::Value peek()) {
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (stack_overflow_) return Token::ILLEGAL;
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return scanner()->peek();
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(Token::Value PeekAhead()) {
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (stack_overflow_) return Token::ILLEGAL;
720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return scanner()->PeekAhead();
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(Token::Value Next()) {
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (stack_overflow_) return Token::ILLEGAL;
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    {
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (GetCurrentStackPosition() < stack_limit_) {
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Any further calls to Next or peek will return the illegal token.
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // The current call must return the next token, which might already
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // have been peek'ed.
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        stack_overflow_ = true;
731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return scanner()->Next();
734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Consume(Token::Value token) {
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Token::Value next = Next();
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    USE(next);
739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    USE(token);
740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(next == token);
741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool Check(Token::Value token) {
744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Token::Value next = peek();
745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next == token) {
746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(next);
747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Expect(Token::Value token, bool* ok) {
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Token::Value next = Next();
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next != token) {
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReportUnexpectedToken(next);
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ExpectSemicolon(bool* ok) {
761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Check for automatic semicolon insertion according to
762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the rules given in ECMA-262, section 7.9, page 21.
763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Token::Value tok = peek();
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (tok == Token::SEMICOLON) {
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Next();
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (scanner()->HasAnyLineTerminatorBeforeNext() ||
769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        tok == Token::RBRACE ||
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        tok == Token::EOS) {
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Expect(Token::SEMICOLON, ok);
774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Dummy functions, just useful as arguments to CHECK_OK_CUSTOM.
777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static void Void() {}
778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  template <typename T>
779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static T Return(T result) {
780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return result;
781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
78313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool is_any_identifier(Token::Value token) {
78413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return token == Token::IDENTIFIER || token == Token::ENUM ||
78513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           token == Token::AWAIT || token == Token::ASYNC ||
78662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           token == Token::ESCAPED_STRICT_RESERVED_WORD ||
78713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET ||
78813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           token == Token::STATIC || token == Token::YIELD;
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
79013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool peek_any_identifier() { return is_any_identifier(peek()); }
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool CheckContextualKeyword(Vector<const char> keyword) {
793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (PeekContextualKeyword(keyword)) {
794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::IDENTIFIER);
795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool PeekContextualKeyword(Vector<const char> keyword) {
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return peek() == Token::IDENTIFIER &&
802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           scanner()->is_next_contextual_keyword(keyword);
803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
805109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void ExpectMetaProperty(Vector<const char> property_name,
806109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                          const char* full_name, int pos, bool* ok);
807109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Expect(Token::IDENTIFIER, CHECK_OK_CUSTOM(Void));
810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!scanner()->is_literal_contextual_keyword(keyword)) {
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReportUnexpectedToken(scanner()->current_token());
812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) {
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (Check(Token::IN)) {
8183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      *visit_mode = ForEachStatement::ENUMERATE;
819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (CheckContextualKeyword(CStrVector("of"))) {
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *visit_mode = ForEachStatement::ITERATE;
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
827109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool PeekInOrOf() {
828109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return peek() == Token::IN || PeekContextualKeyword(CStrVector("of"));
829109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
830109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Checks whether an octal literal was last seen between beg_pos and end_pos.
83262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Only called for strict mode strings.
83362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Scanner::Location octal = scanner()->octal_position();
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (octal.IsValid() && beg_pos <= octal.beg_pos &&
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        octal.end_pos <= end_pos) {
83762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      MessageTemplate::Template message = scanner()->octal_message();
83862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK_NE(message, MessageTemplate::kNone);
839f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(octal, message);
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scanner()->clear_octal_position();
84162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (message == MessageTemplate::kStrictDecimalWithLeadingZero) {
84262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode);
84362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
84862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Checks if an octal literal or an invalid hex or unicode escape sequence
84962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // appears in a template literal. In the presence of such, either
85062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // returns false or reports an error, depending on should_throw. Otherwise
85162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // returns true.
85262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  inline bool CheckTemplateEscapes(bool should_throw, bool* ok) {
85362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!scanner()->has_invalid_template_escape()) {
85462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return true;
85562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
85762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Handle error case(s)
85862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (should_throw) {
85962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->ReportMessageAt(scanner()->invalid_template_escape_location(),
86062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              scanner()->invalid_template_escape_message());
86162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *ok = false;
86262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
86362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scanner()->clear_invalid_template_escape();
86462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return false;
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
867f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos);
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Checking the name of a function literal. This has to be done after parsing
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the function, since the function can declare itself strict.
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         FunctionNameValidity function_name_validity,
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         const Scanner::Location& function_name_loc, bool* ok) {
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (function_name_validity == kSkipFunctionNameCheck) return;
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The function name needs to be checked in strict mode.
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_sloppy(language_mode)) return;
877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
878f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (impl()->IsEvalOrArguments(function_name)) {
879f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(function_name_loc,
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              MessageTemplate::kStrictEvalArguments);
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (function_name_validity == kFunctionNameIsStrictReserved) {
885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(function_name_loc,
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              MessageTemplate::kUnexpectedStrictReserved);
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Determine precedence of given token.
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int Precedence(Token::Value token, bool accept_IN) {
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (token == Token::IN && !accept_IN)
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 0;  // 0 precedence will terminate binary expression parsing
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Token::Precedence(token);
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
899f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::Factory* factory() { return &ast_node_factory_; }
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeclarationScope* GetReceiverScope() const {
902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return scope()->GetReceiverScope();
903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  LanguageMode language_mode() { return scope()->language_mode(); }
905f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void RaiseLanguageMode(LanguageMode mode) {
906f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    LanguageMode old = scope()->language_mode();
907f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->SetLanguageMode(scope(), old > mode ? old : mode);
908f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_generator() const {
910f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IsGeneratorFunction(function_state_->kind());
911f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
912bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bool is_async_function() const {
913f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IsAsyncFunction(function_state_->kind());
914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
915f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_resumable() const {
916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IsResumableFunction(function_state_->kind());
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Report syntax errors.
920f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ReportMessage(MessageTemplate::Template message) {
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Scanner::Location source_location = scanner()->location();
922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(source_location, message,
923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            static_cast<const char*>(nullptr), kSyntaxError);
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
926f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  template <typename T>
927f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ReportMessage(MessageTemplate::Template message, T arg,
928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                     ParseErrorType error_type = kSyntaxError) {
929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Scanner::Location source_location = scanner()->location();
930f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(source_location, message, arg, error_type);
931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void ReportMessageAt(Scanner::Location location,
934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                       MessageTemplate::Template message,
935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                       ParseErrorType error_type) {
936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(location, message,
937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            static_cast<const char*>(nullptr), error_type);
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void GetUnexpectedTokenMessage(
9413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Token::Value token, MessageTemplate::Template* message,
9423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Scanner::Location* location, const char** arg,
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReportUnexpectedToken(Token::Value token);
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReportUnexpectedTokenAt(
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Scanner::Location location, Token::Value token,
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void ReportClassifierError(
951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      const typename ExpressionClassifier::Error& error) {
952f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(error.location, error.message, error.arg,
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            error.type);
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
956f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ValidateExpression(bool* ok) {
957f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!classifier()->is_valid_expression()) {
958f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportClassifierError(classifier()->expression_error());
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
963f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ValidateFormalParameterInitializer(bool* ok) {
964f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!classifier()->is_valid_formal_parameter_initializer()) {
965f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportClassifierError(classifier()->formal_parameter_initializer_error());
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
970f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ValidateBindingPattern(bool* ok) {
971f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!classifier()->is_valid_binding_pattern()) {
972f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportClassifierError(classifier()->binding_pattern_error());
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
977f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ValidateAssignmentPattern(bool* ok) {
978f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!classifier()->is_valid_assignment_pattern()) {
979f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportClassifierError(classifier()->assignment_pattern_error());
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
984f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ValidateFormalParameters(LanguageMode language_mode,
985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                bool allow_duplicates, bool* ok) {
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!allow_duplicates &&
987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        !classifier()->is_valid_formal_parameter_list_without_duplicates()) {
988f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportClassifierError(classifier()->duplicate_formal_parameter_error());
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (is_strict(language_mode) &&
991f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch               !classifier()->is_valid_strict_mode_formal_parameters()) {
992f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportClassifierError(classifier()->strict_mode_formal_parameter_error());
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
99713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool IsValidArrowFormalParametersStart(Token::Value token) {
99813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return is_any_identifier(token) || token == Token::LPAREN;
99913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
100013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1001f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ValidateArrowFormalParameters(ExpressionT expr,
1002bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     bool parenthesized_formals, bool is_async,
1003bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     bool* ok) {
1004f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (classifier()->is_valid_binding_pattern()) {
1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // A simple arrow formal parameter: IDENTIFIER => BODY.
1006f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!impl()->IsIdentifier(expr)) {
1007f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->ReportMessageAt(scanner()->location(),
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                MessageTemplate::kUnexpectedToken,
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                Token::String(scanner()->current_token()));
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        *ok = false;
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1012f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else if (!classifier()->is_valid_arrow_formal_parameters()) {
1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // If after parsing the expr, we see an error but the expression is
1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // neither a valid binding pattern nor a valid parenthesized formal
1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // parameter list, show the "arrow formal parameters" error if the formals
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // started with a parenthesis, and the binding pattern error otherwise.
1017109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      const typename ExpressionClassifier::Error& error =
1018f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          parenthesized_formals ? classifier()->arrow_formal_parameters_error()
1019f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                : classifier()->binding_pattern_error();
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReportClassifierError(error);
1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1023f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (is_async && !classifier()->is_valid_async_arrow_formal_parameters()) {
1024bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      const typename ExpressionClassifier::Error& error =
1025f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          classifier()->async_arrow_formal_parameters_error();
1026bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ReportClassifierError(error);
1027bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      *ok = false;
1028bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1031f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ValidateLetPattern(bool* ok) {
1032f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!classifier()->is_valid_let_pattern()) {
1033f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportClassifierError(classifier()->let_pattern_error());
1034bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      *ok = false;
1035bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1036bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1037bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1038f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void BindingPatternUnexpectedToken() {
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const char* arg;
10413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Scanner::Location location = scanner()->peek_location();
10423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
1043f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordBindingPatternError(location, message, arg);
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1046f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ArrowFormalParametersUnexpectedToken() {
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const char* arg;
10493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Scanner::Location location = scanner()->peek_location();
10503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
1051f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordArrowFormalParametersError(location, message, arg);
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1054f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Recursive descent functions.
1055f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // All ParseXXX functions take as the last argument an *ok parameter
1056f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // which is set to false if parsing failed; it is unchanged otherwise.
1057f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // By making the 'exception handling' explicit, we are forced to check
1058f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // for failure at the call sites. The family of CHECK_OK* macros can
1059f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // be useful for this.
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Parses an identifier that is valid for the current scope, in particular it
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // fails on strict mode future reserved keywords in a strict scope. If
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // "arguments" as identifier even in strict mode (this is needed in cases like
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // "var foo = eval;").
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
1067f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT ParseAndClassifyIdentifier(bool* ok);
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Parses an identifier or a strict mode future reserved word, and indicate
1069f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // whether it is strict mode future reserved. Allows passing in function_kind
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // for the case of parsing the identifier in a function expression, where the
1071f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // relevant "function_kind" bit is of the function being parsed, not the
1072f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // containing function.
1073f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IdentifierT ParseIdentifierOrStrictReservedWord(FunctionKind function_kind,
1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  bool* is_strict_reserved,
1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  bool* ok);
1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  bool* ok) {
1078f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return ParseIdentifierOrStrictReservedWord(function_state_->kind(),
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               is_strict_reserved, ok);
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IdentifierT ParseIdentifierName(bool* ok);
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1084f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ExpressionT ParseRegExpLiteral(bool* ok);
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParsePrimaryExpression(bool* is_async, bool* ok);
1087f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParsePrimaryExpression(bool* ok) {
1088bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    bool is_async;
1089f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return ParsePrimaryExpression(&is_async, ok);
1090bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1091f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1092f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // This method wraps the parsing of the expression inside a new expression
1093f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // classifier and calls RewriteNonPattern if parsing is successful.
1094f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // It should be used whenever we're parsing an expression that will be
1095f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // used as a non-pattern (i.e., in most cases).
1096f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_INLINE ExpressionT ParseExpression(bool accept_IN, bool* ok);
1097f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1098f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // This method does not wrap the parsing of the expression inside a
1099f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // new expression classifier; it uses the top-level classifier instead.
1100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // It should be used whenever we're parsing something with the "cover"
1101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // grammar that recognizes both patterns and non-patterns (which roughly
1102f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // corresponds to what's inside the parentheses generated by the symbol
1103f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017
1104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // specification).
1105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok);
1106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseArrayLiteral(bool* ok);
1108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  enum class PropertyKind {
1110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    kAccessorProperty,
1111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    kValueProperty,
1112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    kShorthandProperty,
1113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    kMethodProperty,
1114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    kClassField,
111562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    kSpreadProperty,
1116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    kNotSet
1117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
1118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind);
1120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind,
1121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                bool* is_generator, bool* is_get, bool* is_set,
1122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                bool* is_async, bool* is_computed_name,
1123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                bool* ok);
1124f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseObjectLiteral(bool* ok);
1125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ClassLiteralPropertyT ParseClassPropertyDefinition(
1126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name,
112762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind,
112862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      bool* is_static, bool* has_name_static_property, bool* ok);
1129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer,
1130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                 bool* ok);
1131f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ObjectLiteralPropertyT ParseObjectPropertyDefinition(
113262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ObjectLiteralChecker* checker, bool* is_computed_name,
113362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      bool* is_rest_property, bool* ok);
1134f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
1135f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 bool maybe_arrow, bool* ok);
1136f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
1137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 bool* ok) {
1138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return ParseArguments(first_spread_pos, false, ok);
1139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
1142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseYieldExpression(bool accept_IN, bool* ok);
1143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
1144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
1145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseUnaryExpression(bool* ok);
1146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParsePostfixExpression(bool* ok);
1147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseLeftHandSideExpression(bool* ok);
1148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok);
1149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseMemberExpression(bool* is_async, bool* ok);
1150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
1151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                bool* is_async, bool* ok);
115262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
115362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // `rewritable_length`: length of the destructuring_assignments_to_rewrite()
115462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // queue in the parent function state, prior to parsing of formal parameters.
115562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // If the arrow function is lazy, any items added during formal parameter
115662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // parsing are removed from the queue.
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        const FormalParametersT& parameters,
115962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        int rewritable_length, bool* ok);
1160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ParseAsyncFunctionBody(Scope* scope, StatementListT body,
1161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              FunctionKind kind, FunctionBodyType type,
1162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              bool accept_IN, int pos, bool* ok);
1163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseAsyncFunctionLiteral(bool* ok);
1164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseClassLiteral(IdentifierT name,
1165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                Scanner::Location class_name_location,
1166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                bool name_is_strict_reserved,
1167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                int class_token_pos, bool* ok);
116862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged,
116962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   bool* ok);
1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ExpressionT ParseSuperExpression(bool is_new, bool* ok);
117162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpressionT ParseDynamicImportExpression(bool* ok);
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExpressionT ParseNewTargetExpression(bool* ok);
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1174f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ParseFormalParameter(FormalParametersT* parameters, bool* ok);
1175f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ParseFormalParameterList(FormalParametersT* parameters, bool* ok);
1176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void CheckArityRestrictions(int param_count, FunctionKind function_type,
1177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                              bool has_rest, int formals_start_pos,
1178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                              int formals_end_pos, bool* ok);
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT ParseVariableDeclarations(VariableDeclarationContext var_context,
1181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   DeclarationParsingResult* parsing_result,
1182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   ZoneList<const AstRawString*>* names,
1183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   bool* ok);
1184f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseAsyncFunctionDeclaration(ZoneList<const AstRawString*>* names,
1185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                           bool default_export, bool* ok);
1186f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseFunctionDeclaration(bool* ok);
1187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseHoistableDeclaration(ZoneList<const AstRawString*>* names,
1188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                       bool default_export, bool* ok);
1189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
1190f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                       ZoneList<const AstRawString*>* names,
1191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                       bool default_export, bool* ok);
1192f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   bool default_export, bool* ok);
1194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseNativeDeclaration(bool* ok);
1195f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
119662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Consumes the ending }.
119762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void ParseFunctionBody(StatementListT result, IdentifierT function_name,
119862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         int pos, const FormalParametersT& parameters,
119962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         FunctionKind kind,
120062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         FunctionLiteral::FunctionType function_type, bool* ok);
120162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Under some circumstances, we allow preparsing to abort if the preparsed
1203f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // function is "long and trivial", and fully parse instead. Our current
1204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // definition of "long and trivial" is:
1205f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - over kLazyParseTrialLimit statements
1206f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - all starting with an identifier (i.e., no if, for, while, etc.)
1207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const int kLazyParseTrialLimit = 200;
1208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TODO(nikolaos, marja): The first argument should not really be passed
1210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // by value. The method is expected to add the parsed statements to the
1211f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // list. This works because in the case of the parser, StatementListT is
1212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // a pointer whereas the preparser does not really modify the body.
1213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_INLINE void ParseStatementList(StatementListT body, int end_token,
1214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    bool* ok) {
1215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    LazyParsingResult result = ParseStatementList(body, end_token, false, ok);
1216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    USE(result);
1217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_EQ(result, kLazyParsingComplete);
1218f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1219f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  LazyParsingResult ParseStatementList(StatementListT body, int end_token,
1220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                       bool may_abort, bool* ok);
1221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseStatementListItem(bool* ok);
122262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok) {
122362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
122462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
1225f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseStatement(ZoneList<const AstRawString*>* labels,
1226f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            AllowLabelledFunctionStatement allow_function,
1227f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            bool* ok);
1228f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseStatementAsUnlabelled(ZoneList<const AstRawString*>* labels,
1229f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                        bool* ok);
1230f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
1231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Parse a SubStatement in strict mode, or with an extra block scope in
1233f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // sloppy mode to handle
1234f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseScopedStatement(ZoneList<const AstRawString*>* labels,
123662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  bool* ok);
1237f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseVariableStatement(VariableDeclarationContext var_context,
1239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    ZoneList<const AstRawString*>* names,
1240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    bool* ok);
1241f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Magical syntax support.
1243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseV8Intrinsic(bool* ok);
1244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT ParseDoExpression(bool* ok);
1246f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseDebuggerStatement(bool* ok);
1248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1249f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseExpressionOrLabelledStatement(
1250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ZoneList<const AstRawString*>* labels,
1251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AllowLabelledFunctionStatement allow_function, bool* ok);
1252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseIfStatement(ZoneList<const AstRawString*>* labels, bool* ok);
1253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseContinueStatement(bool* ok);
1254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels,
1255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 bool* ok);
1256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseReturnStatement(bool* ok);
1257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels,
1258f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                bool* ok);
1259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
1260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   bool* ok);
1261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels,
1262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 bool* ok);
1263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseThrowStatement(bool* ok);
1264f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
1265f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  bool* ok);
1266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseTryStatement(bool* ok);
1267f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
126862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT ParseForEachStatementWithDeclarations(
126962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      int stmt_pos, ForInfo* for_info, ZoneList<const AstRawString*>* labels,
127062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      bool* ok);
127162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT ParseForEachStatementWithoutDeclarations(
127262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
127362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ForInfo* for_info, ZoneList<const AstRawString*>* labels, bool* ok);
127462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
127562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Parse a C-style for loop: 'for (<init>; <cond>; <step>) { ... }'
127662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT ParseStandardForLoop(int stmt_pos, StatementT init,
127762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  bool bound_names_are_lexical,
127862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  ForInfo* for_info, BlockState* for_state,
127962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  ZoneList<const AstRawString*>* labels,
128062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  bool* ok);
128162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT ParseForAwaitStatement(ZoneList<const AstRawString*>* labels,
128262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    bool* ok);
1283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsNextLetKeyword();
1285f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsTrivialExpression();
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Checks if the expression is a valid reference expression (e.g., on the
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // left-hand side of assignments). Although ruled out by ECMA as early errors,
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // we allow calls for web compatibility and rewrite them to a runtime throw.
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExpressionT CheckAndRewriteReferenceExpression(
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ExpressionT expression, int beg_pos, int end_pos,
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MessageTemplate::Template message, bool* ok);
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExpressionT CheckAndRewriteReferenceExpression(
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ExpressionT expression, int beg_pos, int end_pos,
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MessageTemplate::Template message, ParseErrorType type, bool* ok);
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsValidReferenceExpression(ExpressionT expression);
1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsAssignableIdentifier(ExpressionT expression) {
1300f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!impl()->IsIdentifier(expression)) return false;
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_strict(language_mode()) &&
1302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1308109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool IsValidPattern(ExpressionT expression) {
1309109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return expression->IsObjectLiteral() || expression->IsArrayLiteral();
1310109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1311109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
131262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Due to hoisting, the value of a 'var'-declared variable may actually change
131362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // even if the code contains only the "initial" assignment, namely when that
131462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // assignment occurs inside a loop.  For example:
131562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
131662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //   let i = 10;
131762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //   do { var x = i } while (i--):
131862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
131962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // As a simple and very conservative approximation of this, we explicitly mark
132062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // as maybe-assigned any non-lexical variable whose initializing "declaration"
132162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // does not syntactically occur in the function scope.  (In the example above,
132262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // it occurs in a block scope.)
132362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
132462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Note that non-lexical variables include temporaries, which may also get
132562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // assigned inside a loop due to the various rewritings that the parser
132662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // performs.
132762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
132862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static void MarkLoopVariableAsAssigned(Scope* scope, Variable* var);
132962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Keep track of eval() calls since they disable all local variable
1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // optimizations. This checks if expression is an eval call, and if yes,
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // forwards the information to scope.
1333f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression,
1334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                           Scope* scope) {
1335f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (impl()->IsIdentifier(expression) &&
1336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->IsEval(impl()->AsIdentifier(expression))) {
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scope->RecordEvalCall();
13383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (is_sloppy(scope->language_mode())) {
13393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // For sloppy scopes we also have to record the call at function level,
13403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // in case it includes declarations that will be hoisted.
1341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        scope->GetDeclarationScope()->RecordEvalCall();
13423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
1343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return Call::IS_POSSIBLY_EVAL;
1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return Call::NOT_EVAL;
1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
134862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Convenience method which determines the type of return statement to emit
134962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // depending on the current function type.
135062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  inline StatementT BuildReturnStatement(ExpressionT expr, int pos) {
135162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (V8_UNLIKELY(is_async_function())) {
135262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return factory()->NewAsyncReturnStatement(expr, pos);
135362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
135462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return factory()->NewReturnStatement(expr, pos);
135562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
135662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Validation per ES6 object literals.
1358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class ObjectLiteralChecker {
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   public:
1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    explicit ObjectLiteralChecker(ParserBase* parser)
1361f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        : parser_(parser), has_seen_proto_(false) {}
1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1363f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    void CheckDuplicateProto(Token::Value property);
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   private:
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1368f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ParserBase* parser() const { return parser_; }
1369f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scanner* scanner() const { return parser_->scanner(); }
1370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ParserBase* parser_;
1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool has_seen_proto_;
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Validation per ES6 class literals.
1376f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class ClassLiteralChecker {
1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   public:
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    explicit ClassLiteralChecker(ParserBase* parser)
1379f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        : parser_(parser), has_seen_constructor_(false) {}
1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1381f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    void CheckClassMethodName(Token::Value property, PropertyKind type,
1382f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              bool is_generator, bool is_async, bool is_static,
1383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              bool* ok);
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   private:
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsConstructor() {
1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return this->scanner()->LiteralMatches("constructor", 11);
1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsPrototype() {
1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return this->scanner()->LiteralMatches("prototype", 9);
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ParserBase* parser() const { return parser_; }
1394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scanner* scanner() const { return parser_->scanner(); }
1395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ParserBase* parser_;
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool has_seen_constructor_;
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ModuleDescriptor* module() const {
1401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return scope()->AsModuleScope()->module();
1402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
140362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Scope* scope() const { return scope_; }
1404f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1405f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Stack of expression classifiers.
1406f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // The top of the stack is always pointed to by classifier().
1407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_INLINE ExpressionClassifier* classifier() const {
1408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_NOT_NULL(classifier_);
1409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return classifier_;
1410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Accumulates the classifier that is on top of the stack (inner) to
1413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // the one that is right below (outer) and pops the inner.
1414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_INLINE void Accumulate(unsigned productions,
1415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            bool merge_non_patterns = true) {
1416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_NOT_NULL(classifier_);
1417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionClassifier* previous = classifier_->previous();
1418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_NOT_NULL(previous);
1419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    previous->Accumulate(classifier_, productions, merge_non_patterns);
1420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier_ = previous;
1421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1422f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1423f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Pops and discards the classifier that is on top of the stack
1424f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // without accumulating.
1425f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_INLINE void Discard() {
1426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_NOT_NULL(classifier_);
1427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier_->Discard();
1428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier_ = classifier_->previous();
1429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Accumulate errors that can be arbitrarily deep in an expression.
1432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // These correspond to the ECMAScript spec's 'Contains' operation
1433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // on productions. This includes:
1434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
1435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - YieldExpression is disallowed in arrow parameters in a generator.
1436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - AwaitExpression is disallowed in arrow parameters in an async function.
1437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - AwaitExpression is disallowed in async arrow parameters.
1438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
1439f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_INLINE void AccumulateFormalParameterContainmentErrors() {
1440f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Accumulate(ExpressionClassifier::FormalParameterInitializerProduction |
1441f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch               ExpressionClassifier::AsyncArrowFormalParametersProduction);
1442f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1443f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1444f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Parser base's protected field members.
1445f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
144662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Scope* scope_;                   // Scope stack.
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FunctionState* function_state_;  // Function state stack.
1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  v8::Extension* extension_;
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FuncNameInferrer* fni_;
1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AstValueFactory* ast_value_factory_;  // Not owned.
1451f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::Factory ast_node_factory_;
1452c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  RuntimeCallStats* runtime_call_stats_;
145362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool parsing_on_main_thread_;
1454bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bool parsing_module_;
1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uintptr_t stack_limit_;
1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Parser base's private field members.
1458f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* zone_;
1461f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionClassifier* classifier_;
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scanner* scanner_;
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool stack_overflow_;
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1466c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
1467c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
146862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int function_literal_id_;
146962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool allow_natives_;
14713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool allow_tailcalls_;
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool allow_harmony_do_expressions_;
1473109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool allow_harmony_function_sent_;
147413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool allow_harmony_restrictive_generators_;
1475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool allow_harmony_trailing_commas_;
1476f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool allow_harmony_class_fields_;
147762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool allow_harmony_object_rest_spread_;
147862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool allow_harmony_dynamic_import_;
147962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool allow_harmony_async_iteration_;
148062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool allow_harmony_template_escapes_;
1481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class DiscardableZoneScope;
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParserBase<Impl>::FunctionState::FunctionState(
148762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    FunctionState** function_state_stack, Scope** scope_stack,
1488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DeclarationScope* scope)
148962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    : BlockState(scope_stack, scope),
1490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      next_materialized_literal_index_(0),
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      expected_property_count_(0),
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function_state_stack_(function_state_stack),
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      outer_function_state_(*function_state_stack),
149462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      scope_(scope),
149513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      destructuring_assignments_to_rewrite_(16, scope->zone()),
1496bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      tail_call_expressions_(scope->zone()),
1497bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return_expr_context_(ReturnExprContext::kInsideValidBlock),
1498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      non_patterns_to_rewrite_(0, scope->zone()),
149913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      reported_errors_(16, scope->zone()),
150062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      next_function_is_likely_called_(false),
150162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      previous_function_was_likely_called_(false) {
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *function_state_stack = this;
1503bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (outer_function_state_) {
150462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    outer_function_state_->previous_function_was_likely_called_ =
150562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        outer_function_state_->next_function_is_likely_called_;
150662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    outer_function_state_->next_function_is_likely_called_ = false;
1507bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParserBase<Impl>::FunctionState::~FunctionState() {
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *function_state_stack_ = outer_function_state_;
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ParserBase<Impl>::GetUnexpectedTokenMessage(
15173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Token::Value token, MessageTemplate::Template* message,
15183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Scanner::Location* location, const char** arg,
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MessageTemplate::Template default_) {
15203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  *arg = nullptr;
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (token) {
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::EOS:
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *message = MessageTemplate::kUnexpectedEOS;
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::SMI:
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::NUMBER:
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *message = MessageTemplate::kUnexpectedTokenNumber;
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::STRING:
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *message = MessageTemplate::kUnexpectedTokenString;
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::IDENTIFIER:
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *message = MessageTemplate::kUnexpectedTokenIdentifier;
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1535bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case Token::AWAIT:
1536bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case Token::ENUM:
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *message = MessageTemplate::kUnexpectedReserved;
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::LET:
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::STATIC:
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::YIELD:
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::FUTURE_STRICT_RESERVED_WORD:
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *message = is_strict(language_mode())
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     ? MessageTemplate::kUnexpectedStrictReserved
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     : MessageTemplate::kUnexpectedTokenIdentifier;
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::TEMPLATE_SPAN:
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::TEMPLATE_TAIL:
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *message = MessageTemplate::kUnexpectedTemplateString;
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::ESCAPED_STRICT_RESERVED_WORD:
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::ESCAPED_KEYWORD:
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *message = MessageTemplate::kInvalidEscapedReservedWord;
15543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
15553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case Token::ILLEGAL:
15563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (scanner()->has_error()) {
15573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        *message = scanner()->error();
15583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        *location = scanner()->error_location();
15593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
15603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        *message = MessageTemplate::kInvalidOrUnexpectedToken;
15613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case Token::REGEXP_LITERAL:
1564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      *message = MessageTemplate::kUnexpectedTokenRegExp;
1565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      const char* name = Token::String(token);
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(name != NULL);
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *arg = name;
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ReportUnexpectedTokenAt(scanner_->location(), token);
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ParserBase<Impl>::ReportUnexpectedTokenAt(
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Scanner::Location source_location, Token::Value token,
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MessageTemplate::Template message) {
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const char* arg;
15843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
1585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->ReportMessageAt(source_location, message, arg);
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ExpressionClassifier classifier(this);
1592f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  auto result = ParseAndClassifyIdentifier(CHECK_OK_CUSTOM(EmptyIdentifier));
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1595f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ValidateAssignmentPattern(CHECK_OK_CUSTOM(EmptyIdentifier));
1596f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ValidateBindingPattern(CHECK_OK_CUSTOM(EmptyIdentifier));
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::IdentifierT
1604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseAndClassifyIdentifier(bool* ok) {
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value next = Next();
1606bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (next == Token::IDENTIFIER || next == Token::ASYNC ||
1607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      (next == Token::AWAIT && !parsing_module_ && !is_async_function())) {
1608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    IdentifierT name = impl()->GetSymbol();
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // When this function is used to read a formal parameter, we don't always
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // know whether the function is going to be strict or sloppy.  Indeed for
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // arrow functions we don't always know that the identifier we are reading
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // is actually a formal parameter.  Therefore besides the errors that we
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // must detect because we know we're in strict mode, we also record any
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // error that we might make in the future once we know the language mode.
1615f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (impl()->IsEvalOrArguments(name)) {
1616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordStrictModeFormalParameterError(
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          scanner()->location(), MessageTemplate::kStrictEvalArguments);
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (is_strict(language_mode())) {
1619f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordBindingPatternError(
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            scanner()->location(), MessageTemplate::kStrictEvalArguments);
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else if (next == Token::AWAIT) {
1623f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordAsyncArrowFormalParametersError(
1624bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1625bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (classifier()->duplicate_finder() != nullptr &&
162862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        scanner()->FindSymbol(classifier()->duplicate_finder())) {
1629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordDuplicateFormalParameterError(scanner()->location());
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return name;
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (is_sloppy(language_mode()) &&
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              next == Token::ESCAPED_STRICT_RESERVED_WORD ||
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              next == Token::LET || next == Token::STATIC ||
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              (next == Token::YIELD && !is_generator()))) {
1637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordStrictModeFormalParameterError(
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        is_strict(language_mode())) {
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReportUnexpectedToken(next);
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
1643f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyIdentifier();
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1645109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (next == Token::LET ||
1646109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1647109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         scanner()->is_literal_contextual_keyword(CStrVector("let")))) {
1648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordLetPatternError(
1649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->GetSymbol();
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ReportUnexpectedToken(next);
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok = false;
1655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyIdentifier();
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class Impl>
1660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::IdentifierT
1661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParserBase<Impl>::ParseIdentifierOrStrictReservedWord(
1662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    FunctionKind function_kind, bool* is_strict_reserved, bool* ok) {
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value next = Next();
1664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ &&
1665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    !IsAsyncFunction(function_kind)) ||
1666bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      next == Token::ASYNC) {
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *is_strict_reserved = false;
166862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (next == Token::ESCAPED_STRICT_RESERVED_WORD ||
166962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             next == Token::STATIC ||
1671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             (next == Token::YIELD && !IsGeneratorFunction(function_kind))) {
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *is_strict_reserved = true;
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ReportUnexpectedToken(next);
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok = false;
1676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyIdentifier();
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->GetSymbol();
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName(
1684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    bool* ok) {
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value next = Next();
1686bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (next != Token::IDENTIFIER && next != Token::ASYNC &&
1687bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      next != Token::ENUM && next != Token::AWAIT && next != Token::LET &&
1688bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      next != Token::STATIC && next != Token::YIELD &&
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      next != Token::FUTURE_STRICT_RESERVED_WORD &&
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      next != Token::ESCAPED_KEYWORD &&
1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ReportUnexpectedToken(next);
1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok = false;
1694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyIdentifier();
1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->GetSymbol();
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral(
1702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    bool* ok) {
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = peek_position();
1704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!scanner()->ScanRegExpPattern()) {
1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Next();
1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ReportMessage(MessageTemplate::kUnterminatedRegExp);
1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok = false;
1708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyExpression();
1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT js_pattern = impl()->GetNextSymbol();
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
1713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (flags.IsNothing()) {
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Next();
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok = false;
1717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyExpression();
1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int js_flags = flags.FromJust();
1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Next();
172162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return factory()->NewRegExpLiteral(js_pattern, js_flags, pos);
1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
1726f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* is_async, bool* ok) {
1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // PrimaryExpression ::
1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'this'
1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'null'
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'true'
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'false'
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   Identifier
1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   Number
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   String
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   ArrayLiteral
1736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   ObjectLiteral
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   RegExpLiteral
1738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   ClassLiteral
1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '(' Expression ')'
1740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   TemplateLiteral
1741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   do Block
1742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   AsyncFunctionLiteral
1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int beg_pos = peek_position();
1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (peek()) {
1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::THIS: {
1747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      BindingPatternUnexpectedToken();
1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::THIS);
1749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->ThisExpression(beg_pos);
1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::NULL_LITERAL:
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::TRUE_LITERAL:
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::FALSE_LITERAL:
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::SMI:
1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::NUMBER:
1757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      BindingPatternUnexpectedToken();
1758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->ExpressionFromLiteral(Next(), beg_pos);
1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1760bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case Token::ASYNC:
176162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (!scanner()->HasAnyLineTerminatorAfterNext() &&
1762bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          PeekAhead() == Token::FUNCTION) {
1763bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        Consume(Token::ASYNC);
1764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return ParseAsyncFunctionLiteral(CHECK_OK);
1765bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
1766bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      // CoverCallExpressionAndAsyncArrowHead
1767bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      *is_async = true;
1768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    /* falls through */
1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::IDENTIFIER:
1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::LET:
1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::STATIC:
1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::YIELD:
1773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case Token::AWAIT:
1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::ESCAPED_STRICT_RESERVED_WORD:
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::FUTURE_STRICT_RESERVED_WORD: {
1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Using eval or arguments in this context is OK even in strict mode.
1777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK);
1778c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return impl()->ExpressionFromIdentifier(name, beg_pos);
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::STRING: {
1782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      BindingPatternUnexpectedToken();
1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::STRING);
1784f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->ExpressionFromString(beg_pos);
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::ASSIGN_DIV:
1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::DIV:
1789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordBindingPatternError(
1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseRegExpLiteral(ok);
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::LBRACK:
1794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseArrayLiteral(ok);
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::LBRACE:
1797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseObjectLiteral(ok);
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::LPAREN: {
1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Arrow function formal parameters are either a single identifier or a
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // list of BindingPattern productions enclosed in parentheses.
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Parentheses are not valid on the LHS of a BindingPattern, so we use the
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // is_valid_binding_pattern() check to detect multiple levels of
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // parenthesization.
1805f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bool pattern_error = !classifier()->is_valid_binding_pattern();
1806f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordPatternError(scanner()->peek_location(),
1807f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                       MessageTemplate::kUnexpectedToken,
1808f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                       Token::String(Token::LPAREN));
1809f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (pattern_error) ArrowFormalParametersUnexpectedToken();
1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::LPAREN);
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (Check(Token::RPAREN)) {
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // ()=>x.  The continuation that looks for the => is in
1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // ParseAssignmentExpression.
1814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordExpressionError(scanner()->location(),
1815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                            MessageTemplate::kUnexpectedToken,
1816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                            Token::String(Token::RPAREN));
1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return factory()->NewEmptyParentheses(beg_pos);
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Heuristically try to detect immediately called functions before
1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // seeing the call parentheses.
182162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (peek() == Token::FUNCTION ||
182262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          (peek() == Token::ASYNC && PeekAhead() == Token::FUNCTION)) {
182362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        function_state_->set_next_function_is_likely_called();
182462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
1825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT expr = ParseExpressionCoverGrammar(true, CHECK_OK);
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Expect(Token::RPAREN, CHECK_OK);
1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return expr;
1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::CLASS: {
1831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      BindingPatternUnexpectedToken();
1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::CLASS);
1833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      int class_token_pos = position();
1834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      IdentifierT name = impl()->EmptyIdentifier();
1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_strict_reserved_name = false;
1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Scanner::Location class_name_location = Scanner::Location::invalid();
1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (peek_any_identifier()) {
1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   CHECK_OK);
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        class_name_location = scanner()->location();
1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1842f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseClassLiteral(name, class_name_location,
1843f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               is_strict_reserved_name, class_token_pos, ok);
1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::TEMPLATE_SPAN:
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::TEMPLATE_TAIL:
1848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      BindingPatternUnexpectedToken();
184962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, false, ok);
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::MOD:
1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (allow_natives() || extension_ != NULL) {
1853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
1854f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return ParseV8Intrinsic(ok);
1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::DO:
1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (allow_harmony_do_expressions()) {
1860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
1861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return ParseDoExpression(ok);
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReportUnexpectedToken(Next());
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *ok = false;
1871f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->EmptyExpression();
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool accept_IN, bool* ok) {
1877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ExpressionClassifier classifier(this);
1878f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT result = ParseExpressionCoverGrammar(accept_IN, CHECK_OK);
1879f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->RewriteNonPattern(CHECK_OK);
1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1884f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ExpressionT
1885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseExpressionCoverGrammar(bool accept_IN, bool* ok) {
1886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Expression ::
1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   AssignmentExpression
1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   Expression ',' AssignmentExpression
1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1890f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT result = impl()->EmptyExpression();
1891f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  while (true) {
1892f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int comma_pos = position();
189313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    ExpressionClassifier binding_classifier(this);
1894f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT right;
1895f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (Check(Token::ELLIPSIS)) {
1896f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1897f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1898f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // valid expression.
1899f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordExpressionError(scanner()->location(),
1900f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          MessageTemplate::kUnexpectedToken,
1901f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          Token::String(Token::ELLIPSIS));
1902f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      int ellipsis_pos = position();
1903f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      int pattern_pos = peek_position();
1904f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT pattern = ParsePrimaryExpression(CHECK_OK);
1905f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ValidateBindingPattern(CHECK_OK);
1906f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos);
1907f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
1908f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      right = ParseAssignmentExpression(accept_IN, CHECK_OK);
1909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
1910f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // No need to accumulate binding pattern-related errors, since
1911f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // an Expression can't be a binding pattern anyway.
1912f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->Accumulate(ExpressionClassifier::AllProductions &
1913f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       ~(ExpressionClassifier::BindingPatternProduction |
1914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         ExpressionClassifier::LetPatternProduction));
1915f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!impl()->IsIdentifier(right)) classifier()->RecordNonSimpleParameter();
1916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (impl()->IsEmptyExpression(result)) {
1917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // First time through the loop.
1918f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      result = right;
1919f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
1920f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      result =
1921f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          factory()->NewBinaryOperation(Token::COMMA, result, right, comma_pos);
1922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
1923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!Check(Token::COMMA)) break;
1925f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1926f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (right->IsSpread()) {
1927f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordArrowFormalParametersError(
1928f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          scanner()->location(), MessageTemplate::kParamAfterRest);
1929f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
1930f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (allow_harmony_trailing_commas() && peek() == Token::RPAREN &&
1932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        PeekAhead() == Token::ARROW) {
1933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // a trailing comma is allowed at the end of an arrow parameter list
1934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1935109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
193662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
193762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Pass on the 'set_next_function_is_likely_called' flag if we have
193862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // several function literals separated by comma.
193962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (peek() == Token::FUNCTION &&
194062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        function_state_->previous_function_was_likely_called()) {
194162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      function_state_->set_next_function_is_likely_called();
194262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
1949f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
1950f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ArrayLiteral ::
1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '[' Expression? (',' Expression?)* ']'
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = peek_position();
1955f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionListT values = impl()->NewExpressionList(4);
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int first_spread_index = -1;
1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expect(Token::LBRACK, CHECK_OK);
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (peek() != Token::RBRACK) {
1959f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ExpressionT elem;
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (peek() == Token::COMMA) {
1961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      elem = impl()->GetLiteralTheHole(peek_position());
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (peek() == Token::ELLIPSIS) {
1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int start_pos = peek_position();
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::ELLIPSIS);
1965109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int expr_pos = peek_position();
1966f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT argument = ParseAssignmentExpression(true, CHECK_OK);
1967109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      elem = factory()->NewSpread(argument, start_pos, expr_pos);
1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_spread_index < 0) {
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first_spread_index = values->length();
1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (argument->IsAssignment()) {
1974f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordPatternError(
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Scanner::Location(start_pos, scanner()->location().end_pos),
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            MessageTemplate::kInvalidDestructuringTarget);
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1978f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        CheckDestructuringElement(argument, start_pos,
1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  scanner()->location().end_pos);
1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (peek() == Token::COMMA) {
1983f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordPatternError(
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Scanner::Location(start_pos, scanner()->location().end_pos),
1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            MessageTemplate::kElementAfterRest);
1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int beg_pos = peek_position();
1989f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      elem = ParseAssignmentExpression(true, CHECK_OK);
1990f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CheckDestructuringElement(elem, beg_pos, scanner()->location().end_pos);
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values->Add(elem, zone_);
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (peek() != Token::RBRACK) {
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Expect(Token::COMMA, CHECK_OK);
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expect(Token::RBRACK, CHECK_OK);
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
199962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpressionT result =
200062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      factory()->NewArrayLiteral(values, first_spread_index, pos);
2001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (first_spread_index >= 0) {
2002109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result = factory()->NewRewritableExpression(result);
2003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    impl()->QueueNonPatternForRewriting(result, ok);
200413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (!*ok) {
200513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // If the non-pattern rewriting mechanism is used in the future for
200613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // rewriting other things than spreads, this error message will have
200713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // to change.  Also, this error message will never appear while pre-
200813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // parsing (this is OK, as it is an implementation limitation).
200913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ReportMessage(MessageTemplate::kTooManySpreads);
2010f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyExpression();
201113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
2012109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2013109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return result;
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2016f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class Impl>
2017f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token,
2018f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                PropertyKind* kind) {
2019f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // This returns true, setting the property kind, iff the given token is one
2020f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // which must occur after a property name, indicating that the previous token
2021f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // was in fact a name and not a modifier (like the "get" in "get x").
2022f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (token) {
2023f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::COLON:
2024f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *kind = PropertyKind::kValueProperty;
2025f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return true;
2026f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::COMMA:
2027f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::RBRACE:
2028f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::ASSIGN:
2029f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *kind = PropertyKind::kShorthandProperty;
2030f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return true;
2031f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::LPAREN:
2032f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *kind = PropertyKind::kMethodProperty;
2033f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return true;
2034f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::MUL:
2035f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::SEMICOLON:
2036f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *kind = PropertyKind::kClassField;
2037f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return true;
2038f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    default:
2039f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
2040f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2041f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return false;
2042f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2043f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2044f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <class Impl>
2045f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
2046f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_get,
2047f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* is_set, bool* is_async, bool* is_computed_name, bool* ok) {
2048f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(*kind == PropertyKind::kNotSet);
2049f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!*is_generator);
2050f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!*is_get);
2051f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!*is_set);
2052f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!*is_async);
2053f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!*is_computed_name);
2054f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2055f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  *is_generator = Check(Token::MUL);
2056f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (*is_generator) {
2057f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *kind = PropertyKind::kMethodProperty;
2058f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2059f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value token = peek();
2061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = peek_position();
2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
206362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!*is_generator && token == Token::ASYNC &&
2064f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      !scanner()->HasAnyLineTerminatorAfterNext()) {
2065f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Consume(Token::ASYNC);
2066f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    token = peek();
2067f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (SetPropertyKindFromToken(token, kind)) {
2068f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *name = impl()->GetSymbol();  // TODO(bakkot) specialize on 'async'
2069f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->PushLiteralName(*name);
2070f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return factory()->NewStringLiteral(*name, pos);
2071f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
2072f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *kind = PropertyKind::kMethodProperty;
2073f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *is_async = true;
2074f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    pos = peek_position();
2075f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2076f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2077f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (token == Token::IDENTIFIER && !*is_generator && !*is_async) {
2078f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // This is checking for 'get' and 'set' in particular.
2079f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Consume(Token::IDENTIFIER);
2080f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    token = peek();
2081f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (SetPropertyKindFromToken(token, kind) ||
2082f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        !scanner()->IsGetOrSet(is_get, is_set)) {
2083f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *name = impl()->GetSymbol();
2084f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->PushLiteralName(*name);
2085f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return factory()->NewStringLiteral(*name, pos);
2086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
2087f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *kind = PropertyKind::kAccessorProperty;
2088f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    pos = peek_position();
2089f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2090f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // For non computed property names we normalize the name a bit:
2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   "12" -> 12
2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   12.3 -> "12.3"
2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   12.30 -> "12.3"
2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   identifier -> "identifier"
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This is important because we use the property name as a key in a hash
2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // table when we compute constant properties.
2100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT expression = impl()->EmptyExpression();
2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (token) {
2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::STRING:
2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::STRING);
2104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *name = impl()->GetSymbol();
2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::SMI:
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::SMI);
2109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *name = impl()->GetNumberAsSymbol();
2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::NUMBER:
2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::NUMBER);
2114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *name = impl()->GetNumberAsSymbol();
2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::LBRACK: {
2118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *name = impl()->EmptyIdentifier();
2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *is_computed_name = true;
2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Consume(Token::LBRACK);
2121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      ExpressionClassifier computed_name_classifier(this);
2122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      expression = ParseAssignmentExpression(true, CHECK_OK);
2123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->RewriteNonPattern(CHECK_OK);
2124f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->AccumulateFormalParameterContainmentErrors();
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Expect(Token::RBRACK, CHECK_OK);
2126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
212962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case Token::ELLIPSIS:
213062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (allow_harmony_object_rest_spread()) {
213162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        *name = impl()->EmptyIdentifier();
213262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Consume(Token::ELLIPSIS);
213362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        expression = ParseAssignmentExpression(true, CHECK_OK);
213462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        *kind = PropertyKind::kSpreadProperty;
213562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
213662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (expression->IsAssignment()) {
213762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          classifier()->RecordPatternError(
213862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              scanner()->location(),
213962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              MessageTemplate::kInvalidDestructuringTarget);
214062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        } else {
214162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          CheckDestructuringElement(expression, pos,
214262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    scanner()->location().end_pos);
214362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
214462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
214562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (peek() != Token::RBRACE) {
214662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          classifier()->RecordPatternError(scanner()->location(),
214762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           MessageTemplate::kElementAfterRest);
214862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
214962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return expression;
215062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
215162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      *name = ParseIdentifierName(CHECK_OK);
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (*kind == PropertyKind::kNotSet) {
2158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    SetPropertyKindFromToken(peek(), kind);
2159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (*is_computed_name) {
2162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return expression;
2163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->PushLiteralName(*name);
2166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t index;
2168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->IsArrayIndex(*name, &index)
2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             ? factory()->NewNumberLiteral(index, pos)
2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             : factory()->NewStringLiteral(*name, pos);
2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
2174f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ClassLiteralPropertyT
217562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochParserBase<Impl>::ParseClassPropertyDefinition(
217662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name,
217762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind,
217862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool* is_static, bool* has_name_static_property, bool* ok) {
217962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_NOT_NULL(has_seen_constructor);
218062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_NOT_NULL(has_name_static_property);
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_get = false;
2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_set = false;
2183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_generator = false;
2184bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bool is_async = false;
218562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  *is_static = false;
218662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  *property_kind = ClassLiteralProperty::METHOD;
2187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  PropertyKind kind = PropertyKind::kNotSet;
2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value name_token = peek();
2190bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
219162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int function_token_position = scanner()->peek_location().beg_pos;
2192f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT name = impl()->EmptyIdentifier();
2193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT name_expression;
2194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (name_token == Token::STATIC) {
2195f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Consume(Token::STATIC);
219662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    function_token_position = scanner()->peek_location().beg_pos;
2197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (peek() == Token::LPAREN) {
2198f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      kind = PropertyKind::kMethodProperty;
2199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      name = impl()->GetSymbol();  // TODO(bakkot) specialize on 'static'
2200f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      name_expression = factory()->NewStringLiteral(name, position());
2201f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
2202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch               peek() == Token::RBRACE) {
2203f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      name = impl()->GetSymbol();  // TODO(bakkot) specialize on 'static'
2204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      name_expression = factory()->NewStringLiteral(name, position());
2205f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
220662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *is_static = true;
2207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      name_expression = ParsePropertyName(
2208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          &name, &kind, &is_generator, &is_get, &is_set, &is_async,
2209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
2211f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
2212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    name_expression = ParsePropertyName(
2213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        &name, &kind, &is_generator, &is_get, &is_set, &is_async,
2214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
221762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!*has_name_static_property && *is_static && impl()->IsName(name)) {
221862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    *has_name_static_property = true;
221962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
222062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (kind) {
2222f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kClassField:
2223f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kNotSet:  // This case is a name followed by a name or
2224f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 // other property. Here we have to assume
2225f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 // that's an uninitialized field followed by a
2226f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 // linebreak followed by a property, with ASI
2227f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 // adding the semicolon. If not, there will be
2228f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 // a syntax error after parsing the first name
2229f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 // as an uninitialized field.
2230f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kShorthandProperty:
2231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kValueProperty:
2232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (allow_harmony_class_fields()) {
2233f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        bool has_initializer = Check(Token::ASSIGN);
2234f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExpressionT function_literal = ParseClassFieldForInitializer(
2235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            has_initializer, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2236f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExpectSemicolon(CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
223762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        *property_kind = ClassLiteralProperty::FIELD;
2238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return factory()->NewClassLiteralProperty(
223962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            name_expression, function_literal, *property_kind, *is_static,
224062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            *is_computed_name);
2241f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      } else {
2242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ReportUnexpectedToken(Next());
2243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        *ok = false;
2244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return impl()->EmptyClassLiteralProperty();
2245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kMethodProperty: {
2248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(!is_get && !is_set);
2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // MethodDefinition
2251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!*is_computed_name) {
2255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        checker->CheckClassMethodName(
2256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            name_token, PropertyKind::kMethodProperty, is_generator, is_async,
225762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionKind kind = is_generator
2261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              ? FunctionKind::kConciseGeneratorMethod
2262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              : is_async ? FunctionKind::kAsyncConciseMethod
2263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                         : FunctionKind::kConciseMethod;
2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
226562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (!*is_static && impl()->IsConstructor(name)) {
2266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        *has_seen_constructor = true;
226762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        kind = has_extends ? FunctionKind::kDerivedConstructor
2268f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                           : FunctionKind::kBaseConstructor;
2269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT value = impl()->ParseFunctionLiteral(
2272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          name, scanner()->location(), kSkipFunctionNameCheck, kind,
227362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          FLAG_harmony_function_tostring ? function_token_position
227462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         : kNoSourcePosition,
227562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          FunctionLiteral::kAccessorOrMethod, language_mode(),
227662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
227862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *property_kind = ClassLiteralProperty::METHOD;
2279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return factory()->NewClassLiteralProperty(name_expression, value,
228062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                *property_kind, *is_static,
228162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                *is_computed_name);
2282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
2283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2284f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kAccessorProperty: {
2285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK((is_get || is_set) && !is_generator && !is_async);
2286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2287f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!*is_computed_name) {
2288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        checker->CheckClassMethodName(
2289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            name_token, PropertyKind::kAccessorProperty, false, false,
229062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // Make sure the name expression is a string since we need a Name for
2292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2293f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // this statically we can skip the extra runtime check.
2294f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        name_expression =
2295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            factory()->NewStringLiteral(name, name_expression->position());
2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2297f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 : FunctionKind::kSetterFunction;
2300f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionLiteralT value = impl()->ParseFunctionLiteral(
2302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          name, scanner()->location(), kSkipFunctionNameCheck, kind,
230362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          FLAG_harmony_function_tostring ? function_token_position
230462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         : kNoSourcePosition,
230562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          FunctionLiteral::kAccessorOrMethod, language_mode(),
230662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!*is_computed_name) {
2309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->AddAccessorPrefixToFunctionName(is_get, value, name);
2310bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
231262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *property_kind =
231362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER;
231462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return factory()->NewClassLiteralProperty(name_expression, value,
231562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                *property_kind, *is_static,
231662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                *is_computed_name);
2317f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
231862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case PropertyKind::kSpreadProperty:
231962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      UNREACHABLE();
2320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  UNREACHABLE();
2322f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->EmptyClassLiteralProperty();
2323f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2324f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2325f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
2326f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::FunctionLiteralT
2327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer,
2328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                bool* ok) {
2329f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Makes a concise method which evaluates and returns the initialized value
2330f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // (or undefined if absent).
2331f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionKind kind = FunctionKind::kConciseMethod;
2332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DeclarationScope* initializer_scope = NewFunctionScope(kind);
2333f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  initializer_scope->set_start_position(scanner()->location().end_pos);
233462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FunctionState initializer_state(&function_state_, &scope_, initializer_scope);
233562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(initializer_scope, scope());
2336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  scope()->SetLanguageMode(STRICT);
2337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionClassifier expression_classifier(this);
2338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT value;
2339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (has_initializer) {
2340f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    value = this->ParseAssignmentExpression(
2341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        true, CHECK_OK_CUSTOM(EmptyFunctionLiteral));
2342f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyFunctionLiteral));
2343f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
2344f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    value = factory()->NewUndefinedLiteral(kNoSourcePosition);
2345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  initializer_scope->set_end_position(scanner()->location().end_pos);
2347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::StatementList body = impl()->NewStatementList(1);
2348f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone());
2349f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
2350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->EmptyIdentifierString(), initializer_scope, body,
2351c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      initializer_state.expected_property_count(), 0, 0,
2352f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionLiteral::kNoDuplicateParameters,
2353c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_,
235462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      initializer_scope->start_position(), true, GetNextFunctionLiteralId());
2355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return function_literal;
2356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
2359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ObjectLiteralPropertyT
2360f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
2361f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                bool* is_computed_name,
236262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                bool* is_rest_property,
2363f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                bool* ok) {
2364f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_get = false;
2365f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_set = false;
2366f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_generator = false;
2367f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_async = false;
2368f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  PropertyKind kind = PropertyKind::kNotSet;
2369f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT name = impl()->EmptyIdentifier();
2371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Token::Value name_token = peek();
2372f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int next_beg_pos = scanner()->peek_location().beg_pos;
2373f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int next_end_pos = scanner()->peek_location().end_pos;
2374f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2375f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT name_expression = ParsePropertyName(
2376f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      &name, &kind, &is_generator, &is_get, &is_set, &is_async,
2377f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2378f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2379f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (kind) {
238062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case PropertyKind::kSpreadProperty:
238162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK(allow_harmony_object_rest_spread());
238262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK(!is_get && !is_set && !is_generator && !is_async &&
238362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             !*is_computed_name);
238462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK(name_token == Token::ELLIPSIS);
238562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
238662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *is_computed_name = true;
238762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *is_rest_property = true;
238862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
238962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return factory()->NewObjectLiteralProperty(
239062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          impl()->GetLiteralTheHole(kNoSourcePosition), name_expression,
239162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          ObjectLiteralProperty::SPREAD, true);
239262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kValueProperty: {
2394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(!is_get && !is_set && !is_generator && !is_async);
2395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!*is_computed_name) {
2397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        checker->CheckDuplicateProto(name_token);
2398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Consume(Token::COLON);
2400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      int beg_pos = peek_position();
2401f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT value = ParseAssignmentExpression(
2402f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2403f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos);
2404f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2405f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2406f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          name_expression, value, *is_computed_name);
2407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!*is_computed_name) {
2409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->SetFunctionNameFromPropertyName(result, name);
2410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return result;
2413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
2414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kShorthandProperty: {
2416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // PropertyDefinition
2417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      //    IdentifierReference
2418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      //    CoverInitializedName
2419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      //
2420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // CoverInitializedName
2421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      //    IdentifierReference Initializer?
2422f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(!is_get && !is_set && !is_generator && !is_async);
2423f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2424f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!Token::IsIdentifier(name_token, language_mode(),
2425f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               this->is_generator(),
2426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               parsing_module_ || is_async_function())) {
2427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ReportUnexpectedToken(Next());
2428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        *ok = false;
2429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return impl()->EmptyObjectLiteralProperty();
2430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(!*is_computed_name);
2433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (classifier()->duplicate_finder() != nullptr &&
243562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          scanner()->FindSymbol(classifier()->duplicate_finder())) {
2436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordDuplicateFormalParameterError(
2437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            scanner()->location());
2438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2439f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2440f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (impl()->IsEvalOrArguments(name) && is_strict(language_mode())) {
2441f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordBindingPatternError(
2442f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            scanner()->location(), MessageTemplate::kStrictEvalArguments);
2443f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2444f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2445f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (name_token == Token::LET) {
2446f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordLetPatternError(
2447f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            scanner()->location(), MessageTemplate::kLetInLexicalBinding);
2448f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2449f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (name_token == Token::AWAIT) {
2450f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        DCHECK(!is_async_function());
2451f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordAsyncArrowFormalParametersError(
2452f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            Scanner::Location(next_beg_pos, next_end_pos),
2453f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            MessageTemplate::kAwaitBindingIdentifier);
2454f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2455c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      ExpressionT lhs = impl()->ExpressionFromIdentifier(name, next_beg_pos);
2456f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CheckDestructuringElement(lhs, next_beg_pos, next_end_pos);
2457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2458f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT value;
2459f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (peek() == Token::ASSIGN) {
2460f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Consume(Token::ASSIGN);
2461f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExpressionClassifier rhs_classifier(this);
2462f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExpressionT rhs = ParseAssignmentExpression(
2463f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2465f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->AccumulateFormalParameterContainmentErrors();
2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         kNoSourcePosition);
2468f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordExpressionError(
2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            MessageTemplate::kInvalidCoverInitializedName);
2471109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2472f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value = lhs;
2475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return factory()->NewObjectLiteralProperty(
2478f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          name_expression, value, ObjectLiteralProperty::COMPUTED, false);
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2481f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kMethodProperty: {
2482f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(!is_get && !is_set);
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2484f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // MethodDefinition
2485f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2486f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordPatternError(
2489f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2490f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          MessageTemplate::kInvalidDestructuringTarget);
2491f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2492f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionKind kind = is_generator
2493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              ? FunctionKind::kConciseGeneratorMethod
2494f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              : is_async ? FunctionKind::kAsyncConciseMethod
2495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                         : FunctionKind::kConciseMethod;
2496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT value = impl()->ParseFunctionLiteral(
2498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          name, scanner()->location(), kSkipFunctionNameCheck, kind,
249962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition,
250062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          FunctionLiteral::kAccessorOrMethod, language_mode(),
250162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return factory()->NewObjectLiteralProperty(
2504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          name_expression, value, ObjectLiteralProperty::COMPUTED,
2505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          *is_computed_name);
2506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2508f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kAccessorProperty: {
2509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator &&
2510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             !is_async);
2511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2512f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordPatternError(
2513f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          MessageTemplate::kInvalidDestructuringTarget);
2515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2516f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!*is_computed_name) {
2517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // Make sure the name expression is a string since we need a Name for
2518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // this statically we can skip the extra runtime check.
2520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        name_expression =
2521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            factory()->NewStringLiteral(name, name_expression->position());
2522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 : FunctionKind::kSetterFunction;
2526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionLiteralT value = impl()->ParseFunctionLiteral(
2528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          name, scanner()->location(), kSkipFunctionNameCheck, kind,
252962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition,
253062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          FunctionLiteral::kAccessorOrMethod, language_mode(),
253162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!*is_computed_name) {
2534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->AddAccessorPrefixToFunctionName(is_get, value, name);
2535f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return factory()->NewObjectLiteralProperty(
2538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          name_expression, value, is_get ? ObjectLiteralProperty::GETTER
2539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                         : ObjectLiteralProperty::SETTER,
2540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          *is_computed_name);
2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kClassField:
2544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case PropertyKind::kNotSet:
2545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportUnexpectedToken(Next());
2546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *ok = false;
2547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyObjectLiteralProperty();
2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2549f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  UNREACHABLE();
2550f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->EmptyObjectLiteralProperty();
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
2554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
2555f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ObjectLiteral ::
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = peek_position();
2560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::ObjectPropertyList properties =
2561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->NewObjectPropertyList(4);
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int number_of_boilerplate_properties = 0;
256362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool has_computed_names = false;
256562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool has_rest_property = false;
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ObjectLiteralChecker checker(this);
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expect(Token::LBRACE, CHECK_OK);
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (peek() != Token::RBRACE) {
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FuncNameInferrer::State fni_state(fni_);
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool is_computed_name = false;
257462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool is_rest_property = false;
257562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ObjectLiteralPropertyT property = ParseObjectPropertyDefinition(
257662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        &checker, &is_computed_name, &is_rest_property, CHECK_OK);
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_computed_name) {
2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_computed_names = true;
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
258262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (is_rest_property) {
258362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      has_rest_property = true;
258462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
258562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
258662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (impl()->IsBoilerplateProperty(property) && !has_computed_names) {
258762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Count CONSTANT or COMPUTED properties to maintain the enumeration
258862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // order.
2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      number_of_boilerplate_properties++;
2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
259162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    properties->Add(property, zone());
2593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (peek() != Token::RBRACE) {
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Need {} because of the CHECK_OK macro.
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Expect(Token::COMMA, CHECK_OK);
2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (fni_ != nullptr) fni_->Infer();
2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expect(Token::RBRACE, CHECK_OK);
2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
260362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // In pattern rewriter, we rewrite rest property to call out to a
260462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // runtime function passing all the other properties as arguments to
260562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // this runtime function. Here, we make sure that the number of
260662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // properties is less than number of arguments allowed for a runtime
260762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // call.
260862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (has_rest_property && properties->length() > Code::kMaxArguments) {
260962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    this->classifier()->RecordPatternError(Scanner::Location(pos, position()),
261062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           MessageTemplate::kTooManyArguments);
261162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
261362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return factory()->NewObjectLiteral(
261462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      properties, number_of_boilerplate_properties, pos, has_rest_property);
2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
2618f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
2619f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) {
2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Arguments ::
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '(' (AssignmentExpression)*[','] ')'
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scanner::Location spread_arg = Scanner::Location::invalid();
2624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionListT result = impl()->NewExpressionList(4);
2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool done = (peek() == Token::RPAREN);
2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!done) {
2628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int start_pos = peek_position();
2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool is_spread = Check(Token::ELLIPSIS);
2630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int expr_pos = peek_position();
2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2632f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT argument =
2633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList));
263413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (!maybe_arrow) {
2635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList));
263613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_spread) {
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!spread_arg.IsValid()) {
2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        spread_arg.beg_pos = start_pos;
2640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        spread_arg.end_pos = peek_position();
2641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2642109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      argument = factory()->NewSpread(argument, start_pos, expr_pos);
2643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->Add(argument, zone_);
2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (result->length() > Code::kMaxArguments) {
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReportMessage(MessageTemplate::kTooManyArguments);
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
2649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->NullExpressionList();
2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    done = (peek() != Token::COMMA);
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!done) {
2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Next();
2654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) {
2655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // allow trailing comma
2656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        done = true;
2657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scanner::Location location = scanner_->location();
2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Token::RPAREN != Next()) {
2662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok = false;
2664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->NullExpressionList();
2665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *first_spread_arg_loc = spread_arg;
2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
266813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (!maybe_arrow || peek() != Token::ARROW) {
266913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (maybe_arrow) {
2670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList));
267113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Precedence = 2
2678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
2679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
2680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // AssignmentExpression ::
2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   ConditionalExpression
2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   ArrowFunction
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   YieldExpression
2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int lhs_beg_pos = peek_position();
2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (peek() == Token::YIELD && is_generator()) {
2689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return ParseYieldExpression(accept_IN, ok);
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FuncNameInferrer::State fni_state(fni_);
2693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Checkpoint checkpoint(this);
2694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionClassifier arrow_formals_classifier(
2695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      this, classifier()->duplicate_finder());
2696bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Scope::Snapshot scope_snapshot(scope());
269862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int rewritable_length =
269962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      function_state_->destructuring_assignments_to_rewrite().length();
2700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
270162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool is_async = peek() == Token::ASYNC &&
270213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                  !scanner()->HasAnyLineTerminatorAfterNext() &&
270313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                  IsValidArrowFormalParametersStart(PeekAhead());
2704bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool parenthesized_formals = peek() == Token::LPAREN;
2706bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!is_async && !parenthesized_formals) {
2707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ArrowFormalParametersUnexpectedToken();
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2709bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Parse a simple, faster sub-grammar (primary expression) if it's evident
2711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // that we have only a trivial expression to parse.
2712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ExpressionT expression;
2713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (IsTrivialExpression()) {
2714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    expression = ParsePrimaryExpression(&is_async, CHECK_OK);
2715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    expression = ParseConditionalExpression(accept_IN, CHECK_OK);
2717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() &&
2720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      PeekAhead() == Token::ARROW) {
2721bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // async Identifier => AsyncConciseBody
2722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK);
2723c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    expression =
2724c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        impl()->ExpressionFromIdentifier(name, position(), InferName::kNo);
2725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (fni_) {
2726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Remove `async` keyword from inferred name stack.
2727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      fni_->RemoveAsyncKeywordFromEnd();
2728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
2729bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (peek() == Token::ARROW) {
273213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Scanner::Location arrow_loc = scanner()->peek_location();
2733f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ValidateArrowFormalParameters(expression, parenthesized_formals, is_async,
2734f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  CHECK_OK);
27353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // This reads strangely, but is correct: it checks whether any
27363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // sub-expression of the parameter list failed to be a valid formal
27373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // parameter initializer. Since YieldExpressions are banned anywhere
27383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // in an arrow parameter list, this is correct.
27393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
27403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // "YieldExpression", which is its only use.
2741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ValidateFormalParameterInitializer(ok);
2742bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DeclarationScope* scope =
2745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction
2746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  : FunctionKind::kArrowFunction);
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Because the arrow's parameters were parsed in the outer scope, any
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // usage flags that might have been triggered there need to be copied
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // to the arrow scope.
2750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    this->scope()->PropagateUsageFlagsToScope(scope);
2751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    scope_snapshot.Reparent(scope);
275362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    function_state_->SetDestructuringAssignmentsScope(rewritable_length, scope);
2754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FormalParametersT parameters(scope);
2756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!classifier()->is_simple_parameter_list()) {
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scope->SetHasNonSimpleParameters();
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      parameters.is_simple = false;
2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    checkpoint.Restore(&parameters.materialized_literals_count);
2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    scope->set_start_position(lhs_beg_pos);
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Scanner::Location duplicate_loc = Scanner::Location::invalid();
2765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->DeclareArrowFunctionFormalParameters(&parameters, expression, loc,
2766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                 &duplicate_loc, CHECK_OK);
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (duplicate_loc.IsValid()) {
2768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      classifier()->RecordDuplicateFormalParameterError(duplicate_loc);
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
277062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    expression = ParseArrowFunctionLiteral(accept_IN, parameters,
277162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           rewritable_length, CHECK_OK);
2772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->Discard();
2773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordPatternError(arrow_loc,
2774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     MessageTemplate::kUnexpectedToken,
2775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     Token::String(Token::ARROW));
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (fni_ != nullptr) fni_->Infer();
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return expression;
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // "expression" was not itself an arrow function parameter list, but it might
2783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // form part of one.  Propagate speculative formal parameter error locations
2784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // (including those for binding patterns, since formal parameters can
2785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // themselves contain binding patterns).
2786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  unsigned productions = ExpressionClassifier::AllProductions &
2787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         ~ExpressionClassifier::ArrowFormalParametersProduction;
2788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2789f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Parenthesized identifiers and property references are allowed as part
2790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // of a larger assignment pattern, even though parenthesized patterns
2791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // themselves are not allowed, e.g., "[(x)] = []". Only accumulate
2792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // assignment pattern errors if the parsed expression is more complex.
2793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (IsValidReferenceExpression(expression)) {
2794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    productions &= ~ExpressionClassifier::AssignmentPatternProduction;
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const bool is_destructuring_assignment =
2798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      IsValidPattern(expression) && peek() == Token::ASSIGN;
2799f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_destructuring_assignment) {
2800f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // This is definitely not an expression so don't accumulate
2801f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // expression-related errors.
2802c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    productions &= ~ExpressionClassifier::ExpressionProduction;
2803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!Token::IsAssignmentOp(peek())) {
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Parsed conditional expression only (no assignment).
2807f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Pending non-pattern expressions must be merged.
2808f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->Accumulate(productions);
2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return expression;
2810f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
2811f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Pending non-pattern expressions must be discarded.
2812f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->Accumulate(productions, false);
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (is_destructuring_assignment) {
2816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ValidateAssignmentPattern(CHECK_OK);
2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    expression = CheckAndRewriteReferenceExpression(
2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        expression, lhs_beg_pos, scanner()->location().end_pos,
2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
282362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  impl()->MarkExpressionAsAssigned(expression);
2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value op = Next();  // Get assignment operator.
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (op != Token::ASSIGN) {
2827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordPatternError(scanner()->location(),
2828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     MessageTemplate::kUnexpectedToken,
2829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     Token::String(op));
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = position();
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2833109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ExpressionClassifier rhs_classifier(this);
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2835f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2836f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->RewriteNonPattern(CHECK_OK);
2837f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->AccumulateFormalParameterContainmentErrors();
2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(1231235): We try to estimate the set of properties set by
2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // constructors. We define a new property whenever there is an
2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // assignment to a property of 'this'. We should probably only add
2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // properties if we haven't seen them before. Otherwise we'll
2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // probably overestimate the number of properties.
2844f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) {
2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    function_state_->AddProperty();
2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->CheckAssigningFunctionLiteralToProperty(expression, right);
2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (fni_ != NULL) {
2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Check if the right hand side is a call to avoid inferring a
2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // name if we're dealing with "a = function(){...}();"-like
2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // expression.
2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if ((op == Token::INIT || op == Token::ASSIGN) &&
2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (!right->IsCall() && !right->IsCallNew())) {
2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fni_->Infer();
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fni_->RemoveLastFunction();
2859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
286213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (op == Token::ASSIGN) {
2863f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->SetFunctionNameFromIdentifierRef(right, expression);
2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
28663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (op == Token::ASSIGN_EXP) {
28673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(!is_destructuring_assignment);
2868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return impl()->RewriteAssignExponentiation(expression, right, pos);
28693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
28703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_destructuring_assignment) {
2874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result = factory()->NewRewritableExpression(result);
2875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    impl()->QueueDestructuringAssignmentForRewriting(result);
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
2882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
2883f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool accept_IN, bool* ok) {
2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // YieldExpression ::
2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'yield' ([no line terminator] '*'? AssignmentExpression)?
2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = peek_position();
2887f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  classifier()->RecordPatternError(
2888f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      scanner()->peek_location(), MessageTemplate::kInvalidDestructuringTarget);
2889f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  classifier()->RecordFormalParameterInitializerError(
28903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      scanner()->peek_location(), MessageTemplate::kYieldInParameter);
2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expect(Token::YIELD, CHECK_OK);
2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExpressionT generator_object =
2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      factory()->NewVariableProxy(function_state_->generator_object_variable());
2894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // The following initialization is necessary.
2895f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT expression = impl()->EmptyExpression();
28963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool delegating = false;  // yield*
2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
28983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (Check(Token::MUL)) delegating = true;
2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (peek()) {
2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::EOS:
2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::SEMICOLON:
2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::RBRACE:
2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::RBRACK:
2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::RPAREN:
2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::COLON:
2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::COMMA:
2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // The above set of tokens is the complete set of tokens that can appear
2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // after an AssignmentExpression, and none of them can start an
2909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // AssignmentExpression.  This allows us to avoid looking for an RHS for
29103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // a regular yield, given only one look-ahead token.
29113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (!delegating) break;
2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Delegating yields require an RHS; fall through.
2913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
2914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
2915f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
29193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
29203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (delegating) {
2921f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return impl()->RewriteYieldStar(generator_object, expression, pos);
2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
29233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  expression = impl()->BuildIteratorResult(expression, false);
2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(verwaest): Come up with a better solution.
2927f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT yield = factory()->NewYield(generator_object, expression, pos,
2928f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          Yield::kOnExceptionThrow);
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return yield;
2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Precedence = 3
2933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
2934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
2935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
2936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                             bool* ok) {
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ConditionalExpression ::
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   LogicalOrExpression
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = peek_position();
2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We start using the binary expression parser for prec >= 4 only!
2943f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (peek() != Token::CONDITIONAL) return expression;
2945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->RewriteNonPattern(CHECK_OK);
2946f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BindingPatternUnexpectedToken();
2947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ArrowFormalParametersUnexpectedToken();
2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Consume(Token::CONDITIONAL);
2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // In parsing the first assignment expression in conditional
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // expressions we always accept the 'in' keyword; see ECMA-262,
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // section 11.12, page 58.
2952f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT left = ParseAssignmentExpression(true, CHECK_OK);
2953f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->RewriteNonPattern(CHECK_OK);
2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expect(Token::COLON, CHECK_OK);
2955f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2956f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->RewriteNonPattern(CHECK_OK);
2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return factory()->NewConditional(expression, left, right, pos);
2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Precedence >= 4
2962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
2963f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
2964f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int prec, bool accept_IN, bool* ok) {
2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(prec >= 4);
2966f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT x = ParseUnaryExpression(CHECK_OK);
2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // prec1 >= 4
2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (Precedence(peek(), accept_IN) == prec1) {
2970f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->RewriteNonPattern(CHECK_OK);
2971f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      BindingPatternUnexpectedToken();
2972f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ArrowFormalParametersUnexpectedToken();
2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Token::Value op = Next();
2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int pos = position();
29753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
29763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const bool is_right_associative = op == Token::EXP;
29773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const int next_prec = is_right_associative ? prec1 : prec1 + 1;
2978f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK);
2979f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->RewriteNonPattern(CHECK_OK);
2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2981f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) {
2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;
2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // For now we distinguish between comparisons and other binary
2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // operations.  (We could combine the two and get rid of this
2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // code and AST node eventually.)
2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (Token::IsCompareOp(op)) {
2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // We have a comparison.
2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Token::Value cmp = op;
2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        switch (op) {
2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case Token::NE: cmp = Token::EQ; break;
2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          default: break;
2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2996bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        x = factory()->NewCompareOperation(cmp, x, y, pos);
2997bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (cmp != op) {
2998bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          // The comparison was negated - add a NOT.
2999bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
30013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else if (op == Token::EXP) {
3002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        x = impl()->RewriteExponentiation(x, y, pos);
3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // We have a "normal" binary operation.
3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        x = factory()->NewBinaryOperation(op, x, y, pos);
3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return x;
3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
3014f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // UnaryExpression ::
3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   PostfixExpression
3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'delete' UnaryExpression
3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'void' UnaryExpression
3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'typeof' UnaryExpression
3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '++' UnaryExpression
3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '--' UnaryExpression
3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '+' UnaryExpression
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '-' UnaryExpression
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '~' UnaryExpression
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   '!' UnaryExpression
3026bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  //   [+Await] AwaitExpression[?Yield]
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value op = peek();
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Token::IsUnaryOp(op)) {
3030f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    BindingPatternUnexpectedToken();
3031f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ArrowFormalParametersUnexpectedToken();
3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    op = Next();
3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int pos = position();
303562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
303662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Assume "! function ..." indicates the function is likely to be called.
303762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (op == Token::NOT && peek() == Token::FUNCTION) {
303862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      function_state_->set_next_function_is_likely_called();
303962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
304062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3041f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT expression = ParseUnaryExpression(CHECK_OK);
3042f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK);
3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (op == Token::DELETE && is_strict(language_mode())) {
3045f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (impl()->IsIdentifier(expression)) {
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // "delete identifier" is a syntax error in strict mode.
3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ReportMessage(MessageTemplate::kStrictDelete);
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        *ok = false;
3049f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return impl()->EmptyExpression();
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
30533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (peek() == Token::EXP) {
30543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReportUnexpectedToken(Next());
30553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      *ok = false;
3056f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyExpression();
30573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
30583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3059f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Allow the parser's implementation to rewrite the expression.
3060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->BuildUnaryExpression(expression, op, pos);
3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (Token::IsCountOp(op)) {
3062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    BindingPatternUnexpectedToken();
3063f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ArrowFormalParametersUnexpectedToken();
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    op = Next();
3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int beg_pos = peek_position();
3066f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT expression = ParseUnaryExpression(CHECK_OK);
3067f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    expression = CheckAndRewriteReferenceExpression(
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        expression, beg_pos, scanner()->location().end_pos,
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
307062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->MarkExpressionAsAssigned(expression);
3071f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK);
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return factory()->NewCountOperation(op,
3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        true /* prefix */,
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        expression,
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        position());
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3078bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (is_async_function() && peek() == Token::AWAIT) {
3079f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordFormalParameterInitializerError(
3080f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        scanner()->peek_location(),
3081f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        MessageTemplate::kAwaitExpressionFormalParameter);
308213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
308313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int await_pos = peek_position();
3084bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Consume(Token::AWAIT);
3085bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
3086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT value = ParseUnaryExpression(CHECK_OK);
3087bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
3088f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return impl()->RewriteAwaitExpression(value, await_pos);
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3090f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return ParsePostfixExpression(ok);
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3095f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression(
3096f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // PostfixExpression ::
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   LeftHandSideExpression ('++' | '--')?
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int lhs_beg_pos = peek_position();
3101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT expression = ParseLeftHandSideExpression(CHECK_OK);
3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Token::IsCountOp(peek())) {
3104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    BindingPatternUnexpectedToken();
3105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ArrowFormalParametersUnexpectedToken();
3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    expression = CheckAndRewriteReferenceExpression(
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        expression, lhs_beg_pos, scanner()->location().end_pos,
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
311062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->MarkExpressionAsAssigned(expression);
3111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK);
3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Token::Value next = Next();
3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    expression =
3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewCountOperation(next,
3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     false /* postfix */,
3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     expression,
3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     position());
3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return expression;
3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
3125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // LeftHandSideExpression ::
3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   (NewExpression | MemberExpression) ...
3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3129bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bool is_async = false;
3130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT result =
3131f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ParseMemberWithNewPrefixesExpression(&is_async, CHECK_OK);
3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (true) {
3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (peek()) {
3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::LBRACK: {
3136f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
3138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ArrowFormalParametersUnexpectedToken();
3139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Consume(Token::LBRACK);
3140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int pos = position();
3141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
3142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result = factory()->NewProperty(result, index, pos);
3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Expect(Token::RBRACK, CHECK_OK);
3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::LPAREN: {
3149bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        int pos;
3150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (scanner()->current_token() == Token::IDENTIFIER ||
3153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            scanner()->current_token() == Token::SUPER ||
3154bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            scanner()->current_token() == Token::ASYNC) {
3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // For call of an identifier we want to report position of
3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // the identifier as position of the call in the stack trace.
3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          pos = position();
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // For other kinds of calls we record position of the parenthesis as
3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // position of the call. Note that this is extremely important for
3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // expressions of the form function(){...}() for which call position
3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // should not point to the closing brace otherwise it will intersect
3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // with positions recorded for function literal and confuse debugger.
3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          pos = peek_position();
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Also the trailing parenthesis are a hint that the function will
3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // be called immediately. If we happen to have parsed a preceding
3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // function literal eagerly, we can also compile it eagerly.
3168c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (result->IsFunctionLiteral()) {
3169c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            result->AsFunctionLiteral()->SetShouldEagerCompile();
3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Scanner::Location spread_pos;
3173f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExpressionListT args;
3174f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) {
3175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          ExpressionClassifier async_classifier(this);
3176f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          args = ParseArguments(&spread_pos, true, CHECK_OK);
3177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (peek() == Token::ARROW) {
3178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            if (fni_) {
3179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              fni_->RemoveAsyncKeywordFromEnd();
3180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            }
3181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            ValidateBindingPattern(CHECK_OK);
3182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            ValidateFormalParameterInitializer(CHECK_OK);
3183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            if (!classifier()->is_valid_async_arrow_formal_parameters()) {
3184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              ReportClassifierError(
3185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  classifier()->async_arrow_formal_parameters_error());
3186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              *ok = false;
3187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              return impl()->EmptyExpression();
3188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            }
3189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            if (args->length()) {
3190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              // async ( Arguments ) => ...
3191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              return impl()->ExpressionListToExpression(args);
3192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            }
3193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            // async () => ...
3194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            return factory()->NewEmptyParentheses(pos);
3195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          } else {
3196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            impl()->AccumulateFormalParameterContainmentErrors();
3197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          }
3198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        } else {
3199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          args = ParseArguments(&spread_pos, false, CHECK_OK);
3200bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        }
3201bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
3202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ArrowFormalParametersUnexpectedToken();
3203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Keep track of eval() calls since they disable all local variable
3205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // optimizations.
3206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // The calls that need special treatment are the
3207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // direct eval calls. These calls are all of the form eval(...), with
3208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // no explicit receiver.
3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // These calls are marked as potentially direct eval calls. Whether
3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // they are actually direct calls to eval is determined at run time.
3211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Call::PossiblyEval is_possibly_eval =
3212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            CheckPossibleEvalCall(result, scope());
3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        bool is_super_call = result->IsSuperCallReference();
3215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (spread_pos.IsValid()) {
321662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          result = impl()->SpreadCall(result, args, pos, is_possibly_eval);
3217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          result = factory()->NewCall(result, args, pos, is_possibly_eval);
3219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Explicit calls to the super constructor using super() perform an
3222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // implicit binding assignment to the 'this' variable.
3223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (is_super_call) {
3224f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ExpressionT this_expr = impl()->ThisExpression(pos);
3225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          result =
3226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              factory()->NewAssignment(Token::INIT, this_expr, result, pos);
3227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (fni_ != NULL) fni_->RemoveLastFunction();
3230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
3231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::PERIOD: {
3234f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
3236f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ArrowFormalParametersUnexpectedToken();
3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Consume(Token::PERIOD);
3238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int pos = position();
3239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        IdentifierT name = ParseIdentifierName(CHECK_OK);
3240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result = factory()->NewProperty(
3241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            result, factory()->NewStringLiteral(name, pos), pos);
3242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->PushLiteralName(name);
3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::TEMPLATE_SPAN:
3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::TEMPLATE_TAIL: {
3248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3249f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
3250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ArrowFormalParametersUnexpectedToken();
325162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        result = ParseTemplateLiteral(result, position(), true, CHECK_OK);
3252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
3253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return result;
3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
3263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseMemberWithNewPrefixesExpression(bool* is_async,
3264f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                       bool* ok) {
3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // NewExpression ::
3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   ('new')+ MemberExpression
3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // NewTarget ::
3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   'new' '.' 'target'
3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The grammar for new expressions is pretty warped. We can have several 'new'
3272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // keywords following each other, and then a MemberExpression. When we see '('
3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // after the MemberExpression, it's associated with the rightmost unassociated
3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 'new' to create a NewExpression with arguments. However, a NewExpression
3275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // can also occur without arguments.
3276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Examples of new expression:
3278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // new foo.bar().baz means (new (foo.bar)()).baz
3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // new foo()() means (new foo())()
3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // new new foo()() means (new (new foo())())
3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // new new foo means new (new foo)
3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // new new foo() means new (new foo())
3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // new new foo().bar().baz means (new (new foo()).bar()).baz
3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (peek() == Token::NEW) {
3286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    BindingPatternUnexpectedToken();
3287f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ArrowFormalParametersUnexpectedToken();
3288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Consume(Token::NEW);
3289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int new_pos = position();
3290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ExpressionT result;
3291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (peek() == Token::SUPER) {
3292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      const bool is_new = true;
3293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      result = ParseSuperExpression(is_new, CHECK_OK);
329462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT) {
329562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->ReportMessageAt(scanner()->peek_location(),
329662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              MessageTemplate::kImportCallNotNewExpression);
329762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *ok = false;
329862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return impl()->EmptyExpression();
3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (peek() == Token::PERIOD) {
3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ParseNewTargetExpression(CHECK_OK);
3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
3302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      result = ParseMemberWithNewPrefixesExpression(is_async, CHECK_OK);
3303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3304f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK);
3305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (peek() == Token::LPAREN) {
3306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // NewExpression with arguments.
3307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Scanner::Location spread_pos;
3308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK);
3309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (spread_pos.IsValid()) {
3311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        result = impl()->SpreadCallNew(result, args, new_pos);
3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result = factory()->NewCallNew(result, args, new_pos);
3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The expression can still continue with . or [ after the arguments.
3316f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK);
3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return result;
3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // NewExpression without arguments.
3320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos);
3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // No 'new' or 'super' keyword.
3323f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return ParseMemberExpression(is_async, ok);
3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression(
3328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* is_async, bool* ok) {
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // MemberExpression ::
3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
333262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
333362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // CallExpression ::
333462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //   (SuperCall | ImportCall)
333562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
333662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The '[' Expression ']' and '.' Identifier parts are parsed by
3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // caller.
3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Parse the initial primary or function expression.
3342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ExpressionT result;
3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (peek() == Token::FUNCTION) {
3344f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    BindingPatternUnexpectedToken();
3345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ArrowFormalParametersUnexpectedToken();
3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Consume(Token::FUNCTION);
3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int function_token_position = position();
3349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (allow_harmony_function_sent() && peek() == Token::PERIOD) {
3351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // function.sent
3352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int pos = position();
3353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK);
3354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3355109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (!is_generator()) {
3356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // TODO(neis): allow escaping into closures?
3357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->ReportMessageAt(scanner()->location(),
3358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                MessageTemplate::kUnexpectedFunctionSent);
3359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        *ok = false;
3360f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return impl()->EmptyExpression();
3361109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
3362109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3363f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->FunctionSentExpression(pos);
3364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
3365109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    FunctionKind function_kind = Check(Token::MUL)
3367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     ? FunctionKind::kGeneratorFunction
3368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     : FunctionKind::kNormalFunction;
3369f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    IdentifierT name = impl()->EmptyIdentifier();
3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool is_strict_reserved_name = false;
3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Scanner::Location function_name_location = Scanner::Location::invalid();
3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FunctionLiteral::FunctionType function_type =
3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FunctionLiteral::kAnonymousExpression;
337462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (impl()->ParsingDynamicFunctionDeclaration()) {
337562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // We don't want dynamic functions to actually declare their name
337662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // "anonymous". We just want that name in the toString().
337762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Consume(Token::IDENTIFIER);
337862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK(scanner()->UnescapedLiteralMatches("anonymous", 9));
337962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else if (peek_any_identifier()) {
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      name = ParseIdentifierOrStrictReservedWord(
3381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          function_kind, &is_strict_reserved_name, CHECK_OK);
3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function_name_location = scanner()->location();
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function_type = FunctionLiteral::kNamedExpression;
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    result = impl()->ParseFunctionLiteral(
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        name, function_name_location,
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        is_strict_reserved_name ? kFunctionNameIsStrictReserved
3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                : kFunctionNameValidityUnknown,
3389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        function_kind, function_token_position, function_type, language_mode(),
3390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        CHECK_OK);
3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (peek() == Token::SUPER) {
3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const bool is_new = false;
3393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    result = ParseSuperExpression(is_new, CHECK_OK);
339462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT) {
339562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result = ParseDynamicImportExpression(CHECK_OK);
3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    result = ParsePrimaryExpression(is_async, CHECK_OK);
3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK);
3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3404f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
340562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypename ParserBase<Impl>::ExpressionT
340662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochParserBase<Impl>::ParseDynamicImportExpression(bool* ok) {
340762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(allow_harmony_dynamic_import());
340862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Consume(Token::IMPORT);
340962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int pos = position();
341062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::LPAREN, CHECK_OK);
341162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpressionT arg = ParseAssignmentExpression(true, CHECK_OK);
341262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::RPAREN, CHECK_OK);
341362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ZoneList<ExpressionT>* args = new (zone()) ZoneList<ExpressionT>(1, zone());
341462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  args->Add(arg, zone());
341562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return factory()->NewCallRuntime(Runtime::kDynamicImportCall, args, pos);
341662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
341762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
341862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename Impl>
3419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression(
3420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    bool is_new, bool* ok) {
3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expect(Token::SUPER, CHECK_OK);
3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = position();
3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeclarationScope* scope = GetReceiverScope();
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FunctionKind kind = scope->function_kind();
3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      IsClassConstructor(kind)) {
3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scope->RecordSuperPropertyUsage();
3430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->NewSuperPropertyReference(pos);
3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // new super() is never allowed.
3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // super() is only allowed in derived constructor
343462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!is_new && peek() == Token::LPAREN && IsDerivedConstructor(kind)) {
3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(rossberg): This might not be the correct FunctionState for the
3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // method here.
3437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->NewSuperCallReference(pos);
3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3441f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->ReportMessageAt(scanner()->location(),
3442f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          MessageTemplate::kUnexpectedSuper);
3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *ok = false;
3444f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->EmptyExpression();
3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ParserBase<Impl>::ExpectMetaProperty(Vector<const char> property_name,
3449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                          const char* full_name, int pos,
3450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                          bool* ok) {
3451109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Consume(Token::PERIOD);
3452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void));
3453109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (scanner()->literal_contains_escapes()) {
3454f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(
3455109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Scanner::Location(pos, scanner()->location().end_pos),
3456109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        MessageTemplate::kInvalidEscapedMetaProperty, full_name);
3457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    *ok = false;
3458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3459109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3461f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3462f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
3463f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParserBase<Impl>::ParseNewTargetExpression(bool* ok) {
3464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = position();
3465109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!GetReceiverScope()->is_function_scope()) {
3468f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(scanner()->location(),
3469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            MessageTemplate::kUnexpectedNewTarget);
3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok = false;
3471f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyExpression();
3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3474f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->NewTargetExpression(pos);
3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
3479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
3480f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                    bool* is_async, bool* ok) {
3481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Parses this part of MemberExpression:
3482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (true) {
3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (peek()) {
3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::LBRACK: {
3486bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        *is_async = false;
3487f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
3489f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ArrowFormalParametersUnexpectedToken();
3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Consume(Token::LBRACK);
3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int pos = position();
3493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
3494f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        expression = factory()->NewProperty(expression, index, pos);
3496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->PushPropertyName(index);
3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Expect(Token::RBRACK, CHECK_OK);
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::PERIOD: {
3501bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        *is_async = false;
3502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
3504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ArrowFormalParametersUnexpectedToken();
3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Consume(Token::PERIOD);
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int pos = position();
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        IdentifierT name = ParseIdentifierName(CHECK_OK);
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        expression = factory()->NewProperty(
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            expression, factory()->NewStringLiteral(name, pos), pos);
3511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->PushLiteralName(name);
3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::TEMPLATE_SPAN:
3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::TEMPLATE_TAIL: {
3516bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        *is_async = false;
3517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
3518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BindingPatternUnexpectedToken();
3519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ArrowFormalParametersUnexpectedToken();
3520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int pos;
3521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (scanner()->current_token() == Token::IDENTIFIER) {
3522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          pos = position();
3523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          pos = peek_position();
3525c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (expression->IsFunctionLiteral()) {
3526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            // If the tag function looks like an IIFE, set_parenthesized() to
3527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            // force eager compilation.
3528c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            expression->AsFunctionLiteral()->SetShouldEagerCompile();
3529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
353162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        expression = ParseTemplateLiteral(expression, pos, true, CHECK_OK);
3532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
3533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
35343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case Token::ILLEGAL: {
35353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
35363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        *ok = false;
3537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return impl()->EmptyExpression();
35383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
3539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
3540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return expression;
3541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(false);
3544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->EmptyExpression();
3545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters,
3549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                            bool* ok) {
3550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // FormalParameter[Yield,GeneratorParameter] :
3551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   BindingElement[?Yield, ?GeneratorParameter]
3552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_rest = parameters->has_rest;
3553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3554f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(Void));
3555f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ValidateBindingPattern(CHECK_OK_CUSTOM(Void));
3556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3557f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!impl()->IsIdentifier(pattern)) {
3558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    parameters->is_simple = false;
3559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void));
3560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordNonSimpleParameter();
3561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT initializer = impl()->EmptyExpression();
35643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!is_rest && Check(Token::ASSIGN)) {
3565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    ExpressionClassifier init_classifier(this);
3566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void));
3567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void));
3568f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void));
3569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    parameters->is_simple = false;
3570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->Discard();
3571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordNonSimpleParameter();
3572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->SetFunctionNameFromIdentifierRef(initializer, pattern);
3574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3576f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->AddFormalParameter(parameters, pattern, initializer,
3577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             scanner()->location().end_pos, is_rest);
3578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
3581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters,
3582f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                bool* ok) {
3583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // FormalParameters[Yield] :
3584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   [empty]
3585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   FunctionRestParameter[?Yield]
3586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //   FormalParameterList[?Yield]
3587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //   FormalParameterList[?Yield] ,
3588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //   FormalParameterList[?Yield] , FunctionRestParameter[?Yield]
3589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
3590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // FormalParameterList[Yield] :
3591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //   FormalParameter[?Yield]
3592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //   FormalParameterList[?Yield] , FormalParameter[?Yield]
3593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3594c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(0, parameters->arity);
3595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (peek() != Token::RPAREN) {
3597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    while (true) {
3598c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (parameters->arity > Code::kMaxArguments) {
3599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ReportMessage(MessageTemplate::kTooManyParameters);
3600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        *ok = false;
3601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
3602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      parameters->has_rest = Check(Token::ELLIPSIS);
3604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ParseFormalParameter(parameters, CHECK_OK_CUSTOM(Void));
3605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (parameters->has_rest) {
3607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        parameters->is_simple = false;
3608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        classifier()->RecordNonSimpleParameter();
3609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (peek() == Token::COMMA) {
3610f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          impl()->ReportMessageAt(scanner()->peek_location(),
3611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  MessageTemplate::kParamAfterRest);
3612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          *ok = false;
3613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          return;
3614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
3615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
3616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
3617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (!Check(Token::COMMA)) break;
3618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) {
3619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // allow the trailing comma
3620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
3621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
362562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  impl()->DeclareFormalParameters(parameters->scope, parameters->params);
3626f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
3627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
3629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations(
3630f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    VariableDeclarationContext var_context,
3631f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DeclarationParsingResult* parsing_result,
3632f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* names, bool* ok) {
3633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // VariableDeclarations ::
3634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
3635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ES6:
3637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
3638f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // declaration syntax.
3639f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3640f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_NOT_NULL(parsing_result);
3641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
3642f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  parsing_result->descriptor.declaration_pos = peek_position();
3643f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  parsing_result->descriptor.initialization_pos = peek_position();
3644f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT init_block = impl()->NullBlock();
3646f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (var_context != kForStatement) {
3647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    init_block = factory()->NewBlock(
3648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        nullptr, 1, true, parsing_result->descriptor.declaration_pos);
3649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (peek()) {
3652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::VAR:
3653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      parsing_result->descriptor.mode = VAR;
3654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Consume(Token::VAR);
3655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
3656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::CONST:
3657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Consume(Token::CONST);
3658f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(var_context != kStatement);
3659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      parsing_result->descriptor.mode = CONST;
3660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
3661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::LET:
3662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Consume(Token::LET);
3663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(var_context != kStatement);
3664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      parsing_result->descriptor.mode = LET;
3665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
3666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    default:
3667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      UNREACHABLE();  // by current callers
3668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
3669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  parsing_result->descriptor.scope = scope();
3672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int bindings_start = peek_position();
3674f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  do {
3675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Parse binding pattern.
3676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    FuncNameInferrer::State fni_state(fni_);
3677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3678f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT pattern = impl()->EmptyExpression();
3679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int decl_pos = peek_position();
3680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    {
3681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionClassifier pattern_classifier(this);
3682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(NullBlock));
3683f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ValidateBindingPattern(CHECK_OK_CUSTOM(NullBlock));
3685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
3686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ValidateLetPattern(CHECK_OK_CUSTOM(NullBlock));
3687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
3688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
3689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scanner::Location variable_loc = scanner()->location();
3691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool single_name = impl()->IsIdentifier(pattern);
3692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (single_name) {
3694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->PushVariableName(impl()->AsIdentifier(pattern));
3695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
3696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT value = impl()->EmptyExpression();
3698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int initializer_position = kNoSourcePosition;
3699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (Check(Token::ASSIGN)) {
3700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionClassifier classifier(this);
3701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      value = ParseAssignmentExpression(var_context != kForStatement,
3702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                        CHECK_OK_CUSTOM(NullBlock));
3703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullBlock));
3704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      variable_loc.end_pos = scanner()->location().end_pos;
3705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!parsing_result->first_initializer_loc.IsValid()) {
3707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        parsing_result->first_initializer_loc = variable_loc;
3708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
3709f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3710f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Don't infer if it is "a = function(){...}();"-like expression.
3711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (single_name && fni_ != nullptr) {
3712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (!value->IsCall() && !value->IsCallNew()) {
3713f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          fni_->Infer();
3714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        } else {
3715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          fni_->RemoveLastFunction();
3716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
3717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
3718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->SetFunctionNameFromIdentifierRef(value, pattern);
3720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3721f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // End position of the initializer is after the assignment expression.
3722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      initializer_position = scanner()->location().end_pos;
3723f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
3724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (var_context != kForStatement || !PeekInOrOf()) {
3725f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // ES6 'const' and binding patterns require initializers.
3726f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (parsing_result->descriptor.mode == CONST ||
3727f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            !impl()->IsIdentifier(pattern)) {
3728f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          impl()->ReportMessageAt(
3729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              Scanner::Location(decl_pos, scanner()->location().end_pos),
3730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              MessageTemplate::kDeclarationMissingInitializer,
3731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              !impl()->IsIdentifier(pattern) ? "destructuring" : "const");
3732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          *ok = false;
3733f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return impl()->NullBlock();
3734f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
3735f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // 'let x' initializes 'x' to undefined.
3736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (parsing_result->descriptor.mode == LET) {
3737f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          value = impl()->GetLiteralUndefined(position());
3738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
3739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
3740f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // End position of the initializer is after the variable.
3742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      initializer_position = position();
3743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
3744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    typename DeclarationParsingResult::Declaration decl(
3746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        pattern, initializer_position, value);
3747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (var_context == kForStatement) {
3748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Save the declaration for further handling in ParseForStatement.
3749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      parsing_result->declarations.Add(decl);
3750f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
3751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Immediately declare the variable otherwise. This avoids O(N^2)
3752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // behavior (where N is the number of variables in a single
3753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // declaration) in the PatternRewriter having to do with removing
3754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // and adding VariableProxies to the Scope (see bug 4699).
3755f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->DeclareAndInitializeVariables(init_block,
3756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                            &parsing_result->descriptor, &decl,
3757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                            names, CHECK_OK_CUSTOM(NullBlock));
3758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
3759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } while (Check(Token::COMMA));
3760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  parsing_result->bindings_loc =
3762f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Scanner::Location(bindings_start, scanner()->location().end_pos);
3763f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(*ok);
3765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return init_block;
3766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
3767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
3769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT
3770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseFunctionDeclaration(bool* ok) {
3771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Consume(Token::FUNCTION);
3772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = position();
3773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
3774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (Check(Token::MUL)) {
3775c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    impl()->ReportMessageAt(scanner()->location(),
3776c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                            MessageTemplate::kGeneratorInLegacyContext);
3777c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *ok = false;
3778c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return impl()->NullStatement();
3779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return ParseHoistableDeclaration(pos, flags, nullptr, false, ok);
3781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
3782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3783f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
3784f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT
3785f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseHoistableDeclaration(
3786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
3787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
3788f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = position();
3789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
3790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (Check(Token::MUL)) {
3791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    flags |= ParseFunctionFlags::kIsGenerator;
3792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
3794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
3795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
3797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT
3798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseHoistableDeclaration(
3799f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
3800f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool default_export, bool* ok) {
3801f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // FunctionDeclaration ::
3802f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
3803f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'function' '(' FormalParameters ')' '{' FunctionBody '}'
3804f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // GeneratorDeclaration ::
3805f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
3806f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
3807f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3808f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // The anonymous forms are allowed iff [default_export] is true.
3809f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3810f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // 'function' and '*' (if present) have been consumed by the caller.
3811f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3812f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
3813f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const bool is_async = flags & ParseFunctionFlags::kIsAsync;
3814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!is_generator || !is_async);
3815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT name;
3817f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionNameValidity name_validity;
3818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT variable_name;
3819f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (default_export && peek() == Token::LPAREN) {
3820f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->GetDefaultStrings(&name, &variable_name);
3821f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    name_validity = kSkipFunctionNameCheck;
3822f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
3823f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool is_strict_reserved;
3824f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
3825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                               CHECK_OK_CUSTOM(NullStatement));
3826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
3827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                       : kFunctionNameValidityUnknown;
3828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    variable_name = name;
3829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FuncNameInferrer::State fni_state(fni_);
3832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->PushEnclosingName(name);
3833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionLiteralT function = impl()->ParseFunctionLiteral(
3834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      name, scanner()->location(), name_validity,
3835f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      is_generator ? FunctionKind::kGeneratorFunction
3836f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                   : is_async ? FunctionKind::kAsyncFunction
3837f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              : FunctionKind::kNormalFunction,
3838f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      pos, FunctionLiteral::kDeclaration, language_mode(),
3839f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CHECK_OK_CUSTOM(NullStatement));
3840f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
384162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // In ES6, a function behaves as a lexical binding, except in
384262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // a script scope, or the initial scope of eval or another function.
384362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  VariableMode mode =
384462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET
384562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                                       : VAR;
384662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Async functions don't undergo sloppy mode block scoped hoisting, and don't
384762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // allow duplicates in a block. Both are represented by the
384862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // sloppy_block_function_map. Don't add them to the map for async functions.
384962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Generators are also supposed to be prohibited; currently doing this behind
385062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // a flag and UseCounting violations to assess web compatibility.
385162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool is_sloppy_block_function =
385262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      is_sloppy(language_mode()) && !scope()->is_declaration_scope() &&
385362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      !is_async && !(allow_harmony_restrictive_generators() && is_generator);
385462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
385562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return impl()->DeclareFunction(variable_name, function, mode, pos,
385662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 is_sloppy_block_function, names, ok);
3857f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
3858f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3859f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
3860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
3861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
3862f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ClassDeclaration ::
3863f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
3864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
3865f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // The anonymous form is allowed iff [default_export] is true.
3867f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3868f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // 'class' is expected to be consumed by the caller.
3869f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3870f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // A ClassDeclaration
3871f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3872f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   class C { ... }
3873f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3874f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // has the same semantics as:
3875f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3876f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   let C = class C { ... };
3877f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
3878f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // so rewrite it as such.
3879f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3880f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int class_token_pos = position();
3881f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT name = impl()->EmptyIdentifier();
3882f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_strict_reserved = false;
3883f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT variable_name = impl()->EmptyIdentifier();
3884f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
3885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->GetDefaultStrings(&name, &variable_name);
3886f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
3887f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
3888f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                               CHECK_OK_CUSTOM(NullStatement));
3889f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    variable_name = name;
3890f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3891f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3892f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionClassifier no_classifier(this);
3893f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT value =
3894f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ParseClassLiteral(name, scanner()->location(), is_strict_reserved,
3895f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        class_token_pos, CHECK_OK_CUSTOM(NullStatement));
3896f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int end_pos = position();
3897f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->DeclareClass(variable_name, value, names, class_token_pos,
3898f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              end_pos, ok);
3899f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
3900f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3901f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Language extension which is only enabled for source files loaded
3902f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// through the API's extension mechanism.  A native function
3903f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// declaration is resolved by looking up the function through a
3904f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// callback provided by the extension.
3905f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
3906f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseNativeDeclaration(
3907f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
3908f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = peek_position();
3909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
3910f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Allow "eval" or "arguments" for backward compatibility.
3911f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers,
3912f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     CHECK_OK_CUSTOM(NullStatement));
3913f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullStatement));
3914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (peek() != Token::RPAREN) {
3915f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    do {
3916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ParseIdentifier(kAllowRestrictedIdentifiers,
3917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      CHECK_OK_CUSTOM(NullStatement));
3918f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } while (Check(Token::COMMA));
3919f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3920f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullStatement));
3921f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::SEMICOLON, CHECK_OK_CUSTOM(NullStatement));
3922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->DeclareNative(name, pos, ok);
3923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
3924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3925f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
3926f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT
3927f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseAsyncFunctionDeclaration(
3928f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
3929f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // AsyncFunctionDeclaration ::
3930f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   async [no LineTerminator here] function BindingIdentifier[Await]
3931f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //       ( FormalParameters[Await] ) { AsyncFunctionBody }
3932f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
3933f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = position();
3934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (scanner()->HasAnyLineTerminatorBeforeNext()) {
3935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *ok = false;
3936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportUnexpectedToken(scanner()->current_token());
3937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->NullStatement();
3938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3939f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
3940f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
3941f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
3942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3944f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
394562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid ParserBase<Impl>::ParseFunctionBody(
394662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    typename ParserBase<Impl>::StatementListT result, IdentifierT function_name,
394762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int pos, const FormalParametersT& parameters, FunctionKind kind,
394862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    FunctionLiteral::FunctionType function_type, bool* ok) {
394962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const int kFunctionNameAssignmentIndex = 0;
395062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (function_type == FunctionLiteral::kNamedExpression) {
395162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(!impl()->IsEmptyIdentifier(function_name));
395262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // If we have a named function expression, we add a local variable
395362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // declaration to the body of the function with the name of the
395462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // function and let it refer to the function itself (closure).
395562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Not having parsed the function body, the language mode may still change,
395662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // so we reserve a spot and create the actual const assignment later.
395762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
395862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result->Add(impl()->NullStatement(), zone());
395962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
396062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
396162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeclarationScope* function_scope = scope()->AsDeclarationScope();
396262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeclarationScope* inner_scope = function_scope;
396362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BlockT inner_block = impl()->NullBlock();
396462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
396562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementListT body = result;
396662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!parameters.is_simple) {
396762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inner_scope = NewVarblockScope();
396862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inner_scope->set_start_position(scanner()->location().beg_pos);
396962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
397062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inner_block->set_scope(inner_scope);
397162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    body = inner_block->statements();
397262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
397362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
397462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
397562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState block_state(&scope_, inner_scope);
397662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
397762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (IsGeneratorFunction(kind)) {
397862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok);
397962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else if (IsAsyncFunction(kind)) {
398062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      const bool accept_IN = true;
398162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal,
398262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             accept_IN, pos, CHECK_OK_VOID);
398362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else {
398462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID);
398562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
398662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
398762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (IsDerivedConstructor(kind)) {
398862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      body->Add(factory()->NewReturnStatement(impl()->ThisExpression(),
398962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                              kNoSourcePosition),
399062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                zone());
399162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
399262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
399362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
399462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::RBRACE, CHECK_OK_VOID);
399562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  scope()->set_end_position(scanner()->location().end_pos);
399662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
399762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!parameters.is_simple) {
399862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_NOT_NULL(inner_scope);
399962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_EQ(function_scope, scope());
400062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_EQ(function_scope, inner_scope->outer_scope());
400162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->SetLanguageMode(function_scope, inner_scope->language_mode());
400262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockT init_block =
400362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        impl()->BuildParameterInitializationBlock(parameters, CHECK_OK_VOID);
400462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
400562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (is_sloppy(inner_scope->language_mode())) {
400662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->InsertSloppyBlockFunctionVarBindings(inner_scope);
400762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
400862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
400962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // TODO(littledan): Merge the two rejection blocks into one
401062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (IsAsyncFunction(kind)) {
401162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      init_block = impl()->BuildRejectPromiseOnException(init_block);
401262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
401362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
401462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inner_scope->set_end_position(scanner()->location().end_pos);
401562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (inner_scope->FinalizeBlockScope() != nullptr) {
401662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->CheckConflictingVarDeclarations(inner_scope, CHECK_OK_VOID);
401762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->InsertShadowingVarBindingInitializers(inner_block);
401862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else {
401962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      inner_block->set_scope(nullptr);
402062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
402162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inner_scope = nullptr;
402262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
402362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result->Add(init_block, zone());
402462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result->Add(inner_block, zone());
402562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
402662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_EQ(inner_scope, function_scope);
402762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (is_sloppy(function_scope->language_mode())) {
402862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
402962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
403062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
403162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
403262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!IsArrowFunction(kind)) {
403362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Declare arguments after parsing the function since lexical 'arguments'
403462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // masks the arguments object. Declare arguments before declaring the
403562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // function var since the arguments object masks 'function arguments'.
403662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    function_scope->DeclareArguments(ast_value_factory());
403762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
403862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
403962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  impl()->CreateFunctionNameAssignment(function_name, pos, function_type,
404062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       function_scope, result,
404162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       kFunctionNameAssignmentIndex);
404262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  impl()->MarkCollectedTailCallExpressions();
404362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
404462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
404562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename Impl>
4046f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ParserBase<Impl>::CheckArityRestrictions(int param_count,
4047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              FunctionKind function_kind,
4048f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              bool has_rest,
4049f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              int formals_start_pos,
4050f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              int formals_end_pos, bool* ok) {
4051109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (IsGetterFunction(function_kind)) {
4052109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (param_count != 0) {
4053f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(
4054f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Scanner::Location(formals_start_pos, formals_end_pos),
4055f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          MessageTemplate::kBadGetterArity);
4056109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      *ok = false;
4057109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
4058109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else if (IsSetterFunction(function_kind)) {
4059109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (param_count != 1) {
4060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(
4061f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Scanner::Location(formals_start_pos, formals_end_pos),
4062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          MessageTemplate::kBadSetterArity);
4063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      *ok = false;
4064109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
4065109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (has_rest) {
4066f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(
4067f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Scanner::Location(formals_start_pos, formals_end_pos),
4068f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          MessageTemplate::kBadSetterRestParameter);
4069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      *ok = false;
4070109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
4071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4074f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
4075f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool ParserBase<Impl>::IsNextLetKeyword() {
4076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(peek() == Token::LET);
4077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value next_next = PeekAhead();
4078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (next_next) {
4079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::LBRACE:
4080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::LBRACK:
4081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::IDENTIFIER:
4082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::STATIC:
4083bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case Token::LET:  // `let let;` is disallowed by static semantics, but the
4084bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      // token must be first interpreted as a keyword in order
4085bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      // for those semantics to apply. This ensures that ASI is
4086bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      // not honored when a LineTerminator separates the
4087bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      // tokens.
4088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Token::YIELD:
4089bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case Token::AWAIT:
4090bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case Token::ASYNC:
4091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
4092bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case Token::FUTURE_STRICT_RESERVED_WORD:
4093bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return is_sloppy(language_mode());
4094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
4095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
4096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4099f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
4100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool ParserBase<Impl>::IsTrivialExpression() {
4101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Token::Value peek_token = peek();
4102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (peek_token == Token::SMI || peek_token == Token::NUMBER ||
4103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL ||
4104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      peek_token == Token::FALSE_LITERAL || peek_token == Token::STRING ||
4105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      peek_token == Token::IDENTIFIER || peek_token == Token::THIS) {
4106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // PeekAhead() is expensive & may not always be called, so we only call it
4107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // after checking peek().
4108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Token::Value peek_ahead = PeekAhead();
4109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN ||
4110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) {
4111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return true;
4112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
4113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
4114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return false;
4115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
4116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
4117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
4118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
4119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParserBase<Impl>::ParseArrowFunctionLiteral(
412062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool accept_IN, const FormalParametersT& formal_parameters,
412162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int rewritable_length, bool* ok) {
412262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const RuntimeCallStats::CounterId counters[2][2] = {
412362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      {&RuntimeCallStats::ParseBackgroundArrowFunctionLiteral,
412462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       &RuntimeCallStats::ParseArrowFunctionLiteral},
412562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      {&RuntimeCallStats::PreParseBackgroundArrowFunctionLiteral,
412662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       &RuntimeCallStats::PreParseArrowFunctionLiteral}};
4127c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  RuntimeCallTimerScope runtime_timer(
4128c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      runtime_call_stats_,
412962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      counters[Impl::IsPreParser()][parsing_on_main_thread_]);
4130c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
4131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
4132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // ASI inserts `;` after arrow parameters if a line terminator is found.
4133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // `=> ...` is never a valid expression, so report as syntax error.
4134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If next token is not `=>`, it's a syntax error anyways.
4135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
4136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok = false;
4137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyExpression();
4138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementListT body = impl()->NullStatementList();
4141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int expected_property_count = -1;
414262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int function_literal_id = GetNextFunctionLiteralId();
4143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionKind kind = formal_parameters.scope->function_kind();
4145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionLiteral::EagerCompileHint eager_compile_hint =
4146c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      default_eager_compile_hint_;
4147c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool can_preparse = impl()->parse_lazily() &&
4148c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                      eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
4149c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // TODO(marja): consider lazy-parsing inner arrow functions too. is_this
4150c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // handling in Scope::ResolveVariable needs to change.
4151c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool is_lazy_top_level_function =
4152c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
4153f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool should_be_used_once_hint = false;
4154c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool has_braces = true;
4155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
415662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    FunctionState function_state(&function_state_, &scope_,
4157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 formal_parameters.scope);
4158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Expect(Token::ARROW, CHECK_OK);
4160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (peek() == Token::LBRACE) {
4162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Multiple statement body
4163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DCHECK_EQ(scope(), formal_parameters.scope);
4164c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (is_lazy_top_level_function) {
4165c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // FIXME(marja): Arrow function parameters will be parsed even if the
4166c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // body is preparsed; move relevant parts of parameter handling to
4167c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // simulate consistent parameter handling.
4168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Scanner::BookmarkScope bookmark(scanner());
4169f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        bookmark.Set();
4170c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // For arrow functions, we don't need to retrieve data about function
4171c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // parameters.
4172c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        int dummy_num_parameters = -1;
4173c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        int dummy_function_length = -1;
4174c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        bool dummy_has_duplicate_parameters = false;
4175c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        DCHECK((kind & FunctionKind::kArrowFunction) != 0);
4176c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        LazyParsingResult result = impl()->SkipFunction(
4177c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            kind, formal_parameters.scope, &dummy_num_parameters,
4178c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            &dummy_function_length, &dummy_has_duplicate_parameters,
417962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            &expected_property_count, false, true, CHECK_OK);
4180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        formal_parameters.scope->ResetAfterPreparsing(
4181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            ast_value_factory_, result == kLazyParsingAborted);
4182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (result == kLazyParsingAborted) {
4184f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          bookmark.Apply();
4185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // Trigger eager (re-)parsing, just below this block.
4186c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          is_lazy_top_level_function = false;
4187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // This is probably an initialization function. Inform the compiler it
4189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // should also eager-compile this function, and that we expect it to
4190f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // be used once.
4191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4192f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          should_be_used_once_hint = true;
4193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
4194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
4195c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (!is_lazy_top_level_function) {
4196c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Consume(Token::LBRACE);
419762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        body = impl()->NewStatementList(8);
419862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(),
419962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  kNoSourcePosition, formal_parameters, kind,
420062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  FunctionLiteral::kAnonymousExpression,
420162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  CHECK_OK);
4202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        expected_property_count = function_state.expected_property_count();
4203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
4204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
4205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Single-expression body
4206c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      has_braces = false;
4207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int pos = position();
4208bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DCHECK(ReturnExprContext::kInsideValidBlock ==
4209bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             function_state_->return_expr_context());
4210bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ReturnExprScope allow_tail_calls(
4211bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          function_state_, ReturnExprContext::kInsideValidReturnStatement);
4212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      body = impl()->NewStatementList(1);
4213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->AddParameterInitializationBlock(
4214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK);
421513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ExpressionClassifier classifier(this);
4216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (kind == kAsyncArrowFunction) {
4217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction,
4218f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               FunctionBodyType::kSingleExpression, accept_IN,
4219f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               pos, CHECK_OK);
4220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
4221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      } else {
4222f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
4223f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteNonPattern(CHECK_OK);
422462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        body->Add(BuildReturnStatement(expression, expression->position()),
422562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  zone());
4226bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (allow_tailcalls() && !is_sloppy(language_mode())) {
4227bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          // ES6 14.6.1 Static Semantics: IsInTailPosition
4228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          impl()->MarkTailPosition(expression);
4229bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        }
4230bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
4231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      expected_property_count = function_state.expected_property_count();
4232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      impl()->MarkCollectedTailCallExpressions();
4233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    formal_parameters.scope->set_end_position(scanner()->location().end_pos);
4236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Arrow function formal parameters are parsed as StrictFormalParameterList,
4238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // which is not the same as "parameters of a strict function"; it only means
4239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // that duplicates are not allowed.  Of course, the arrow function may
4240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // itself be strict as well.
4241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const bool allow_duplicate_parameters = false;
4242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ValidateFormalParameters(language_mode(), allow_duplicate_parameters,
4243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                             CHECK_OK);
4244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Validate strict mode.
4246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_strict(language_mode())) {
4247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
4248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              scanner()->location().end_pos, CHECK_OK);
4249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
4251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
425262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (is_lazy_top_level_function) {
425362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      FunctionState* parent_state = function_state.outer();
425462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK_NOT_NULL(parent_state);
425562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK_GE(parent_state->destructuring_assignments_to_rewrite().length(),
425662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                rewritable_length);
425762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      parent_state->RewindDestructuringAssignments(rewritable_length);
425862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
425962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
4260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    impl()->RewriteDestructuringAssignments();
4261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4263c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (FLAG_trace_preparse) {
4264c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Scope* scope = formal_parameters.scope;
4265c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    PrintF("  [%s]: %i-%i (arrow function)\n",
4266c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch           is_lazy_top_level_function ? "Preparse no-resolution" : "Full parse",
4267c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch           scope->start_position(), scope->end_position());
4268c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
4269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
4270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->EmptyIdentifierString(), formal_parameters.scope, body,
427162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      expected_property_count, formal_parameters.num_parameters(),
427262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      formal_parameters.function_length,
4273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FunctionLiteral::kNoDuplicateParameters,
4274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionLiteral::kAnonymousExpression, eager_compile_hint,
427562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      formal_parameters.scope->start_position(), has_braces,
427662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      function_literal_id);
4277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  function_literal->set_function_token_position(
4279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      formal_parameters.scope->start_position());
4280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (should_be_used_once_hint) {
4281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    function_literal->set_should_be_used_once_hint();
4282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4284f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->AddFunctionForNameInference(function_literal);
4285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return function_literal;
4287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
4290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
4291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    IdentifierT name, Scanner::Location class_name_location,
4292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool name_is_strict_reserved, int class_token_pos, bool* ok) {
4293f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // All parts of a ClassDeclaration and ClassExpression are strict code.
4294f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (name_is_strict_reserved) {
4295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(class_name_location,
4296f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            MessageTemplate::kUnexpectedStrictReserved);
4297f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *ok = false;
4298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyExpression();
4299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4300f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (impl()->IsEvalOrArguments(name)) {
4301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->ReportMessageAt(class_name_location,
4302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            MessageTemplate::kStrictEvalArguments);
4303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *ok = false;
4304f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyExpression();
4305f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
430762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BlockState block_state(zone(), &scope_);
4308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  RaiseLanguageMode(STRICT);
4309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ClassInfo class_info(this);
431162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  impl()->DeclareClassVariable(name, &class_info, class_token_pos, CHECK_OK);
4312f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
431362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  scope()->set_start_position(scanner()->location().end_pos);
4314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (Check(Token::EXTENDS)) {
4315f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionClassifier extends_classifier(this);
4316f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    class_info.extends = ParseLeftHandSideExpression(CHECK_OK);
4317f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK);
4318f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->AccumulateFormalParameterContainmentErrors();
4319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ClassLiteralChecker checker(this);
4322f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4323f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LBRACE, CHECK_OK);
4324f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4325f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const bool has_extends = !impl()->IsEmptyExpression(class_info.extends);
4326f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  while (peek() != Token::RBRACE) {
4327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (Check(Token::SEMICOLON)) continue;
4328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    FuncNameInferrer::State fni_state(fni_);
4329f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool is_computed_name = false;  // Classes do not care about computed
4330f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    // property names here.
433162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool is_static;
433262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ClassLiteralProperty::Kind property_kind;
4333f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionClassifier property_classifier(this);
433462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // If we haven't seen the constructor yet, it potentially is the next
433562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // property.
433662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool is_constructor = !class_info.has_seen_constructor;
4337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ClassLiteralPropertyT property = ParseClassPropertyDefinition(
4338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        &checker, has_extends, &is_computed_name,
433962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        &class_info.has_seen_constructor, &property_kind, &is_static,
434062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        &class_info.has_name_static_property, CHECK_OK);
434162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!class_info.has_static_computed_names && is_static &&
434262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        is_computed_name) {
434362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      class_info.has_static_computed_names = true;
434462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
434562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    is_constructor &= class_info.has_seen_constructor;
4346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK);
4347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->AccumulateFormalParameterContainmentErrors();
4348f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
434962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->DeclareClassProperty(name, property, property_kind, is_static,
435062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 is_constructor, &class_info, CHECK_OK);
4351f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->InferFunctionName();
4352f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4353f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::RBRACE, CHECK_OK);
4355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok);
4356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body,
4360f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                              FunctionKind kind,
4361f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                              FunctionBodyType body_type,
4362f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                              bool accept_IN, int pos,
4363f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                              bool* ok) {
4364f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->PrepareAsyncFunctionBody(body, kind, pos);
4365f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4366f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
4367f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4368f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT return_value = impl()->EmptyExpression();
4369f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (body_type == FunctionBodyType::kNormal) {
4370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ParseStatementList(block->statements(), Token::RBRACE,
4371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       CHECK_OK_CUSTOM(Void));
4372f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return_value = factory()->NewUndefinedLiteral(kNoSourcePosition);
4373f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
4374f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return_value = ParseAssignmentExpression(accept_IN, CHECK_OK_CUSTOM(Void));
4375f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void));
4376f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4377f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4378f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  impl()->RewriteAsyncFunctionBody(body, block, return_value,
4379f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   CHECK_OK_CUSTOM(Void));
4380f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  scope->set_end_position(scanner()->location().end_pos);
4381f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4382f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4384f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ExpressionT
4385f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
4386f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // AsyncFunctionLiteral ::
4387f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   async [no LineTerminator here] function ( FormalParameters[Await] )
4388f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //       { AsyncFunctionBody }
4389f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
4390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   async [no LineTerminator here] function BindingIdentifier[Await]
4391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //       ( FormalParameters[Await] ) { AsyncFunctionBody }
4392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = position();
4394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::FUNCTION, CHECK_OK);
4395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_strict_reserved = false;
4396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT name = impl()->EmptyIdentifier();
4397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
4398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
439962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (impl()->ParsingDynamicFunctionDeclaration()) {
440062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // We don't want dynamic functions to actually declare their name
440162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // "anonymous". We just want that name in the toString().
440262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Consume(Token::IDENTIFIER);
440362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(scanner()->UnescapedLiteralMatches("anonymous", 9));
440462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (peek_any_identifier()) {
4405f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    type = FunctionLiteral::kNamedExpression;
4406f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction,
4407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                               &is_strict_reserved, CHECK_OK);
4408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->ParseFunctionLiteral(
4410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      name, scanner()->location(),
4411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      is_strict_reserved ? kFunctionNameIsStrictReserved
4412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         : kFunctionNameValidityUnknown,
4413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK);
4414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
441862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionT tag, int start, bool tagged, bool* ok) {
4419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
4420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // text followed by a substitution expression), finalized by a single
4421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TEMPLATE_TAIL.
4422f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
4423f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
4424f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
4425f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // NoSubstitutionTemplate.
4426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
4427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // When parsing a TemplateLiteral, we must have scanned either an initial
4428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
4429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
443162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool forbid_illegal_escapes = !allow_harmony_template_escapes() || !tagged;
443262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
4433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
4434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // In this case we may simply consume the token and build a template with a
4435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // single TEMPLATE_SPAN and no expressions.
4436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (peek() == Token::TEMPLATE_TAIL) {
4437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Consume(Token::TEMPLATE_TAIL);
4438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int pos = position();
4439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
444062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
444162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->AddTemplateSpan(&ts, is_valid, true);
4442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return impl()->CloseTemplateLiteral(&ts, start, tag);
4443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Consume(Token::TEMPLATE_SPAN);
4446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = position();
4447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
444862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
444962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  impl()->AddTemplateSpan(&ts, is_valid, false);
4450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value next;
4451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
4453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // and repeat if the following token is a TEMPLATE_SPAN as well (in this
4454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // case, representing a TemplateMiddle).
4455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {
4457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next = peek();
4458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next == Token::EOS) {
4459f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(Scanner::Location(start, peek_position()),
4460f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              MessageTemplate::kUnterminatedTemplate);
4461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
4462f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyExpression();
4463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (next == Token::ILLEGAL) {
4464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(
4465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Scanner::Location(position() + 1, peek_position()),
4466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
4468f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyExpression();
4469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int expr_pos = peek_position();
4472f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT expression = ParseExpressionCoverGrammar(true, CHECK_OK);
4473f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    impl()->RewriteNonPattern(CHECK_OK);
4474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    impl()->AddTemplateExpression(&ts, expression);
4475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (peek() != Token::RBRACE) {
4477f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
4478f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              MessageTemplate::kUnterminatedTemplateExpr);
4479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
4480f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyExpression();
4481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If we didn't die parsing that expression, our next token should be a
4484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // TEMPLATE_SPAN or TEMPLATE_TAIL.
4485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next = scanner()->ScanTemplateContinuation();
4486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Next();
4487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pos = position();
4488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next == Token::EOS) {
4490f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(Scanner::Location(start, pos),
4491f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              MessageTemplate::kUnterminatedTemplate);
4492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
4493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyExpression();
4494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (next == Token::ILLEGAL) {
4495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(
4496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Scanner::Location(position() + 1, peek_position()),
4497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
4499f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->EmptyExpression();
4500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
450262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
450362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL);
4504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (next == Token::TEMPLATE_SPAN);
4505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(next, Token::TEMPLATE_TAIL);
4507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return impl()->CloseTemplateLiteral(&ts, start, tag);
4509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
4512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
4513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParserBase<Impl>::CheckAndRewriteReferenceExpression(
4514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ExpressionT expression, int beg_pos, int end_pos,
4515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MessageTemplate::Template message, bool* ok) {
4516f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
4517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                            message, kReferenceError, ok);
4518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
4521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParserBase<Impl>::ExpressionT
4522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParserBase<Impl>::CheckAndRewriteReferenceExpression(
4523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ExpressionT expression, int beg_pos, int end_pos,
4524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MessageTemplate::Template message, ParseErrorType type, bool* ok) {
4525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (impl()->IsIdentifier(expression) && is_strict(language_mode()) &&
4526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
45273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ReportMessageAt(Scanner::Location(beg_pos, end_pos),
45283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                    MessageTemplate::kStrictEvalArguments, kSyntaxError);
45293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    *ok = false;
4530f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->EmptyExpression();
4531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (expression->IsValidReferenceExpression()) {
4533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return expression;
45343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
45353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (expression->IsCall()) {
4536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If it is a call, make it a runtime error for legacy web compatibility.
453762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480
4538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Rewrite `expr' to `expr[throw ReferenceError]'.
453962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->CountUsage(
454062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        is_strict(language_mode())
454162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            ? v8::Isolate::kAssigmentExpressionLHSIsCallInStrict
454262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            : v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy);
4543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos);
45443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return factory()->NewProperty(expression, error, beg_pos);
4545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
45463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
45473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  *ok = false;
4548f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->EmptyExpression();
4549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
4552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
4553f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAssignableIdentifier(expression) || expression->IsProperty();
4554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
4557f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression,
4558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                 int begin, int end) {
4559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!IsValidPattern(expression) && !expression->IsAssignment() &&
4560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      !IsValidReferenceExpression(expression)) {
4561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    classifier()->RecordAssignmentPatternError(
4562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Scanner::Location(begin, end),
4563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        MessageTemplate::kInvalidDestructuringTarget);
4564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4568f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic(
4569f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
4570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // CallRuntime ::
4571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   '%' Identifier Arguments
4572f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = peek_position();
4574f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::MOD, CHECK_OK);
4575f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Allow "eval" or "arguments" for backward compatibility.
4576f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4577f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Scanner::Location spread_pos;
4578f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionClassifier classifier(this);
4579f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK);
4580f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!spread_pos.IsValid());
4582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4583f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->NewV8Intrinsic(name, args, pos, ok);
4584f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4586f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4587f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression(
4588f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
4589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // AssignmentExpression ::
4590f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //     do '{' StatementList '}'
4591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4592f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = peek_position();
4593f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::DO, CHECK_OK);
4594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT block = ParseBlock(nullptr, CHECK_OK);
4595f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->RewriteDoExpression(block, pos, ok);
4596f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4597f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4598f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Redefinition of CHECK_OK for parsing statements.
4599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef CHECK_OK
4600f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define CHECK_OK CHECK_OK_CUSTOM(NullStatement)
4601f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4603f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::LazyParsingResult
4604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseStatementList(StatementListT body, int end_token,
4605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     bool may_abort, bool* ok) {
4606f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // StatementList ::
4607f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   (StatementListItem)* <end_token>
4608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4609f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Allocate a target stack to use for this set of source
4610f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // elements. This way, all scripts and functions get their own
4611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // target stack thus avoiding illegal breaks and continues across
4612f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // functions.
4613f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::TargetScope target_scope(this);
4614f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int count_statements = 0;
4615f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!impl()->IsNullStatementList(body));
4617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool directive_prologue = true;  // Parsing directive prologue.
4618f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4619f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  while (peek() != end_token) {
4620f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (directive_prologue && peek() != Token::STRING) {
4621f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      directive_prologue = false;
4622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
4623f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool starts_with_identifier = peek() == Token::IDENTIFIER;
4625f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Scanner::Location token_loc = scanner()->peek_location();
4626f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    StatementT stat =
4627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ParseStatementListItem(CHECK_OK_CUSTOM(Return, kLazyParsingComplete));
4628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (impl()->IsNullStatement(stat) || impl()->IsEmptyStatement(stat)) {
4630f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      directive_prologue = false;  // End of directive prologue.
4631f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      continue;
4632f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
4633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (directive_prologue) {
4635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // The length of the token is used to distinguish between strings literals
4636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // that evaluate equal to directives but contain either escape sequences
4637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // (e.g., "use \x73trict") or line continuations (e.g., "use \(newline)
4638f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // strict").
4639f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (impl()->IsUseStrictDirective(stat) &&
4640f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          token_loc.end_pos - token_loc.beg_pos == sizeof("use strict") + 1) {
4641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // Directive "use strict" (ES5 14.1).
4642f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        RaiseLanguageMode(STRICT);
4643f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (!scope()->HasSimpleParameters()) {
4644f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // TC39 deemed "use strict" directives to be an error when occurring
4645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // in the body of a function with non-simple parameter list, on
4646f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // 29/7/2015. https://goo.gl/ueA7Ln
4647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          impl()->ReportMessageAt(
4648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              token_loc, MessageTemplate::kIllegalLanguageModeDirective,
4649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              "use strict");
4650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          *ok = false;
4651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return kLazyParsingComplete;
4652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
4653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      } else if (impl()->IsUseAsmDirective(stat) &&
4654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                 token_loc.end_pos - token_loc.beg_pos ==
4655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                     sizeof("use asm") + 1) {
4656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // Directive "use asm".
4657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->SetAsmModule();
4658f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      } else if (impl()->IsStringLiteral(stat)) {
4659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // Possibly an unknown directive.
4660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // Should not change mode, but will increment usage counters
4661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // as appropriate. Ditto usages below.
4662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        RaiseLanguageMode(SLOPPY);
4663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      } else {
4664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // End of the directive prologue.
4665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        directive_prologue = false;
4666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        RaiseLanguageMode(SLOPPY);
4667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
4668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
4669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      RaiseLanguageMode(SLOPPY);
4670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
4671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // If we're allowed to abort, we will do so when we see a "long and
4673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // trivial" function. Our current definition of "long and trivial" is:
4674f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // - over kLazyParseTrialLimit statements
4675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // - all starting with an identifier (i.e., no if, for, while, etc.)
4676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (may_abort) {
4677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!starts_with_identifier) {
4678f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        may_abort = false;
4679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      } else if (++count_statements > kLazyParseTrialLimit) {
4680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return kLazyParsingAborted;
4681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
4682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
4683f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    body->Add(stat, zone());
4685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return kLazyParsingComplete;
4687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatementListItem(
4691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
4692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ECMA 262 6th Edition
4693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // StatementListItem[Yield, Return] :
4694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   Statement[?Yield, ?Return]
4695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   Declaration[?Yield]
4696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
4697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Declaration[Yield] :
4698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   HoistableDeclaration[?Yield]
4699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   ClassDeclaration[?Yield]
4700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   LexicalDeclaration[In, ?Yield]
4701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
4702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // HoistableDeclaration[Yield, Default] :
4703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   FunctionDeclaration[?Yield, ?Default]
4704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   GeneratorDeclaration[?Yield, ?Default]
4705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
4706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // LexicalDeclaration[In, Yield] :
4707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   LetOrConst BindingList[?In, ?Yield] ;
4708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4709f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (peek()) {
4710f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::FUNCTION:
4711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseHoistableDeclaration(nullptr, false, ok);
4712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::CLASS:
4713f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Consume(Token::CLASS);
4714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseClassDeclaration(nullptr, false, ok);
4715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::VAR:
4716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::CONST:
4717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseVariableStatement(kStatementListItem, nullptr, ok);
4718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::LET:
4719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (IsNextLetKeyword()) {
4720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return ParseVariableStatement(kStatementListItem, nullptr, ok);
4721f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
4722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
4723f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::ASYNC:
472462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (PeekAhead() == Token::FUNCTION &&
4725f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          !scanner()->HasAnyLineTerminatorAfterNext()) {
4726f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Consume(Token::ASYNC);
4727f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return ParseAsyncFunctionDeclaration(nullptr, false, ok);
4728f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
4729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    /* falls through */
4730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    default:
4731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
4732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4733f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return ParseStatement(nullptr, kAllowLabelledFunctionStatement, ok);
4734f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4735f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4737f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
4738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels,
4739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AllowLabelledFunctionStatement allow_function, bool* ok) {
4740f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Statement ::
4741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   Block
4742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   VariableStatement
4743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   EmptyStatement
4744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   ExpressionStatement
4745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   IfStatement
4746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   IterationStatement
4747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   ContinueStatement
4748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   BreakStatement
4749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   ReturnStatement
4750f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   WithStatement
4751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   LabelledStatement
4752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   SwitchStatement
4753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   ThrowStatement
4754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   TryStatement
4755f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   DebuggerStatement
4756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Note: Since labels can only be used by 'break' and 'continue'
4758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // statements, which themselves are only valid within blocks,
4759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // iterations or 'switch' statements (i.e., BreakableStatements),
4760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // labels can be simply ignored in all other cases; except for
4761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // trivial labeled break statements 'label: break label' which is
4762f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // parsed into an empty statement.
4763f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (peek()) {
4764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::LBRACE:
4765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseBlock(labels, ok);
4766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::SEMICOLON:
4767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Next();
4768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return factory()->NewEmptyStatement(kNoSourcePosition);
4769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::IF:
4770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseIfStatement(labels, ok);
4771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::DO:
4772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseDoWhileStatement(labels, ok);
4773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::WHILE:
4774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseWhileStatement(labels, ok);
4775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::FOR:
477662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (V8_UNLIKELY(allow_harmony_async_iteration() && is_async_function() &&
477762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      PeekAhead() == Token::AWAIT)) {
477862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return ParseForAwaitStatement(labels, ok);
477962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
4780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseForStatement(labels, ok);
4781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::CONTINUE:
4782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::BREAK:
4783f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::RETURN:
4784f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::THROW:
4785f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::TRY: {
4786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // These statements must have their labels preserved in an enclosing
4787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // block, as the corresponding AST nodes do not currently store their
4788f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // labels.
4789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // TODO(nikolaos, marja): Consider adding the labels to the AST nodes.
4790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (labels == nullptr) {
4791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return ParseStatementAsUnlabelled(labels, ok);
4792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      } else {
4793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        BlockT result =
4794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            factory()->NewBlock(labels, 1, false, kNoSourcePosition);
4795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        typename Types::Target target(this, result);
4796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
4797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        result->statements()->Add(statement, zone());
4798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return result;
4799f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
4800f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
4801f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::WITH:
4802f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseWithStatement(labels, ok);
4803f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::SWITCH:
4804f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseSwitchStatement(labels, ok);
4805f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::FUNCTION:
4806f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // FunctionDeclaration only allowed as a StatementListItem, not in
4807f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // an arbitrary Statement position. Exceptions such as
4808f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
4809f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // are handled by calling ParseScopedStatement rather than
4810f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // ParseStatement directly.
4811f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(scanner()->peek_location(),
4812f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              is_strict(language_mode())
4813f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  ? MessageTemplate::kStrictFunction
4814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  : MessageTemplate::kSloppyFunction);
4815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *ok = false;
4816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->NullStatement();
4817f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::DEBUGGER:
4818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseDebuggerStatement(ok);
4819f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::VAR:
4820f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseVariableStatement(kStatement, nullptr, ok);
4821f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    default:
4822f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseExpressionOrLabelledStatement(labels, allow_function, ok);
4823f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4824f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// This method parses a subset of statements (break, continue, return, throw,
4827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// try) which are to be grouped because they all require their labeles to be
4828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// preserved in an enclosing block.
4829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT
4831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseStatementAsUnlabelled(
4832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
4833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (peek()) {
4834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::CONTINUE:
4835f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseContinueStatement(ok);
4836f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::BREAK:
4837f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseBreakStatement(labels, ok);
4838f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::RETURN:
4839f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseReturnStatement(ok);
4840f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::THROW:
4841f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseThrowStatement(ok);
4842f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::TRY:
4843f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ParseTryStatement(ok);
4844f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    default:
4845f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      UNREACHABLE();
4846f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->NullStatement();
4847f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4849f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4850f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4851f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
4852f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
4853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Block ::
4854f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   '{' StatementList '}'
4855f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4856f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Construct block expecting 16 statements.
4857f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT body = factory()->NewBlock(labels, 16, false, kNoSourcePosition);
4858f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4859f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Parse the statements and collect escaping labels.
4860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullBlock));
4861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
486262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState block_state(zone(), &scope_);
486362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_start_position(scanner()->location().beg_pos);
4864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    typename Types::Target target(this, body);
4865f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    while (peek() != Token::RBRACE) {
4867f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      StatementT stat = ParseStatementListItem(CHECK_OK_CUSTOM(NullBlock));
4868f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!impl()->IsNullStatement(stat) && !impl()->IsEmptyStatement(stat)) {
4869f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        body->statements()->Add(stat, zone());
4870f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
4871f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
4872f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4873f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullBlock));
487462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_end_position(scanner()->location().end_pos);
487562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    body->set_scope(scope()->FinalizeBlockScope());
4876f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4877f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return body;
4878f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4879f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4880f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4881f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement(
488262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
488362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (is_strict(language_mode()) || peek() != Token::FUNCTION) {
488462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return ParseStatement(labels, ok);
4885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
4886f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Make a block around the statement for a lexical binding
4887f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // is introduced by a FunctionDeclaration.
488862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState block_state(zone(), &scope_);
488962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_start_position(scanner()->location().beg_pos);
4890f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    BlockT block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
4891f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    StatementT body = ParseFunctionDeclaration(CHECK_OK);
4892f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    block->statements()->Add(body, zone());
489362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_end_position(scanner()->location().end_pos);
489462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    block->set_scope(scope()->FinalizeBlockScope());
4895f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return block;
4896f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4897f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4898f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4899f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4900f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseVariableStatement(
4901f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    VariableDeclarationContext var_context,
4902f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* names, bool* ok) {
4903f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // VariableStatement ::
4904f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   VariableDeclarations ';'
4905f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4906f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // The scope of a var declared variable anywhere inside a function
4907f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
4908f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // transform a source-level var declaration into a (Function) Scope
4909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // declaration, and rewrite the source-level initialization into an assignment
4910f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // statement. We use a block to collect multiple assignments.
4911f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
4912f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // We mark the block as initializer block because we don't want the
4913f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // rewriter to add a '.result' assignment to such a block (to get compliant
4914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // behavior for code such as print(eval('var x = 7')), and for cosmetic
4915f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // reasons when pretty-printing. Also, unless an assignment (initialization)
4916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // is inside an initializer block, it is ignored.
4917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4918f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DeclarationParsingResult parsing_result;
4919f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT result =
4920f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK);
4921f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpectSemicolon(CHECK_OK);
4922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return result;
4923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4925f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4926f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDebuggerStatement(
4927f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
4928f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
4929f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // contexts this is used as a statement which invokes the debugger as i a
4930f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // break point is present.
4931f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // DebuggerStatement ::
4932f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'debugger' ';'
4933f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = peek_position();
4935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::DEBUGGER, CHECK_OK);
4936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpectSemicolon(CHECK_OK);
4937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return factory()->NewDebuggerStatement(pos);
4938f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4939f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4940f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
4941f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT
4942f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochParserBase<Impl>::ParseExpressionOrLabelledStatement(
4943f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels,
4944f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AllowLabelledFunctionStatement allow_function, bool* ok) {
4945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ExpressionStatement | LabelledStatement ::
4946f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   Expression ';'
4947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   Identifier ':' Statement
4948f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
4949f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ExpressionStatement[Yield] :
4950c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  //   [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
4951f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4952f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = peek_position();
4953f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4954f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (peek()) {
4955f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::FUNCTION:
4956f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::LBRACE:
4957f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      UNREACHABLE();  // Always handled by the callers.
4958f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case Token::CLASS:
4959f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReportUnexpectedToken(Next());
4960f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *ok = false;
4961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->NullStatement();
496262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case Token::LET: {
496362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Token::Value next_next = PeekAhead();
496462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // "let" followed by either "[", "{" or an identifier means a lexical
496562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // declaration, which should not appear here.
496662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (next_next != Token::LBRACK && next_next != Token::LBRACE &&
496762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          next_next != Token::IDENTIFIER) {
496862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        break;
496962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
497062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->ReportMessageAt(scanner()->peek_location(),
497162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              MessageTemplate::kUnexpectedLexicalDeclaration);
497262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *ok = false;
497362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return impl()->NullStatement();
497462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
4975f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    default:
4976f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
4977f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4978f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4979f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool starts_with_identifier = peek_any_identifier();
4980f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT expr = ParseExpression(true, CHECK_OK);
4981f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (peek() == Token::COLON && starts_with_identifier &&
4982f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->IsIdentifier(expr)) {
4983f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // The whole expression was a single identifier, and not, e.g.,
4984f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // something starting with an identifier or a parenthesized identifier.
4985f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    labels = impl()->DeclareLabel(labels, impl()->AsIdentifierExpression(expr),
4986f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  CHECK_OK);
4987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Consume(Token::COLON);
4988f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // ES#sec-labelled-function-declarations Labelled Function Declarations
498962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (peek() == Token::FUNCTION && is_sloppy(language_mode()) &&
499062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        allow_function == kAllowLabelledFunctionStatement) {
499162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ParseFunctionDeclaration(ok);
4992f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
499362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return ParseStatement(labels, ok);
4994f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4995f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4996f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // If we have an extension, we allow a native function declaration.
4997f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // A native function declaration starts with "native function" with
4998f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // no line-terminator between the two words.
4999f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (extension_ != nullptr && peek() == Token::FUNCTION &&
5000f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      !scanner()->HasAnyLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
5001f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      !scanner()->literal_contains_escapes()) {
5002f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return ParseNativeDeclaration(ok);
5003f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5004f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5005f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Parsed expression statement, followed by semicolon.
5006f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpectSemicolon(CHECK_OK);
5007f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return factory()->NewExpressionStatement(expr, pos);
5008f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5009f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5010f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5011f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
5012f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
5013f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // IfStatement ::
5014f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'if' '(' Expression ')' Statement ('else' Statement)?
5015f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5016f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = peek_position();
5017f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::IF, CHECK_OK);
5018f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LPAREN, CHECK_OK);
5019f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT condition = ParseExpression(true, CHECK_OK);
5020f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::RPAREN, CHECK_OK);
502162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT then_statement = ParseScopedStatement(labels, CHECK_OK);
5022f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT else_statement = impl()->NullStatement();
5023f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (Check(Token::ELSE)) {
502462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    else_statement = ParseScopedStatement(labels, CHECK_OK);
5025f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
5026f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    else_statement = factory()->NewEmptyStatement(kNoSourcePosition);
5027f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5028f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return factory()->NewIfStatement(condition, then_statement, else_statement,
5029f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   pos);
5030f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5031f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5032f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5033f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement(
5034f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
5035f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ContinueStatement ::
5036f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'continue' Identifier? ';'
5037f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5038f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = peek_position();
5039f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::CONTINUE, CHECK_OK);
5040f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT label = impl()->EmptyIdentifier();
5041f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Token::Value tok = peek();
5042f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
5043f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      tok != Token::RBRACE && tok != Token::EOS) {
5044f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // ECMA allows "eval" or "arguments" as labels even in strict mode.
5045f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
5046f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5047f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::IterationStatement target =
5048f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->LookupContinueTarget(label, CHECK_OK);
5049f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (impl()->IsNullStatement(target)) {
5050f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Illegal continue statement.
5051f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
5052f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!impl()->IsEmptyIdentifier(label)) {
5053f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      message = MessageTemplate::kUnknownLabel;
5054f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5055f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ReportMessage(message, label);
5056f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *ok = false;
5057f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->NullStatement();
5058f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5059f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpectSemicolon(CHECK_OK);
5060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return factory()->NewContinueStatement(target, pos);
5061f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5063f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5064f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
5065f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
5066f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // BreakStatement ::
5067f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'break' Identifier? ';'
5068f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5069f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = peek_position();
5070f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::BREAK, CHECK_OK);
5071f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IdentifierT label = impl()->EmptyIdentifier();
5072f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Token::Value tok = peek();
5073f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
5074f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      tok != Token::RBRACE && tok != Token::EOS) {
5075f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // ECMA allows "eval" or "arguments" as labels even in strict mode.
5076f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
5077f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5078f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Parse labeled break statements that target themselves into
5079f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // empty statements, e.g. 'l1: l2: l3: break l2;'
5080f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!impl()->IsEmptyIdentifier(label) &&
5081f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ContainsLabel(labels, label)) {
5082f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ExpectSemicolon(CHECK_OK);
5083f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return factory()->NewEmptyStatement(pos);
5084f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5085f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::BreakableStatement target =
5086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->LookupBreakTarget(label, CHECK_OK);
5087f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (impl()->IsNullStatement(target)) {
5088f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Illegal break statement.
5089f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
5090f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!impl()->IsEmptyIdentifier(label)) {
5091f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      message = MessageTemplate::kUnknownLabel;
5092f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5093f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ReportMessage(message, label);
5094f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *ok = false;
5095f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->NullStatement();
5096f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5097f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpectSemicolon(CHECK_OK);
5098f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return factory()->NewBreakStatement(target, pos);
5099f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5102f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement(
5103f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
5104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ReturnStatement ::
5105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'return' [no line terminator] Expression? ';'
5106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Consume the return token. It is necessary to do that before
5108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // reporting any errors on it, because of the way errors are
5109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // reported (underlining).
5110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::RETURN, CHECK_OK);
5111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Scanner::Location loc = scanner()->location();
5112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (GetDeclarationScope()->scope_type()) {
5114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case SCRIPT_SCOPE:
5115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case EVAL_SCOPE:
5116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case MODULE_SCOPE:
5117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
5118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *ok = false;
5119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return impl()->NullStatement();
5120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    default:
5121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
5122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5124f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Token::Value tok = peek();
5125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT return_value = impl()->EmptyExpression();
5126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (scanner()->HasAnyLineTerminatorBeforeNext() || tok == Token::SEMICOLON ||
5127f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      tok == Token::RBRACE || tok == Token::EOS) {
512862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (IsDerivedConstructor(function_state_->kind())) {
5129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return_value = impl()->ThisExpression(loc.beg_pos);
5130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
5131f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return_value = impl()->GetLiteralUndefined(position());
5132f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5133f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
513462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (IsDerivedConstructor(function_state_->kind())) {
5135f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Because of the return code rewriting that happens in case of a subclass
5136f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // constructor we don't want to accept tail calls, therefore we don't set
5137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // ReturnExprScope to kInsideValidReturnStatement here.
5138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return_value = ParseExpression(true, CHECK_OK);
5139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
5140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReturnExprScope maybe_allow_tail_calls(
5141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          function_state_, ReturnExprContext::kInsideValidReturnStatement);
5142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return_value = ParseExpression(true, CHECK_OK);
5143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (allow_tailcalls() && !is_sloppy(language_mode()) && !is_resumable()) {
5145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // ES6 14.6.1 Static Semantics: IsInTailPosition
5146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        function_state_->AddImplicitTailCallExpression(return_value);
5147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
5148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpectSemicolon(CHECK_OK);
5151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
515262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return BuildReturnStatement(return_value, loc.beg_pos);
5153f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
5156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
5157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
5158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // WithStatement ::
5159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'with' '(' Expression ')' Statement
5160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::WITH, CHECK_OK);
5162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = position();
5163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_strict(language_mode())) {
5165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ReportMessage(MessageTemplate::kStrictWith);
5166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *ok = false;
5167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->NullStatement();
5168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5169f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5170f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LPAREN, CHECK_OK);
5171f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT expr = ParseExpression(true, CHECK_OK);
5172f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::RPAREN, CHECK_OK);
5173f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5174f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Scope* with_scope = NewScope(WITH_SCOPE);
5175f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT body = impl()->NullStatement();
5176f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
517762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState block_state(&scope_, with_scope);
5178f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    with_scope->set_start_position(scanner()->peek_location().beg_pos);
517962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    body = ParseStatement(labels, CHECK_OK);
5180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    with_scope->set_end_position(scanner()->location().end_pos);
5181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return factory()->NewWithStatement(with_scope, expr, body, pos);
5183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5184f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5186f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement(
5187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
5188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // DoStatement ::
5189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'do' Statement 'while' '(' Expression ')' ';'
5190f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  auto loop = factory()->NewDoWhileStatement(labels, peek_position());
5192f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::Target target(this, loop);
5193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::DO, CHECK_OK);
519562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT body = ParseStatement(nullptr, CHECK_OK);
5196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::WHILE, CHECK_OK);
5197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LPAREN, CHECK_OK);
5198f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT cond = ParseExpression(true, CHECK_OK);
5200f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::RPAREN, CHECK_OK);
5201f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Allow do-statements to be terminated with and without
5203f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // semi-colons. This allows code such as 'do;while(0)return' to
5204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // parse, which would not be the case if we had used the
5205f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ExpectSemicolon() functionality here.
5206f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Check(Token::SEMICOLON);
5207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  loop->Initialize(cond, body);
5209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return loop;
5210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5211f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement(
5214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
5215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // WhileStatement ::
5216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'while' '(' Expression ')' Statement
5217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5218f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  auto loop = factory()->NewWhileStatement(labels, peek_position());
5219f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::Target target(this, loop);
5220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::WHILE, CHECK_OK);
5222f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LPAREN, CHECK_OK);
5223f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT cond = ParseExpression(true, CHECK_OK);
5224f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::RPAREN, CHECK_OK);
522562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT body = ParseStatement(nullptr, CHECK_OK);
5226f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5227f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  loop->Initialize(cond, body);
5228f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return loop;
5229f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5230f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement(
5233f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
5234f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // ThrowStatement ::
5235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'throw' Expression ';'
5236f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5237f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::THROW, CHECK_OK);
5238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = position();
5239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (scanner()->HasAnyLineTerminatorBeforeNext()) {
5240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ReportMessage(MessageTemplate::kNewlineAfterThrow);
5241f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *ok = false;
5242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->NullStatement();
5243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT exception = ParseExpression(true, CHECK_OK);
5245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpectSemicolon(CHECK_OK);
5246f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->NewThrowStatement(exception, pos);
5248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5249f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
5252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
5253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // SwitchStatement ::
5254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'switch' '(' Expression ')' '{' CaseClause* '}'
5255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // CaseClause ::
5256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'case' Expression ':' StatementList
5257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'default' ':' StatementList
5258f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int switch_pos = peek_position();
5260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::SWITCH, CHECK_OK);
5262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LPAREN, CHECK_OK);
5263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT tag = ParseExpression(true, CHECK_OK);
5264f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::RPAREN, CHECK_OK);
5265f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos);
5267f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5268f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
526962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState cases_block_state(zone(), &scope_);
527062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_start_position(switch_pos);
527162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->SetNonlinear();
5272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    typename Types::Target target(this, switch_statement);
5273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool default_seen = false;
5275f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    auto cases = impl()->NewCaseClauseList(4);
5276f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Expect(Token::LBRACE, CHECK_OK);
5277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    while (peek() != Token::RBRACE) {
5278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // An empty label indicates the default case.
5279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT label = impl()->EmptyExpression();
5280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (Check(Token::CASE)) {
5281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        label = ParseExpression(true, CHECK_OK);
5282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      } else {
5283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Expect(Token::DEFAULT, CHECK_OK);
5284f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (default_seen) {
5285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
5286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          *ok = false;
5287f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return impl()->NullStatement();
5288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
5289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        default_seen = true;
5290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
5291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Expect(Token::COLON, CHECK_OK);
5292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      int clause_pos = position();
5293f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      StatementListT statements = impl()->NewStatementList(5);
5294f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      while (peek() != Token::CASE && peek() != Token::DEFAULT &&
5295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             peek() != Token::RBRACE) {
5296f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        StatementT stat = ParseStatementListItem(CHECK_OK);
5297f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        statements->Add(stat, zone());
5298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
5299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      auto clause = factory()->NewCaseClause(label, statements, clause_pos);
5300f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      cases->Add(clause, zone());
5301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Expect(Token::RBRACE, CHECK_OK);
5303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
530462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_end_position(scanner()->location().end_pos);
530562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return impl()->RewriteSwitchStatement(tag, switch_statement, cases,
530662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          scope()->FinalizeBlockScope());
5307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5311f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement(
5312f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool* ok) {
5313f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TryStatement ::
5314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'try' Block Catch
5315f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'try' Block Finally
5316f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'try' Block Catch Finally
5317f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
5318f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Catch ::
5319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'catch' '(' Identifier ')' Block
5320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //
5321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Finally ::
5322f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   'finally' Block
5323f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5324f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::TRY, CHECK_OK);
5325f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pos = position();
5326f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT try_block = impl()->NullBlock();
5328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
5329f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ReturnExprScope no_tail_calls(function_state_,
5330f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  ReturnExprContext::kInsideTryBlock);
5331f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    try_block = ParseBlock(nullptr, CHECK_OK);
5332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5333f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5334f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  CatchInfo catch_info(this);
5335f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (peek() != Token::CATCH && peek() != Token::FINALLY) {
5337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ReportMessage(MessageTemplate::kNoCatchOrFinally);
5338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    *ok = false;
5339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return impl()->NullStatement();
5340f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5342f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT catch_block = impl()->NullBlock();
5343f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (Check(Token::CATCH)) {
5344f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Expect(Token::LPAREN, CHECK_OK);
5345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    catch_info.scope = NewScope(CATCH_SCOPE);
5346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    catch_info.scope->set_start_position(scanner()->location().beg_pos);
5347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5348f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    {
5349f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CollectExpressionsInTailPositionToListScope
5350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          collect_tail_call_expressions_scope(
5351f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              function_state_, &catch_info.tail_call_expressions);
535262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      BlockState catch_block_state(&scope_, catch_info.scope);
5353f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
5355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Create a block scope to hold any lexical declarations created
5357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // as part of destructuring the catch parameter.
5358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      {
535962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        BlockState catch_variable_block_state(zone(), &scope_);
536062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        scope()->set_start_position(scanner()->location().beg_pos);
5361f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        typename Types::Target target(this, catch_block);
5362f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5363f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // This does not simply call ParsePrimaryExpression to avoid
5364f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // ExpressionFromIdentifier from being called in the first
5365f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // branch, which would introduce an unresolved symbol and mess
5366f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        // with arrow function names.
5367f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (peek_any_identifier()) {
5368f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          catch_info.name =
5369f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
5370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        } else {
5371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ExpressionClassifier pattern_classifier(this);
5372f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          catch_info.pattern = ParsePrimaryExpression(CHECK_OK);
5373f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ValidateBindingPattern(CHECK_OK);
5374f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
5375f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5376f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Expect(Token::RPAREN, CHECK_OK);
5377f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->RewriteCatchPattern(&catch_info, CHECK_OK);
5378f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (!impl()->IsNullStatement(catch_info.init_block)) {
5379f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          catch_block->statements()->Add(catch_info.init_block, zone());
5380f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
5381f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5382f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        catch_info.inner_block = ParseBlock(nullptr, CHECK_OK);
5383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        catch_block->statements()->Add(catch_info.inner_block, zone());
5384f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        impl()->ValidateCatchBlock(catch_info, CHECK_OK);
538562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        scope()->set_end_position(scanner()->location().end_pos);
538662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        catch_block->set_scope(scope()->FinalizeBlockScope());
5387f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
5388f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5389f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    catch_info.scope->set_end_position(scanner()->location().end_pos);
5391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BlockT finally_block = impl()->NullBlock();
5394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(peek() == Token::FINALLY || !impl()->IsNullStatement(catch_block));
5395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (Check(Token::FINALLY)) {
5396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    finally_block = ParseBlock(nullptr, CHECK_OK);
5397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return impl()->RewriteTryStatement(try_block, catch_block, finally_block,
5400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     catch_info, pos);
5401f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5402f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5403f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5404f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
5405f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
5406f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int stmt_pos = peek_position();
5407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ForInfo for_info(this);
5408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool bound_names_are_lexical = false;
5409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Create an in-between scope for let-bound iteration variables.
541162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BlockState for_state(zone(), &scope_);
5412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::FOR, CHECK_OK);
5413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::LPAREN, CHECK_OK);
541462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  scope()->set_start_position(scanner()->location().beg_pos);
541562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  scope()->set_is_hidden();
5416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT init = impl()->NullStatement();
5418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
541962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (peek() == Token::VAR || peek() == Token::CONST ||
542062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      (peek() == Token::LET && IsNextLetKeyword())) {
542162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // The initializer contains declarations.
542262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr,
542362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              CHECK_OK);
542462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bound_names_are_lexical =
542562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IsLexicalVariableMode(for_info.parsing_result.descriptor.mode);
542662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    for_info.position = scanner()->location().beg_pos;
542762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
542862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (CheckInOrOf(&for_info.mode)) {
542962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ParseForEachStatementWithDeclarations(stmt_pos, &for_info, labels,
543062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                   ok);
543162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
543262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
543362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // One or more declaration not followed by in/of.
543462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    init = impl()->BuildInitializationBlock(
543562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        &for_info.parsing_result,
543662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        bound_names_are_lexical ? &for_info.bound_names : nullptr, CHECK_OK);
543762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (peek() != Token::SEMICOLON) {
543862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // The initializer does not contain declarations.
543962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int lhs_beg_pos = peek_position();
544062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionClassifier classifier(this);
544162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK);
544262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int lhs_end_pos = scanner()->location().end_pos;
544362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
544462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool is_for_each = CheckInOrOf(&for_info.mode);
544562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
544662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                            expression->IsObjectLiteral());
544762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
544862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (is_destructuring) {
544962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ValidateAssignmentPattern(CHECK_OK);
545062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else {
545162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->RewriteNonPattern(CHECK_OK);
545262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
5453f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
545462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (is_for_each) {
545562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ParseForEachStatementWithoutDeclarations(stmt_pos, expression,
545662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                      lhs_beg_pos, lhs_end_pos,
545762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                      &for_info, labels, ok);
545862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
545962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Initializer is just an expression.
546062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
546162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
5462f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
546362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Standard 'for' loop, we have parsed the initializer at this point.
546462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return ParseStandardForLoop(stmt_pos, init, bound_names_are_lexical,
546562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              &for_info, &for_state, labels, ok);
546662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
5467f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
546862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename Impl>
546962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypename ParserBase<Impl>::StatementT
547062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochParserBase<Impl>::ParseForEachStatementWithDeclarations(
547162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int stmt_pos, ForInfo* for_info, ZoneList<const AstRawString*>* labels,
547262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool* ok) {
547362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Just one declaration followed by in/of.
547462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (for_info->parsing_result.declarations.length() != 1) {
547562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->ReportMessageAt(for_info->parsing_result.bindings_loc,
547662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                            MessageTemplate::kForInOfLoopMultiBindings,
547762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                            ForEachStatement::VisitModeString(for_info->mode));
547862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    *ok = false;
547962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return impl()->NullStatement();
548062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
548162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (for_info->parsing_result.first_initializer_loc.IsValid() &&
548262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      (is_strict(language_mode()) ||
548362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       for_info->mode == ForEachStatement::ITERATE ||
548462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
548562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       !impl()->IsIdentifier(
548662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           for_info->parsing_result.declarations[0].pattern))) {
548762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->ReportMessageAt(for_info->parsing_result.first_initializer_loc,
548862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                            MessageTemplate::kForInOfLoopInitializer,
548962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                            ForEachStatement::VisitModeString(for_info->mode));
549062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    *ok = false;
549162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return impl()->NullStatement();
549262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
5493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
549462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BlockT init_block = impl()->RewriteForVarInLegacy(*for_info);
5495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
549662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto loop = factory()->NewForEachStatement(for_info->mode, labels, stmt_pos);
549762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typename Types::Target target(this, loop);
5498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
549962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int each_keyword_pos = scanner()->location().beg_pos;
5500f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
550162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpressionT enumerable = impl()->EmptyExpression();
550262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (for_info->mode == ForEachStatement::ITERATE) {
550362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionClassifier classifier(this);
550462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    enumerable = ParseAssignmentExpression(true, CHECK_OK);
550562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->RewriteNonPattern(CHECK_OK);
550662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
550762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    enumerable = ParseExpression(true, CHECK_OK);
550862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
5509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
551062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::RPAREN, CHECK_OK);
5511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
551262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT final_loop = impl()->NullStatement();
551362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
551462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ReturnExprScope no_tail_calls(function_state_,
551562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  ReturnExprContext::kInsideForInOfBody);
551662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState block_state(zone(), &scope_);
551762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_start_position(scanner()->location().beg_pos);
5518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
551962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StatementT body = ParseStatement(nullptr, CHECK_OK);
5520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
552162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockT body_block = impl()->NullBlock();
552262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionT each_variable = impl()->EmptyExpression();
552362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->DesugarBindingInForEachStatement(for_info, &body_block,
552462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                             &each_variable, CHECK_OK);
552562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    body_block->statements()->Add(body, zone());
552662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    final_loop = impl()->InitializeForEachStatement(
552762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        loop, each_variable, enumerable, body_block, each_keyword_pos);
5528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
552962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_end_position(scanner()->location().end_pos);
553062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    body_block->set_scope(scope()->FinalizeBlockScope());
553162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
5532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
553362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info, ok);
5534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
553562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  scope()->set_end_position(scanner()->location().end_pos);
553662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Scope* for_scope = scope()->FinalizeBlockScope();
553762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Parsed for-in loop w/ variable declarations.
553862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!impl()->IsNullStatement(init_block)) {
553962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    init_block->statements()->Add(final_loop, zone());
554062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    init_block->set_scope(for_scope);
554162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return init_block;
554262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
5543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
554462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_NULL(for_scope);
554562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return final_loop;
554662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
554762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
554862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename Impl>
554962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypename ParserBase<Impl>::StatementT
555062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
555162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
555262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ForInfo* for_info, ZoneList<const AstRawString*>* labels, bool* ok) {
555362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Initializer is reference followed by in/of.
555462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!expression->IsArrayLiteral() && !expression->IsObjectLiteral()) {
555562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    expression = impl()->CheckAndRewriteReferenceExpression(
555662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
555762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        kSyntaxError, CHECK_OK);
5558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
556062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto loop = factory()->NewForEachStatement(for_info->mode, labels, stmt_pos);
556162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typename Types::Target target(this, loop);
556262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
556362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int each_keyword_pos = scanner()->location().beg_pos;
556462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
556562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpressionT enumerable = impl()->EmptyExpression();
556662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (for_info->mode == ForEachStatement::ITERATE) {
556762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionClassifier classifier(this);
556862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    enumerable = ParseAssignmentExpression(true, CHECK_OK);
556962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->RewriteNonPattern(CHECK_OK);
557062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
557162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    enumerable = ParseExpression(true, CHECK_OK);
557262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
557362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
557462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::RPAREN, CHECK_OK);
557562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Scope* for_scope = scope();
557662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
557762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
557862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ReturnExprScope no_tail_calls(function_state_,
557962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  ReturnExprContext::kInsideForInOfBody);
558062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState block_state(zone(), &scope_);
558162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_start_position(scanner()->location().beg_pos);
558262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
558362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StatementT body = ParseStatement(nullptr, CHECK_OK);
558462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_end_position(scanner()->location().end_pos);
558562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StatementT final_loop = impl()->InitializeForEachStatement(
558662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        loop, expression, enumerable, body, each_keyword_pos);
558762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
558862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    for_scope = for_scope->FinalizeBlockScope();
558962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    USE(for_scope);
559062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_NULL(for_scope);
559162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Scope* block_scope = scope()->FinalizeBlockScope();
559262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    USE(block_scope);
559362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_NULL(block_scope);
559462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return final_loop;
559562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
559662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
559762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
559862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename Impl>
559962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStandardForLoop(
560062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int stmt_pos, StatementT init, bool bound_names_are_lexical,
560162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ForInfo* for_info, BlockState* for_state,
560262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
5603f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  auto loop = factory()->NewForStatement(labels, stmt_pos);
5604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typename Types::Target target(this, loop);
5605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5606f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expect(Token::SEMICOLON, CHECK_OK);
5607f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ExpressionT cond = impl()->EmptyExpression();
5609f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT next = impl()->NullStatement();
5610f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StatementT body = impl()->NullStatement();
5611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5612f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // If there are let bindings, then condition and the next statement of the
5613f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // for loop must be parsed in a new scope.
5614f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Scope* inner_scope = scope();
561562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (bound_names_are_lexical && for_info->bound_names.length() > 0) {
5616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE);
5617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    inner_scope->set_start_position(scanner()->location().beg_pos);
5618f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5619f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
562062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState block_state(&scope_, inner_scope);
5621f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (peek() != Token::SEMICOLON) {
5623f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      cond = ParseExpression(true, CHECK_OK);
5624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5625f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Expect(Token::SEMICOLON, CHECK_OK);
5626f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (peek() != Token::RPAREN) {
5628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ExpressionT exp = ParseExpression(true, CHECK_OK);
5629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      next = factory()->NewExpressionStatement(exp, exp->position());
5630f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5631f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Expect(Token::RPAREN, CHECK_OK);
5632f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
563362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    body = ParseStatement(nullptr, CHECK_OK);
5634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
563662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (bound_names_are_lexical && for_info->bound_names.length() > 0) {
5637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    auto result = impl()->DesugarLexicalBindingsInForStatement(
563862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        loop, init, cond, next, body, inner_scope, *for_info, CHECK_OK);
563962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_end_position(scanner()->location().end_pos);
564062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inner_scope->set_end_position(scanner()->location().end_pos);
5641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return result;
564262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
564362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
564462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  scope()->set_end_position(scanner()->location().end_pos);
564562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Scope* for_scope = scope()->FinalizeBlockScope();
564662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (for_scope != nullptr) {
564762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Rewrite a for statement of the form
564862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   for (const x = i; c; n) b
564962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //
565062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // into
565162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //
565262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   {
565362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //     const x = i;
565462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //     for (; c; n) b
565562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   }
565662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //
565762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // or, desugar
565862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   for (; c; n) b
565962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // into
566062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   {
566162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //     for (; c; n) b
566262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   }
566362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // just in case b introduces a lexical binding some other way, e.g., if b
566462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // is a FunctionDeclaration.
566562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockT block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
566662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!impl()->IsNullStatement(init)) {
566762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      block->statements()->Add(init, zone());
566862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
566962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    block->statements()->Add(loop, zone());
567062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    block->set_scope(for_scope);
567162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    loop->Initialize(init, cond, next, body);
567262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return block;
567362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
567462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
567562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  loop->Initialize(init, cond, next, body);
567662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return loop;
567762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
567862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
567962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename Impl>
568062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid ParserBase<Impl>::MarkLoopVariableAsAssigned(Scope* scope, Variable* var) {
568162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!IsLexicalVariableMode(var->mode()) && !scope->is_function_scope()) {
568262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    var->set_maybe_assigned();
568362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
568462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
568562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
568662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename Impl>
568762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
568862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ZoneList<const AstRawString*>* labels, bool* ok) {
568962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // for await '(' ForDeclaration of AssignmentExpression ')'
569062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(is_async_function());
569162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(allow_harmony_async_iteration());
569262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
569362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int stmt_pos = peek_position();
569462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
569562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ForInfo for_info(this);
569662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for_info.mode = ForEachStatement::ITERATE;
569762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
569862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Create an in-between scope for let-bound iteration variables.
569962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BlockState for_state(zone(), &scope_);
570062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::FOR, CHECK_OK);
570162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::AWAIT, CHECK_OK);
570262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::LPAREN, CHECK_OK);
570362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  scope()->set_start_position(scanner()->location().beg_pos);
570462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  scope()->set_is_hidden();
570562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
570662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto loop = factory()->NewForOfStatement(labels, stmt_pos);
570762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typename Types::Target target(this, loop);
570862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
570962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpressionT each_variable = impl()->EmptyExpression();
571062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
571162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool has_declarations = false;
571262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
571362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (peek() == Token::VAR || peek() == Token::CONST ||
571462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      (peek() == Token::LET && IsNextLetKeyword())) {
571562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // The initializer contains declarations
571662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
571762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //     Statement
571862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
571962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //     Statement
572062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    has_declarations = true;
572162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr,
572262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              CHECK_OK);
572362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    for_info.position = scanner()->location().beg_pos;
572462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
572562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Only a single declaration is allowed in for-await-of loops
572662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (for_info.parsing_result.declarations.length() != 1) {
572762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->ReportMessageAt(for_info.parsing_result.bindings_loc,
572862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              MessageTemplate::kForInOfLoopMultiBindings,
572962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              "for-await-of");
573062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *ok = false;
573162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return impl()->NullStatement();
573262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
573362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
573462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // for-await-of's declarations do not permit initializers.
573562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (for_info.parsing_result.first_initializer_loc.IsValid()) {
573662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->ReportMessageAt(for_info.parsing_result.first_initializer_loc,
573762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              MessageTemplate::kForInOfLoopInitializer,
573862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              "for-await-of");
573962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *ok = false;
574062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return impl()->NullStatement();
574162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
5742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
574362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // The initializer does not contain declarations.
574462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')'
574562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //     Statement
574662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int lhs_beg_pos = peek_position();
574762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionClassifier classifier(this);
574862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionT lhs = each_variable = ParseLeftHandSideExpression(CHECK_OK);
574962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int lhs_end_pos = scanner()->location().end_pos;
575062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
575162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) {
575262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ValidateAssignmentPattern(CHECK_OK);
5753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
575462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->RewriteNonPattern(CHECK_OK);
575562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      each_variable = impl()->CheckAndRewriteReferenceExpression(
575662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
575762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          kSyntaxError, CHECK_OK);
5758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
5759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
576162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpectContextualKeyword(CStrVector("of"), CHECK_OK);
576262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int each_keyword_pos = scanner()->location().beg_pos;
576362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
576462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const bool kAllowIn = true;
576562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExpressionT iterable = impl()->EmptyExpression();
576662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
576762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
576862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ExpressionClassifier classifier(this);
576962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    iterable = ParseAssignmentExpression(kAllowIn, CHECK_OK);
577062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    impl()->RewriteNonPattern(CHECK_OK);
577162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
577262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
577362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Expect(Token::RPAREN, CHECK_OK);
577462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
577562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StatementT final_loop = impl()->NullStatement();
577662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Scope* for_scope = scope();
577762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
577862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ReturnExprScope no_tail_calls(function_state_,
577962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  ReturnExprContext::kInsideForInOfBody);
578062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BlockState block_state(zone(), &scope_);
578162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_start_position(scanner()->location().beg_pos);
578262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
578362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StatementT body = ParseStatement(nullptr, CHECK_OK);
578462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    scope()->set_end_position(scanner()->location().end_pos);
578562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
578662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (has_declarations) {
578762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      BlockT body_block = impl()->NullBlock();
578862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
578962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                               &each_variable, CHECK_OK);
579062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      body_block->statements()->Add(body, zone());
579162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      body_block->set_scope(scope()->FinalizeBlockScope());
579262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
579362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      const bool finalize = true;
579462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      final_loop = impl()->InitializeForOfStatement(
579562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          loop, each_variable, iterable, body_block, finalize,
579662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          IteratorType::kAsync, each_keyword_pos);
579762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else {
579862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      const bool finalize = true;
579962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      final_loop = impl()->InitializeForOfStatement(
580062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          loop, each_variable, iterable, body, finalize, IteratorType::kAsync,
580162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          each_keyword_pos);
580262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
580362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      for_scope = for_scope->FinalizeBlockScope();
580462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK_NULL(for_scope);
580562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      USE(for_scope);
580662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Scope* block_scope = scope()->FinalizeBlockScope();
580762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK_NULL(block_scope);
580862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      USE(block_scope);
580962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return final_loop;
581062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
581162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
581262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
581362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(has_declarations);
581462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BlockT init_block =
581562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      impl()->CreateForEachStatementTDZ(impl()->NullBlock(), for_info, ok);
581662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
581762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for_scope->set_end_position(scanner()->location().end_pos);
581862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for_scope = for_scope->FinalizeBlockScope();
581962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Parsed for-in loop w/ variable declarations.
582062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!impl()->IsNullStatement(init_block)) {
582162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    init_block->statements()->Add(final_loop, zone());
582262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    init_block->set_scope(for_scope);
582362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return init_block;
582462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
582562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_NULL(for_scope);
582662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return final_loop;
582762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
5828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate <typename Impl>
5830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
5831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Token::Value property) {
5832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (property == Token::SMI || property == Token::NUMBER) return;
5833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (IsProto()) {
5835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (has_seen_proto_) {
5836f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      this->parser()->classifier()->RecordExpressionError(
5837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          this->scanner()->location(), MessageTemplate::kDuplicateProto);
5838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
5839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    has_seen_proto_ = true;
5841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename Impl>
5845f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName(
5846f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Token::Value property, PropertyKind type, bool is_generator, bool is_async,
5847f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool is_static, bool* ok) {
5848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(type == PropertyKind::kMethodProperty ||
5849f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         type == PropertyKind::kAccessorProperty);
5850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (property == Token::SMI || property == Token::NUMBER) return;
5852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_static) {
5854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (IsPrototype()) {
5855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
5856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
5857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
5858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (IsConstructor()) {
5860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (is_generator || is_async || type == PropertyKind::kAccessorProperty) {
5861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MessageTemplate::Template msg =
5862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          is_generator ? MessageTemplate::kConstructorIsGenerator
5863bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                       : is_async ? MessageTemplate::kConstructorIsAsync
5864bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  : MessageTemplate::kConstructorIsAccessor;
5865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      this->parser()->ReportMessage(msg);
5866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
5867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
5868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (has_seen_constructor_) {
5870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
5871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *ok = false;
5872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
5873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    has_seen_constructor_ = true;
5875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
5876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
587962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef CHECK_OK
588062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef CHECK_OK_CUSTOM
588162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef CHECK_OK_VOID
5882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
5883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
5884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
5885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_PARSING_PARSER_BASE_H
5887