blob: 669defa27f0fdf1f1c4555412ee07198138defa5 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_PARSING_PARSER_BASE_H
6#define V8_PARSING_PARSER_BASE_H
7
8#include "src/ast/scopes.h"
9#include "src/bailout-reason.h"
Ben Murdoch61f157c2016-09-16 13:49:30 +010010#include "src/base/hashmap.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/messages.h"
12#include "src/parsing/expression-classifier.h"
13#include "src/parsing/func-name-inferrer.h"
14#include "src/parsing/scanner.h"
15#include "src/parsing/token.h"
16
17namespace v8 {
18namespace internal {
19
20
21enum FunctionNameValidity {
22 kFunctionNameIsStrictReserved,
23 kSkipFunctionNameCheck,
24 kFunctionNameValidityUnknown
25};
26
Ben Murdochda12d292016-06-02 14:46:10 +010027enum AllowLabelledFunctionStatement {
28 kAllowLabelledFunctionStatement,
29 kDisallowLabelledFunctionStatement,
30};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000031
Ben Murdochc5610432016-08-08 18:44:38 +010032enum class FunctionBody { Normal, SingleExpression };
33
34enum class ParseFunctionFlags {
35 kIsNormal = 0,
36 kIsGenerator = 1,
37 kIsAsync = 2,
38 kIsDefault = 4
39};
40
41static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs,
42 ParseFunctionFlags rhs) {
43 typedef unsigned char T;
44 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) |
45 static_cast<T>(rhs));
46}
47
48static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs,
49 const ParseFunctionFlags& rhs) {
50 lhs = lhs | rhs;
51 return lhs;
52}
53
54static inline bool operator&(ParseFunctionFlags bitfield,
55 ParseFunctionFlags mask) {
56 typedef unsigned char T;
57 return static_cast<T>(bitfield) & static_cast<T>(mask);
58}
59
60enum class MethodKind {
61 Normal = 0,
62 Static = 1 << 0,
63 Generator = 1 << 1,
64 StaticGenerator = Static | Generator,
65 Async = 1 << 2,
66 StaticAsync = Static | Async,
67
68 /* Any non-ordinary method kinds */
69 SpecialMask = Generator | Async
70};
71
72inline bool IsValidMethodKind(MethodKind kind) {
73 return kind == MethodKind::Normal || kind == MethodKind::Static ||
74 kind == MethodKind::Generator || kind == MethodKind::StaticGenerator ||
75 kind == MethodKind::Async || kind == MethodKind::StaticAsync;
76}
77
78static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) {
79 typedef unsigned char T;
80 return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs));
81}
82
83static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) {
84 lhs = lhs | rhs;
85 DCHECK(IsValidMethodKind(lhs));
86 return lhs;
87}
88
89static inline bool operator&(MethodKind bitfield, MethodKind mask) {
90 typedef unsigned char T;
91 return static_cast<T>(bitfield) & static_cast<T>(mask);
92}
93
94inline bool IsNormalMethod(MethodKind kind) {
95 return kind == MethodKind::Normal;
96}
97
98inline bool IsSpecialMethod(MethodKind kind) {
99 return kind & MethodKind::SpecialMask;
100}
101
102inline bool IsStaticMethod(MethodKind kind) {
103 return kind & MethodKind::Static;
104}
105
106inline bool IsGeneratorMethod(MethodKind kind) {
107 return kind & MethodKind::Generator;
108}
109
110inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::Async; }
111
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112struct FormalParametersBase {
113 explicit FormalParametersBase(Scope* scope) : scope(scope) {}
114 Scope* scope;
115 bool has_rest = false;
116 bool is_simple = true;
117 int materialized_literals_count = 0;
118};
119
120
121// Common base class shared between parser and pre-parser. Traits encapsulate
122// the differences between Parser and PreParser:
123
124// - Return types: For example, Parser functions return Expression* and
125// PreParser functions return PreParserExpression.
126
127// - Creating parse tree nodes: Parser generates an AST during the recursive
128// descent. PreParser doesn't create a tree. Instead, it passes around minimal
129// data objects (PreParserExpression, PreParserIdentifier etc.) which contain
130// just enough data for the upper layer functions. PreParserFactory is
131// responsible for creating these dummy objects. It provides a similar kind of
132// interface as AstNodeFactory, so ParserBase doesn't need to care which one is
133// used.
134
135// - Miscellaneous other tasks interleaved with the recursive descent. For
136// example, Parser keeps track of which function literals should be marked as
137// pretenured, and PreParser doesn't care.
138
139// The traits are expected to contain the following typedefs:
140// struct Traits {
141// // In particular...
142// struct Type {
143// // Used by FunctionState and BlockState.
144// typedef Scope;
145// typedef GeneratorVariable;
146// // Return types for traversing functions.
147// typedef Identifier;
148// typedef Expression;
149// typedef FunctionLiteral;
150// typedef ClassLiteral;
151// typedef ObjectLiteralProperty;
152// typedef Literal;
153// typedef ExpressionList;
154// typedef PropertyList;
155// typedef FormalParameter;
156// typedef FormalParameters;
157// // For constructing objects returned by the traversing functions.
158// typedef Factory;
159// };
160// // ...
161// };
162
163template <typename Traits>
164class ParserBase : public Traits {
165 public:
166 // Shorten type names defined by Traits.
167 typedef typename Traits::Type::Expression ExpressionT;
168 typedef typename Traits::Type::Identifier IdentifierT;
169 typedef typename Traits::Type::FormalParameter FormalParameterT;
170 typedef typename Traits::Type::FormalParameters FormalParametersT;
171 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
172 typedef typename Traits::Type::Literal LiteralT;
173 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
174 typedef typename Traits::Type::StatementList StatementListT;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100175 typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176
177 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
178 v8::Extension* extension, AstValueFactory* ast_value_factory,
179 ParserRecorder* log, typename Traits::Type::Parser this_object)
180 : Traits(this_object),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000181 scope_(NULL),
182 function_state_(NULL),
183 extension_(extension),
184 fni_(NULL),
185 ast_value_factory_(ast_value_factory),
186 log_(log),
187 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
Ben Murdochc5610432016-08-08 18:44:38 +0100188 parsing_module_(false),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189 stack_limit_(stack_limit),
190 zone_(zone),
191 scanner_(scanner),
192 stack_overflow_(false),
193 allow_lazy_(false),
194 allow_natives_(false),
Ben Murdochda12d292016-06-02 14:46:10 +0100195 allow_tailcalls_(false),
Ben Murdochda12d292016-06-02 14:46:10 +0100196 allow_harmony_restrictive_declarations_(false),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000197 allow_harmony_do_expressions_(false),
Ben Murdochc5610432016-08-08 18:44:38 +0100198 allow_harmony_for_in_(false),
Ben Murdochc5610432016-08-08 18:44:38 +0100199 allow_harmony_function_sent_(false),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100200 allow_harmony_async_await_(false),
201 allow_harmony_restrictive_generators_(false) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202
203#define ALLOW_ACCESSORS(name) \
204 bool allow_##name() const { return allow_##name##_; } \
205 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
206
Ben Murdochda12d292016-06-02 14:46:10 +0100207#define SCANNER_ACCESSORS(name) \
208 bool allow_##name() const { return scanner_->allow_##name(); } \
209 void set_allow_##name(bool allow) { \
210 return scanner_->set_allow_##name(allow); \
211 }
212
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000213 ALLOW_ACCESSORS(lazy);
214 ALLOW_ACCESSORS(natives);
Ben Murdochda12d292016-06-02 14:46:10 +0100215 ALLOW_ACCESSORS(tailcalls);
Ben Murdochda12d292016-06-02 14:46:10 +0100216 ALLOW_ACCESSORS(harmony_restrictive_declarations);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000217 ALLOW_ACCESSORS(harmony_do_expressions);
Ben Murdochc5610432016-08-08 18:44:38 +0100218 ALLOW_ACCESSORS(harmony_for_in);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100219 ALLOW_ACCESSORS(harmony_function_sent);
Ben Murdochc5610432016-08-08 18:44:38 +0100220 ALLOW_ACCESSORS(harmony_async_await);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100221 ALLOW_ACCESSORS(harmony_restrictive_generators);
Ben Murdochda12d292016-06-02 14:46:10 +0100222 SCANNER_ACCESSORS(harmony_exponentiation_operator);
223
224#undef SCANNER_ACCESSORS
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000225#undef ALLOW_ACCESSORS
226
227 uintptr_t stack_limit() const { return stack_limit_; }
228
229 protected:
230 enum AllowRestrictedIdentifiers {
231 kAllowRestrictedIdentifiers,
232 kDontAllowRestrictedIdentifiers
233 };
234
235 enum Mode {
236 PARSE_LAZILY,
237 PARSE_EAGERLY
238 };
239
240 enum VariableDeclarationContext {
241 kStatementListItem,
242 kStatement,
243 kForStatement
244 };
245
246 class Checkpoint;
247 class ObjectLiteralCheckerBase;
248
249 // ---------------------------------------------------------------------------
250 // FunctionState and BlockState together implement the parser's scope stack.
251 // The parser's current scope is in scope_. BlockState and FunctionState
252 // constructors push on the scope stack and the destructors pop. They are also
253 // used to hold the parser's per-function and per-block state.
254 class BlockState BASE_EMBEDDED {
255 public:
256 BlockState(Scope** scope_stack, Scope* scope)
257 : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
258 *scope_stack_ = scope;
259 }
260 ~BlockState() { *scope_stack_ = outer_scope_; }
261
262 private:
263 Scope** scope_stack_;
264 Scope* outer_scope_;
265 };
266
267 struct DestructuringAssignment {
268 public:
269 DestructuringAssignment(ExpressionT expression, Scope* scope)
270 : assignment(expression), scope(scope) {}
271
272 ExpressionT assignment;
273 Scope* scope;
274 };
275
Ben Murdochc5610432016-08-08 18:44:38 +0100276 class TailCallExpressionList {
277 public:
278 explicit TailCallExpressionList(Zone* zone)
279 : zone_(zone), expressions_(0, zone), has_explicit_tail_calls_(false) {}
280
281 const ZoneList<ExpressionT>& expressions() const { return expressions_; }
282 const Scanner::Location& location() const { return loc_; }
283
284 bool has_explicit_tail_calls() const { return has_explicit_tail_calls_; }
285
286 void Swap(TailCallExpressionList& other) {
287 expressions_.Swap(&other.expressions_);
288 std::swap(loc_, other.loc_);
289 std::swap(has_explicit_tail_calls_, other.has_explicit_tail_calls_);
290 }
291
292 void AddImplicitTailCall(ExpressionT expr) {
293 expressions_.Add(expr, zone_);
294 }
295
296 void AddExplicitTailCall(ExpressionT expr, const Scanner::Location& loc) {
297 if (!has_explicit_tail_calls()) {
298 loc_ = loc;
299 has_explicit_tail_calls_ = true;
300 }
301 expressions_.Add(expr, zone_);
302 }
303
304 void Append(const TailCallExpressionList& other) {
305 if (!has_explicit_tail_calls()) {
306 loc_ = other.loc_;
307 has_explicit_tail_calls_ = other.has_explicit_tail_calls_;
308 }
309 expressions_.AddAll(other.expressions_, zone_);
310 }
311
312 private:
313 Zone* zone_;
314 ZoneList<ExpressionT> expressions_;
315 Scanner::Location loc_;
316 bool has_explicit_tail_calls_;
317 };
318
319 // Defines whether tail call expressions are allowed or not.
320 enum class ReturnExprContext {
321 // We are inside return statement which is allowed to contain tail call
322 // expressions. Tail call expressions are allowed.
323 kInsideValidReturnStatement,
324
325 // We are inside a block in which tail call expressions are allowed but
326 // not yet inside a return statement.
327 kInsideValidBlock,
328
329 // Tail call expressions are not allowed in the following blocks.
330 kInsideTryBlock,
331 kInsideForInOfBody,
332 };
333
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000334 class FunctionState BASE_EMBEDDED {
335 public:
336 FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
337 Scope* scope, FunctionKind kind,
338 typename Traits::Type::Factory* factory);
339 ~FunctionState();
340
341 int NextMaterializedLiteralIndex() {
342 return next_materialized_literal_index_++;
343 }
344 int materialized_literal_count() {
345 return next_materialized_literal_index_;
346 }
347
348 void SkipMaterializedLiterals(int count) {
349 next_materialized_literal_index_ += count;
350 }
351
352 void AddProperty() { expected_property_count_++; }
353 int expected_property_count() { return expected_property_count_; }
354
355 Scanner::Location this_location() const { return this_location_; }
356 Scanner::Location super_location() const { return super_location_; }
357 Scanner::Location return_location() const { return return_location_; }
358 void set_this_location(Scanner::Location location) {
359 this_location_ = location;
360 }
361 void set_super_location(Scanner::Location location) {
362 super_location_ = location;
363 }
364 void set_return_location(Scanner::Location location) {
365 return_location_ = location;
366 }
367
368 bool is_generator() const { return IsGeneratorFunction(kind_); }
Ben Murdochc5610432016-08-08 18:44:38 +0100369 bool is_async_function() const { return IsAsyncFunction(kind_); }
370 bool is_resumable() const { return is_generator() || is_async_function(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000371
372 FunctionKind kind() const { return kind_; }
373 FunctionState* outer() const { return outer_function_state_; }
374
375 void set_generator_object_variable(
376 typename Traits::Type::GeneratorVariable* variable) {
377 DCHECK(variable != NULL);
Ben Murdochc5610432016-08-08 18:44:38 +0100378 DCHECK(is_resumable());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000379 generator_object_variable_ = variable;
380 }
381 typename Traits::Type::GeneratorVariable* generator_object_variable()
382 const {
383 return generator_object_variable_;
384 }
385
386 typename Traits::Type::Factory* factory() { return factory_; }
387
Ben Murdoch61f157c2016-09-16 13:49:30 +0100388 const ZoneList<DestructuringAssignment>&
389 destructuring_assignments_to_rewrite() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390 return destructuring_assignments_to_rewrite_;
391 }
392
Ben Murdochc5610432016-08-08 18:44:38 +0100393 TailCallExpressionList& tail_call_expressions() {
394 return tail_call_expressions_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100395 }
Ben Murdochc5610432016-08-08 18:44:38 +0100396 void AddImplicitTailCallExpression(ExpressionT expression) {
397 if (return_expr_context() ==
398 ReturnExprContext::kInsideValidReturnStatement) {
399 tail_call_expressions_.AddImplicitTailCall(expression);
400 }
401 }
402 void AddExplicitTailCallExpression(ExpressionT expression,
403 const Scanner::Location& loc) {
404 DCHECK(expression->IsCall());
405 if (return_expr_context() ==
406 ReturnExprContext::kInsideValidReturnStatement) {
407 tail_call_expressions_.AddExplicitTailCall(expression, loc);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100408 }
409 }
410
Ben Murdoch61f157c2016-09-16 13:49:30 +0100411 ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() {
412 return &reported_errors_;
413 }
414
Ben Murdochc5610432016-08-08 18:44:38 +0100415 ReturnExprContext return_expr_context() const {
416 return return_expr_context_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100417 }
Ben Murdochc5610432016-08-08 18:44:38 +0100418 void set_return_expr_context(ReturnExprContext context) {
419 return_expr_context_ = context;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100420 }
421
422 ZoneList<ExpressionT>* non_patterns_to_rewrite() {
423 return &non_patterns_to_rewrite_;
424 }
425
Ben Murdochc5610432016-08-08 18:44:38 +0100426 void next_function_is_parenthesized(bool parenthesized) {
427 next_function_is_parenthesized_ = parenthesized;
428 }
429
430 bool this_function_is_parenthesized() const {
431 return this_function_is_parenthesized_;
432 }
433
Ben Murdoch097c5b22016-05-18 11:27:45 +0100434 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435 void AddDestructuringAssignment(DestructuringAssignment pair) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100436 destructuring_assignments_to_rewrite_.Add(pair, (*scope_stack_)->zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437 }
438
Ben Murdoch097c5b22016-05-18 11:27:45 +0100439 V8_INLINE Scope* scope() { return *scope_stack_; }
440
Ben Murdoch61f157c2016-09-16 13:49:30 +0100441 void AddNonPatternForRewriting(ExpressionT expr, bool* ok) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100442 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100443 if (non_patterns_to_rewrite_.length() >=
444 std::numeric_limits<uint16_t>::max())
445 *ok = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100446 }
447
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000448 // Used to assign an index to each literal that needs materialization in
449 // the function. Includes regexp literals, and boilerplate for object and
450 // array literals.
451 int next_materialized_literal_index_;
452
453 // Properties count estimation.
454 int expected_property_count_;
455
456 // Location of most recent use of 'this' (invalid if none).
457 Scanner::Location this_location_;
458
459 // Location of most recent 'return' statement (invalid if none).
460 Scanner::Location return_location_;
461
462 // Location of call to the "super" constructor (invalid if none).
463 Scanner::Location super_location_;
464
465 FunctionKind kind_;
466 // For generators, this variable may hold the generator object. It variable
467 // is used by yield expressions and return statements. It is not necessary
468 // for generator functions to have this variable set.
469 Variable* generator_object_variable_;
470
471 FunctionState** function_state_stack_;
472 FunctionState* outer_function_state_;
473 Scope** scope_stack_;
474 Scope* outer_scope_;
475
Ben Murdoch61f157c2016-09-16 13:49:30 +0100476 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_;
Ben Murdochc5610432016-08-08 18:44:38 +0100477 TailCallExpressionList tail_call_expressions_;
478 ReturnExprContext return_expr_context_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100479 ZoneList<ExpressionT> non_patterns_to_rewrite_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000480
Ben Murdoch61f157c2016-09-16 13:49:30 +0100481 ZoneList<typename ExpressionClassifier::Error> reported_errors_;
482
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000483 typename Traits::Type::Factory* factory_;
484
Ben Murdochc5610432016-08-08 18:44:38 +0100485 // If true, the next (and immediately following) function literal is
486 // preceded by a parenthesis.
487 bool next_function_is_parenthesized_;
488
489 // The value of the parents' next_function_is_parenthesized_, as it applies
490 // to this function. Filled in by constructor.
491 bool this_function_is_parenthesized_;
492
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000493 friend class ParserTraits;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100494 friend class PreParserTraits;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000495 friend class Checkpoint;
496 };
497
Ben Murdochc5610432016-08-08 18:44:38 +0100498 // This scope sets current ReturnExprContext to given value.
499 class ReturnExprScope {
500 public:
501 explicit ReturnExprScope(FunctionState* function_state,
502 ReturnExprContext return_expr_context)
503 : function_state_(function_state),
504 sav_return_expr_context_(function_state->return_expr_context()) {
505 // Don't update context if we are requested to enable tail call
506 // expressions but current block does not allow them.
507 if (return_expr_context !=
508 ReturnExprContext::kInsideValidReturnStatement ||
509 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) {
510 function_state->set_return_expr_context(return_expr_context);
511 }
512 }
513 ~ReturnExprScope() {
514 function_state_->set_return_expr_context(sav_return_expr_context_);
515 }
516
517 private:
518 FunctionState* function_state_;
519 ReturnExprContext sav_return_expr_context_;
520 };
521
522 // Collects all return expressions at tail call position in this scope
523 // to a separate list.
524 class CollectExpressionsInTailPositionToListScope {
525 public:
526 CollectExpressionsInTailPositionToListScope(FunctionState* function_state,
527 TailCallExpressionList* list)
528 : function_state_(function_state), list_(list) {
529 function_state->tail_call_expressions().Swap(*list_);
530 }
531 ~CollectExpressionsInTailPositionToListScope() {
532 function_state_->tail_call_expressions().Swap(*list_);
533 }
534
535 private:
536 FunctionState* function_state_;
537 TailCallExpressionList* list_;
538 };
539
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000540 // Annoyingly, arrow functions first parse as comma expressions, then when we
541 // see the => we have to go back and reinterpret the arguments as being formal
542 // parameters. To do so we need to reset some of the parser state back to
543 // what it was before the arguments were first seen.
544 class Checkpoint BASE_EMBEDDED {
545 public:
546 explicit Checkpoint(ParserBase* parser) {
547 function_state_ = parser->function_state_;
548 next_materialized_literal_index_ =
549 function_state_->next_materialized_literal_index_;
550 expected_property_count_ = function_state_->expected_property_count_;
551 }
552
553 void Restore(int* materialized_literal_index_delta) {
554 *materialized_literal_index_delta =
555 function_state_->next_materialized_literal_index_ -
556 next_materialized_literal_index_;
557 function_state_->next_materialized_literal_index_ =
558 next_materialized_literal_index_;
559 function_state_->expected_property_count_ = expected_property_count_;
560 }
561
562 private:
563 FunctionState* function_state_;
564 int next_materialized_literal_index_;
565 int expected_property_count_;
566 };
567
568 class ParsingModeScope BASE_EMBEDDED {
569 public:
570 ParsingModeScope(ParserBase* parser, Mode mode)
571 : parser_(parser),
572 old_mode_(parser->mode()) {
573 parser_->mode_ = mode;
574 }
575 ~ParsingModeScope() {
576 parser_->mode_ = old_mode_;
577 }
578
579 private:
580 ParserBase* parser_;
581 Mode old_mode_;
582 };
583
584 Scope* NewScope(Scope* parent, ScopeType scope_type) {
585 // Must always pass the function kind for FUNCTION_SCOPE.
586 DCHECK(scope_type != FUNCTION_SCOPE);
587 return NewScope(parent, scope_type, kNormalFunction);
588 }
589
590 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
591 DCHECK(ast_value_factory());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592 Scope* result = new (zone())
593 Scope(zone(), parent, scope_type, ast_value_factory(), kind);
594 result->Initialize();
595 return result;
596 }
597
598 Scanner* scanner() const { return scanner_; }
599 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
600 int position() { return scanner_->location().beg_pos; }
601 int peek_position() { return scanner_->peek_location().beg_pos; }
602 bool stack_overflow() const { return stack_overflow_; }
603 void set_stack_overflow() { stack_overflow_ = true; }
604 Mode mode() const { return mode_; }
605 Zone* zone() const { return zone_; }
606
607 INLINE(Token::Value peek()) {
608 if (stack_overflow_) return Token::ILLEGAL;
609 return scanner()->peek();
610 }
611
612 INLINE(Token::Value PeekAhead()) {
613 if (stack_overflow_) return Token::ILLEGAL;
614 return scanner()->PeekAhead();
615 }
616
617 INLINE(Token::Value Next()) {
618 if (stack_overflow_) return Token::ILLEGAL;
619 {
620 if (GetCurrentStackPosition() < stack_limit_) {
621 // Any further calls to Next or peek will return the illegal token.
622 // The current call must return the next token, which might already
623 // have been peek'ed.
624 stack_overflow_ = true;
625 }
626 }
627 return scanner()->Next();
628 }
629
630 void Consume(Token::Value token) {
631 Token::Value next = Next();
632 USE(next);
633 USE(token);
634 DCHECK(next == token);
635 }
636
637 bool Check(Token::Value token) {
638 Token::Value next = peek();
639 if (next == token) {
640 Consume(next);
641 return true;
642 }
643 return false;
644 }
645
646 void Expect(Token::Value token, bool* ok) {
647 Token::Value next = Next();
648 if (next != token) {
649 ReportUnexpectedToken(next);
650 *ok = false;
651 }
652 }
653
654 void ExpectSemicolon(bool* ok) {
655 // Check for automatic semicolon insertion according to
656 // the rules given in ECMA-262, section 7.9, page 21.
657 Token::Value tok = peek();
658 if (tok == Token::SEMICOLON) {
659 Next();
660 return;
661 }
662 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
663 tok == Token::RBRACE ||
664 tok == Token::EOS) {
665 return;
666 }
667 Expect(Token::SEMICOLON, ok);
668 }
669
Ben Murdoch61f157c2016-09-16 13:49:30 +0100670 bool is_any_identifier(Token::Value token) {
671 return token == Token::IDENTIFIER || token == Token::ENUM ||
672 token == Token::AWAIT || token == Token::ASYNC ||
673 token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET ||
674 token == Token::STATIC || token == Token::YIELD;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000675 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100676 bool peek_any_identifier() { return is_any_identifier(peek()); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000677
678 bool CheckContextualKeyword(Vector<const char> keyword) {
679 if (PeekContextualKeyword(keyword)) {
680 Consume(Token::IDENTIFIER);
681 return true;
682 }
683 return false;
684 }
685
686 bool PeekContextualKeyword(Vector<const char> keyword) {
687 return peek() == Token::IDENTIFIER &&
688 scanner()->is_next_contextual_keyword(keyword);
689 }
690
Ben Murdoch097c5b22016-05-18 11:27:45 +0100691 void ExpectMetaProperty(Vector<const char> property_name,
692 const char* full_name, int pos, bool* ok);
693
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000694 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
695 Expect(Token::IDENTIFIER, ok);
696 if (!*ok) return;
697 if (!scanner()->is_literal_contextual_keyword(keyword)) {
698 ReportUnexpectedToken(scanner()->current_token());
699 *ok = false;
700 }
701 }
702
703 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
704 if (Check(Token::IN)) {
Ben Murdochda12d292016-06-02 14:46:10 +0100705 *visit_mode = ForEachStatement::ENUMERATE;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000706 return true;
707 } else if (CheckContextualKeyword(CStrVector("of"))) {
708 *visit_mode = ForEachStatement::ITERATE;
709 return true;
710 }
711 return false;
712 }
713
Ben Murdoch097c5b22016-05-18 11:27:45 +0100714 bool PeekInOrOf() {
715 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of"));
716 }
717
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000718 // Checks whether an octal literal was last seen between beg_pos and end_pos.
719 // If so, reports an error. Only called for strict mode and template strings.
720 void CheckOctalLiteral(int beg_pos, int end_pos,
721 MessageTemplate::Template message, bool* ok) {
722 Scanner::Location octal = scanner()->octal_position();
723 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
724 octal.end_pos <= end_pos) {
725 ReportMessageAt(octal, message);
726 scanner()->clear_octal_position();
727 *ok = false;
728 }
729 }
Ben Murdochc5610432016-08-08 18:44:38 +0100730 // for now, this check just collects statistics.
731 void CheckDecimalLiteralWithLeadingZero(int* use_counts, int beg_pos,
732 int end_pos) {
733 Scanner::Location token_location =
734 scanner()->decimal_with_leading_zero_position();
735 if (token_location.IsValid() && beg_pos <= token_location.beg_pos &&
736 token_location.end_pos <= end_pos) {
737 scanner()->clear_decimal_with_leading_zero_position();
738 if (use_counts != nullptr)
739 ++use_counts[v8::Isolate::kDecimalWithLeadingZeroInStrictMode];
740 }
741 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000742
743 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
744 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
745 ok);
746 }
747
748 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
749 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
750 ok);
751 }
752
753 void CheckDestructuringElement(ExpressionT element,
754 ExpressionClassifier* classifier, int beg_pos,
755 int end_pos);
756
757 // Checking the name of a function literal. This has to be done after parsing
758 // the function, since the function can declare itself strict.
759 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
760 FunctionNameValidity function_name_validity,
761 const Scanner::Location& function_name_loc, bool* ok) {
762 if (function_name_validity == kSkipFunctionNameCheck) return;
763 // The function name needs to be checked in strict mode.
764 if (is_sloppy(language_mode)) return;
765
766 if (this->IsEvalOrArguments(function_name)) {
767 Traits::ReportMessageAt(function_name_loc,
768 MessageTemplate::kStrictEvalArguments);
769 *ok = false;
770 return;
771 }
772 if (function_name_validity == kFunctionNameIsStrictReserved) {
773 Traits::ReportMessageAt(function_name_loc,
774 MessageTemplate::kUnexpectedStrictReserved);
775 *ok = false;
776 return;
777 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000778 }
779
780 // Determine precedence of given token.
781 static int Precedence(Token::Value token, bool accept_IN) {
782 if (token == Token::IN && !accept_IN)
783 return 0; // 0 precedence will terminate binary expression parsing
784 return Token::Precedence(token);
785 }
786
787 typename Traits::Type::Factory* factory() {
788 return function_state_->factory();
789 }
790
791 LanguageMode language_mode() { return scope_->language_mode(); }
792 bool is_generator() const { return function_state_->is_generator(); }
Ben Murdochc5610432016-08-08 18:44:38 +0100793 bool is_async_function() const {
794 return function_state_->is_async_function();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000795 }
Ben Murdochc5610432016-08-08 18:44:38 +0100796 bool is_resumable() const { return function_state_->is_resumable(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000797
798 // Report syntax errors.
799 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
800 ParseErrorType error_type = kSyntaxError) {
801 Scanner::Location source_location = scanner()->location();
802 Traits::ReportMessageAt(source_location, message, arg, error_type);
803 }
804
805 void ReportMessageAt(Scanner::Location location,
806 MessageTemplate::Template message,
807 ParseErrorType error_type = kSyntaxError) {
808 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
809 error_type);
810 }
811
812 void GetUnexpectedTokenMessage(
Ben Murdochda12d292016-06-02 14:46:10 +0100813 Token::Value token, MessageTemplate::Template* message,
814 Scanner::Location* location, const char** arg,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000815 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
816
817 void ReportUnexpectedToken(Token::Value token);
818 void ReportUnexpectedTokenAt(
819 Scanner::Location location, Token::Value token,
820 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
821
Ben Murdoch097c5b22016-05-18 11:27:45 +0100822 void ReportClassifierError(
823 const typename ExpressionClassifier::Error& error) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000824 Traits::ReportMessageAt(error.location, error.message, error.arg,
825 error.type);
826 }
827
828 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
829 if (!classifier->is_valid_expression() ||
830 classifier->has_cover_initialized_name()) {
831 const Scanner::Location& a = classifier->expression_error().location;
832 const Scanner::Location& b =
833 classifier->cover_initialized_name_error().location;
834 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
835 ReportClassifierError(classifier->cover_initialized_name_error());
836 } else {
837 ReportClassifierError(classifier->expression_error());
838 }
839 *ok = false;
840 }
841 }
842
843 void ValidateFormalParameterInitializer(
844 const ExpressionClassifier* classifier, bool* ok) {
845 if (!classifier->is_valid_formal_parameter_initializer()) {
846 ReportClassifierError(classifier->formal_parameter_initializer_error());
847 *ok = false;
848 }
849 }
850
851 void ValidateBindingPattern(const ExpressionClassifier* classifier,
852 bool* ok) {
Ben Murdochc5610432016-08-08 18:44:38 +0100853 if (!classifier->is_valid_binding_pattern() ||
854 !classifier->is_valid_async_binding_pattern()) {
855 const Scanner::Location& a = classifier->binding_pattern_error().location;
856 const Scanner::Location& b =
857 classifier->async_binding_pattern_error().location;
858 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
859 ReportClassifierError(classifier->async_binding_pattern_error());
860 } else {
861 ReportClassifierError(classifier->binding_pattern_error());
862 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000863 *ok = false;
864 }
865 }
866
867 void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
868 bool* ok) {
869 if (!classifier->is_valid_assignment_pattern()) {
870 ReportClassifierError(classifier->assignment_pattern_error());
871 *ok = false;
872 }
873 }
874
875 void ValidateFormalParameters(const ExpressionClassifier* classifier,
876 LanguageMode language_mode,
877 bool allow_duplicates, bool* ok) {
878 if (!allow_duplicates &&
879 !classifier->is_valid_formal_parameter_list_without_duplicates()) {
880 ReportClassifierError(classifier->duplicate_formal_parameter_error());
881 *ok = false;
882 } else if (is_strict(language_mode) &&
883 !classifier->is_valid_strict_mode_formal_parameters()) {
884 ReportClassifierError(classifier->strict_mode_formal_parameter_error());
885 *ok = false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000886 }
887 }
888
Ben Murdoch61f157c2016-09-16 13:49:30 +0100889 bool IsValidArrowFormalParametersStart(Token::Value token) {
890 return is_any_identifier(token) || token == Token::LPAREN;
891 }
892
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000893 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
894 ExpressionT expr,
Ben Murdochc5610432016-08-08 18:44:38 +0100895 bool parenthesized_formals, bool is_async,
896 bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000897 if (classifier->is_valid_binding_pattern()) {
898 // A simple arrow formal parameter: IDENTIFIER => BODY.
899 if (!this->IsIdentifier(expr)) {
900 Traits::ReportMessageAt(scanner()->location(),
901 MessageTemplate::kUnexpectedToken,
902 Token::String(scanner()->current_token()));
903 *ok = false;
904 }
905 } else if (!classifier->is_valid_arrow_formal_parameters()) {
906 // If after parsing the expr, we see an error but the expression is
907 // neither a valid binding pattern nor a valid parenthesized formal
908 // parameter list, show the "arrow formal parameters" error if the formals
909 // started with a parenthesis, and the binding pattern error otherwise.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100910 const typename ExpressionClassifier::Error& error =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000911 parenthesized_formals ? classifier->arrow_formal_parameters_error()
912 : classifier->binding_pattern_error();
913 ReportClassifierError(error);
914 *ok = false;
915 }
Ben Murdochc5610432016-08-08 18:44:38 +0100916 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) {
917 const typename ExpressionClassifier::Error& error =
918 classifier->async_arrow_formal_parameters_error();
919 ReportClassifierError(error);
920 *ok = false;
921 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000922 }
923
924 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) {
925 if (!classifier->is_valid_let_pattern()) {
926 ReportClassifierError(classifier->let_pattern_error());
927 *ok = false;
928 }
929 }
930
Ben Murdochc5610432016-08-08 18:44:38 +0100931 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier,
932 bool* ok) {
933 if (FLAG_harmony_explicit_tailcalls &&
934 classifier->has_tail_call_expression()) {
935 ReportClassifierError(classifier->tail_call_expression_error());
936 *ok = false;
937 }
938 }
939
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000940 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
941 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
942 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100943 Scanner::Location location = scanner()->peek_location();
944 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
945 classifier->RecordExpressionError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000946 }
947
948 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
949 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
950 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100951 Scanner::Location location = scanner()->peek_location();
952 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
953 classifier->RecordBindingPatternError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000954 }
955
956 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
957 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
958 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100959 Scanner::Location location = scanner()->peek_location();
960 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
961 classifier->RecordArrowFormalParametersError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000962 }
963
964 // Recursive descent functions:
965
966 // Parses an identifier that is valid for the current scope, in particular it
967 // fails on strict mode future reserved keywords in a strict scope. If
968 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
969 // "arguments" as identifier even in strict mode (this is needed in cases like
970 // "var foo = eval;").
971 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
972 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
973 bool* ok);
974 // Parses an identifier or a strict mode future reserved word, and indicate
975 // whether it is strict mode future reserved. Allows passing in is_generator
976 // for the case of parsing the identifier in a function expression, where the
977 // relevant "is_generator" bit is of the function being parsed, not the
978 // containing
979 // function.
980 IdentifierT ParseIdentifierOrStrictReservedWord(bool is_generator,
981 bool* is_strict_reserved,
982 bool* ok);
983 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
984 bool* ok) {
985 return ParseIdentifierOrStrictReservedWord(this->is_generator(),
986 is_strict_reserved, ok);
987 }
988
989 IdentifierT ParseIdentifierName(bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000990
991 ExpressionT ParseRegExpLiteral(bool seen_equal,
992 ExpressionClassifier* classifier, bool* ok);
993
994 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
Ben Murdochc5610432016-08-08 18:44:38 +0100995 bool* is_async, bool* ok);
996 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
997 bool* ok) {
998 bool is_async;
999 return ParsePrimaryExpression(classifier, &is_async, ok);
1000 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001001 ExpressionT ParseExpression(bool accept_IN, bool* ok);
1002 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
1003 bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001004 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
1005 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
Ben Murdochc5610432016-08-08 18:44:38 +01001006 bool* is_await, bool* is_computed_name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001007 ExpressionClassifier* classifier, bool* ok);
1008 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
1009 ObjectLiteralPropertyT ParsePropertyDefinition(
1010 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
Ben Murdochc5610432016-08-08 18:44:38 +01001011 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001012 ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
1013 typename Traits::Type::ExpressionList ParseArguments(
Ben Murdochc5610432016-08-08 18:44:38 +01001014 Scanner::Location* first_spread_pos, bool maybe_arrow,
1015 ExpressionClassifier* classifier, bool* ok);
1016 typename Traits::Type::ExpressionList ParseArguments(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001017 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
Ben Murdochc5610432016-08-08 18:44:38 +01001018 bool* ok) {
1019 return ParseArguments(first_spread_pos, false, classifier, ok);
1020 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001021
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001022 ExpressionT ParseAssignmentExpression(bool accept_IN,
1023 ExpressionClassifier* classifier,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001024 bool* ok);
Ben Murdochc5610432016-08-08 18:44:38 +01001025 ExpressionT ParseYieldExpression(bool accept_IN,
1026 ExpressionClassifier* classifier, bool* ok);
1027 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier,
1028 bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001029 ExpressionT ParseConditionalExpression(bool accept_IN,
1030 ExpressionClassifier* classifier,
1031 bool* ok);
1032 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
1033 ExpressionClassifier* classifier, bool* ok);
1034 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
1035 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
1036 bool* ok);
1037 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
1038 bool* ok);
1039 ExpressionT ParseMemberWithNewPrefixesExpression(
Ben Murdochc5610432016-08-08 18:44:38 +01001040 ExpressionClassifier* classifier, bool* is_async, bool* ok);
1041 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier,
1042 bool* is_async, bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001043 ExpressionT ParseMemberExpressionContinuation(
Ben Murdochc5610432016-08-08 18:44:38 +01001044 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
1045 bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001046 ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
1047 const FormalParametersT& parameters,
Ben Murdochc5610432016-08-08 18:44:38 +01001048 bool is_async,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001049 const ExpressionClassifier& classifier,
1050 bool* ok);
1051 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
1052 ExpressionClassifier* classifier, bool* ok);
1053 void AddTemplateExpression(ExpressionT);
1054 ExpressionT ParseSuperExpression(bool is_new,
1055 ExpressionClassifier* classifier, bool* ok);
1056 ExpressionT ParseNewTargetExpression(bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001057
1058 void ParseFormalParameter(FormalParametersT* parameters,
1059 ExpressionClassifier* classifier, bool* ok);
1060 void ParseFormalParameterList(FormalParametersT* parameters,
1061 ExpressionClassifier* classifier, bool* ok);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001062 void CheckArityRestrictions(int param_count, FunctionKind function_type,
1063 bool has_rest, int formals_start_pos,
1064 int formals_end_pos, bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001065
1066 bool IsNextLetKeyword();
1067
1068 // Checks if the expression is a valid reference expression (e.g., on the
1069 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1070 // we allow calls for web compatibility and rewrite them to a runtime throw.
1071 ExpressionT CheckAndRewriteReferenceExpression(
1072 ExpressionT expression, int beg_pos, int end_pos,
1073 MessageTemplate::Template message, bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001074 ExpressionT CheckAndRewriteReferenceExpression(
1075 ExpressionT expression, int beg_pos, int end_pos,
1076 MessageTemplate::Template message, ParseErrorType type, bool* ok);
1077
1078 bool IsValidReferenceExpression(ExpressionT expression);
1079
1080 bool IsAssignableIdentifier(ExpressionT expression) {
1081 if (!Traits::IsIdentifier(expression)) return false;
1082 if (is_strict(language_mode()) &&
1083 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
1084 return false;
1085 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001086 return true;
1087 }
1088
Ben Murdoch097c5b22016-05-18 11:27:45 +01001089 bool IsValidPattern(ExpressionT expression) {
1090 return expression->IsObjectLiteral() || expression->IsArrayLiteral();
1091 }
1092
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001093 // Keep track of eval() calls since they disable all local variable
1094 // optimizations. This checks if expression is an eval call, and if yes,
1095 // forwards the information to scope.
1096 void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) {
1097 if (Traits::IsIdentifier(expression) &&
1098 Traits::IsEval(Traits::AsIdentifier(expression))) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001099 scope->RecordEvalCall();
Ben Murdochda12d292016-06-02 14:46:10 +01001100 if (is_sloppy(scope->language_mode())) {
1101 // For sloppy scopes we also have to record the call at function level,
1102 // in case it includes declarations that will be hoisted.
1103 scope->DeclarationScope()->RecordEvalCall();
1104 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001105 }
1106 }
1107
1108 // Used to validate property names in object literals and class literals
1109 enum PropertyKind {
1110 kAccessorProperty,
1111 kValueProperty,
1112 kMethodProperty
1113 };
1114
1115 class ObjectLiteralCheckerBase {
1116 public:
1117 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
1118
1119 virtual void CheckProperty(Token::Value property, PropertyKind type,
Ben Murdochc5610432016-08-08 18:44:38 +01001120 MethodKind method_type, bool* ok) = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001121
1122 virtual ~ObjectLiteralCheckerBase() {}
1123
1124 protected:
1125 ParserBase* parser() const { return parser_; }
1126 Scanner* scanner() const { return parser_->scanner(); }
1127
1128 private:
1129 ParserBase* parser_;
1130 };
1131
1132 // Validation per ES6 object literals.
1133 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
1134 public:
1135 explicit ObjectLiteralChecker(ParserBase* parser)
1136 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
1137
Ben Murdochc5610432016-08-08 18:44:38 +01001138 void CheckProperty(Token::Value property, PropertyKind type,
1139 MethodKind method_type, bool* ok) override;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001140
1141 private:
1142 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
1143
1144 bool has_seen_proto_;
1145 };
1146
1147 // Validation per ES6 class literals.
1148 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
1149 public:
1150 explicit ClassLiteralChecker(ParserBase* parser)
1151 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
1152
Ben Murdochc5610432016-08-08 18:44:38 +01001153 void CheckProperty(Token::Value property, PropertyKind type,
1154 MethodKind method_type, bool* ok) override;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001155
1156 private:
1157 bool IsConstructor() {
1158 return this->scanner()->LiteralMatches("constructor", 11);
1159 }
1160 bool IsPrototype() {
1161 return this->scanner()->LiteralMatches("prototype", 9);
1162 }
1163
1164 bool has_seen_constructor_;
1165 };
1166
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001167 Scope* scope_; // Scope stack.
1168 FunctionState* function_state_; // Function state stack.
1169 v8::Extension* extension_;
1170 FuncNameInferrer* fni_;
1171 AstValueFactory* ast_value_factory_; // Not owned.
1172 ParserRecorder* log_;
1173 Mode mode_;
Ben Murdochc5610432016-08-08 18:44:38 +01001174 bool parsing_module_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001175 uintptr_t stack_limit_;
1176
1177 private:
1178 Zone* zone_;
1179
1180 Scanner* scanner_;
1181 bool stack_overflow_;
1182
1183 bool allow_lazy_;
1184 bool allow_natives_;
Ben Murdochda12d292016-06-02 14:46:10 +01001185 bool allow_tailcalls_;
Ben Murdochda12d292016-06-02 14:46:10 +01001186 bool allow_harmony_restrictive_declarations_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001187 bool allow_harmony_do_expressions_;
Ben Murdochc5610432016-08-08 18:44:38 +01001188 bool allow_harmony_for_in_;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001189 bool allow_harmony_function_sent_;
Ben Murdochc5610432016-08-08 18:44:38 +01001190 bool allow_harmony_async_await_;
Ben Murdoch61f157c2016-09-16 13:49:30 +01001191 bool allow_harmony_restrictive_generators_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001192};
1193
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001194template <class Traits>
1195ParserBase<Traits>::FunctionState::FunctionState(
1196 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1197 FunctionKind kind, typename Traits::Type::Factory* factory)
1198 : next_materialized_literal_index_(0),
1199 expected_property_count_(0),
1200 this_location_(Scanner::Location::invalid()),
1201 return_location_(Scanner::Location::invalid()),
1202 super_location_(Scanner::Location::invalid()),
1203 kind_(kind),
1204 generator_object_variable_(NULL),
1205 function_state_stack_(function_state_stack),
1206 outer_function_state_(*function_state_stack),
1207 scope_stack_(scope_stack),
1208 outer_scope_(*scope_stack),
Ben Murdoch61f157c2016-09-16 13:49:30 +01001209 destructuring_assignments_to_rewrite_(16, scope->zone()),
Ben Murdochc5610432016-08-08 18:44:38 +01001210 tail_call_expressions_(scope->zone()),
1211 return_expr_context_(ReturnExprContext::kInsideValidBlock),
Ben Murdoch097c5b22016-05-18 11:27:45 +01001212 non_patterns_to_rewrite_(0, scope->zone()),
Ben Murdoch61f157c2016-09-16 13:49:30 +01001213 reported_errors_(16, scope->zone()),
Ben Murdochc5610432016-08-08 18:44:38 +01001214 factory_(factory),
1215 next_function_is_parenthesized_(false),
1216 this_function_is_parenthesized_(false) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001217 *scope_stack_ = scope;
1218 *function_state_stack = this;
Ben Murdochc5610432016-08-08 18:44:38 +01001219 if (outer_function_state_) {
1220 this_function_is_parenthesized_ =
1221 outer_function_state_->next_function_is_parenthesized_;
1222 outer_function_state_->next_function_is_parenthesized_ = false;
1223 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224}
1225
1226
1227template <class Traits>
1228ParserBase<Traits>::FunctionState::~FunctionState() {
1229 *scope_stack_ = outer_scope_;
1230 *function_state_stack_ = outer_function_state_;
1231}
1232
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001233template <class Traits>
1234void ParserBase<Traits>::GetUnexpectedTokenMessage(
Ben Murdochda12d292016-06-02 14:46:10 +01001235 Token::Value token, MessageTemplate::Template* message,
1236 Scanner::Location* location, const char** arg,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001237 MessageTemplate::Template default_) {
Ben Murdochda12d292016-06-02 14:46:10 +01001238 *arg = nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001239 switch (token) {
1240 case Token::EOS:
1241 *message = MessageTemplate::kUnexpectedEOS;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001242 break;
1243 case Token::SMI:
1244 case Token::NUMBER:
1245 *message = MessageTemplate::kUnexpectedTokenNumber;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001246 break;
1247 case Token::STRING:
1248 *message = MessageTemplate::kUnexpectedTokenString;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001249 break;
1250 case Token::IDENTIFIER:
1251 *message = MessageTemplate::kUnexpectedTokenIdentifier;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001252 break;
Ben Murdochc5610432016-08-08 18:44:38 +01001253 case Token::AWAIT:
1254 case Token::ENUM:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001255 *message = MessageTemplate::kUnexpectedReserved;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001256 break;
1257 case Token::LET:
1258 case Token::STATIC:
1259 case Token::YIELD:
1260 case Token::FUTURE_STRICT_RESERVED_WORD:
1261 *message = is_strict(language_mode())
1262 ? MessageTemplate::kUnexpectedStrictReserved
1263 : MessageTemplate::kUnexpectedTokenIdentifier;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001264 break;
1265 case Token::TEMPLATE_SPAN:
1266 case Token::TEMPLATE_TAIL:
1267 *message = MessageTemplate::kUnexpectedTemplateString;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001268 break;
1269 case Token::ESCAPED_STRICT_RESERVED_WORD:
1270 case Token::ESCAPED_KEYWORD:
1271 *message = MessageTemplate::kInvalidEscapedReservedWord;
Ben Murdochda12d292016-06-02 14:46:10 +01001272 break;
1273 case Token::ILLEGAL:
1274 if (scanner()->has_error()) {
1275 *message = scanner()->error();
1276 *location = scanner()->error_location();
1277 } else {
1278 *message = MessageTemplate::kInvalidOrUnexpectedToken;
1279 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001280 break;
1281 default:
1282 const char* name = Token::String(token);
1283 DCHECK(name != NULL);
1284 *arg = name;
1285 break;
1286 }
1287}
1288
1289
1290template <class Traits>
1291void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1292 return ReportUnexpectedTokenAt(scanner_->location(), token);
1293}
1294
1295
1296template <class Traits>
1297void ParserBase<Traits>::ReportUnexpectedTokenAt(
1298 Scanner::Location source_location, Token::Value token,
1299 MessageTemplate::Template message) {
1300 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +01001301 GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001302 Traits::ReportMessageAt(source_location, message, arg);
1303}
1304
1305
1306template <class Traits>
1307typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1308 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001309 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001310 auto result = ParseAndClassifyIdentifier(&classifier, ok);
1311 if (!*ok) return Traits::EmptyIdentifier();
1312
1313 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1314 ValidateAssignmentPattern(&classifier, ok);
1315 if (!*ok) return Traits::EmptyIdentifier();
1316 ValidateBindingPattern(&classifier, ok);
1317 if (!*ok) return Traits::EmptyIdentifier();
1318 }
1319
1320 return result;
1321}
1322
1323
1324template <class Traits>
1325typename ParserBase<Traits>::IdentifierT
1326ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1327 bool* ok) {
1328 Token::Value next = Next();
Ben Murdochc5610432016-08-08 18:44:38 +01001329 if (next == Token::IDENTIFIER || next == Token::ASYNC ||
1330 (next == Token::AWAIT && !parsing_module_)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001331 IdentifierT name = this->GetSymbol(scanner());
1332 // When this function is used to read a formal parameter, we don't always
1333 // know whether the function is going to be strict or sloppy. Indeed for
1334 // arrow functions we don't always know that the identifier we are reading
1335 // is actually a formal parameter. Therefore besides the errors that we
1336 // must detect because we know we're in strict mode, we also record any
1337 // error that we might make in the future once we know the language mode.
1338 if (this->IsEval(name)) {
1339 classifier->RecordStrictModeFormalParameterError(
1340 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1341 if (is_strict(language_mode())) {
1342 classifier->RecordBindingPatternError(
1343 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1344 }
1345 }
1346 if (this->IsArguments(name)) {
1347 scope_->RecordArgumentsUsage();
1348 classifier->RecordStrictModeFormalParameterError(
1349 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1350 if (is_strict(language_mode())) {
1351 classifier->RecordBindingPatternError(
1352 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1353 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001354 }
Ben Murdochc5610432016-08-08 18:44:38 +01001355 if (this->IsAwait(name)) {
1356 if (is_async_function()) {
1357 classifier->RecordPatternError(
1358 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1359 }
1360 classifier->RecordAsyncArrowFormalParametersError(
1361 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1362 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001363
1364 if (classifier->duplicate_finder() != nullptr &&
1365 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1366 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1367 }
1368 return name;
1369 } else if (is_sloppy(language_mode()) &&
1370 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1371 next == Token::ESCAPED_STRICT_RESERVED_WORD ||
1372 next == Token::LET || next == Token::STATIC ||
1373 (next == Token::YIELD && !is_generator()))) {
1374 classifier->RecordStrictModeFormalParameterError(
1375 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1376 if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1377 is_strict(language_mode())) {
1378 ReportUnexpectedToken(next);
1379 *ok = false;
1380 return Traits::EmptyIdentifier();
1381 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001382 if (next == Token::LET ||
1383 (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1384 scanner()->is_literal_contextual_keyword(CStrVector("let")))) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001385 classifier->RecordLetPatternError(scanner()->location(),
1386 MessageTemplate::kLetInLexicalBinding);
1387 }
1388 return this->GetSymbol(scanner());
1389 } else {
1390 this->ReportUnexpectedToken(next);
1391 *ok = false;
1392 return Traits::EmptyIdentifier();
1393 }
1394}
1395
1396
1397template <class Traits>
1398typename ParserBase<Traits>::IdentifierT
1399ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
1400 bool is_generator, bool* is_strict_reserved, bool* ok) {
1401 Token::Value next = Next();
Ben Murdochc5610432016-08-08 18:44:38 +01001402 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_) ||
1403 next == Token::ASYNC) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001404 *is_strict_reserved = false;
1405 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1406 next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
1407 *is_strict_reserved = true;
1408 } else {
1409 ReportUnexpectedToken(next);
1410 *ok = false;
1411 return Traits::EmptyIdentifier();
1412 }
1413
1414 IdentifierT name = this->GetSymbol(scanner());
1415 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1416 return name;
1417}
1418
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001419template <class Traits>
1420typename ParserBase<Traits>::IdentifierT
1421ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1422 Token::Value next = Next();
Ben Murdochc5610432016-08-08 18:44:38 +01001423 if (next != Token::IDENTIFIER && next != Token::ASYNC &&
1424 next != Token::ENUM && next != Token::AWAIT && next != Token::LET &&
1425 next != Token::STATIC && next != Token::YIELD &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001426 next != Token::FUTURE_STRICT_RESERVED_WORD &&
1427 next != Token::ESCAPED_KEYWORD &&
1428 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1429 this->ReportUnexpectedToken(next);
1430 *ok = false;
1431 return Traits::EmptyIdentifier();
1432 }
1433
1434 IdentifierT name = this->GetSymbol(scanner());
1435 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1436 return name;
1437}
1438
1439
1440template <class Traits>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001441typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1442 bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
1443 int pos = peek_position();
1444 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1445 Next();
1446 ReportMessage(MessageTemplate::kUnterminatedRegExp);
1447 *ok = false;
1448 return Traits::EmptyExpression();
1449 }
1450
1451 int literal_index = function_state_->NextMaterializedLiteralIndex();
1452
1453 IdentifierT js_pattern = this->GetNextSymbol(scanner());
1454 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
1455 if (flags.IsNothing()) {
1456 Next();
1457 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1458 *ok = false;
1459 return Traits::EmptyExpression();
1460 }
1461 int js_flags = flags.FromJust();
1462 Next();
Ben Murdochda12d292016-06-02 14:46:10 +01001463 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001464}
1465
1466
1467#define CHECK_OK ok); \
1468 if (!*ok) return this->EmptyExpression(); \
1469 ((void)0
1470#define DUMMY ) // to make indentation work
1471#undef DUMMY
1472
1473// Used in functions where the return type is not ExpressionT.
1474#define CHECK_OK_CUSTOM(x) ok); \
1475 if (!*ok) return this->x(); \
1476 ((void)0
1477#define DUMMY ) // to make indentation work
1478#undef DUMMY
1479
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001480template <class Traits>
1481typename ParserBase<Traits>::ExpressionT
1482ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
Ben Murdochc5610432016-08-08 18:44:38 +01001483 bool* is_async, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001484 // PrimaryExpression ::
1485 // 'this'
1486 // 'null'
1487 // 'true'
1488 // 'false'
1489 // Identifier
1490 // Number
1491 // String
1492 // ArrayLiteral
1493 // ObjectLiteral
1494 // RegExpLiteral
1495 // ClassLiteral
1496 // '(' Expression ')'
1497 // TemplateLiteral
1498 // do Block
Ben Murdochc5610432016-08-08 18:44:38 +01001499 // AsyncFunctionExpression
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001500
1501 int beg_pos = peek_position();
1502 switch (peek()) {
1503 case Token::THIS: {
1504 BindingPatternUnexpectedToken(classifier);
1505 Consume(Token::THIS);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001506 return this->ThisExpression(scope_, factory(), beg_pos);
1507 }
1508
1509 case Token::NULL_LITERAL:
1510 case Token::TRUE_LITERAL:
1511 case Token::FALSE_LITERAL:
1512 BindingPatternUnexpectedToken(classifier);
1513 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1514 case Token::SMI:
1515 case Token::NUMBER:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001516 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001517 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1518
Ben Murdochc5610432016-08-08 18:44:38 +01001519 case Token::ASYNC:
1520 if (allow_harmony_async_await() &&
1521 !scanner()->HasAnyLineTerminatorAfterNext() &&
1522 PeekAhead() == Token::FUNCTION) {
1523 Consume(Token::ASYNC);
1524 return this->ParseAsyncFunctionExpression(CHECK_OK);
1525 }
1526 // CoverCallExpressionAndAsyncArrowHead
1527 *is_async = true;
1528 /* falls through */
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001529 case Token::IDENTIFIER:
1530 case Token::LET:
1531 case Token::STATIC:
1532 case Token::YIELD:
Ben Murdochc5610432016-08-08 18:44:38 +01001533 case Token::AWAIT:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001534 case Token::ESCAPED_STRICT_RESERVED_WORD:
1535 case Token::FUTURE_STRICT_RESERVED_WORD: {
1536 // Using eval or arguments in this context is OK even in strict mode.
1537 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
1538 return this->ExpressionFromIdentifier(
1539 name, beg_pos, scanner()->location().end_pos, scope_, factory());
1540 }
1541
1542 case Token::STRING: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001543 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001544 Consume(Token::STRING);
1545 return this->ExpressionFromString(beg_pos, scanner(), factory());
1546 }
1547
1548 case Token::ASSIGN_DIV:
1549 classifier->RecordBindingPatternError(
1550 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1551 return this->ParseRegExpLiteral(true, classifier, ok);
1552
1553 case Token::DIV:
1554 classifier->RecordBindingPatternError(
1555 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1556 return this->ParseRegExpLiteral(false, classifier, ok);
1557
1558 case Token::LBRACK:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001559 return this->ParseArrayLiteral(classifier, ok);
1560
1561 case Token::LBRACE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001562 return this->ParseObjectLiteral(classifier, ok);
1563
1564 case Token::LPAREN: {
1565 // Arrow function formal parameters are either a single identifier or a
1566 // list of BindingPattern productions enclosed in parentheses.
1567 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
1568 // is_valid_binding_pattern() check to detect multiple levels of
1569 // parenthesization.
Ben Murdoch61f157c2016-09-16 13:49:30 +01001570 bool pattern_error = !classifier->is_valid_binding_pattern();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001571 classifier->RecordPatternError(scanner()->peek_location(),
1572 MessageTemplate::kUnexpectedToken,
1573 Token::String(Token::LPAREN));
Ben Murdoch61f157c2016-09-16 13:49:30 +01001574 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001575 Consume(Token::LPAREN);
1576 if (Check(Token::RPAREN)) {
1577 // ()=>x. The continuation that looks for the => is in
1578 // ParseAssignmentExpression.
1579 classifier->RecordExpressionError(scanner()->location(),
1580 MessageTemplate::kUnexpectedToken,
1581 Token::String(Token::RPAREN));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001582 return factory()->NewEmptyParentheses(beg_pos);
1583 } else if (Check(Token::ELLIPSIS)) {
1584 // (...x)=>x. The continuation that looks for the => is in
1585 // ParseAssignmentExpression.
1586 int ellipsis_pos = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001587 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001588 classifier->RecordExpressionError(scanner()->location(),
1589 MessageTemplate::kUnexpectedToken,
1590 Token::String(Token::ELLIPSIS));
1591 classifier->RecordNonSimpleParameter();
Ben Murdoch61f157c2016-09-16 13:49:30 +01001592 ExpressionClassifier binding_classifier(this);
1593 ExpressionT expr = this->ParseAssignmentExpression(
1594 true, &binding_classifier, CHECK_OK);
1595 classifier->Accumulate(&binding_classifier,
1596 ExpressionClassifier::AllProductions);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001597 if (!this->IsIdentifier(expr) && !IsValidPattern(expr)) {
1598 classifier->RecordArrowFormalParametersError(
1599 Scanner::Location(ellipsis_pos, scanner()->location().end_pos),
1600 MessageTemplate::kInvalidRestParameter);
1601 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001602 if (peek() == Token::COMMA) {
1603 ReportMessageAt(scanner()->peek_location(),
1604 MessageTemplate::kParamAfterRest);
1605 *ok = false;
1606 return this->EmptyExpression();
1607 }
1608 Expect(Token::RPAREN, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001609 return factory()->NewSpread(expr, ellipsis_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001610 }
1611 // Heuristically try to detect immediately called functions before
1612 // seeing the call parentheses.
Ben Murdochc5610432016-08-08 18:44:38 +01001613 function_state_->next_function_is_parenthesized(peek() ==
1614 Token::FUNCTION);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001615 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001616 Expect(Token::RPAREN, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001617 return expr;
1618 }
1619
1620 case Token::CLASS: {
1621 BindingPatternUnexpectedToken(classifier);
1622 Consume(Token::CLASS);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001623 int class_token_position = position();
1624 IdentifierT name = this->EmptyIdentifier();
1625 bool is_strict_reserved_name = false;
1626 Scanner::Location class_name_location = Scanner::Location::invalid();
1627 if (peek_any_identifier()) {
1628 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1629 CHECK_OK);
1630 class_name_location = scanner()->location();
1631 }
Ben Murdochda12d292016-06-02 14:46:10 +01001632 return this->ParseClassLiteral(classifier, name, class_name_location,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001633 is_strict_reserved_name,
1634 class_token_position, ok);
1635 }
1636
1637 case Token::TEMPLATE_SPAN:
1638 case Token::TEMPLATE_TAIL:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001639 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001640 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
1641 classifier, ok);
1642
1643 case Token::MOD:
1644 if (allow_natives() || extension_ != NULL) {
1645 BindingPatternUnexpectedToken(classifier);
1646 return this->ParseV8Intrinsic(ok);
1647 }
1648 break;
1649
1650 case Token::DO:
1651 if (allow_harmony_do_expressions()) {
1652 BindingPatternUnexpectedToken(classifier);
1653 return Traits::ParseDoExpression(ok);
1654 }
1655 break;
1656
1657 default:
1658 break;
1659 }
1660
1661 ReportUnexpectedToken(Next());
1662 *ok = false;
1663 return this->EmptyExpression();
1664}
1665
1666
1667template <class Traits>
1668typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1669 bool accept_IN, bool* ok) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001670 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001671 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001672 Traits::RewriteNonPattern(&classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001673 return result;
1674}
1675
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001676template <class Traits>
1677typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1678 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001679 // Expression ::
1680 // AssignmentExpression
1681 // Expression ',' AssignmentExpression
1682
Ben Murdoch61f157c2016-09-16 13:49:30 +01001683 ExpressionT result = this->EmptyExpression();
1684 {
1685 ExpressionClassifier binding_classifier(this);
1686 result = this->ParseAssignmentExpression(accept_IN, &binding_classifier,
1687 CHECK_OK);
1688 classifier->Accumulate(&binding_classifier,
1689 ExpressionClassifier::AllProductions);
1690 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001691 bool is_simple_parameter_list = this->IsIdentifier(result);
1692 bool seen_rest = false;
1693 while (peek() == Token::COMMA) {
Ben Murdochc5610432016-08-08 18:44:38 +01001694 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001695 if (seen_rest) {
1696 // At this point the production can't possibly be valid, but we don't know
1697 // which error to signal.
1698 classifier->RecordArrowFormalParametersError(
1699 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
1700 }
1701 Consume(Token::COMMA);
1702 bool is_rest = false;
1703 if (peek() == Token::ELLIPSIS) {
1704 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1705 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1706 // valid expression or binding pattern.
1707 ExpressionUnexpectedToken(classifier);
1708 BindingPatternUnexpectedToken(classifier);
1709 Consume(Token::ELLIPSIS);
1710 seen_rest = is_rest = true;
1711 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001712 int pos = position(), expr_pos = peek_position();
Ben Murdoch61f157c2016-09-16 13:49:30 +01001713 ExpressionClassifier binding_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001714 ExpressionT right = this->ParseAssignmentExpression(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001715 accept_IN, &binding_classifier, CHECK_OK);
1716 classifier->Accumulate(&binding_classifier,
1717 ExpressionClassifier::AllProductions);
1718 if (is_rest) {
1719 if (!this->IsIdentifier(right) && !IsValidPattern(right)) {
1720 classifier->RecordArrowFormalParametersError(
1721 Scanner::Location(pos, scanner()->location().end_pos),
1722 MessageTemplate::kInvalidRestParameter);
1723 }
1724 right = factory()->NewSpread(right, pos, expr_pos);
1725 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001726 is_simple_parameter_list =
1727 is_simple_parameter_list && this->IsIdentifier(right);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001728 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1729 }
1730 if (!is_simple_parameter_list || seen_rest) {
1731 classifier->RecordNonSimpleParameter();
1732 }
1733
1734 return result;
1735}
1736
1737
1738template <class Traits>
1739typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
1740 ExpressionClassifier* classifier, bool* ok) {
1741 // ArrayLiteral ::
1742 // '[' Expression? (',' Expression?)* ']'
1743
1744 int pos = peek_position();
1745 typename Traits::Type::ExpressionList values =
1746 this->NewExpressionList(4, zone_);
1747 int first_spread_index = -1;
1748 Expect(Token::LBRACK, CHECK_OK);
1749 while (peek() != Token::RBRACK) {
1750 ExpressionT elem = this->EmptyExpression();
1751 if (peek() == Token::COMMA) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001752 elem = this->GetLiteralTheHole(peek_position(), factory());
1753 } else if (peek() == Token::ELLIPSIS) {
1754 int start_pos = peek_position();
1755 Consume(Token::ELLIPSIS);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001756 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001757 ExpressionT argument =
1758 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01001759 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001760 elem = factory()->NewSpread(argument, start_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001761
1762 if (first_spread_index < 0) {
1763 first_spread_index = values->length();
1764 }
1765
1766 if (argument->IsAssignment()) {
1767 classifier->RecordPatternError(
1768 Scanner::Location(start_pos, scanner()->location().end_pos),
1769 MessageTemplate::kInvalidDestructuringTarget);
1770 } else {
1771 CheckDestructuringElement(argument, classifier, start_pos,
1772 scanner()->location().end_pos);
1773 }
1774
1775 if (peek() == Token::COMMA) {
1776 classifier->RecordPatternError(
1777 Scanner::Location(start_pos, scanner()->location().end_pos),
1778 MessageTemplate::kElementAfterRest);
1779 }
1780 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001781 int beg_pos = peek_position();
1782 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01001783 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001784 CheckDestructuringElement(elem, classifier, beg_pos,
1785 scanner()->location().end_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001786 }
1787 values->Add(elem, zone_);
1788 if (peek() != Token::RBRACK) {
1789 Expect(Token::COMMA, CHECK_OK);
1790 }
1791 }
1792 Expect(Token::RBRACK, CHECK_OK);
1793
1794 // Update the scope information before the pre-parsing bailout.
1795 int literal_index = function_state_->NextMaterializedLiteralIndex();
1796
Ben Murdochda12d292016-06-02 14:46:10 +01001797 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index,
1798 literal_index, pos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001799 if (first_spread_index >= 0) {
1800 result = factory()->NewRewritableExpression(result);
Ben Murdoch61f157c2016-09-16 13:49:30 +01001801 Traits::QueueNonPatternForRewriting(result, ok);
1802 if (!*ok) {
1803 // If the non-pattern rewriting mechanism is used in the future for
1804 // rewriting other things than spreads, this error message will have
1805 // to change. Also, this error message will never appear while pre-
1806 // parsing (this is OK, as it is an implementation limitation).
1807 ReportMessage(MessageTemplate::kTooManySpreads);
1808 return this->EmptyExpression();
1809 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001810 }
1811 return result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001812}
1813
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001814template <class Traits>
1815typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
Ben Murdochc5610432016-08-08 18:44:38 +01001816 IdentifierT* name, bool* is_get, bool* is_set, bool* is_await,
1817 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001818 Token::Value token = peek();
1819 int pos = peek_position();
1820
1821 // For non computed property names we normalize the name a bit:
1822 //
1823 // "12" -> 12
1824 // 12.3 -> "12.3"
1825 // 12.30 -> "12.3"
1826 // identifier -> "identifier"
1827 //
1828 // This is important because we use the property name as a key in a hash
1829 // table when we compute constant properties.
1830 switch (token) {
1831 case Token::STRING:
1832 Consume(Token::STRING);
1833 *name = this->GetSymbol(scanner());
1834 break;
1835
1836 case Token::SMI:
1837 Consume(Token::SMI);
1838 *name = this->GetNumberAsSymbol(scanner());
1839 break;
1840
1841 case Token::NUMBER:
1842 Consume(Token::NUMBER);
1843 *name = this->GetNumberAsSymbol(scanner());
1844 break;
1845
1846 case Token::LBRACK: {
1847 *is_computed_name = true;
1848 Consume(Token::LBRACK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001849 ExpressionClassifier computed_name_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001850 ExpressionT expression =
1851 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001852 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK);
1853 classifier->Accumulate(&computed_name_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001854 ExpressionClassifier::ExpressionProductions);
1855 Expect(Token::RBRACK, CHECK_OK);
1856 return expression;
1857 }
1858
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001859 default:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001860 *name = ParseIdentifierName(CHECK_OK);
1861 scanner()->IsGetOrSet(is_get, is_set);
Ben Murdochc5610432016-08-08 18:44:38 +01001862 if (this->IsAwait(*name)) {
1863 *is_await = true;
1864 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001865 break;
1866 }
1867
1868 uint32_t index;
1869 return this->IsArrayIndex(*name, &index)
1870 ? factory()->NewNumberLiteral(index, pos)
1871 : factory()->NewStringLiteral(*name, pos);
1872}
1873
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001874template <class Traits>
1875typename ParserBase<Traits>::ObjectLiteralPropertyT
1876ParserBase<Traits>::ParsePropertyDefinition(
1877 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
Ben Murdochc5610432016-08-08 18:44:38 +01001878 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001879 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
Ben Murdochc5610432016-08-08 18:44:38 +01001880 DCHECK(!in_class || IsStaticMethod(method_kind) ||
1881 has_seen_constructor != nullptr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001882 ExpressionT value = this->EmptyExpression();
1883 bool is_get = false;
1884 bool is_set = false;
Ben Murdochc5610432016-08-08 18:44:38 +01001885 bool is_await = false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001886 bool is_generator = Check(Token::MUL);
Ben Murdochc5610432016-08-08 18:44:38 +01001887 bool is_async = false;
1888 const bool is_static = IsStaticMethod(method_kind);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001889
1890 Token::Value name_token = peek();
Ben Murdochc5610432016-08-08 18:44:38 +01001891
1892 if (is_generator) {
1893 method_kind |= MethodKind::Generator;
1894 } else if (allow_harmony_async_await() && name_token == Token::ASYNC &&
1895 !scanner()->HasAnyLineTerminatorAfterNext() &&
1896 PeekAhead() != Token::LPAREN && PeekAhead()) {
1897 is_async = true;
1898 }
1899
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001900 int next_beg_pos = scanner()->peek_location().beg_pos;
1901 int next_end_pos = scanner()->peek_location().end_pos;
Ben Murdochc5610432016-08-08 18:44:38 +01001902 ExpressionT name_expression = ParsePropertyName(
1903 name, &is_get, &is_set, &is_await, is_computed_name, classifier,
1904 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001905
1906 if (fni_ != nullptr && !*is_computed_name) {
1907 this->PushLiteralName(fni_, *name);
1908 }
1909
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001910 if (!in_class && !is_generator) {
Ben Murdochc5610432016-08-08 18:44:38 +01001911 DCHECK(!IsStaticMethod(method_kind));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001912
1913 if (peek() == Token::COLON) {
1914 // PropertyDefinition
1915 // PropertyName ':' AssignmentExpression
1916 if (!*is_computed_name) {
Ben Murdochc5610432016-08-08 18:44:38 +01001917 checker->CheckProperty(name_token, kValueProperty, MethodKind::Normal,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001918 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1919 }
1920 Consume(Token::COLON);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001921 int beg_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001922 value = this->ParseAssignmentExpression(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001923 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1924 CheckDestructuringElement(value, classifier, beg_pos,
1925 scanner()->location().end_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001926
Ben Murdochc5610432016-08-08 18:44:38 +01001927 return factory()->NewObjectLiteralProperty(name_expression, value,
1928 is_static, *is_computed_name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001929 }
1930
Ben Murdochc5610432016-08-08 18:44:38 +01001931 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(),
1932 parsing_module_) &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001933 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1934 peek() == Token::ASSIGN)) {
1935 // PropertyDefinition
1936 // IdentifierReference
1937 // CoverInitializedName
1938 //
1939 // CoverInitializedName
1940 // IdentifierReference Initializer?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001941 if (classifier->duplicate_finder() != nullptr &&
1942 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1943 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1944 }
1945 if (name_token == Token::LET) {
1946 classifier->RecordLetPatternError(
1947 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1948 }
Ben Murdoch61f157c2016-09-16 13:49:30 +01001949 if (is_await) {
1950 if (is_async_function()) {
1951 classifier->RecordPatternError(
1952 Scanner::Location(next_beg_pos, next_end_pos),
1953 MessageTemplate::kAwaitBindingIdentifier);
1954 } else {
1955 classifier->RecordAsyncArrowFormalParametersError(
1956 Scanner::Location(next_beg_pos, next_end_pos),
1957 MessageTemplate::kAwaitBindingIdentifier);
1958 }
Ben Murdochc5610432016-08-08 18:44:38 +01001959 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001960 ExpressionT lhs = this->ExpressionFromIdentifier(
1961 *name, next_beg_pos, next_end_pos, scope_, factory());
1962 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos);
1963
1964 if (peek() == Token::ASSIGN) {
1965 Consume(Token::ASSIGN);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001966 ExpressionClassifier rhs_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001967 ExpressionT rhs = this->ParseAssignmentExpression(
1968 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001969 Traits::RewriteNonPattern(&rhs_classifier,
1970 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1971 classifier->Accumulate(&rhs_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001972 ExpressionClassifier::ExpressionProductions);
1973 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
1974 RelocInfo::kNoPosition);
1975 classifier->RecordCoverInitializedNameError(
1976 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1977 MessageTemplate::kInvalidCoverInitializedName);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001978
Ben Murdoch61f157c2016-09-16 13:49:30 +01001979 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001980 } else {
1981 value = lhs;
1982 }
1983
1984 return factory()->NewObjectLiteralProperty(
Ben Murdochc5610432016-08-08 18:44:38 +01001985 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001986 false);
1987 }
1988 }
1989
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001990 // Method definitions are never valid in patterns.
1991 classifier->RecordPatternError(
1992 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1993 MessageTemplate::kInvalidDestructuringTarget);
1994
Ben Murdochc5610432016-08-08 18:44:38 +01001995 if (is_async && !IsSpecialMethod(method_kind)) {
1996 DCHECK(!is_get);
1997 DCHECK(!is_set);
1998 bool dont_care;
1999 name_expression = ParsePropertyName(
2000 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2001 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2002 method_kind |= MethodKind::Async;
2003 }
2004
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002005 if (is_generator || peek() == Token::LPAREN) {
2006 // MethodDefinition
2007 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2008 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2009 if (!*is_computed_name) {
Ben Murdochc5610432016-08-08 18:44:38 +01002010 checker->CheckProperty(name_token, kMethodProperty, method_kind,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002011 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2012 }
2013
Ben Murdochc5610432016-08-08 18:44:38 +01002014 FunctionKind kind = is_generator
2015 ? FunctionKind::kConciseGeneratorMethod
2016 : is_async ? FunctionKind::kAsyncConciseMethod
2017 : FunctionKind::kConciseMethod;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002018
Ben Murdochc5610432016-08-08 18:44:38 +01002019 if (in_class && !IsStaticMethod(method_kind) &&
2020 this->IsConstructor(*name)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002021 *has_seen_constructor = true;
2022 kind = has_extends ? FunctionKind::kSubclassConstructor
2023 : FunctionKind::kBaseConstructor;
2024 }
2025
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002026 value = this->ParseFunctionLiteral(
2027 *name, scanner()->location(), kSkipFunctionNameCheck, kind,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002028 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
2029 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002030
2031 return factory()->NewObjectLiteralProperty(name_expression, value,
2032 ObjectLiteralProperty::COMPUTED,
2033 is_static, *is_computed_name);
2034 }
2035
Ben Murdochc5610432016-08-08 18:44:38 +01002036 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002037 // ClassElement (static)
2038 // 'static' MethodDefinition
2039 *name = this->EmptyIdentifier();
2040 ObjectLiteralPropertyT property = ParsePropertyDefinition(
Ben Murdochc5610432016-08-08 18:44:38 +01002041 checker, true, has_extends, MethodKind::Static, is_computed_name,
2042 nullptr, classifier, name, ok);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002043 Traits::RewriteNonPattern(classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002044 return property;
2045 }
2046
2047 if (is_get || is_set) {
2048 // MethodDefinition (Accessors)
2049 // get PropertyName '(' ')' '{' FunctionBody '}'
2050 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2051 *name = this->EmptyIdentifier();
2052 bool dont_care = false;
2053 name_token = peek();
2054
2055 name_expression = ParsePropertyName(
Ben Murdochc5610432016-08-08 18:44:38 +01002056 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002057 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002058
2059 if (!*is_computed_name) {
Ben Murdochc5610432016-08-08 18:44:38 +01002060 checker->CheckProperty(name_token, kAccessorProperty, method_kind,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002061 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2062 }
2063
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002064 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002065 *name, scanner()->location(), kSkipFunctionNameCheck,
2066 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction,
2067 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002068 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2069
2070 // Make sure the name expression is a string since we need a Name for
2071 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2072 // statically we can skip the extra runtime check.
2073 if (!*is_computed_name) {
2074 name_expression =
2075 factory()->NewStringLiteral(*name, name_expression->position());
2076 }
2077
2078 return factory()->NewObjectLiteralProperty(
2079 name_expression, value,
2080 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2081 is_static, *is_computed_name);
2082 }
2083
2084 Token::Value next = Next();
2085 ReportUnexpectedToken(next);
2086 *ok = false;
2087 return this->EmptyObjectLiteralProperty();
2088}
2089
2090
2091template <class Traits>
2092typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2093 ExpressionClassifier* classifier, bool* ok) {
2094 // ObjectLiteral ::
2095 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2096
2097 int pos = peek_position();
2098 typename Traits::Type::PropertyList properties =
2099 this->NewPropertyList(4, zone_);
2100 int number_of_boilerplate_properties = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002101 bool has_computed_names = false;
2102 ObjectLiteralChecker checker(this);
2103
2104 Expect(Token::LBRACE, CHECK_OK);
2105
2106 while (peek() != Token::RBRACE) {
2107 FuncNameInferrer::State fni_state(fni_);
2108
2109 const bool in_class = false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002110 const bool has_extends = false;
2111 bool is_computed_name = false;
2112 IdentifierT name = this->EmptyIdentifier();
2113 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
Ben Murdochc5610432016-08-08 18:44:38 +01002114 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name,
2115 NULL, classifier, &name, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002116
2117 if (is_computed_name) {
2118 has_computed_names = true;
2119 }
2120
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002121 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2122 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2123 number_of_boilerplate_properties++;
2124 }
2125 properties->Add(property, zone());
2126
2127 if (peek() != Token::RBRACE) {
2128 // Need {} because of the CHECK_OK macro.
2129 Expect(Token::COMMA, CHECK_OK);
2130 }
2131
2132 if (fni_ != nullptr) fni_->Infer();
2133
Ben Murdoch61f157c2016-09-16 13:49:30 +01002134 Traits::SetFunctionNameFromPropertyName(property, name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002135 }
2136 Expect(Token::RBRACE, CHECK_OK);
2137
2138 // Computation of literal_index must happen before pre parse bailout.
2139 int literal_index = function_state_->NextMaterializedLiteralIndex();
2140
2141 return factory()->NewObjectLiteral(properties,
2142 literal_index,
2143 number_of_boilerplate_properties,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002144 pos);
2145}
2146
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002147template <class Traits>
2148typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
Ben Murdochc5610432016-08-08 18:44:38 +01002149 Scanner::Location* first_spread_arg_loc, bool maybe_arrow,
2150 ExpressionClassifier* classifier, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002151 // Arguments ::
2152 // '(' (AssignmentExpression)*[','] ')'
2153
2154 Scanner::Location spread_arg = Scanner::Location::invalid();
2155 typename Traits::Type::ExpressionList result =
2156 this->NewExpressionList(4, zone_);
2157 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2158 bool done = (peek() == Token::RPAREN);
2159 bool was_unspread = false;
2160 int unspread_sequences_count = 0;
2161 while (!done) {
2162 int start_pos = peek_position();
2163 bool is_spread = Check(Token::ELLIPSIS);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002164 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002165
2166 ExpressionT argument = this->ParseAssignmentExpression(
2167 true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
Ben Murdochc5610432016-08-08 18:44:38 +01002168 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList));
Ben Murdoch61f157c2016-09-16 13:49:30 +01002169 if (!maybe_arrow) {
2170 Traits::RewriteNonPattern(classifier,
2171 CHECK_OK_CUSTOM(NullExpressionList));
2172 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002173 if (is_spread) {
2174 if (!spread_arg.IsValid()) {
2175 spread_arg.beg_pos = start_pos;
2176 spread_arg.end_pos = peek_position();
2177 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002178 argument = factory()->NewSpread(argument, start_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002179 }
2180 result->Add(argument, zone_);
2181
2182 // unspread_sequences_count is the number of sequences of parameters which
2183 // are not prefixed with a spread '...' operator.
2184 if (is_spread) {
2185 was_unspread = false;
2186 } else if (!was_unspread) {
2187 was_unspread = true;
2188 unspread_sequences_count++;
2189 }
2190
2191 if (result->length() > Code::kMaxArguments) {
2192 ReportMessage(MessageTemplate::kTooManyArguments);
2193 *ok = false;
2194 return this->NullExpressionList();
2195 }
2196 done = (peek() != Token::COMMA);
2197 if (!done) {
2198 Next();
2199 }
2200 }
2201 Scanner::Location location = scanner_->location();
2202 if (Token::RPAREN != Next()) {
2203 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2204 *ok = false;
2205 return this->NullExpressionList();
2206 }
2207 *first_spread_arg_loc = spread_arg;
2208
Ben Murdoch61f157c2016-09-16 13:49:30 +01002209 if (!maybe_arrow || peek() != Token::ARROW) {
2210 if (maybe_arrow) {
2211 Traits::RewriteNonPattern(classifier,
2212 CHECK_OK_CUSTOM(NullExpressionList));
2213 }
2214 if (spread_arg.IsValid()) {
2215 // Unspread parameter sequences are translated into array literals in the
2216 // parser. Ensure that the number of materialized literals matches between
2217 // the parser and preparser
2218 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2219 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002220 }
2221
2222 return result;
2223}
2224
2225// Precedence = 2
2226template <class Traits>
2227typename ParserBase<Traits>::ExpressionT
Ben Murdoch097c5b22016-05-18 11:27:45 +01002228ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002229 ExpressionClassifier* classifier,
2230 bool* ok) {
2231 // AssignmentExpression ::
2232 // ConditionalExpression
2233 // ArrowFunction
2234 // YieldExpression
2235 // LeftHandSideExpression AssignmentOperator AssignmentExpression
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002236 bool is_destructuring_assignment = false;
2237 int lhs_beg_pos = peek_position();
2238
2239 if (peek() == Token::YIELD && is_generator()) {
Ben Murdochc5610432016-08-08 18:44:38 +01002240 return this->ParseYieldExpression(accept_IN, classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002241 }
2242
2243 FuncNameInferrer::State fni_state(fni_);
2244 ParserBase<Traits>::Checkpoint checkpoint(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002245 ExpressionClassifier arrow_formals_classifier(this,
2246 classifier->duplicate_finder());
Ben Murdochc5610432016-08-08 18:44:38 +01002247
2248 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC &&
Ben Murdoch61f157c2016-09-16 13:49:30 +01002249 !scanner()->HasAnyLineTerminatorAfterNext() &&
2250 IsValidArrowFormalParametersStart(PeekAhead());
Ben Murdochc5610432016-08-08 18:44:38 +01002251
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002252 bool parenthesized_formals = peek() == Token::LPAREN;
Ben Murdochc5610432016-08-08 18:44:38 +01002253 if (!is_async && !parenthesized_formals) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002254 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2255 }
2256 ExpressionT expression = this->ParseConditionalExpression(
2257 accept_IN, &arrow_formals_classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002258
2259 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) {
2260 // async Identifier => AsyncConciseBody
2261 IdentifierT name =
2262 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK);
2263 expression = this->ExpressionFromIdentifier(
2264 name, position(), scanner()->location().end_pos, scope_, factory());
2265 }
2266
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002267 if (peek() == Token::ARROW) {
Ben Murdoch61f157c2016-09-16 13:49:30 +01002268 Scanner::Location arrow_loc = scanner()->peek_location();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002269 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
Ben Murdochc5610432016-08-08 18:44:38 +01002270 parenthesized_formals, is_async, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01002271 // This reads strangely, but is correct: it checks whether any
2272 // sub-expression of the parameter list failed to be a valid formal
2273 // parameter initializer. Since YieldExpressions are banned anywhere
2274 // in an arrow parameter list, this is correct.
2275 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
2276 // "YieldExpression", which is its only use.
2277 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok);
Ben Murdochc5610432016-08-08 18:44:38 +01002278
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002279 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
Ben Murdochc5610432016-08-08 18:44:38 +01002280 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE,
2281 is_async ? FunctionKind::kAsyncArrowFunction
2282 : FunctionKind::kArrowFunction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002283 // Because the arrow's parameters were parsed in the outer scope, any
2284 // usage flags that might have been triggered there need to be copied
2285 // to the arrow scope.
2286 scope_->PropagateUsageFlagsToScope(scope);
2287 FormalParametersT parameters(scope);
2288 if (!arrow_formals_classifier.is_simple_parameter_list()) {
2289 scope->SetHasNonSimpleParameters();
2290 parameters.is_simple = false;
2291 }
2292
2293 checkpoint.Restore(&parameters.materialized_literals_count);
2294
2295 scope->set_start_position(lhs_beg_pos);
2296 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2297 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2298 &duplicate_loc, CHECK_OK);
2299 if (duplicate_loc.IsValid()) {
2300 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2301 duplicate_loc);
2302 }
2303 expression = this->ParseArrowFunctionLiteral(
Ben Murdochc5610432016-08-08 18:44:38 +01002304 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK);
Ben Murdoch61f157c2016-09-16 13:49:30 +01002305 arrow_formals_classifier.Discard();
2306 classifier->RecordPatternError(arrow_loc,
2307 MessageTemplate::kUnexpectedToken,
2308 Token::String(Token::ARROW));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002309
2310 if (fni_ != nullptr) fni_->Infer();
2311
2312 return expression;
2313 }
2314
2315 if (this->IsValidReferenceExpression(expression)) {
2316 arrow_formals_classifier.ForgiveAssignmentPatternError();
2317 }
2318
2319 // "expression" was not itself an arrow function parameter list, but it might
2320 // form part of one. Propagate speculative formal parameter error locations.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002321 // Do not merge pending non-pattern expressions yet!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002322 classifier->Accumulate(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002323 &arrow_formals_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002324 ExpressionClassifier::StandardProductions |
Ben Murdochc5610432016-08-08 18:44:38 +01002325 ExpressionClassifier::FormalParametersProductions |
2326 ExpressionClassifier::CoverInitializedNameProduction |
2327 ExpressionClassifier::AsyncArrowFormalParametersProduction |
2328 ExpressionClassifier::AsyncBindingPatternProduction,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002329 false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002330
2331 if (!Token::IsAssignmentOp(peek())) {
2332 // Parsed conditional expression only (no assignment).
Ben Murdoch097c5b22016-05-18 11:27:45 +01002333 // Now pending non-pattern expressions must be merged.
2334 classifier->MergeNonPatterns(&arrow_formals_classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002335 return expression;
2336 }
2337
Ben Murdoch097c5b22016-05-18 11:27:45 +01002338 // Now pending non-pattern expressions must be discarded.
2339 arrow_formals_classifier.Discard();
2340
Ben Murdochc5610432016-08-08 18:44:38 +01002341 CheckNoTailCallExpressions(classifier, CHECK_OK);
2342
Ben Murdochda12d292016-06-02 14:46:10 +01002343 if (IsValidPattern(expression) && peek() == Token::ASSIGN) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002344 classifier->ForgiveCoverInitializedNameError();
2345 ValidateAssignmentPattern(classifier, CHECK_OK);
2346 is_destructuring_assignment = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002347 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002348 expression = this->CheckAndRewriteReferenceExpression(
2349 expression, lhs_beg_pos, scanner()->location().end_pos,
2350 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2351 }
2352
2353 expression = this->MarkExpressionAsAssigned(expression);
2354
2355 Token::Value op = Next(); // Get assignment operator.
2356 if (op != Token::ASSIGN) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002357 classifier->RecordPatternError(scanner()->location(),
2358 MessageTemplate::kUnexpectedToken,
2359 Token::String(op));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002360 }
2361 int pos = position();
2362
Ben Murdoch097c5b22016-05-18 11:27:45 +01002363 ExpressionClassifier rhs_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002364
2365 ExpressionT right =
2366 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002367 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002368 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002369 classifier->Accumulate(
Ben Murdochc5610432016-08-08 18:44:38 +01002370 &rhs_classifier,
2371 ExpressionClassifier::ExpressionProductions |
2372 ExpressionClassifier::CoverInitializedNameProduction |
2373 ExpressionClassifier::AsyncArrowFormalParametersProduction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002374
2375 // TODO(1231235): We try to estimate the set of properties set by
2376 // constructors. We define a new property whenever there is an
2377 // assignment to a property of 'this'. We should probably only add
2378 // properties if we haven't seen them before. Otherwise we'll
2379 // probably overestimate the number of properties.
2380 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2381 function_state_->AddProperty();
2382 }
2383
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002384 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2385
2386 if (fni_ != NULL) {
2387 // Check if the right hand side is a call to avoid inferring a
2388 // name if we're dealing with "a = function(){...}();"-like
2389 // expression.
2390 if ((op == Token::INIT || op == Token::ASSIGN) &&
2391 (!right->IsCall() && !right->IsCallNew())) {
2392 fni_->Infer();
2393 } else {
2394 fni_->RemoveLastFunction();
2395 }
2396 }
2397
Ben Murdoch61f157c2016-09-16 13:49:30 +01002398 if (op == Token::ASSIGN) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002399 Traits::SetFunctionNameFromIdentifierRef(right, expression);
2400 }
2401
Ben Murdochda12d292016-06-02 14:46:10 +01002402 if (op == Token::ASSIGN_EXP) {
2403 DCHECK(!is_destructuring_assignment);
2404 return Traits::RewriteAssignExponentiation(expression, right, pos);
2405 }
2406
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002407 ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2408
2409 if (is_destructuring_assignment) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002410 result = factory()->NewRewritableExpression(result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002411 Traits::QueueDestructuringAssignmentForRewriting(result);
2412 }
2413
2414 return result;
2415}
2416
2417template <class Traits>
2418typename ParserBase<Traits>::ExpressionT
Ben Murdochc5610432016-08-08 18:44:38 +01002419ParserBase<Traits>::ParseYieldExpression(bool accept_IN,
2420 ExpressionClassifier* classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002421 bool* ok) {
2422 // YieldExpression ::
2423 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2424 int pos = peek_position();
2425 classifier->RecordPatternError(scanner()->peek_location(),
2426 MessageTemplate::kInvalidDestructuringTarget);
Ben Murdochda12d292016-06-02 14:46:10 +01002427 classifier->RecordFormalParameterInitializerError(
2428 scanner()->peek_location(), MessageTemplate::kYieldInParameter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002429 Expect(Token::YIELD, CHECK_OK);
2430 ExpressionT generator_object =
2431 factory()->NewVariableProxy(function_state_->generator_object_variable());
2432 ExpressionT expression = Traits::EmptyExpression();
Ben Murdochda12d292016-06-02 14:46:10 +01002433 bool delegating = false; // yield*
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002434 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
Ben Murdochda12d292016-06-02 14:46:10 +01002435 if (Check(Token::MUL)) delegating = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002436 switch (peek()) {
2437 case Token::EOS:
2438 case Token::SEMICOLON:
2439 case Token::RBRACE:
2440 case Token::RBRACK:
2441 case Token::RPAREN:
2442 case Token::COLON:
2443 case Token::COMMA:
2444 // The above set of tokens is the complete set of tokens that can appear
2445 // after an AssignmentExpression, and none of them can start an
2446 // AssignmentExpression. This allows us to avoid looking for an RHS for
Ben Murdochda12d292016-06-02 14:46:10 +01002447 // a regular yield, given only one look-ahead token.
2448 if (!delegating) break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002449 // Delegating yields require an RHS; fall through.
2450 default:
Ben Murdochc5610432016-08-08 18:44:38 +01002451 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002452 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002453 break;
2454 }
2455 }
Ben Murdochda12d292016-06-02 14:46:10 +01002456
2457 if (delegating) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002458 return Traits::RewriteYieldStar(generator_object, expression, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002459 }
Ben Murdochda12d292016-06-02 14:46:10 +01002460
2461 expression = Traits::BuildIteratorResult(expression, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002462 // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2463 // TODO(verwaest): Come up with a better solution.
2464 typename Traits::Type::YieldExpression yield =
Ben Murdochda12d292016-06-02 14:46:10 +01002465 factory()->NewYield(generator_object, expression, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002466 return yield;
2467}
2468
Ben Murdochc5610432016-08-08 18:44:38 +01002469template <class Traits>
2470typename ParserBase<Traits>::ExpressionT
2471ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier,
2472 bool* ok) {
2473 // TailCallExpression::
2474 // 'continue' MemberExpression Arguments
2475 // 'continue' CallExpression Arguments
2476 // 'continue' MemberExpression TemplateLiteral
2477 // 'continue' CallExpression TemplateLiteral
2478 Expect(Token::CONTINUE, CHECK_OK);
2479 int pos = position();
2480 int sub_expression_pos = peek_position();
2481 ExpressionT expression =
2482 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2483 CheckNoTailCallExpressions(classifier, CHECK_OK);
2484
2485 Scanner::Location loc(pos, scanner()->location().end_pos);
2486 if (!expression->IsCall()) {
2487 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
2488 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall);
2489 *ok = false;
2490 return Traits::EmptyExpression();
2491 }
2492 if (Traits::IsDirectEvalCall(expression)) {
2493 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
2494 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCallOfEval);
2495 *ok = false;
2496 return Traits::EmptyExpression();
2497 }
2498 if (!is_strict(language_mode())) {
2499 ReportMessageAt(loc, MessageTemplate::kUnexpectedSloppyTailCall);
2500 *ok = false;
2501 return Traits::EmptyExpression();
2502 }
Ben Murdoch61f157c2016-09-16 13:49:30 +01002503 if (is_resumable()) {
2504 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
2505 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCall);
2506 *ok = false;
2507 return Traits::EmptyExpression();
2508 }
Ben Murdochc5610432016-08-08 18:44:38 +01002509 ReturnExprContext return_expr_context =
2510 function_state_->return_expr_context();
2511 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) {
2512 MessageTemplate::Template msg = MessageTemplate::kNone;
2513 switch (return_expr_context) {
2514 case ReturnExprContext::kInsideValidReturnStatement:
2515 UNREACHABLE();
2516 return Traits::EmptyExpression();
2517 case ReturnExprContext::kInsideValidBlock:
2518 msg = MessageTemplate::kUnexpectedTailCall;
2519 break;
2520 case ReturnExprContext::kInsideTryBlock:
2521 msg = MessageTemplate::kUnexpectedTailCallInTryBlock;
2522 break;
2523 case ReturnExprContext::kInsideForInOfBody:
2524 msg = MessageTemplate::kUnexpectedTailCallInForInOf;
2525 break;
2526 }
2527 ReportMessageAt(loc, msg);
2528 *ok = false;
2529 return Traits::EmptyExpression();
2530 }
2531 classifier->RecordTailCallExpressionError(
2532 loc, MessageTemplate::kUnexpectedTailCall);
2533 function_state_->AddExplicitTailCallExpression(expression, loc);
2534 return expression;
2535}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002536
2537// Precedence = 3
2538template <class Traits>
2539typename ParserBase<Traits>::ExpressionT
2540ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
2541 ExpressionClassifier* classifier,
2542 bool* ok) {
2543 // ConditionalExpression ::
2544 // LogicalOrExpression
2545 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2546
2547 int pos = peek_position();
2548 // We start using the binary expression parser for prec >= 4 only!
2549 ExpressionT expression =
2550 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2551 if (peek() != Token::CONDITIONAL) return expression;
Ben Murdochc5610432016-08-08 18:44:38 +01002552 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002553 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002554 BindingPatternUnexpectedToken(classifier);
Ben Murdoch61f157c2016-09-16 13:49:30 +01002555 ArrowFormalParametersUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002556 Consume(Token::CONDITIONAL);
2557 // In parsing the first assignment expression in conditional
2558 // expressions we always accept the 'in' keyword; see ECMA-262,
2559 // section 11.12, page 58.
2560 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002561 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002562 Expect(Token::COLON, CHECK_OK);
2563 ExpressionT right =
2564 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002565 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002566 return factory()->NewConditional(expression, left, right, pos);
2567}
2568
2569
2570// Precedence >= 4
2571template <class Traits>
2572typename ParserBase<Traits>::ExpressionT
2573ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
2574 ExpressionClassifier* classifier,
2575 bool* ok) {
2576 DCHECK(prec >= 4);
2577 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2578 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2579 // prec1 >= 4
2580 while (Precedence(peek(), accept_IN) == prec1) {
Ben Murdochc5610432016-08-08 18:44:38 +01002581 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002582 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002583 BindingPatternUnexpectedToken(classifier);
2584 ArrowFormalParametersUnexpectedToken(classifier);
2585 Token::Value op = Next();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002586 int pos = position();
Ben Murdochda12d292016-06-02 14:46:10 +01002587
2588 const bool is_right_associative = op == Token::EXP;
2589 const int next_prec = is_right_associative ? prec1 : prec1 + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002590 ExpressionT y =
Ben Murdochda12d292016-06-02 14:46:10 +01002591 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002592 if (op != Token::OR && op != Token::AND) {
2593 CheckNoTailCallExpressions(classifier, CHECK_OK);
2594 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002595 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002596
2597 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2598 factory())) {
2599 continue;
2600 }
2601
2602 // For now we distinguish between comparisons and other binary
2603 // operations. (We could combine the two and get rid of this
2604 // code and AST node eventually.)
2605 if (Token::IsCompareOp(op)) {
2606 // We have a comparison.
2607 Token::Value cmp = op;
2608 switch (op) {
2609 case Token::NE: cmp = Token::EQ; break;
2610 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2611 default: break;
2612 }
Ben Murdochc5610432016-08-08 18:44:38 +01002613 x = factory()->NewCompareOperation(cmp, x, y, pos);
2614 if (cmp != op) {
2615 // The comparison was negated - add a NOT.
2616 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002617 }
Ben Murdochda12d292016-06-02 14:46:10 +01002618 } else if (op == Token::EXP) {
2619 x = Traits::RewriteExponentiation(x, y, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002620 } else {
2621 // We have a "normal" binary operation.
2622 x = factory()->NewBinaryOperation(op, x, y, pos);
2623 }
2624 }
2625 }
2626 return x;
2627}
2628
2629
2630template <class Traits>
2631typename ParserBase<Traits>::ExpressionT
2632ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
2633 bool* ok) {
2634 // UnaryExpression ::
2635 // PostfixExpression
2636 // 'delete' UnaryExpression
2637 // 'void' UnaryExpression
2638 // 'typeof' UnaryExpression
2639 // '++' UnaryExpression
2640 // '--' UnaryExpression
2641 // '+' UnaryExpression
2642 // '-' UnaryExpression
2643 // '~' UnaryExpression
2644 // '!' UnaryExpression
Ben Murdochc5610432016-08-08 18:44:38 +01002645 // [+Await] AwaitExpression[?Yield]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002646
2647 Token::Value op = peek();
2648 if (Token::IsUnaryOp(op)) {
2649 BindingPatternUnexpectedToken(classifier);
2650 ArrowFormalParametersUnexpectedToken(classifier);
2651
2652 op = Next();
2653 int pos = position();
2654 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002655 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002656 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002657
2658 if (op == Token::DELETE && is_strict(language_mode())) {
Ben Murdochda12d292016-06-02 14:46:10 +01002659 if (this->IsIdentifier(expression)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002660 // "delete identifier" is a syntax error in strict mode.
2661 ReportMessage(MessageTemplate::kStrictDelete);
2662 *ok = false;
2663 return this->EmptyExpression();
2664 }
2665 }
2666
Ben Murdochda12d292016-06-02 14:46:10 +01002667 if (peek() == Token::EXP) {
2668 ReportUnexpectedToken(Next());
2669 *ok = false;
2670 return this->EmptyExpression();
2671 }
2672
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002673 // Allow Traits do rewrite the expression.
2674 return this->BuildUnaryExpression(expression, op, pos, factory());
2675 } else if (Token::IsCountOp(op)) {
2676 BindingPatternUnexpectedToken(classifier);
2677 ArrowFormalParametersUnexpectedToken(classifier);
2678 op = Next();
2679 int beg_pos = peek_position();
2680 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002681 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002682 expression = this->CheckAndRewriteReferenceExpression(
2683 expression, beg_pos, scanner()->location().end_pos,
2684 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
2685 this->MarkExpressionAsAssigned(expression);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002686 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002687
2688 return factory()->NewCountOperation(op,
2689 true /* prefix */,
2690 expression,
2691 position());
2692
Ben Murdochc5610432016-08-08 18:44:38 +01002693 } else if (is_async_function() && peek() == Token::AWAIT) {
2694 int beg_pos = peek_position();
2695 switch (PeekAhead()) {
2696 case Token::RPAREN:
2697 case Token::RBRACK:
2698 case Token::RBRACE:
2699 case Token::ASSIGN:
2700 case Token::COMMA: {
2701 Next();
2702 IdentifierT name = this->GetSymbol(scanner());
2703
2704 // Possibly async arrow formals --- record ExpressionError just in case.
2705 ExpressionUnexpectedToken(classifier);
2706 classifier->RecordAsyncBindingPatternError(
2707 Scanner::Location(beg_pos, scanner()->location().end_pos),
2708 MessageTemplate::kAwaitBindingIdentifier);
2709 classifier->RecordAsyncArrowFormalParametersError(
2710 Scanner::Location(beg_pos, scanner()->location().end_pos),
2711 MessageTemplate::kAwaitBindingIdentifier);
2712
2713 return this->ExpressionFromIdentifier(
2714 name, beg_pos, scanner()->location().end_pos, scope_, factory());
2715 }
2716 default:
2717 break;
2718 }
Ben Murdoch61f157c2016-09-16 13:49:30 +01002719
2720 int await_pos = peek_position();
Ben Murdochc5610432016-08-08 18:44:38 +01002721 Consume(Token::AWAIT);
2722
2723 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK);
2724
2725 classifier->RecordFormalParameterInitializerError(
2726 Scanner::Location(beg_pos, scanner()->location().end_pos),
2727 MessageTemplate::kAwaitExpressionFormalParameter);
Ben Murdoch61f157c2016-09-16 13:49:30 +01002728 return Traits::RewriteAwaitExpression(value, await_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002729 } else {
2730 return this->ParsePostfixExpression(classifier, ok);
2731 }
2732}
2733
2734
2735template <class Traits>
2736typename ParserBase<Traits>::ExpressionT
2737ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
2738 bool* ok) {
2739 // PostfixExpression ::
2740 // LeftHandSideExpression ('++' | '--')?
2741
2742 int lhs_beg_pos = peek_position();
2743 ExpressionT expression =
2744 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2745 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2746 Token::IsCountOp(peek())) {
Ben Murdochc5610432016-08-08 18:44:38 +01002747 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002748 BindingPatternUnexpectedToken(classifier);
2749 ArrowFormalParametersUnexpectedToken(classifier);
2750
2751 expression = this->CheckAndRewriteReferenceExpression(
2752 expression, lhs_beg_pos, scanner()->location().end_pos,
2753 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
2754 expression = this->MarkExpressionAsAssigned(expression);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002755 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002756
2757 Token::Value next = Next();
2758 expression =
2759 factory()->NewCountOperation(next,
2760 false /* postfix */,
2761 expression,
2762 position());
2763 }
2764 return expression;
2765}
2766
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002767template <class Traits>
2768typename ParserBase<Traits>::ExpressionT
2769ParserBase<Traits>::ParseLeftHandSideExpression(
2770 ExpressionClassifier* classifier, bool* ok) {
2771 // LeftHandSideExpression ::
2772 // (NewExpression | MemberExpression) ...
2773
Ben Murdochc5610432016-08-08 18:44:38 +01002774 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) {
2775 return this->ParseTailCallExpression(classifier, ok);
2776 }
2777
2778 bool is_async = false;
2779 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(
2780 classifier, &is_async, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002781
2782 while (true) {
2783 switch (peek()) {
2784 case Token::LBRACK: {
Ben Murdochc5610432016-08-08 18:44:38 +01002785 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002786 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002787 BindingPatternUnexpectedToken(classifier);
2788 ArrowFormalParametersUnexpectedToken(classifier);
2789 Consume(Token::LBRACK);
2790 int pos = position();
2791 ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002792 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002793 result = factory()->NewProperty(result, index, pos);
2794 Expect(Token::RBRACK, CHECK_OK);
2795 break;
2796 }
2797
2798 case Token::LPAREN: {
Ben Murdochc5610432016-08-08 18:44:38 +01002799 CheckNoTailCallExpressions(classifier, CHECK_OK);
2800 int pos;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002801 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002802 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002803 if (scanner()->current_token() == Token::IDENTIFIER ||
Ben Murdochc5610432016-08-08 18:44:38 +01002804 scanner()->current_token() == Token::SUPER ||
2805 scanner()->current_token() == Token::ASYNC) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002806 // For call of an identifier we want to report position of
2807 // the identifier as position of the call in the stack trace.
2808 pos = position();
2809 } else {
2810 // For other kinds of calls we record position of the parenthesis as
2811 // position of the call. Note that this is extremely important for
2812 // expressions of the form function(){...}() for which call position
2813 // should not point to the closing brace otherwise it will intersect
2814 // with positions recorded for function literal and confuse debugger.
2815 pos = peek_position();
2816 // Also the trailing parenthesis are a hint that the function will
2817 // be called immediately. If we happen to have parsed a preceding
2818 // function literal eagerly, we can also compile it eagerly.
2819 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2820 result->AsFunctionLiteral()->set_should_eager_compile();
2821 }
2822 }
2823 Scanner::Location spread_pos;
2824 typename Traits::Type::ExpressionList args =
Ben Murdochc5610432016-08-08 18:44:38 +01002825 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK);
2826
2827 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) {
2828 if (args->length()) {
2829 // async ( Arguments ) => ...
2830 return Traits::ExpressionListToExpression(args);
2831 }
2832 // async () => ...
2833 return factory()->NewEmptyParentheses(pos);
2834 }
2835
2836 ArrowFormalParametersUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002837
2838 // Keep track of eval() calls since they disable all local variable
2839 // optimizations.
2840 // The calls that need special treatment are the
2841 // direct eval calls. These calls are all of the form eval(...), with
2842 // no explicit receiver.
2843 // These calls are marked as potentially direct eval calls. Whether
2844 // they are actually direct calls to eval is determined at run time.
2845 this->CheckPossibleEvalCall(result, scope_);
2846
2847 bool is_super_call = result->IsSuperCallReference();
2848 if (spread_pos.IsValid()) {
2849 args = Traits::PrepareSpreadArguments(args);
2850 result = Traits::SpreadCall(result, args, pos);
2851 } else {
2852 result = factory()->NewCall(result, args, pos);
2853 }
2854
2855 // Explicit calls to the super constructor using super() perform an
2856 // implicit binding assignment to the 'this' variable.
2857 if (is_super_call) {
2858 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2859 result =
2860 factory()->NewAssignment(Token::INIT, this_expr, result, pos);
2861 }
2862
2863 if (fni_ != NULL) fni_->RemoveLastFunction();
2864 break;
2865 }
2866
2867 case Token::PERIOD: {
Ben Murdochc5610432016-08-08 18:44:38 +01002868 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002869 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002870 BindingPatternUnexpectedToken(classifier);
2871 ArrowFormalParametersUnexpectedToken(classifier);
2872 Consume(Token::PERIOD);
2873 int pos = position();
2874 IdentifierT name = ParseIdentifierName(CHECK_OK);
2875 result = factory()->NewProperty(
2876 result, factory()->NewStringLiteral(name, pos), pos);
2877 if (fni_ != NULL) this->PushLiteralName(fni_, name);
2878 break;
2879 }
2880
2881 case Token::TEMPLATE_SPAN:
2882 case Token::TEMPLATE_TAIL: {
Ben Murdochc5610432016-08-08 18:44:38 +01002883 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002884 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002885 BindingPatternUnexpectedToken(classifier);
2886 ArrowFormalParametersUnexpectedToken(classifier);
2887 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
2888 break;
2889 }
2890
2891 default:
2892 return result;
2893 }
2894 }
2895}
2896
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002897template <class Traits>
2898typename ParserBase<Traits>::ExpressionT
2899ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
Ben Murdochc5610432016-08-08 18:44:38 +01002900 ExpressionClassifier* classifier, bool* is_async, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002901 // NewExpression ::
2902 // ('new')+ MemberExpression
2903 //
2904 // NewTarget ::
2905 // 'new' '.' 'target'
2906
2907 // The grammar for new expressions is pretty warped. We can have several 'new'
2908 // keywords following each other, and then a MemberExpression. When we see '('
2909 // after the MemberExpression, it's associated with the rightmost unassociated
2910 // 'new' to create a NewExpression with arguments. However, a NewExpression
2911 // can also occur without arguments.
2912
2913 // Examples of new expression:
2914 // new foo.bar().baz means (new (foo.bar)()).baz
2915 // new foo()() means (new foo())()
2916 // new new foo()() means (new (new foo())())
2917 // new new foo means new (new foo)
2918 // new new foo() means new (new foo())
2919 // new new foo().bar().baz means (new (new foo()).bar()).baz
2920
2921 if (peek() == Token::NEW) {
2922 BindingPatternUnexpectedToken(classifier);
2923 ArrowFormalParametersUnexpectedToken(classifier);
2924 Consume(Token::NEW);
2925 int new_pos = position();
2926 ExpressionT result = this->EmptyExpression();
2927 if (peek() == Token::SUPER) {
2928 const bool is_new = true;
2929 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
2930 } else if (peek() == Token::PERIOD) {
2931 return ParseNewTargetExpression(CHECK_OK);
2932 } else {
Ben Murdochc5610432016-08-08 18:44:38 +01002933 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async,
2934 CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002935 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002936 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002937 if (peek() == Token::LPAREN) {
2938 // NewExpression with arguments.
2939 Scanner::Location spread_pos;
2940 typename Traits::Type::ExpressionList args =
2941 this->ParseArguments(&spread_pos, classifier, CHECK_OK);
2942
2943 if (spread_pos.IsValid()) {
2944 args = Traits::PrepareSpreadArguments(args);
2945 result = Traits::SpreadCallNew(result, args, new_pos);
2946 } else {
2947 result = factory()->NewCallNew(result, args, new_pos);
2948 }
2949 // The expression can still continue with . or [ after the arguments.
Ben Murdochc5610432016-08-08 18:44:38 +01002950 result = this->ParseMemberExpressionContinuation(result, is_async,
2951 classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002952 return result;
2953 }
2954 // NewExpression without arguments.
2955 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2956 new_pos);
2957 }
2958 // No 'new' or 'super' keyword.
Ben Murdochc5610432016-08-08 18:44:38 +01002959 return this->ParseMemberExpression(classifier, is_async, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002960}
2961
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002962template <class Traits>
2963typename ParserBase<Traits>::ExpressionT
2964ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
Ben Murdochc5610432016-08-08 18:44:38 +01002965 bool* is_async, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002966 // MemberExpression ::
2967 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
2968 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
2969
2970 // The '[' Expression ']' and '.' Identifier parts are parsed by
2971 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2972 // caller.
2973
2974 // Parse the initial primary or function expression.
2975 ExpressionT result = this->EmptyExpression();
2976 if (peek() == Token::FUNCTION) {
2977 BindingPatternUnexpectedToken(classifier);
2978 ArrowFormalParametersUnexpectedToken(classifier);
2979
2980 Consume(Token::FUNCTION);
2981 int function_token_position = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002982
2983 if (allow_harmony_function_sent() && peek() == Token::PERIOD) {
2984 // function.sent
2985 int pos = position();
2986 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK);
2987
2988 if (!is_generator()) {
2989 // TODO(neis): allow escaping into closures?
2990 ReportMessageAt(scanner()->location(),
2991 MessageTemplate::kUnexpectedFunctionSent);
2992 *ok = false;
2993 return this->EmptyExpression();
2994 }
2995
2996 return this->FunctionSentExpression(scope_, factory(), pos);
2997 }
2998
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002999 bool is_generator = Check(Token::MUL);
3000 IdentifierT name = this->EmptyIdentifier();
3001 bool is_strict_reserved_name = false;
3002 Scanner::Location function_name_location = Scanner::Location::invalid();
3003 FunctionLiteral::FunctionType function_type =
3004 FunctionLiteral::kAnonymousExpression;
3005 if (peek_any_identifier()) {
3006 name = ParseIdentifierOrStrictReservedWord(
3007 is_generator, &is_strict_reserved_name, CHECK_OK);
3008 function_name_location = scanner()->location();
3009 function_type = FunctionLiteral::kNamedExpression;
3010 }
3011 result = this->ParseFunctionLiteral(
3012 name, function_name_location,
3013 is_strict_reserved_name ? kFunctionNameIsStrictReserved
3014 : kFunctionNameValidityUnknown,
3015 is_generator ? FunctionKind::kGeneratorFunction
3016 : FunctionKind::kNormalFunction,
Ben Murdoch097c5b22016-05-18 11:27:45 +01003017 function_token_position, function_type, language_mode(), CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003018 } else if (peek() == Token::SUPER) {
3019 const bool is_new = false;
3020 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3021 } else {
Ben Murdochc5610432016-08-08 18:44:38 +01003022 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003023 }
3024
Ben Murdochc5610432016-08-08 18:44:38 +01003025 result =
3026 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003027 return result;
3028}
3029
3030
3031template <class Traits>
3032typename ParserBase<Traits>::ExpressionT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003033ParserBase<Traits>::ParseSuperExpression(bool is_new,
3034 ExpressionClassifier* classifier,
3035 bool* ok) {
3036 Expect(Token::SUPER, CHECK_OK);
3037 int pos = position();
3038
3039 Scope* scope = scope_->ReceiverScope();
3040 FunctionKind kind = scope->function_kind();
3041 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3042 IsClassConstructor(kind)) {
3043 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3044 scope->RecordSuperPropertyUsage();
3045 return this->SuperPropertyReference(scope_, factory(), pos);
3046 }
3047 // new super() is never allowed.
3048 // super() is only allowed in derived constructor
3049 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003050 // TODO(rossberg): This might not be the correct FunctionState for the
3051 // method here.
3052 function_state_->set_super_location(scanner()->location());
3053 return this->SuperCallReference(scope_, factory(), pos);
3054 }
3055 }
3056
3057 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
3058 *ok = false;
3059 return this->EmptyExpression();
3060}
3061
Ben Murdoch097c5b22016-05-18 11:27:45 +01003062template <class Traits>
3063void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
3064 const char* full_name, int pos,
3065 bool* ok) {
3066 Consume(Token::PERIOD);
3067 ExpectContextualKeyword(property_name, ok);
3068 if (!*ok) return;
3069 if (scanner()->literal_contains_escapes()) {
3070 Traits::ReportMessageAt(
3071 Scanner::Location(pos, scanner()->location().end_pos),
3072 MessageTemplate::kInvalidEscapedMetaProperty, full_name);
3073 *ok = false;
3074 }
3075}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003076
3077template <class Traits>
3078typename ParserBase<Traits>::ExpressionT
3079ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
3080 int pos = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01003081 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003082
3083 if (!scope_->ReceiverScope()->is_function_scope()) {
3084 ReportMessageAt(scanner()->location(),
3085 MessageTemplate::kUnexpectedNewTarget);
3086 *ok = false;
3087 return this->EmptyExpression();
3088 }
3089
3090 return this->NewTargetExpression(scope_, factory(), pos);
3091}
3092
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003093template <class Traits>
3094typename ParserBase<Traits>::ExpressionT
3095ParserBase<Traits>::ParseMemberExpressionContinuation(
Ben Murdochc5610432016-08-08 18:44:38 +01003096 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
3097 bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003098 // Parses this part of MemberExpression:
3099 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3100 while (true) {
3101 switch (peek()) {
3102 case Token::LBRACK: {
Ben Murdochc5610432016-08-08 18:44:38 +01003103 *is_async = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003104 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003105 BindingPatternUnexpectedToken(classifier);
3106 ArrowFormalParametersUnexpectedToken(classifier);
3107
3108 Consume(Token::LBRACK);
3109 int pos = position();
3110 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003111 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003112 expression = factory()->NewProperty(expression, index, pos);
3113 if (fni_ != NULL) {
3114 this->PushPropertyName(fni_, index);
3115 }
3116 Expect(Token::RBRACK, CHECK_OK);
3117 break;
3118 }
3119 case Token::PERIOD: {
Ben Murdochc5610432016-08-08 18:44:38 +01003120 *is_async = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003121 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003122 BindingPatternUnexpectedToken(classifier);
3123 ArrowFormalParametersUnexpectedToken(classifier);
3124
3125 Consume(Token::PERIOD);
3126 int pos = position();
3127 IdentifierT name = ParseIdentifierName(CHECK_OK);
3128 expression = factory()->NewProperty(
3129 expression, factory()->NewStringLiteral(name, pos), pos);
3130 if (fni_ != NULL) {
3131 this->PushLiteralName(fni_, name);
3132 }
3133 break;
3134 }
3135 case Token::TEMPLATE_SPAN:
3136 case Token::TEMPLATE_TAIL: {
Ben Murdochc5610432016-08-08 18:44:38 +01003137 *is_async = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003138 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003139 BindingPatternUnexpectedToken(classifier);
3140 ArrowFormalParametersUnexpectedToken(classifier);
3141 int pos;
3142 if (scanner()->current_token() == Token::IDENTIFIER) {
3143 pos = position();
3144 } else {
3145 pos = peek_position();
3146 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3147 // If the tag function looks like an IIFE, set_parenthesized() to
3148 // force eager compilation.
3149 expression->AsFunctionLiteral()->set_should_eager_compile();
3150 }
3151 }
3152 expression =
3153 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
3154 break;
3155 }
Ben Murdochda12d292016-06-02 14:46:10 +01003156 case Token::ILLEGAL: {
3157 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
3158 *ok = false;
3159 return this->EmptyExpression();
3160 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003161 default:
3162 return expression;
3163 }
3164 }
3165 DCHECK(false);
3166 return this->EmptyExpression();
3167}
3168
3169
3170template <class Traits>
3171void ParserBase<Traits>::ParseFormalParameter(
3172 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3173 // FormalParameter[Yield,GeneratorParameter] :
3174 // BindingElement[?Yield, ?GeneratorParameter]
3175 bool is_rest = parameters->has_rest;
3176
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003177 ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
3178 if (!*ok) return;
3179
3180 ValidateBindingPattern(classifier, ok);
3181 if (!*ok) return;
3182
3183 if (!Traits::IsIdentifier(pattern)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003184 parameters->is_simple = false;
3185 ValidateFormalParameterInitializer(classifier, ok);
3186 if (!*ok) return;
3187 classifier->RecordNonSimpleParameter();
3188 }
3189
3190 ExpressionT initializer = Traits::EmptyExpression();
Ben Murdochda12d292016-06-02 14:46:10 +01003191 if (!is_rest && Check(Token::ASSIGN)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003192 ExpressionClassifier init_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003193 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3194 if (!*ok) return;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003195 Traits::RewriteNonPattern(&init_classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003196 ValidateFormalParameterInitializer(&init_classifier, ok);
3197 if (!*ok) return;
3198 parameters->is_simple = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003199 init_classifier.Discard();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003200 classifier->RecordNonSimpleParameter();
Ben Murdoch097c5b22016-05-18 11:27:45 +01003201
Ben Murdoch61f157c2016-09-16 13:49:30 +01003202 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003203 }
3204
3205 Traits::AddFormalParameter(parameters, pattern, initializer,
3206 scanner()->location().end_pos, is_rest);
3207}
3208
3209
3210template <class Traits>
3211void ParserBase<Traits>::ParseFormalParameterList(
3212 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3213 // FormalParameters[Yield,GeneratorParameter] :
3214 // [empty]
3215 // FormalParameterList[?Yield, ?GeneratorParameter]
3216 //
3217 // FormalParameterList[Yield,GeneratorParameter] :
3218 // FunctionRestParameter[?Yield]
3219 // FormalsList[?Yield, ?GeneratorParameter]
3220 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
3221 //
3222 // FormalsList[Yield,GeneratorParameter] :
3223 // FormalParameter[?Yield, ?GeneratorParameter]
3224 // FormalsList[?Yield, ?GeneratorParameter] ,
3225 // FormalParameter[?Yield,?GeneratorParameter]
3226
3227 DCHECK_EQ(0, parameters->Arity());
3228
3229 if (peek() != Token::RPAREN) {
3230 do {
3231 if (parameters->Arity() > Code::kMaxArguments) {
3232 ReportMessage(MessageTemplate::kTooManyParameters);
3233 *ok = false;
3234 return;
3235 }
3236 parameters->has_rest = Check(Token::ELLIPSIS);
3237 ParseFormalParameter(parameters, classifier, ok);
3238 if (!*ok) return;
3239 } while (!parameters->has_rest && Check(Token::COMMA));
3240
3241 if (parameters->has_rest) {
3242 parameters->is_simple = false;
3243 classifier->RecordNonSimpleParameter();
3244 if (peek() == Token::COMMA) {
3245 ReportMessageAt(scanner()->peek_location(),
3246 MessageTemplate::kParamAfterRest);
3247 *ok = false;
3248 return;
3249 }
3250 }
3251 }
3252
3253 for (int i = 0; i < parameters->Arity(); ++i) {
3254 auto parameter = parameters->at(i);
3255 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
3256 }
3257}
3258
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003259template <class Traits>
Ben Murdoch097c5b22016-05-18 11:27:45 +01003260void ParserBase<Traits>::CheckArityRestrictions(int param_count,
3261 FunctionKind function_kind,
3262 bool has_rest,
3263 int formals_start_pos,
3264 int formals_end_pos, bool* ok) {
3265 if (IsGetterFunction(function_kind)) {
3266 if (param_count != 0) {
3267 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3268 MessageTemplate::kBadGetterArity);
3269 *ok = false;
3270 }
3271 } else if (IsSetterFunction(function_kind)) {
3272 if (param_count != 1) {
3273 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3274 MessageTemplate::kBadSetterArity);
3275 *ok = false;
3276 }
3277 if (has_rest) {
3278 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3279 MessageTemplate::kBadSetterRestParameter);
3280 *ok = false;
3281 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003282 }
3283}
3284
3285
3286template <class Traits>
3287bool ParserBase<Traits>::IsNextLetKeyword() {
3288 DCHECK(peek() == Token::LET);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003289 Token::Value next_next = PeekAhead();
3290 switch (next_next) {
3291 case Token::LBRACE:
3292 case Token::LBRACK:
3293 case Token::IDENTIFIER:
3294 case Token::STATIC:
Ben Murdochc5610432016-08-08 18:44:38 +01003295 case Token::LET: // `let let;` is disallowed by static semantics, but the
3296 // token must be first interpreted as a keyword in order
3297 // for those semantics to apply. This ensures that ASI is
3298 // not honored when a LineTerminator separates the
3299 // tokens.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003300 case Token::YIELD:
Ben Murdochc5610432016-08-08 18:44:38 +01003301 case Token::AWAIT:
3302 case Token::ASYNC:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003303 return true;
Ben Murdochc5610432016-08-08 18:44:38 +01003304 case Token::FUTURE_STRICT_RESERVED_WORD:
3305 return is_sloppy(language_mode());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003306 default:
3307 return false;
3308 }
3309}
3310
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003311template <class Traits>
3312typename ParserBase<Traits>::ExpressionT
3313ParserBase<Traits>::ParseArrowFunctionLiteral(
Ben Murdochc5610432016-08-08 18:44:38 +01003314 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003315 const ExpressionClassifier& formals_classifier, bool* ok) {
3316 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3317 // ASI inserts `;` after arrow parameters if a line terminator is found.
3318 // `=> ...` is never a valid expression, so report as syntax error.
3319 // If next token is not `=>`, it's a syntax error anyways.
3320 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3321 *ok = false;
3322 return this->EmptyExpression();
3323 }
3324
3325 typename Traits::Type::StatementList body;
3326 int num_parameters = formal_parameters.scope->num_parameters();
3327 int materialized_literal_count = -1;
3328 int expected_property_count = -1;
3329 Scanner::Location super_loc;
3330
Ben Murdochc5610432016-08-08 18:44:38 +01003331 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003332 {
3333 typename Traits::Type::Factory function_factory(ast_value_factory());
3334 FunctionState function_state(&function_state_, &scope_,
Ben Murdochc5610432016-08-08 18:44:38 +01003335 formal_parameters.scope, arrow_kind,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003336 &function_factory);
3337
3338 function_state.SkipMaterializedLiterals(
3339 formal_parameters.materialized_literals_count);
3340
3341 this->ReindexLiterals(formal_parameters);
3342
3343 Expect(Token::ARROW, CHECK_OK);
3344
3345 if (peek() == Token::LBRACE) {
3346 // Multiple statement body
3347 Consume(Token::LBRACE);
3348 bool is_lazily_parsed =
3349 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing());
3350 if (is_lazily_parsed) {
3351 body = this->NewStatementList(0, zone());
3352 this->SkipLazyFunctionBody(&materialized_literal_count,
3353 &expected_property_count, CHECK_OK);
3354 if (formal_parameters.materialized_literals_count > 0) {
3355 materialized_literal_count +=
3356 formal_parameters.materialized_literals_count;
3357 }
3358 } else {
3359 body = this->ParseEagerFunctionBody(
3360 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
Ben Murdochc5610432016-08-08 18:44:38 +01003361 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003362 materialized_literal_count =
3363 function_state.materialized_literal_count();
3364 expected_property_count = function_state.expected_property_count();
3365 }
3366 } else {
3367 // Single-expression body
3368 int pos = position();
Ben Murdochc5610432016-08-08 18:44:38 +01003369 DCHECK(ReturnExprContext::kInsideValidBlock ==
3370 function_state_->return_expr_context());
3371 ReturnExprScope allow_tail_calls(
3372 function_state_, ReturnExprContext::kInsideValidReturnStatement);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003373 body = this->NewStatementList(1, zone());
Ben Murdochc5610432016-08-08 18:44:38 +01003374 this->AddParameterInitializationBlock(formal_parameters, body, is_async,
3375 CHECK_OK);
Ben Murdoch61f157c2016-09-16 13:49:30 +01003376 ExpressionClassifier classifier(this);
Ben Murdochc5610432016-08-08 18:44:38 +01003377 if (is_async) {
3378 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier,
3379 pos, CHECK_OK);
3380 Traits::RewriteNonPattern(&classifier, CHECK_OK);
3381 } else {
3382 ExpressionT expression =
3383 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
3384 Traits::RewriteNonPattern(&classifier, CHECK_OK);
3385 body->Add(factory()->NewReturnStatement(expression, pos), zone());
3386 if (allow_tailcalls() && !is_sloppy(language_mode())) {
3387 // ES6 14.6.1 Static Semantics: IsInTailPosition
3388 this->MarkTailPosition(expression);
3389 }
3390 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003391 materialized_literal_count = function_state.materialized_literal_count();
3392 expected_property_count = function_state.expected_property_count();
Ben Murdochc5610432016-08-08 18:44:38 +01003393 this->MarkCollectedTailCallExpressions();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003394 }
3395 super_loc = function_state.super_location();
3396
3397 formal_parameters.scope->set_end_position(scanner()->location().end_pos);
3398
3399 // Arrow function formal parameters are parsed as StrictFormalParameterList,
3400 // which is not the same as "parameters of a strict function"; it only means
3401 // that duplicates are not allowed. Of course, the arrow function may
3402 // itself be strict as well.
3403 const bool allow_duplicate_parameters = false;
3404 this->ValidateFormalParameters(&formals_classifier, language_mode(),
3405 allow_duplicate_parameters, CHECK_OK);
3406
3407 // Validate strict mode.
3408 if (is_strict(language_mode())) {
3409 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
3410 scanner()->location().end_pos, CHECK_OK);
3411 }
Ben Murdochc5610432016-08-08 18:44:38 +01003412 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003413
3414 Traits::RewriteDestructuringAssignments();
3415 }
3416
3417 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
3418 this->EmptyIdentifierString(), formal_parameters.scope, body,
3419 materialized_literal_count, expected_property_count, num_parameters,
3420 FunctionLiteral::kNoDuplicateParameters,
3421 FunctionLiteral::kAnonymousExpression,
Ben Murdochc5610432016-08-08 18:44:38 +01003422 FunctionLiteral::kShouldLazyCompile, arrow_kind,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003423 formal_parameters.scope->start_position());
3424
3425 function_literal->set_function_token_position(
3426 formal_parameters.scope->start_position());
3427 if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
3428
3429 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
3430
3431 return function_literal;
3432}
3433
3434
3435template <typename Traits>
3436typename ParserBase<Traits>::ExpressionT
3437ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
3438 ExpressionClassifier* classifier,
3439 bool* ok) {
3440 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3441 // text followed by a substitution expression), finalized by a single
3442 // TEMPLATE_TAIL.
3443 //
3444 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3445 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3446 // NoSubstitutionTemplate.
3447 //
3448 // When parsing a TemplateLiteral, we must have scanned either an initial
3449 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
3450 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
3451
3452 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
3453 // In this case we may simply consume the token and build a template with a
3454 // single TEMPLATE_SPAN and no expressions.
3455 if (peek() == Token::TEMPLATE_TAIL) {
3456 Consume(Token::TEMPLATE_TAIL);
3457 int pos = position();
3458 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3459 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3460 Traits::AddTemplateSpan(&ts, true);
3461 return Traits::CloseTemplateLiteral(&ts, start, tag);
3462 }
3463
3464 Consume(Token::TEMPLATE_SPAN);
3465 int pos = position();
3466 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3467 Traits::AddTemplateSpan(&ts, false);
3468 Token::Value next;
3469
3470 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
3471 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
3472 // case, representing a TemplateMiddle).
3473
3474 do {
3475 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3476 next = peek();
3477 if (next == Token::EOS) {
3478 ReportMessageAt(Scanner::Location(start, peek_position()),
3479 MessageTemplate::kUnterminatedTemplate);
3480 *ok = false;
3481 return Traits::EmptyExpression();
3482 } else if (next == Token::ILLEGAL) {
3483 Traits::ReportMessageAt(
3484 Scanner::Location(position() + 1, peek_position()),
3485 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3486 *ok = false;
3487 return Traits::EmptyExpression();
3488 }
3489
3490 int expr_pos = peek_position();
3491 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01003492 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003493 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003494 Traits::AddTemplateExpression(&ts, expression);
3495
3496 if (peek() != Token::RBRACE) {
3497 ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
3498 MessageTemplate::kUnterminatedTemplateExpr);
3499 *ok = false;
3500 return Traits::EmptyExpression();
3501 }
3502
3503 // If we didn't die parsing that expression, our next token should be a
3504 // TEMPLATE_SPAN or TEMPLATE_TAIL.
3505 next = scanner()->ScanTemplateContinuation();
3506 Next();
3507 pos = position();
3508
3509 if (next == Token::EOS) {
3510 ReportMessageAt(Scanner::Location(start, pos),
3511 MessageTemplate::kUnterminatedTemplate);
3512 *ok = false;
3513 return Traits::EmptyExpression();
3514 } else if (next == Token::ILLEGAL) {
3515 Traits::ReportMessageAt(
3516 Scanner::Location(position() + 1, peek_position()),
3517 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3518 *ok = false;
3519 return Traits::EmptyExpression();
3520 }
3521
3522 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
3523 } while (next == Token::TEMPLATE_SPAN);
3524
3525 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
3526 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3527 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3528 return Traits::CloseTemplateLiteral(&ts, start, tag);
3529}
3530
3531
3532template <typename Traits>
3533typename ParserBase<Traits>::ExpressionT
3534ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3535 ExpressionT expression, int beg_pos, int end_pos,
3536 MessageTemplate::Template message, bool* ok) {
3537 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
3538 message, kReferenceError, ok);
3539}
3540
3541
3542template <typename Traits>
3543typename ParserBase<Traits>::ExpressionT
3544ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3545 ExpressionT expression, int beg_pos, int end_pos,
3546 MessageTemplate::Template message, ParseErrorType type, bool* ok) {
Ben Murdochda12d292016-06-02 14:46:10 +01003547 if (this->IsIdentifier(expression) && is_strict(language_mode()) &&
3548 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3549 ReportMessageAt(Scanner::Location(beg_pos, end_pos),
3550 MessageTemplate::kStrictEvalArguments, kSyntaxError);
3551 *ok = false;
3552 return this->EmptyExpression();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003553 }
3554 if (expression->IsValidReferenceExpression()) {
3555 return expression;
Ben Murdochda12d292016-06-02 14:46:10 +01003556 }
3557 if (expression->IsCall()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003558 // If it is a call, make it a runtime error for legacy web compatibility.
3559 // Rewrite `expr' to `expr[throw ReferenceError]'.
Ben Murdochda12d292016-06-02 14:46:10 +01003560 ExpressionT error = this->NewThrowReferenceError(message, beg_pos);
3561 return factory()->NewProperty(expression, error, beg_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003562 }
Ben Murdochda12d292016-06-02 14:46:10 +01003563 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
3564 *ok = false;
3565 return this->EmptyExpression();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003566}
3567
3568
3569template <typename Traits>
3570bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) {
3571 return this->IsAssignableIdentifier(expression) || expression->IsProperty();
3572}
3573
3574
3575template <typename Traits>
3576void ParserBase<Traits>::CheckDestructuringElement(
3577 ExpressionT expression, ExpressionClassifier* classifier, int begin,
3578 int end) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003579 if (!IsValidPattern(expression) && !expression->IsAssignment() &&
3580 !IsValidReferenceExpression(expression)) {
3581 classifier->RecordAssignmentPatternError(
3582 Scanner::Location(begin, end),
3583 MessageTemplate::kInvalidDestructuringTarget);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003584 }
3585}
3586
3587
3588#undef CHECK_OK
3589#undef CHECK_OK_CUSTOM
3590
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003591template <typename Traits>
3592void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
Ben Murdochc5610432016-08-08 18:44:38 +01003593 Token::Value property, PropertyKind type, MethodKind method_type,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003594 bool* ok) {
Ben Murdochc5610432016-08-08 18:44:38 +01003595 DCHECK(!IsStaticMethod(method_type));
3596 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003597
3598 if (property == Token::SMI || property == Token::NUMBER) return;
3599
3600 if (type == kValueProperty && IsProto()) {
3601 if (has_seen_proto_) {
3602 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
3603 *ok = false;
3604 return;
3605 }
3606 has_seen_proto_ = true;
3607 return;
3608 }
3609}
3610
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003611template <typename Traits>
3612void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
Ben Murdochc5610432016-08-08 18:44:38 +01003613 Token::Value property, PropertyKind type, MethodKind method_type,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003614 bool* ok) {
3615 DCHECK(type == kMethodProperty || type == kAccessorProperty);
3616
3617 if (property == Token::SMI || property == Token::NUMBER) return;
3618
Ben Murdochc5610432016-08-08 18:44:38 +01003619 if (IsStaticMethod(method_type)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003620 if (IsPrototype()) {
3621 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
3622 *ok = false;
3623 return;
3624 }
3625 } else if (IsConstructor()) {
Ben Murdochc5610432016-08-08 18:44:38 +01003626 const bool is_generator = IsGeneratorMethod(method_type);
3627 const bool is_async = IsAsyncMethod(method_type);
3628 if (is_generator || is_async || type == kAccessorProperty) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003629 MessageTemplate::Template msg =
3630 is_generator ? MessageTemplate::kConstructorIsGenerator
Ben Murdochc5610432016-08-08 18:44:38 +01003631 : is_async ? MessageTemplate::kConstructorIsAsync
3632 : MessageTemplate::kConstructorIsAccessor;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003633 this->parser()->ReportMessage(msg);
3634 *ok = false;
3635 return;
3636 }
3637 if (has_seen_constructor_) {
3638 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
3639 *ok = false;
3640 return;
3641 }
3642 has_seen_constructor_ = true;
3643 return;
3644 }
3645}
Ben Murdoch097c5b22016-05-18 11:27:45 +01003646
3647
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003648} // namespace internal
3649} // namespace v8
3650
3651#endif // V8_PARSING_PARSER_BASE_H