blob: 6086f7af196b863a590c18a7252fd1f5143a4e5c [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"
10#include "src/hashmap.h"
11#include "src/messages.h"
12#include "src/parsing/expression-classifier.h"
13#include "src/parsing/func-name-inferrer.h"
14#include "src/parsing/scanner.h"
15#include "src/parsing/token.h"
16
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 Murdoch097c5b22016-05-18 11:27:45 +0100199 allow_harmony_function_name_(false),
Ben Murdochc5610432016-08-08 18:44:38 +0100200 allow_harmony_function_sent_(false),
201 allow_harmony_async_await_(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 Murdoch4a90d5f2016-03-22 12:00:34 +0000219 ALLOW_ACCESSORS(harmony_function_name);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100220 ALLOW_ACCESSORS(harmony_function_sent);
Ben Murdochc5610432016-08-08 18:44:38 +0100221 ALLOW_ACCESSORS(harmony_async_await);
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
388 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite()
389 const {
390 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 Murdochc5610432016-08-08 18:44:38 +0100411 ReturnExprContext return_expr_context() const {
412 return return_expr_context_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100413 }
Ben Murdochc5610432016-08-08 18:44:38 +0100414 void set_return_expr_context(ReturnExprContext context) {
415 return_expr_context_ = context;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100416 }
417
418 ZoneList<ExpressionT>* non_patterns_to_rewrite() {
419 return &non_patterns_to_rewrite_;
420 }
421
Ben Murdochc5610432016-08-08 18:44:38 +0100422 void next_function_is_parenthesized(bool parenthesized) {
423 next_function_is_parenthesized_ = parenthesized;
424 }
425
426 bool this_function_is_parenthesized() const {
427 return this_function_is_parenthesized_;
428 }
429
Ben Murdoch097c5b22016-05-18 11:27:45 +0100430 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000431 void AddDestructuringAssignment(DestructuringAssignment pair) {
432 destructuring_assignments_to_rewrite_.Add(pair);
433 }
434
Ben Murdoch097c5b22016-05-18 11:27:45 +0100435 V8_INLINE Scope* scope() { return *scope_stack_; }
436
437 void AddNonPatternForRewriting(ExpressionT expr) {
438 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone());
439 }
440
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 // Used to assign an index to each literal that needs materialization in
442 // the function. Includes regexp literals, and boilerplate for object and
443 // array literals.
444 int next_materialized_literal_index_;
445
446 // Properties count estimation.
447 int expected_property_count_;
448
449 // Location of most recent use of 'this' (invalid if none).
450 Scanner::Location this_location_;
451
452 // Location of most recent 'return' statement (invalid if none).
453 Scanner::Location return_location_;
454
455 // Location of call to the "super" constructor (invalid if none).
456 Scanner::Location super_location_;
457
458 FunctionKind kind_;
459 // For generators, this variable may hold the generator object. It variable
460 // is used by yield expressions and return statements. It is not necessary
461 // for generator functions to have this variable set.
462 Variable* generator_object_variable_;
463
464 FunctionState** function_state_stack_;
465 FunctionState* outer_function_state_;
466 Scope** scope_stack_;
467 Scope* outer_scope_;
468
469 List<DestructuringAssignment> destructuring_assignments_to_rewrite_;
Ben Murdochc5610432016-08-08 18:44:38 +0100470 TailCallExpressionList tail_call_expressions_;
471 ReturnExprContext return_expr_context_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100472 ZoneList<ExpressionT> non_patterns_to_rewrite_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000473
474 typename Traits::Type::Factory* factory_;
475
Ben Murdochc5610432016-08-08 18:44:38 +0100476 // If true, the next (and immediately following) function literal is
477 // preceded by a parenthesis.
478 bool next_function_is_parenthesized_;
479
480 // The value of the parents' next_function_is_parenthesized_, as it applies
481 // to this function. Filled in by constructor.
482 bool this_function_is_parenthesized_;
483
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000484 friend class ParserTraits;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100485 friend class PreParserTraits;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000486 friend class Checkpoint;
487 };
488
Ben Murdochc5610432016-08-08 18:44:38 +0100489 // This scope sets current ReturnExprContext to given value.
490 class ReturnExprScope {
491 public:
492 explicit ReturnExprScope(FunctionState* function_state,
493 ReturnExprContext return_expr_context)
494 : function_state_(function_state),
495 sav_return_expr_context_(function_state->return_expr_context()) {
496 // Don't update context if we are requested to enable tail call
497 // expressions but current block does not allow them.
498 if (return_expr_context !=
499 ReturnExprContext::kInsideValidReturnStatement ||
500 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) {
501 function_state->set_return_expr_context(return_expr_context);
502 }
503 }
504 ~ReturnExprScope() {
505 function_state_->set_return_expr_context(sav_return_expr_context_);
506 }
507
508 private:
509 FunctionState* function_state_;
510 ReturnExprContext sav_return_expr_context_;
511 };
512
513 // Collects all return expressions at tail call position in this scope
514 // to a separate list.
515 class CollectExpressionsInTailPositionToListScope {
516 public:
517 CollectExpressionsInTailPositionToListScope(FunctionState* function_state,
518 TailCallExpressionList* list)
519 : function_state_(function_state), list_(list) {
520 function_state->tail_call_expressions().Swap(*list_);
521 }
522 ~CollectExpressionsInTailPositionToListScope() {
523 function_state_->tail_call_expressions().Swap(*list_);
524 }
525
526 private:
527 FunctionState* function_state_;
528 TailCallExpressionList* list_;
529 };
530
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000531 // Annoyingly, arrow functions first parse as comma expressions, then when we
532 // see the => we have to go back and reinterpret the arguments as being formal
533 // parameters. To do so we need to reset some of the parser state back to
534 // what it was before the arguments were first seen.
535 class Checkpoint BASE_EMBEDDED {
536 public:
537 explicit Checkpoint(ParserBase* parser) {
538 function_state_ = parser->function_state_;
539 next_materialized_literal_index_ =
540 function_state_->next_materialized_literal_index_;
541 expected_property_count_ = function_state_->expected_property_count_;
542 }
543
544 void Restore(int* materialized_literal_index_delta) {
545 *materialized_literal_index_delta =
546 function_state_->next_materialized_literal_index_ -
547 next_materialized_literal_index_;
548 function_state_->next_materialized_literal_index_ =
549 next_materialized_literal_index_;
550 function_state_->expected_property_count_ = expected_property_count_;
551 }
552
553 private:
554 FunctionState* function_state_;
555 int next_materialized_literal_index_;
556 int expected_property_count_;
557 };
558
559 class ParsingModeScope BASE_EMBEDDED {
560 public:
561 ParsingModeScope(ParserBase* parser, Mode mode)
562 : parser_(parser),
563 old_mode_(parser->mode()) {
564 parser_->mode_ = mode;
565 }
566 ~ParsingModeScope() {
567 parser_->mode_ = old_mode_;
568 }
569
570 private:
571 ParserBase* parser_;
572 Mode old_mode_;
573 };
574
575 Scope* NewScope(Scope* parent, ScopeType scope_type) {
576 // Must always pass the function kind for FUNCTION_SCOPE.
577 DCHECK(scope_type != FUNCTION_SCOPE);
578 return NewScope(parent, scope_type, kNormalFunction);
579 }
580
581 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
582 DCHECK(ast_value_factory());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000583 Scope* result = new (zone())
584 Scope(zone(), parent, scope_type, ast_value_factory(), kind);
585 result->Initialize();
586 return result;
587 }
588
589 Scanner* scanner() const { return scanner_; }
590 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
591 int position() { return scanner_->location().beg_pos; }
592 int peek_position() { return scanner_->peek_location().beg_pos; }
593 bool stack_overflow() const { return stack_overflow_; }
594 void set_stack_overflow() { stack_overflow_ = true; }
595 Mode mode() const { return mode_; }
596 Zone* zone() const { return zone_; }
597
598 INLINE(Token::Value peek()) {
599 if (stack_overflow_) return Token::ILLEGAL;
600 return scanner()->peek();
601 }
602
603 INLINE(Token::Value PeekAhead()) {
604 if (stack_overflow_) return Token::ILLEGAL;
605 return scanner()->PeekAhead();
606 }
607
608 INLINE(Token::Value Next()) {
609 if (stack_overflow_) return Token::ILLEGAL;
610 {
611 if (GetCurrentStackPosition() < stack_limit_) {
612 // Any further calls to Next or peek will return the illegal token.
613 // The current call must return the next token, which might already
614 // have been peek'ed.
615 stack_overflow_ = true;
616 }
617 }
618 return scanner()->Next();
619 }
620
621 void Consume(Token::Value token) {
622 Token::Value next = Next();
623 USE(next);
624 USE(token);
625 DCHECK(next == token);
626 }
627
628 bool Check(Token::Value token) {
629 Token::Value next = peek();
630 if (next == token) {
631 Consume(next);
632 return true;
633 }
634 return false;
635 }
636
637 void Expect(Token::Value token, bool* ok) {
638 Token::Value next = Next();
639 if (next != token) {
640 ReportUnexpectedToken(next);
641 *ok = false;
642 }
643 }
644
645 void ExpectSemicolon(bool* ok) {
646 // Check for automatic semicolon insertion according to
647 // the rules given in ECMA-262, section 7.9, page 21.
648 Token::Value tok = peek();
649 if (tok == Token::SEMICOLON) {
650 Next();
651 return;
652 }
653 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
654 tok == Token::RBRACE ||
655 tok == Token::EOS) {
656 return;
657 }
658 Expect(Token::SEMICOLON, ok);
659 }
660
661 bool peek_any_identifier() {
662 Token::Value next = peek();
Ben Murdochc5610432016-08-08 18:44:38 +0100663 return next == Token::IDENTIFIER || next == Token::ENUM ||
664 next == Token::AWAIT || next == Token::ASYNC ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000665 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
666 next == Token::STATIC || next == Token::YIELD;
667 }
668
669 bool CheckContextualKeyword(Vector<const char> keyword) {
670 if (PeekContextualKeyword(keyword)) {
671 Consume(Token::IDENTIFIER);
672 return true;
673 }
674 return false;
675 }
676
677 bool PeekContextualKeyword(Vector<const char> keyword) {
678 return peek() == Token::IDENTIFIER &&
679 scanner()->is_next_contextual_keyword(keyword);
680 }
681
Ben Murdoch097c5b22016-05-18 11:27:45 +0100682 void ExpectMetaProperty(Vector<const char> property_name,
683 const char* full_name, int pos, bool* ok);
684
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000685 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
686 Expect(Token::IDENTIFIER, ok);
687 if (!*ok) return;
688 if (!scanner()->is_literal_contextual_keyword(keyword)) {
689 ReportUnexpectedToken(scanner()->current_token());
690 *ok = false;
691 }
692 }
693
694 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
695 if (Check(Token::IN)) {
Ben Murdochda12d292016-06-02 14:46:10 +0100696 *visit_mode = ForEachStatement::ENUMERATE;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000697 return true;
698 } else if (CheckContextualKeyword(CStrVector("of"))) {
699 *visit_mode = ForEachStatement::ITERATE;
700 return true;
701 }
702 return false;
703 }
704
Ben Murdoch097c5b22016-05-18 11:27:45 +0100705 bool PeekInOrOf() {
706 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of"));
707 }
708
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000709 // Checks whether an octal literal was last seen between beg_pos and end_pos.
710 // If so, reports an error. Only called for strict mode and template strings.
711 void CheckOctalLiteral(int beg_pos, int end_pos,
712 MessageTemplate::Template message, bool* ok) {
713 Scanner::Location octal = scanner()->octal_position();
714 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
715 octal.end_pos <= end_pos) {
716 ReportMessageAt(octal, message);
717 scanner()->clear_octal_position();
718 *ok = false;
719 }
720 }
Ben Murdochc5610432016-08-08 18:44:38 +0100721 // for now, this check just collects statistics.
722 void CheckDecimalLiteralWithLeadingZero(int* use_counts, int beg_pos,
723 int end_pos) {
724 Scanner::Location token_location =
725 scanner()->decimal_with_leading_zero_position();
726 if (token_location.IsValid() && beg_pos <= token_location.beg_pos &&
727 token_location.end_pos <= end_pos) {
728 scanner()->clear_decimal_with_leading_zero_position();
729 if (use_counts != nullptr)
730 ++use_counts[v8::Isolate::kDecimalWithLeadingZeroInStrictMode];
731 }
732 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000733
734 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
735 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
736 ok);
737 }
738
739 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
740 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
741 ok);
742 }
743
744 void CheckDestructuringElement(ExpressionT element,
745 ExpressionClassifier* classifier, int beg_pos,
746 int end_pos);
747
748 // Checking the name of a function literal. This has to be done after parsing
749 // the function, since the function can declare itself strict.
750 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
751 FunctionNameValidity function_name_validity,
752 const Scanner::Location& function_name_loc, bool* ok) {
753 if (function_name_validity == kSkipFunctionNameCheck) return;
754 // The function name needs to be checked in strict mode.
755 if (is_sloppy(language_mode)) return;
756
757 if (this->IsEvalOrArguments(function_name)) {
758 Traits::ReportMessageAt(function_name_loc,
759 MessageTemplate::kStrictEvalArguments);
760 *ok = false;
761 return;
762 }
763 if (function_name_validity == kFunctionNameIsStrictReserved) {
764 Traits::ReportMessageAt(function_name_loc,
765 MessageTemplate::kUnexpectedStrictReserved);
766 *ok = false;
767 return;
768 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000769 }
770
771 // Determine precedence of given token.
772 static int Precedence(Token::Value token, bool accept_IN) {
773 if (token == Token::IN && !accept_IN)
774 return 0; // 0 precedence will terminate binary expression parsing
775 return Token::Precedence(token);
776 }
777
778 typename Traits::Type::Factory* factory() {
779 return function_state_->factory();
780 }
781
782 LanguageMode language_mode() { return scope_->language_mode(); }
783 bool is_generator() const { return function_state_->is_generator(); }
Ben Murdochc5610432016-08-08 18:44:38 +0100784 bool is_async_function() const {
785 return function_state_->is_async_function();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000786 }
Ben Murdochc5610432016-08-08 18:44:38 +0100787 bool is_resumable() const { return function_state_->is_resumable(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000788
789 // Report syntax errors.
790 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
791 ParseErrorType error_type = kSyntaxError) {
792 Scanner::Location source_location = scanner()->location();
793 Traits::ReportMessageAt(source_location, message, arg, error_type);
794 }
795
796 void ReportMessageAt(Scanner::Location location,
797 MessageTemplate::Template message,
798 ParseErrorType error_type = kSyntaxError) {
799 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
800 error_type);
801 }
802
803 void GetUnexpectedTokenMessage(
Ben Murdochda12d292016-06-02 14:46:10 +0100804 Token::Value token, MessageTemplate::Template* message,
805 Scanner::Location* location, const char** arg,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
807
808 void ReportUnexpectedToken(Token::Value token);
809 void ReportUnexpectedTokenAt(
810 Scanner::Location location, Token::Value token,
811 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
812
Ben Murdoch097c5b22016-05-18 11:27:45 +0100813 void ReportClassifierError(
814 const typename ExpressionClassifier::Error& error) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000815 Traits::ReportMessageAt(error.location, error.message, error.arg,
816 error.type);
817 }
818
819 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
820 if (!classifier->is_valid_expression() ||
821 classifier->has_cover_initialized_name()) {
822 const Scanner::Location& a = classifier->expression_error().location;
823 const Scanner::Location& b =
824 classifier->cover_initialized_name_error().location;
825 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
826 ReportClassifierError(classifier->cover_initialized_name_error());
827 } else {
828 ReportClassifierError(classifier->expression_error());
829 }
830 *ok = false;
831 }
832 }
833
834 void ValidateFormalParameterInitializer(
835 const ExpressionClassifier* classifier, bool* ok) {
836 if (!classifier->is_valid_formal_parameter_initializer()) {
837 ReportClassifierError(classifier->formal_parameter_initializer_error());
838 *ok = false;
839 }
840 }
841
842 void ValidateBindingPattern(const ExpressionClassifier* classifier,
843 bool* ok) {
Ben Murdochc5610432016-08-08 18:44:38 +0100844 if (!classifier->is_valid_binding_pattern() ||
845 !classifier->is_valid_async_binding_pattern()) {
846 const Scanner::Location& a = classifier->binding_pattern_error().location;
847 const Scanner::Location& b =
848 classifier->async_binding_pattern_error().location;
849 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
850 ReportClassifierError(classifier->async_binding_pattern_error());
851 } else {
852 ReportClassifierError(classifier->binding_pattern_error());
853 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000854 *ok = false;
855 }
856 }
857
858 void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
859 bool* ok) {
860 if (!classifier->is_valid_assignment_pattern()) {
861 ReportClassifierError(classifier->assignment_pattern_error());
862 *ok = false;
863 }
864 }
865
866 void ValidateFormalParameters(const ExpressionClassifier* classifier,
867 LanguageMode language_mode,
868 bool allow_duplicates, bool* ok) {
869 if (!allow_duplicates &&
870 !classifier->is_valid_formal_parameter_list_without_duplicates()) {
871 ReportClassifierError(classifier->duplicate_formal_parameter_error());
872 *ok = false;
873 } else if (is_strict(language_mode) &&
874 !classifier->is_valid_strict_mode_formal_parameters()) {
875 ReportClassifierError(classifier->strict_mode_formal_parameter_error());
876 *ok = false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000877 }
878 }
879
880 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
881 ExpressionT expr,
Ben Murdochc5610432016-08-08 18:44:38 +0100882 bool parenthesized_formals, bool is_async,
883 bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000884 if (classifier->is_valid_binding_pattern()) {
885 // A simple arrow formal parameter: IDENTIFIER => BODY.
886 if (!this->IsIdentifier(expr)) {
887 Traits::ReportMessageAt(scanner()->location(),
888 MessageTemplate::kUnexpectedToken,
889 Token::String(scanner()->current_token()));
890 *ok = false;
891 }
892 } else if (!classifier->is_valid_arrow_formal_parameters()) {
893 // If after parsing the expr, we see an error but the expression is
894 // neither a valid binding pattern nor a valid parenthesized formal
895 // parameter list, show the "arrow formal parameters" error if the formals
896 // started with a parenthesis, and the binding pattern error otherwise.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100897 const typename ExpressionClassifier::Error& error =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898 parenthesized_formals ? classifier->arrow_formal_parameters_error()
899 : classifier->binding_pattern_error();
900 ReportClassifierError(error);
901 *ok = false;
902 }
Ben Murdochc5610432016-08-08 18:44:38 +0100903 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) {
904 const typename ExpressionClassifier::Error& error =
905 classifier->async_arrow_formal_parameters_error();
906 ReportClassifierError(error);
907 *ok = false;
908 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000909 }
910
911 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) {
912 if (!classifier->is_valid_let_pattern()) {
913 ReportClassifierError(classifier->let_pattern_error());
914 *ok = false;
915 }
916 }
917
Ben Murdochc5610432016-08-08 18:44:38 +0100918 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier,
919 bool* ok) {
920 if (FLAG_harmony_explicit_tailcalls &&
921 classifier->has_tail_call_expression()) {
922 ReportClassifierError(classifier->tail_call_expression_error());
923 *ok = false;
924 }
925 }
926
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000927 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
928 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
929 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100930 Scanner::Location location = scanner()->peek_location();
931 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
932 classifier->RecordExpressionError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000933 }
934
935 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
936 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
937 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100938 Scanner::Location location = scanner()->peek_location();
939 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
940 classifier->RecordBindingPatternError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000941 }
942
943 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
944 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
945 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100946 Scanner::Location location = scanner()->peek_location();
947 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
948 classifier->RecordArrowFormalParametersError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000949 }
950
951 // Recursive descent functions:
952
953 // Parses an identifier that is valid for the current scope, in particular it
954 // fails on strict mode future reserved keywords in a strict scope. If
955 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
956 // "arguments" as identifier even in strict mode (this is needed in cases like
957 // "var foo = eval;").
958 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
959 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
960 bool* ok);
961 // Parses an identifier or a strict mode future reserved word, and indicate
962 // whether it is strict mode future reserved. Allows passing in is_generator
963 // for the case of parsing the identifier in a function expression, where the
964 // relevant "is_generator" bit is of the function being parsed, not the
965 // containing
966 // function.
967 IdentifierT ParseIdentifierOrStrictReservedWord(bool is_generator,
968 bool* is_strict_reserved,
969 bool* ok);
970 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
971 bool* ok) {
972 return ParseIdentifierOrStrictReservedWord(this->is_generator(),
973 is_strict_reserved, ok);
974 }
975
976 IdentifierT ParseIdentifierName(bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000977
978 ExpressionT ParseRegExpLiteral(bool seen_equal,
979 ExpressionClassifier* classifier, bool* ok);
980
981 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
Ben Murdochc5610432016-08-08 18:44:38 +0100982 bool* is_async, bool* ok);
983 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
984 bool* ok) {
985 bool is_async;
986 return ParsePrimaryExpression(classifier, &is_async, ok);
987 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000988 ExpressionT ParseExpression(bool accept_IN, bool* ok);
989 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
990 bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000991 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
992 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
Ben Murdochc5610432016-08-08 18:44:38 +0100993 bool* is_await, bool* is_computed_name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000994 ExpressionClassifier* classifier, bool* ok);
995 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
996 ObjectLiteralPropertyT ParsePropertyDefinition(
997 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
Ben Murdochc5610432016-08-08 18:44:38 +0100998 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000999 ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
1000 typename Traits::Type::ExpressionList ParseArguments(
Ben Murdochc5610432016-08-08 18:44:38 +01001001 Scanner::Location* first_spread_pos, bool maybe_arrow,
1002 ExpressionClassifier* classifier, bool* ok);
1003 typename Traits::Type::ExpressionList ParseArguments(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001004 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
Ben Murdochc5610432016-08-08 18:44:38 +01001005 bool* ok) {
1006 return ParseArguments(first_spread_pos, false, classifier, ok);
1007 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001008
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001009 ExpressionT ParseAssignmentExpression(bool accept_IN,
1010 ExpressionClassifier* classifier,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001011 bool* ok);
Ben Murdochc5610432016-08-08 18:44:38 +01001012 ExpressionT ParseYieldExpression(bool accept_IN,
1013 ExpressionClassifier* classifier, bool* ok);
1014 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier,
1015 bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001016 ExpressionT ParseConditionalExpression(bool accept_IN,
1017 ExpressionClassifier* classifier,
1018 bool* ok);
1019 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
1020 ExpressionClassifier* classifier, bool* ok);
1021 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
1022 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
1023 bool* ok);
1024 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
1025 bool* ok);
1026 ExpressionT ParseMemberWithNewPrefixesExpression(
Ben Murdochc5610432016-08-08 18:44:38 +01001027 ExpressionClassifier* classifier, bool* is_async, bool* ok);
1028 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier,
1029 bool* is_async, bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001030 ExpressionT ParseMemberExpressionContinuation(
Ben Murdochc5610432016-08-08 18:44:38 +01001031 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
1032 bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001033 ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
1034 const FormalParametersT& parameters,
Ben Murdochc5610432016-08-08 18:44:38 +01001035 bool is_async,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001036 const ExpressionClassifier& classifier,
1037 bool* ok);
1038 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
1039 ExpressionClassifier* classifier, bool* ok);
1040 void AddTemplateExpression(ExpressionT);
1041 ExpressionT ParseSuperExpression(bool is_new,
1042 ExpressionClassifier* classifier, bool* ok);
1043 ExpressionT ParseNewTargetExpression(bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001044
1045 void ParseFormalParameter(FormalParametersT* parameters,
1046 ExpressionClassifier* classifier, bool* ok);
1047 void ParseFormalParameterList(FormalParametersT* parameters,
1048 ExpressionClassifier* classifier, bool* ok);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001049 void CheckArityRestrictions(int param_count, FunctionKind function_type,
1050 bool has_rest, int formals_start_pos,
1051 int formals_end_pos, bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001052
1053 bool IsNextLetKeyword();
1054
1055 // Checks if the expression is a valid reference expression (e.g., on the
1056 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1057 // we allow calls for web compatibility and rewrite them to a runtime throw.
1058 ExpressionT CheckAndRewriteReferenceExpression(
1059 ExpressionT expression, int beg_pos, int end_pos,
1060 MessageTemplate::Template message, bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001061 ExpressionT CheckAndRewriteReferenceExpression(
1062 ExpressionT expression, int beg_pos, int end_pos,
1063 MessageTemplate::Template message, ParseErrorType type, bool* ok);
1064
1065 bool IsValidReferenceExpression(ExpressionT expression);
1066
1067 bool IsAssignableIdentifier(ExpressionT expression) {
1068 if (!Traits::IsIdentifier(expression)) return false;
1069 if (is_strict(language_mode()) &&
1070 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
1071 return false;
1072 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001073 return true;
1074 }
1075
Ben Murdoch097c5b22016-05-18 11:27:45 +01001076 bool IsValidPattern(ExpressionT expression) {
1077 return expression->IsObjectLiteral() || expression->IsArrayLiteral();
1078 }
1079
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001080 // Keep track of eval() calls since they disable all local variable
1081 // optimizations. This checks if expression is an eval call, and if yes,
1082 // forwards the information to scope.
1083 void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) {
1084 if (Traits::IsIdentifier(expression) &&
1085 Traits::IsEval(Traits::AsIdentifier(expression))) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001086 scope->RecordEvalCall();
Ben Murdochda12d292016-06-02 14:46:10 +01001087 if (is_sloppy(scope->language_mode())) {
1088 // For sloppy scopes we also have to record the call at function level,
1089 // in case it includes declarations that will be hoisted.
1090 scope->DeclarationScope()->RecordEvalCall();
1091 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001092 }
1093 }
1094
1095 // Used to validate property names in object literals and class literals
1096 enum PropertyKind {
1097 kAccessorProperty,
1098 kValueProperty,
1099 kMethodProperty
1100 };
1101
1102 class ObjectLiteralCheckerBase {
1103 public:
1104 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
1105
1106 virtual void CheckProperty(Token::Value property, PropertyKind type,
Ben Murdochc5610432016-08-08 18:44:38 +01001107 MethodKind method_type, bool* ok) = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001108
1109 virtual ~ObjectLiteralCheckerBase() {}
1110
1111 protected:
1112 ParserBase* parser() const { return parser_; }
1113 Scanner* scanner() const { return parser_->scanner(); }
1114
1115 private:
1116 ParserBase* parser_;
1117 };
1118
1119 // Validation per ES6 object literals.
1120 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
1121 public:
1122 explicit ObjectLiteralChecker(ParserBase* parser)
1123 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
1124
Ben Murdochc5610432016-08-08 18:44:38 +01001125 void CheckProperty(Token::Value property, PropertyKind type,
1126 MethodKind method_type, bool* ok) override;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001127
1128 private:
1129 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
1130
1131 bool has_seen_proto_;
1132 };
1133
1134 // Validation per ES6 class literals.
1135 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
1136 public:
1137 explicit ClassLiteralChecker(ParserBase* parser)
1138 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
1139
Ben Murdochc5610432016-08-08 18:44:38 +01001140 void CheckProperty(Token::Value property, PropertyKind type,
1141 MethodKind method_type, bool* ok) override;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001142
1143 private:
1144 bool IsConstructor() {
1145 return this->scanner()->LiteralMatches("constructor", 11);
1146 }
1147 bool IsPrototype() {
1148 return this->scanner()->LiteralMatches("prototype", 9);
1149 }
1150
1151 bool has_seen_constructor_;
1152 };
1153
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001154 Scope* scope_; // Scope stack.
1155 FunctionState* function_state_; // Function state stack.
1156 v8::Extension* extension_;
1157 FuncNameInferrer* fni_;
1158 AstValueFactory* ast_value_factory_; // Not owned.
1159 ParserRecorder* log_;
1160 Mode mode_;
Ben Murdochc5610432016-08-08 18:44:38 +01001161 bool parsing_module_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001162 uintptr_t stack_limit_;
1163
1164 private:
1165 Zone* zone_;
1166
1167 Scanner* scanner_;
1168 bool stack_overflow_;
1169
1170 bool allow_lazy_;
1171 bool allow_natives_;
Ben Murdochda12d292016-06-02 14:46:10 +01001172 bool allow_tailcalls_;
Ben Murdochda12d292016-06-02 14:46:10 +01001173 bool allow_harmony_restrictive_declarations_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001174 bool allow_harmony_do_expressions_;
Ben Murdochc5610432016-08-08 18:44:38 +01001175 bool allow_harmony_for_in_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001176 bool allow_harmony_function_name_;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001177 bool allow_harmony_function_sent_;
Ben Murdochc5610432016-08-08 18:44:38 +01001178 bool allow_harmony_async_await_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001179};
1180
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001181template <class Traits>
1182ParserBase<Traits>::FunctionState::FunctionState(
1183 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1184 FunctionKind kind, typename Traits::Type::Factory* factory)
1185 : next_materialized_literal_index_(0),
1186 expected_property_count_(0),
1187 this_location_(Scanner::Location::invalid()),
1188 return_location_(Scanner::Location::invalid()),
1189 super_location_(Scanner::Location::invalid()),
1190 kind_(kind),
1191 generator_object_variable_(NULL),
1192 function_state_stack_(function_state_stack),
1193 outer_function_state_(*function_state_stack),
1194 scope_stack_(scope_stack),
1195 outer_scope_(*scope_stack),
Ben Murdochc5610432016-08-08 18:44:38 +01001196 tail_call_expressions_(scope->zone()),
1197 return_expr_context_(ReturnExprContext::kInsideValidBlock),
Ben Murdoch097c5b22016-05-18 11:27:45 +01001198 non_patterns_to_rewrite_(0, scope->zone()),
Ben Murdochc5610432016-08-08 18:44:38 +01001199 factory_(factory),
1200 next_function_is_parenthesized_(false),
1201 this_function_is_parenthesized_(false) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001202 *scope_stack_ = scope;
1203 *function_state_stack = this;
Ben Murdochc5610432016-08-08 18:44:38 +01001204 if (outer_function_state_) {
1205 this_function_is_parenthesized_ =
1206 outer_function_state_->next_function_is_parenthesized_;
1207 outer_function_state_->next_function_is_parenthesized_ = false;
1208 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001209}
1210
1211
1212template <class Traits>
1213ParserBase<Traits>::FunctionState::~FunctionState() {
1214 *scope_stack_ = outer_scope_;
1215 *function_state_stack_ = outer_function_state_;
1216}
1217
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001218template <class Traits>
1219void ParserBase<Traits>::GetUnexpectedTokenMessage(
Ben Murdochda12d292016-06-02 14:46:10 +01001220 Token::Value token, MessageTemplate::Template* message,
1221 Scanner::Location* location, const char** arg,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001222 MessageTemplate::Template default_) {
Ben Murdochda12d292016-06-02 14:46:10 +01001223 *arg = nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224 switch (token) {
1225 case Token::EOS:
1226 *message = MessageTemplate::kUnexpectedEOS;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001227 break;
1228 case Token::SMI:
1229 case Token::NUMBER:
1230 *message = MessageTemplate::kUnexpectedTokenNumber;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001231 break;
1232 case Token::STRING:
1233 *message = MessageTemplate::kUnexpectedTokenString;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001234 break;
1235 case Token::IDENTIFIER:
1236 *message = MessageTemplate::kUnexpectedTokenIdentifier;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001237 break;
Ben Murdochc5610432016-08-08 18:44:38 +01001238 case Token::AWAIT:
1239 case Token::ENUM:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001240 *message = MessageTemplate::kUnexpectedReserved;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001241 break;
1242 case Token::LET:
1243 case Token::STATIC:
1244 case Token::YIELD:
1245 case Token::FUTURE_STRICT_RESERVED_WORD:
1246 *message = is_strict(language_mode())
1247 ? MessageTemplate::kUnexpectedStrictReserved
1248 : MessageTemplate::kUnexpectedTokenIdentifier;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001249 break;
1250 case Token::TEMPLATE_SPAN:
1251 case Token::TEMPLATE_TAIL:
1252 *message = MessageTemplate::kUnexpectedTemplateString;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001253 break;
1254 case Token::ESCAPED_STRICT_RESERVED_WORD:
1255 case Token::ESCAPED_KEYWORD:
1256 *message = MessageTemplate::kInvalidEscapedReservedWord;
Ben Murdochda12d292016-06-02 14:46:10 +01001257 break;
1258 case Token::ILLEGAL:
1259 if (scanner()->has_error()) {
1260 *message = scanner()->error();
1261 *location = scanner()->error_location();
1262 } else {
1263 *message = MessageTemplate::kInvalidOrUnexpectedToken;
1264 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001265 break;
1266 default:
1267 const char* name = Token::String(token);
1268 DCHECK(name != NULL);
1269 *arg = name;
1270 break;
1271 }
1272}
1273
1274
1275template <class Traits>
1276void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1277 return ReportUnexpectedTokenAt(scanner_->location(), token);
1278}
1279
1280
1281template <class Traits>
1282void ParserBase<Traits>::ReportUnexpectedTokenAt(
1283 Scanner::Location source_location, Token::Value token,
1284 MessageTemplate::Template message) {
1285 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +01001286 GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001287 Traits::ReportMessageAt(source_location, message, arg);
1288}
1289
1290
1291template <class Traits>
1292typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1293 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001294 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001295 auto result = ParseAndClassifyIdentifier(&classifier, ok);
1296 if (!*ok) return Traits::EmptyIdentifier();
1297
1298 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1299 ValidateAssignmentPattern(&classifier, ok);
1300 if (!*ok) return Traits::EmptyIdentifier();
1301 ValidateBindingPattern(&classifier, ok);
1302 if (!*ok) return Traits::EmptyIdentifier();
1303 }
1304
1305 return result;
1306}
1307
1308
1309template <class Traits>
1310typename ParserBase<Traits>::IdentifierT
1311ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1312 bool* ok) {
1313 Token::Value next = Next();
Ben Murdochc5610432016-08-08 18:44:38 +01001314 if (next == Token::IDENTIFIER || next == Token::ASYNC ||
1315 (next == Token::AWAIT && !parsing_module_)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001316 IdentifierT name = this->GetSymbol(scanner());
1317 // When this function is used to read a formal parameter, we don't always
1318 // know whether the function is going to be strict or sloppy. Indeed for
1319 // arrow functions we don't always know that the identifier we are reading
1320 // is actually a formal parameter. Therefore besides the errors that we
1321 // must detect because we know we're in strict mode, we also record any
1322 // error that we might make in the future once we know the language mode.
1323 if (this->IsEval(name)) {
1324 classifier->RecordStrictModeFormalParameterError(
1325 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1326 if (is_strict(language_mode())) {
1327 classifier->RecordBindingPatternError(
1328 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1329 }
1330 }
1331 if (this->IsArguments(name)) {
1332 scope_->RecordArgumentsUsage();
1333 classifier->RecordStrictModeFormalParameterError(
1334 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1335 if (is_strict(language_mode())) {
1336 classifier->RecordBindingPatternError(
1337 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1338 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001339 }
Ben Murdochc5610432016-08-08 18:44:38 +01001340 if (this->IsAwait(name)) {
1341 if (is_async_function()) {
1342 classifier->RecordPatternError(
1343 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1344 }
1345 classifier->RecordAsyncArrowFormalParametersError(
1346 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1347 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001348
1349 if (classifier->duplicate_finder() != nullptr &&
1350 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1351 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1352 }
1353 return name;
1354 } else if (is_sloppy(language_mode()) &&
1355 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1356 next == Token::ESCAPED_STRICT_RESERVED_WORD ||
1357 next == Token::LET || next == Token::STATIC ||
1358 (next == Token::YIELD && !is_generator()))) {
1359 classifier->RecordStrictModeFormalParameterError(
1360 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1361 if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1362 is_strict(language_mode())) {
1363 ReportUnexpectedToken(next);
1364 *ok = false;
1365 return Traits::EmptyIdentifier();
1366 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001367 if (next == Token::LET ||
1368 (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1369 scanner()->is_literal_contextual_keyword(CStrVector("let")))) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001370 classifier->RecordLetPatternError(scanner()->location(),
1371 MessageTemplate::kLetInLexicalBinding);
1372 }
1373 return this->GetSymbol(scanner());
1374 } else {
1375 this->ReportUnexpectedToken(next);
1376 *ok = false;
1377 return Traits::EmptyIdentifier();
1378 }
1379}
1380
1381
1382template <class Traits>
1383typename ParserBase<Traits>::IdentifierT
1384ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
1385 bool is_generator, bool* is_strict_reserved, bool* ok) {
1386 Token::Value next = Next();
Ben Murdochc5610432016-08-08 18:44:38 +01001387 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_) ||
1388 next == Token::ASYNC) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001389 *is_strict_reserved = false;
1390 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1391 next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
1392 *is_strict_reserved = true;
1393 } else {
1394 ReportUnexpectedToken(next);
1395 *ok = false;
1396 return Traits::EmptyIdentifier();
1397 }
1398
1399 IdentifierT name = this->GetSymbol(scanner());
1400 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1401 return name;
1402}
1403
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001404template <class Traits>
1405typename ParserBase<Traits>::IdentifierT
1406ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1407 Token::Value next = Next();
Ben Murdochc5610432016-08-08 18:44:38 +01001408 if (next != Token::IDENTIFIER && next != Token::ASYNC &&
1409 next != Token::ENUM && next != Token::AWAIT && next != Token::LET &&
1410 next != Token::STATIC && next != Token::YIELD &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001411 next != Token::FUTURE_STRICT_RESERVED_WORD &&
1412 next != Token::ESCAPED_KEYWORD &&
1413 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1414 this->ReportUnexpectedToken(next);
1415 *ok = false;
1416 return Traits::EmptyIdentifier();
1417 }
1418
1419 IdentifierT name = this->GetSymbol(scanner());
1420 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1421 return name;
1422}
1423
1424
1425template <class Traits>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001426typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1427 bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
1428 int pos = peek_position();
1429 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1430 Next();
1431 ReportMessage(MessageTemplate::kUnterminatedRegExp);
1432 *ok = false;
1433 return Traits::EmptyExpression();
1434 }
1435
1436 int literal_index = function_state_->NextMaterializedLiteralIndex();
1437
1438 IdentifierT js_pattern = this->GetNextSymbol(scanner());
1439 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
1440 if (flags.IsNothing()) {
1441 Next();
1442 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1443 *ok = false;
1444 return Traits::EmptyExpression();
1445 }
1446 int js_flags = flags.FromJust();
1447 Next();
Ben Murdochda12d292016-06-02 14:46:10 +01001448 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001449}
1450
1451
1452#define CHECK_OK ok); \
1453 if (!*ok) return this->EmptyExpression(); \
1454 ((void)0
1455#define DUMMY ) // to make indentation work
1456#undef DUMMY
1457
1458// Used in functions where the return type is not ExpressionT.
1459#define CHECK_OK_CUSTOM(x) ok); \
1460 if (!*ok) return this->x(); \
1461 ((void)0
1462#define DUMMY ) // to make indentation work
1463#undef DUMMY
1464
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001465template <class Traits>
1466typename ParserBase<Traits>::ExpressionT
1467ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
Ben Murdochc5610432016-08-08 18:44:38 +01001468 bool* is_async, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001469 // PrimaryExpression ::
1470 // 'this'
1471 // 'null'
1472 // 'true'
1473 // 'false'
1474 // Identifier
1475 // Number
1476 // String
1477 // ArrayLiteral
1478 // ObjectLiteral
1479 // RegExpLiteral
1480 // ClassLiteral
1481 // '(' Expression ')'
1482 // TemplateLiteral
1483 // do Block
Ben Murdochc5610432016-08-08 18:44:38 +01001484 // AsyncFunctionExpression
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001485
1486 int beg_pos = peek_position();
1487 switch (peek()) {
1488 case Token::THIS: {
1489 BindingPatternUnexpectedToken(classifier);
1490 Consume(Token::THIS);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001491 return this->ThisExpression(scope_, factory(), beg_pos);
1492 }
1493
1494 case Token::NULL_LITERAL:
1495 case Token::TRUE_LITERAL:
1496 case Token::FALSE_LITERAL:
1497 BindingPatternUnexpectedToken(classifier);
1498 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1499 case Token::SMI:
1500 case Token::NUMBER:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001501 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001502 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1503
Ben Murdochc5610432016-08-08 18:44:38 +01001504 case Token::ASYNC:
1505 if (allow_harmony_async_await() &&
1506 !scanner()->HasAnyLineTerminatorAfterNext() &&
1507 PeekAhead() == Token::FUNCTION) {
1508 Consume(Token::ASYNC);
1509 return this->ParseAsyncFunctionExpression(CHECK_OK);
1510 }
1511 // CoverCallExpressionAndAsyncArrowHead
1512 *is_async = true;
1513 /* falls through */
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001514 case Token::IDENTIFIER:
1515 case Token::LET:
1516 case Token::STATIC:
1517 case Token::YIELD:
Ben Murdochc5610432016-08-08 18:44:38 +01001518 case Token::AWAIT:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001519 case Token::ESCAPED_STRICT_RESERVED_WORD:
1520 case Token::FUTURE_STRICT_RESERVED_WORD: {
1521 // Using eval or arguments in this context is OK even in strict mode.
1522 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
1523 return this->ExpressionFromIdentifier(
1524 name, beg_pos, scanner()->location().end_pos, scope_, factory());
1525 }
1526
1527 case Token::STRING: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001528 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001529 Consume(Token::STRING);
1530 return this->ExpressionFromString(beg_pos, scanner(), factory());
1531 }
1532
1533 case Token::ASSIGN_DIV:
1534 classifier->RecordBindingPatternError(
1535 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1536 return this->ParseRegExpLiteral(true, classifier, ok);
1537
1538 case Token::DIV:
1539 classifier->RecordBindingPatternError(
1540 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1541 return this->ParseRegExpLiteral(false, classifier, ok);
1542
1543 case Token::LBRACK:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001544 return this->ParseArrayLiteral(classifier, ok);
1545
1546 case Token::LBRACE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001547 return this->ParseObjectLiteral(classifier, ok);
1548
1549 case Token::LPAREN: {
1550 // Arrow function formal parameters are either a single identifier or a
1551 // list of BindingPattern productions enclosed in parentheses.
1552 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
1553 // is_valid_binding_pattern() check to detect multiple levels of
1554 // parenthesization.
1555 if (!classifier->is_valid_binding_pattern()) {
1556 ArrowFormalParametersUnexpectedToken(classifier);
1557 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001558 classifier->RecordPatternError(scanner()->peek_location(),
1559 MessageTemplate::kUnexpectedToken,
1560 Token::String(Token::LPAREN));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001561 Consume(Token::LPAREN);
1562 if (Check(Token::RPAREN)) {
1563 // ()=>x. The continuation that looks for the => is in
1564 // ParseAssignmentExpression.
1565 classifier->RecordExpressionError(scanner()->location(),
1566 MessageTemplate::kUnexpectedToken,
1567 Token::String(Token::RPAREN));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001568 return factory()->NewEmptyParentheses(beg_pos);
1569 } else if (Check(Token::ELLIPSIS)) {
1570 // (...x)=>x. The continuation that looks for the => is in
1571 // ParseAssignmentExpression.
1572 int ellipsis_pos = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001573 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001574 classifier->RecordExpressionError(scanner()->location(),
1575 MessageTemplate::kUnexpectedToken,
1576 Token::String(Token::ELLIPSIS));
1577 classifier->RecordNonSimpleParameter();
1578 ExpressionT expr =
1579 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001580 if (!this->IsIdentifier(expr) && !IsValidPattern(expr)) {
1581 classifier->RecordArrowFormalParametersError(
1582 Scanner::Location(ellipsis_pos, scanner()->location().end_pos),
1583 MessageTemplate::kInvalidRestParameter);
1584 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001585 if (peek() == Token::COMMA) {
1586 ReportMessageAt(scanner()->peek_location(),
1587 MessageTemplate::kParamAfterRest);
1588 *ok = false;
1589 return this->EmptyExpression();
1590 }
1591 Expect(Token::RPAREN, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001592 return factory()->NewSpread(expr, ellipsis_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001593 }
1594 // Heuristically try to detect immediately called functions before
1595 // seeing the call parentheses.
Ben Murdochc5610432016-08-08 18:44:38 +01001596 function_state_->next_function_is_parenthesized(peek() ==
1597 Token::FUNCTION);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001598 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001599 Expect(Token::RPAREN, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001600 return expr;
1601 }
1602
1603 case Token::CLASS: {
1604 BindingPatternUnexpectedToken(classifier);
1605 Consume(Token::CLASS);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001606 int class_token_position = position();
1607 IdentifierT name = this->EmptyIdentifier();
1608 bool is_strict_reserved_name = false;
1609 Scanner::Location class_name_location = Scanner::Location::invalid();
1610 if (peek_any_identifier()) {
1611 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1612 CHECK_OK);
1613 class_name_location = scanner()->location();
1614 }
Ben Murdochda12d292016-06-02 14:46:10 +01001615 return this->ParseClassLiteral(classifier, name, class_name_location,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001616 is_strict_reserved_name,
1617 class_token_position, ok);
1618 }
1619
1620 case Token::TEMPLATE_SPAN:
1621 case Token::TEMPLATE_TAIL:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001622 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001623 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
1624 classifier, ok);
1625
1626 case Token::MOD:
1627 if (allow_natives() || extension_ != NULL) {
1628 BindingPatternUnexpectedToken(classifier);
1629 return this->ParseV8Intrinsic(ok);
1630 }
1631 break;
1632
1633 case Token::DO:
1634 if (allow_harmony_do_expressions()) {
1635 BindingPatternUnexpectedToken(classifier);
1636 return Traits::ParseDoExpression(ok);
1637 }
1638 break;
1639
1640 default:
1641 break;
1642 }
1643
1644 ReportUnexpectedToken(Next());
1645 *ok = false;
1646 return this->EmptyExpression();
1647}
1648
1649
1650template <class Traits>
1651typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1652 bool accept_IN, bool* ok) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001653 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001654 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001655 Traits::RewriteNonPattern(&classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001656 return result;
1657}
1658
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001659template <class Traits>
1660typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1661 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001662 // Expression ::
1663 // AssignmentExpression
1664 // Expression ',' AssignmentExpression
1665
Ben Murdoch097c5b22016-05-18 11:27:45 +01001666 ExpressionClassifier binding_classifier(this);
1667 ExpressionT result =
1668 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
1669 classifier->Accumulate(&binding_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001670 ExpressionClassifier::AllProductions);
1671 bool is_simple_parameter_list = this->IsIdentifier(result);
1672 bool seen_rest = false;
1673 while (peek() == Token::COMMA) {
Ben Murdochc5610432016-08-08 18:44:38 +01001674 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001675 if (seen_rest) {
1676 // At this point the production can't possibly be valid, but we don't know
1677 // which error to signal.
1678 classifier->RecordArrowFormalParametersError(
1679 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
1680 }
1681 Consume(Token::COMMA);
1682 bool is_rest = false;
1683 if (peek() == Token::ELLIPSIS) {
1684 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1685 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1686 // valid expression or binding pattern.
1687 ExpressionUnexpectedToken(classifier);
1688 BindingPatternUnexpectedToken(classifier);
1689 Consume(Token::ELLIPSIS);
1690 seen_rest = is_rest = true;
1691 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001692 int pos = position(), expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001693 ExpressionT right = this->ParseAssignmentExpression(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001694 accept_IN, &binding_classifier, CHECK_OK);
1695 classifier->Accumulate(&binding_classifier,
1696 ExpressionClassifier::AllProductions);
1697 if (is_rest) {
1698 if (!this->IsIdentifier(right) && !IsValidPattern(right)) {
1699 classifier->RecordArrowFormalParametersError(
1700 Scanner::Location(pos, scanner()->location().end_pos),
1701 MessageTemplate::kInvalidRestParameter);
1702 }
1703 right = factory()->NewSpread(right, pos, expr_pos);
1704 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001705 is_simple_parameter_list =
1706 is_simple_parameter_list && this->IsIdentifier(right);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001707 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1708 }
1709 if (!is_simple_parameter_list || seen_rest) {
1710 classifier->RecordNonSimpleParameter();
1711 }
1712
1713 return result;
1714}
1715
1716
1717template <class Traits>
1718typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
1719 ExpressionClassifier* classifier, bool* ok) {
1720 // ArrayLiteral ::
1721 // '[' Expression? (',' Expression?)* ']'
1722
1723 int pos = peek_position();
1724 typename Traits::Type::ExpressionList values =
1725 this->NewExpressionList(4, zone_);
1726 int first_spread_index = -1;
1727 Expect(Token::LBRACK, CHECK_OK);
1728 while (peek() != Token::RBRACK) {
1729 ExpressionT elem = this->EmptyExpression();
1730 if (peek() == Token::COMMA) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001731 elem = this->GetLiteralTheHole(peek_position(), factory());
1732 } else if (peek() == Token::ELLIPSIS) {
1733 int start_pos = peek_position();
1734 Consume(Token::ELLIPSIS);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001735 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001736 ExpressionT argument =
1737 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01001738 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001739 elem = factory()->NewSpread(argument, start_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001740
1741 if (first_spread_index < 0) {
1742 first_spread_index = values->length();
1743 }
1744
1745 if (argument->IsAssignment()) {
1746 classifier->RecordPatternError(
1747 Scanner::Location(start_pos, scanner()->location().end_pos),
1748 MessageTemplate::kInvalidDestructuringTarget);
1749 } else {
1750 CheckDestructuringElement(argument, classifier, start_pos,
1751 scanner()->location().end_pos);
1752 }
1753
1754 if (peek() == Token::COMMA) {
1755 classifier->RecordPatternError(
1756 Scanner::Location(start_pos, scanner()->location().end_pos),
1757 MessageTemplate::kElementAfterRest);
1758 }
1759 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001760 int beg_pos = peek_position();
1761 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01001762 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001763 CheckDestructuringElement(elem, classifier, beg_pos,
1764 scanner()->location().end_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001765 }
1766 values->Add(elem, zone_);
1767 if (peek() != Token::RBRACK) {
1768 Expect(Token::COMMA, CHECK_OK);
1769 }
1770 }
1771 Expect(Token::RBRACK, CHECK_OK);
1772
1773 // Update the scope information before the pre-parsing bailout.
1774 int literal_index = function_state_->NextMaterializedLiteralIndex();
1775
Ben Murdochda12d292016-06-02 14:46:10 +01001776 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index,
1777 literal_index, pos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001778 if (first_spread_index >= 0) {
1779 result = factory()->NewRewritableExpression(result);
1780 Traits::QueueNonPatternForRewriting(result);
1781 }
1782 return result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001783}
1784
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001785template <class Traits>
1786typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
Ben Murdochc5610432016-08-08 18:44:38 +01001787 IdentifierT* name, bool* is_get, bool* is_set, bool* is_await,
1788 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001789 Token::Value token = peek();
1790 int pos = peek_position();
1791
1792 // For non computed property names we normalize the name a bit:
1793 //
1794 // "12" -> 12
1795 // 12.3 -> "12.3"
1796 // 12.30 -> "12.3"
1797 // identifier -> "identifier"
1798 //
1799 // This is important because we use the property name as a key in a hash
1800 // table when we compute constant properties.
1801 switch (token) {
1802 case Token::STRING:
1803 Consume(Token::STRING);
1804 *name = this->GetSymbol(scanner());
1805 break;
1806
1807 case Token::SMI:
1808 Consume(Token::SMI);
1809 *name = this->GetNumberAsSymbol(scanner());
1810 break;
1811
1812 case Token::NUMBER:
1813 Consume(Token::NUMBER);
1814 *name = this->GetNumberAsSymbol(scanner());
1815 break;
1816
1817 case Token::LBRACK: {
1818 *is_computed_name = true;
1819 Consume(Token::LBRACK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001820 ExpressionClassifier computed_name_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001821 ExpressionT expression =
1822 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001823 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK);
1824 classifier->Accumulate(&computed_name_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001825 ExpressionClassifier::ExpressionProductions);
1826 Expect(Token::RBRACK, CHECK_OK);
1827 return expression;
1828 }
1829
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001830 default:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001831 *name = ParseIdentifierName(CHECK_OK);
1832 scanner()->IsGetOrSet(is_get, is_set);
Ben Murdochc5610432016-08-08 18:44:38 +01001833 if (this->IsAwait(*name)) {
1834 *is_await = true;
1835 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001836 break;
1837 }
1838
1839 uint32_t index;
1840 return this->IsArrayIndex(*name, &index)
1841 ? factory()->NewNumberLiteral(index, pos)
1842 : factory()->NewStringLiteral(*name, pos);
1843}
1844
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001845template <class Traits>
1846typename ParserBase<Traits>::ObjectLiteralPropertyT
1847ParserBase<Traits>::ParsePropertyDefinition(
1848 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
Ben Murdochc5610432016-08-08 18:44:38 +01001849 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001850 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
Ben Murdochc5610432016-08-08 18:44:38 +01001851 DCHECK(!in_class || IsStaticMethod(method_kind) ||
1852 has_seen_constructor != nullptr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001853 ExpressionT value = this->EmptyExpression();
1854 bool is_get = false;
1855 bool is_set = false;
Ben Murdochc5610432016-08-08 18:44:38 +01001856 bool is_await = false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001857 bool is_generator = Check(Token::MUL);
Ben Murdochc5610432016-08-08 18:44:38 +01001858 bool is_async = false;
1859 const bool is_static = IsStaticMethod(method_kind);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001860
1861 Token::Value name_token = peek();
Ben Murdochc5610432016-08-08 18:44:38 +01001862
1863 if (is_generator) {
1864 method_kind |= MethodKind::Generator;
1865 } else if (allow_harmony_async_await() && name_token == Token::ASYNC &&
1866 !scanner()->HasAnyLineTerminatorAfterNext() &&
1867 PeekAhead() != Token::LPAREN && PeekAhead()) {
1868 is_async = true;
1869 }
1870
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001871 int next_beg_pos = scanner()->peek_location().beg_pos;
1872 int next_end_pos = scanner()->peek_location().end_pos;
Ben Murdochc5610432016-08-08 18:44:38 +01001873 ExpressionT name_expression = ParsePropertyName(
1874 name, &is_get, &is_set, &is_await, is_computed_name, classifier,
1875 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001876
1877 if (fni_ != nullptr && !*is_computed_name) {
1878 this->PushLiteralName(fni_, *name);
1879 }
1880
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001881 if (!in_class && !is_generator) {
Ben Murdochc5610432016-08-08 18:44:38 +01001882 DCHECK(!IsStaticMethod(method_kind));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001883
1884 if (peek() == Token::COLON) {
1885 // PropertyDefinition
1886 // PropertyName ':' AssignmentExpression
1887 if (!*is_computed_name) {
Ben Murdochc5610432016-08-08 18:44:38 +01001888 checker->CheckProperty(name_token, kValueProperty, MethodKind::Normal,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001889 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1890 }
1891 Consume(Token::COLON);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001892 int beg_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001893 value = this->ParseAssignmentExpression(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001894 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1895 CheckDestructuringElement(value, classifier, beg_pos,
1896 scanner()->location().end_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001897
Ben Murdochc5610432016-08-08 18:44:38 +01001898 return factory()->NewObjectLiteralProperty(name_expression, value,
1899 is_static, *is_computed_name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001900 }
1901
Ben Murdochc5610432016-08-08 18:44:38 +01001902 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(),
1903 parsing_module_) &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001904 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1905 peek() == Token::ASSIGN)) {
1906 // PropertyDefinition
1907 // IdentifierReference
1908 // CoverInitializedName
1909 //
1910 // CoverInitializedName
1911 // IdentifierReference Initializer?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001912 if (classifier->duplicate_finder() != nullptr &&
1913 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1914 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1915 }
1916 if (name_token == Token::LET) {
1917 classifier->RecordLetPatternError(
1918 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1919 }
Ben Murdochc5610432016-08-08 18:44:38 +01001920 if (is_await && is_async_function()) {
1921 classifier->RecordPatternError(
1922 Scanner::Location(next_beg_pos, next_end_pos),
1923 MessageTemplate::kAwaitBindingIdentifier);
1924 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001925 ExpressionT lhs = this->ExpressionFromIdentifier(
1926 *name, next_beg_pos, next_end_pos, scope_, factory());
1927 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos);
1928
1929 if (peek() == Token::ASSIGN) {
1930 Consume(Token::ASSIGN);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001931 ExpressionClassifier rhs_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001932 ExpressionT rhs = this->ParseAssignmentExpression(
1933 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001934 Traits::RewriteNonPattern(&rhs_classifier,
1935 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1936 classifier->Accumulate(&rhs_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001937 ExpressionClassifier::ExpressionProductions);
1938 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
1939 RelocInfo::kNoPosition);
1940 classifier->RecordCoverInitializedNameError(
1941 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1942 MessageTemplate::kInvalidCoverInitializedName);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001943
1944 if (allow_harmony_function_name()) {
1945 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs);
1946 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001947 } else {
1948 value = lhs;
1949 }
1950
1951 return factory()->NewObjectLiteralProperty(
Ben Murdochc5610432016-08-08 18:44:38 +01001952 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001953 false);
1954 }
1955 }
1956
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001957 // Method definitions are never valid in patterns.
1958 classifier->RecordPatternError(
1959 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1960 MessageTemplate::kInvalidDestructuringTarget);
1961
Ben Murdochc5610432016-08-08 18:44:38 +01001962 if (is_async && !IsSpecialMethod(method_kind)) {
1963 DCHECK(!is_get);
1964 DCHECK(!is_set);
1965 bool dont_care;
1966 name_expression = ParsePropertyName(
1967 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
1968 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1969 method_kind |= MethodKind::Async;
1970 }
1971
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001972 if (is_generator || peek() == Token::LPAREN) {
1973 // MethodDefinition
1974 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1975 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1976 if (!*is_computed_name) {
Ben Murdochc5610432016-08-08 18:44:38 +01001977 checker->CheckProperty(name_token, kMethodProperty, method_kind,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001978 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1979 }
1980
Ben Murdochc5610432016-08-08 18:44:38 +01001981 FunctionKind kind = is_generator
1982 ? FunctionKind::kConciseGeneratorMethod
1983 : is_async ? FunctionKind::kAsyncConciseMethod
1984 : FunctionKind::kConciseMethod;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001985
Ben Murdochc5610432016-08-08 18:44:38 +01001986 if (in_class && !IsStaticMethod(method_kind) &&
1987 this->IsConstructor(*name)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001988 *has_seen_constructor = true;
1989 kind = has_extends ? FunctionKind::kSubclassConstructor
1990 : FunctionKind::kBaseConstructor;
1991 }
1992
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001993 value = this->ParseFunctionLiteral(
1994 *name, scanner()->location(), kSkipFunctionNameCheck, kind,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001995 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
1996 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001997
1998 return factory()->NewObjectLiteralProperty(name_expression, value,
1999 ObjectLiteralProperty::COMPUTED,
2000 is_static, *is_computed_name);
2001 }
2002
Ben Murdochc5610432016-08-08 18:44:38 +01002003 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002004 // ClassElement (static)
2005 // 'static' MethodDefinition
2006 *name = this->EmptyIdentifier();
2007 ObjectLiteralPropertyT property = ParsePropertyDefinition(
Ben Murdochc5610432016-08-08 18:44:38 +01002008 checker, true, has_extends, MethodKind::Static, is_computed_name,
2009 nullptr, classifier, name, ok);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002010 Traits::RewriteNonPattern(classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002011 return property;
2012 }
2013
2014 if (is_get || is_set) {
2015 // MethodDefinition (Accessors)
2016 // get PropertyName '(' ')' '{' FunctionBody '}'
2017 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2018 *name = this->EmptyIdentifier();
2019 bool dont_care = false;
2020 name_token = peek();
2021
2022 name_expression = ParsePropertyName(
Ben Murdochc5610432016-08-08 18:44:38 +01002023 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002024 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002025
2026 if (!*is_computed_name) {
Ben Murdochc5610432016-08-08 18:44:38 +01002027 checker->CheckProperty(name_token, kAccessorProperty, method_kind,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002028 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2029 }
2030
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002031 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002032 *name, scanner()->location(), kSkipFunctionNameCheck,
2033 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction,
2034 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002035 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2036
2037 // Make sure the name expression is a string since we need a Name for
2038 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2039 // statically we can skip the extra runtime check.
2040 if (!*is_computed_name) {
2041 name_expression =
2042 factory()->NewStringLiteral(*name, name_expression->position());
2043 }
2044
2045 return factory()->NewObjectLiteralProperty(
2046 name_expression, value,
2047 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2048 is_static, *is_computed_name);
2049 }
2050
2051 Token::Value next = Next();
2052 ReportUnexpectedToken(next);
2053 *ok = false;
2054 return this->EmptyObjectLiteralProperty();
2055}
2056
2057
2058template <class Traits>
2059typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2060 ExpressionClassifier* classifier, bool* ok) {
2061 // ObjectLiteral ::
2062 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2063
2064 int pos = peek_position();
2065 typename Traits::Type::PropertyList properties =
2066 this->NewPropertyList(4, zone_);
2067 int number_of_boilerplate_properties = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002068 bool has_computed_names = false;
2069 ObjectLiteralChecker checker(this);
2070
2071 Expect(Token::LBRACE, CHECK_OK);
2072
2073 while (peek() != Token::RBRACE) {
2074 FuncNameInferrer::State fni_state(fni_);
2075
2076 const bool in_class = false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002077 const bool has_extends = false;
2078 bool is_computed_name = false;
2079 IdentifierT name = this->EmptyIdentifier();
2080 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
Ben Murdochc5610432016-08-08 18:44:38 +01002081 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name,
2082 NULL, classifier, &name, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002083
2084 if (is_computed_name) {
2085 has_computed_names = true;
2086 }
2087
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002088 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2089 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2090 number_of_boilerplate_properties++;
2091 }
2092 properties->Add(property, zone());
2093
2094 if (peek() != Token::RBRACE) {
2095 // Need {} because of the CHECK_OK macro.
2096 Expect(Token::COMMA, CHECK_OK);
2097 }
2098
2099 if (fni_ != nullptr) fni_->Infer();
2100
2101 if (allow_harmony_function_name()) {
2102 Traits::SetFunctionNameFromPropertyName(property, name);
2103 }
2104 }
2105 Expect(Token::RBRACE, CHECK_OK);
2106
2107 // Computation of literal_index must happen before pre parse bailout.
2108 int literal_index = function_state_->NextMaterializedLiteralIndex();
2109
2110 return factory()->NewObjectLiteral(properties,
2111 literal_index,
2112 number_of_boilerplate_properties,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002113 pos);
2114}
2115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002116template <class Traits>
2117typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
Ben Murdochc5610432016-08-08 18:44:38 +01002118 Scanner::Location* first_spread_arg_loc, bool maybe_arrow,
2119 ExpressionClassifier* classifier, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002120 // Arguments ::
2121 // '(' (AssignmentExpression)*[','] ')'
2122
2123 Scanner::Location spread_arg = Scanner::Location::invalid();
2124 typename Traits::Type::ExpressionList result =
2125 this->NewExpressionList(4, zone_);
2126 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2127 bool done = (peek() == Token::RPAREN);
2128 bool was_unspread = false;
2129 int unspread_sequences_count = 0;
2130 while (!done) {
2131 int start_pos = peek_position();
2132 bool is_spread = Check(Token::ELLIPSIS);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002133 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002134
2135 ExpressionT argument = this->ParseAssignmentExpression(
2136 true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
Ben Murdochc5610432016-08-08 18:44:38 +01002137 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002138 Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002139 if (is_spread) {
2140 if (!spread_arg.IsValid()) {
2141 spread_arg.beg_pos = start_pos;
2142 spread_arg.end_pos = peek_position();
2143 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002144 argument = factory()->NewSpread(argument, start_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002145 }
2146 result->Add(argument, zone_);
2147
2148 // unspread_sequences_count is the number of sequences of parameters which
2149 // are not prefixed with a spread '...' operator.
2150 if (is_spread) {
2151 was_unspread = false;
2152 } else if (!was_unspread) {
2153 was_unspread = true;
2154 unspread_sequences_count++;
2155 }
2156
2157 if (result->length() > Code::kMaxArguments) {
2158 ReportMessage(MessageTemplate::kTooManyArguments);
2159 *ok = false;
2160 return this->NullExpressionList();
2161 }
2162 done = (peek() != Token::COMMA);
2163 if (!done) {
2164 Next();
2165 }
2166 }
2167 Scanner::Location location = scanner_->location();
2168 if (Token::RPAREN != Next()) {
2169 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2170 *ok = false;
2171 return this->NullExpressionList();
2172 }
2173 *first_spread_arg_loc = spread_arg;
2174
Ben Murdochc5610432016-08-08 18:44:38 +01002175 if ((!maybe_arrow || peek() != Token::ARROW) && spread_arg.IsValid()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002176 // Unspread parameter sequences are translated into array literals in the
2177 // parser. Ensure that the number of materialized literals matches between
2178 // the parser and preparser
2179 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2180 }
2181
2182 return result;
2183}
2184
2185// Precedence = 2
2186template <class Traits>
2187typename ParserBase<Traits>::ExpressionT
Ben Murdoch097c5b22016-05-18 11:27:45 +01002188ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002189 ExpressionClassifier* classifier,
2190 bool* ok) {
2191 // AssignmentExpression ::
2192 // ConditionalExpression
2193 // ArrowFunction
2194 // YieldExpression
2195 // LeftHandSideExpression AssignmentOperator AssignmentExpression
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002196 bool is_destructuring_assignment = false;
2197 int lhs_beg_pos = peek_position();
2198
2199 if (peek() == Token::YIELD && is_generator()) {
Ben Murdochc5610432016-08-08 18:44:38 +01002200 return this->ParseYieldExpression(accept_IN, classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002201 }
2202
2203 FuncNameInferrer::State fni_state(fni_);
2204 ParserBase<Traits>::Checkpoint checkpoint(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002205 ExpressionClassifier arrow_formals_classifier(this,
2206 classifier->duplicate_finder());
Ben Murdochc5610432016-08-08 18:44:38 +01002207
2208 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC &&
2209 !scanner()->HasAnyLineTerminatorAfterNext();
2210
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002211 bool parenthesized_formals = peek() == Token::LPAREN;
Ben Murdochc5610432016-08-08 18:44:38 +01002212 if (!is_async && !parenthesized_formals) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002213 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2214 }
2215 ExpressionT expression = this->ParseConditionalExpression(
2216 accept_IN, &arrow_formals_classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002217
2218 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) {
2219 // async Identifier => AsyncConciseBody
2220 IdentifierT name =
2221 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK);
2222 expression = this->ExpressionFromIdentifier(
2223 name, position(), scanner()->location().end_pos, scope_, factory());
2224 }
2225
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002226 if (peek() == Token::ARROW) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002227 classifier->RecordPatternError(scanner()->peek_location(),
2228 MessageTemplate::kUnexpectedToken,
2229 Token::String(Token::ARROW));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002230 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
Ben Murdochc5610432016-08-08 18:44:38 +01002231 parenthesized_formals, is_async, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01002232 // This reads strangely, but is correct: it checks whether any
2233 // sub-expression of the parameter list failed to be a valid formal
2234 // parameter initializer. Since YieldExpressions are banned anywhere
2235 // in an arrow parameter list, this is correct.
2236 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
2237 // "YieldExpression", which is its only use.
2238 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok);
Ben Murdochc5610432016-08-08 18:44:38 +01002239
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002240 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
Ben Murdochc5610432016-08-08 18:44:38 +01002241 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE,
2242 is_async ? FunctionKind::kAsyncArrowFunction
2243 : FunctionKind::kArrowFunction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002244 // Because the arrow's parameters were parsed in the outer scope, any
2245 // usage flags that might have been triggered there need to be copied
2246 // to the arrow scope.
2247 scope_->PropagateUsageFlagsToScope(scope);
2248 FormalParametersT parameters(scope);
2249 if (!arrow_formals_classifier.is_simple_parameter_list()) {
2250 scope->SetHasNonSimpleParameters();
2251 parameters.is_simple = false;
2252 }
2253
2254 checkpoint.Restore(&parameters.materialized_literals_count);
2255
2256 scope->set_start_position(lhs_beg_pos);
2257 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2258 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2259 &duplicate_loc, CHECK_OK);
2260 if (duplicate_loc.IsValid()) {
2261 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2262 duplicate_loc);
2263 }
2264 expression = this->ParseArrowFunctionLiteral(
Ben Murdochc5610432016-08-08 18:44:38 +01002265 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002266
2267 if (fni_ != nullptr) fni_->Infer();
2268
2269 return expression;
2270 }
2271
2272 if (this->IsValidReferenceExpression(expression)) {
2273 arrow_formals_classifier.ForgiveAssignmentPatternError();
2274 }
2275
2276 // "expression" was not itself an arrow function parameter list, but it might
2277 // form part of one. Propagate speculative formal parameter error locations.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002278 // Do not merge pending non-pattern expressions yet!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002279 classifier->Accumulate(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002280 &arrow_formals_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002281 ExpressionClassifier::StandardProductions |
Ben Murdochc5610432016-08-08 18:44:38 +01002282 ExpressionClassifier::FormalParametersProductions |
2283 ExpressionClassifier::CoverInitializedNameProduction |
2284 ExpressionClassifier::AsyncArrowFormalParametersProduction |
2285 ExpressionClassifier::AsyncBindingPatternProduction,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002286 false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002287
2288 if (!Token::IsAssignmentOp(peek())) {
2289 // Parsed conditional expression only (no assignment).
Ben Murdoch097c5b22016-05-18 11:27:45 +01002290 // Now pending non-pattern expressions must be merged.
2291 classifier->MergeNonPatterns(&arrow_formals_classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002292 return expression;
2293 }
2294
Ben Murdoch097c5b22016-05-18 11:27:45 +01002295 // Now pending non-pattern expressions must be discarded.
2296 arrow_formals_classifier.Discard();
2297
Ben Murdochc5610432016-08-08 18:44:38 +01002298 CheckNoTailCallExpressions(classifier, CHECK_OK);
2299
Ben Murdochda12d292016-06-02 14:46:10 +01002300 if (IsValidPattern(expression) && peek() == Token::ASSIGN) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002301 classifier->ForgiveCoverInitializedNameError();
2302 ValidateAssignmentPattern(classifier, CHECK_OK);
2303 is_destructuring_assignment = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002304 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002305 expression = this->CheckAndRewriteReferenceExpression(
2306 expression, lhs_beg_pos, scanner()->location().end_pos,
2307 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2308 }
2309
2310 expression = this->MarkExpressionAsAssigned(expression);
2311
2312 Token::Value op = Next(); // Get assignment operator.
2313 if (op != Token::ASSIGN) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002314 classifier->RecordPatternError(scanner()->location(),
2315 MessageTemplate::kUnexpectedToken,
2316 Token::String(op));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002317 }
2318 int pos = position();
2319
Ben Murdoch097c5b22016-05-18 11:27:45 +01002320 ExpressionClassifier rhs_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002321
2322 ExpressionT right =
2323 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002324 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002325 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002326 classifier->Accumulate(
Ben Murdochc5610432016-08-08 18:44:38 +01002327 &rhs_classifier,
2328 ExpressionClassifier::ExpressionProductions |
2329 ExpressionClassifier::CoverInitializedNameProduction |
2330 ExpressionClassifier::AsyncArrowFormalParametersProduction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002331
2332 // TODO(1231235): We try to estimate the set of properties set by
2333 // constructors. We define a new property whenever there is an
2334 // assignment to a property of 'this'. We should probably only add
2335 // properties if we haven't seen them before. Otherwise we'll
2336 // probably overestimate the number of properties.
2337 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2338 function_state_->AddProperty();
2339 }
2340
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002341 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2342
2343 if (fni_ != NULL) {
2344 // Check if the right hand side is a call to avoid inferring a
2345 // name if we're dealing with "a = function(){...}();"-like
2346 // expression.
2347 if ((op == Token::INIT || op == Token::ASSIGN) &&
2348 (!right->IsCall() && !right->IsCallNew())) {
2349 fni_->Infer();
2350 } else {
2351 fni_->RemoveLastFunction();
2352 }
2353 }
2354
2355 if (op == Token::ASSIGN && allow_harmony_function_name()) {
2356 Traits::SetFunctionNameFromIdentifierRef(right, expression);
2357 }
2358
Ben Murdochda12d292016-06-02 14:46:10 +01002359 if (op == Token::ASSIGN_EXP) {
2360 DCHECK(!is_destructuring_assignment);
2361 return Traits::RewriteAssignExponentiation(expression, right, pos);
2362 }
2363
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002364 ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2365
2366 if (is_destructuring_assignment) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002367 result = factory()->NewRewritableExpression(result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002368 Traits::QueueDestructuringAssignmentForRewriting(result);
2369 }
2370
2371 return result;
2372}
2373
2374template <class Traits>
2375typename ParserBase<Traits>::ExpressionT
Ben Murdochc5610432016-08-08 18:44:38 +01002376ParserBase<Traits>::ParseYieldExpression(bool accept_IN,
2377 ExpressionClassifier* classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002378 bool* ok) {
2379 // YieldExpression ::
2380 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2381 int pos = peek_position();
2382 classifier->RecordPatternError(scanner()->peek_location(),
2383 MessageTemplate::kInvalidDestructuringTarget);
Ben Murdochda12d292016-06-02 14:46:10 +01002384 classifier->RecordFormalParameterInitializerError(
2385 scanner()->peek_location(), MessageTemplate::kYieldInParameter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002386 Expect(Token::YIELD, CHECK_OK);
2387 ExpressionT generator_object =
2388 factory()->NewVariableProxy(function_state_->generator_object_variable());
2389 ExpressionT expression = Traits::EmptyExpression();
Ben Murdochda12d292016-06-02 14:46:10 +01002390 bool delegating = false; // yield*
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002391 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
Ben Murdochda12d292016-06-02 14:46:10 +01002392 if (Check(Token::MUL)) delegating = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002393 switch (peek()) {
2394 case Token::EOS:
2395 case Token::SEMICOLON:
2396 case Token::RBRACE:
2397 case Token::RBRACK:
2398 case Token::RPAREN:
2399 case Token::COLON:
2400 case Token::COMMA:
2401 // The above set of tokens is the complete set of tokens that can appear
2402 // after an AssignmentExpression, and none of them can start an
2403 // AssignmentExpression. This allows us to avoid looking for an RHS for
Ben Murdochda12d292016-06-02 14:46:10 +01002404 // a regular yield, given only one look-ahead token.
2405 if (!delegating) break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002406 // Delegating yields require an RHS; fall through.
2407 default:
Ben Murdochc5610432016-08-08 18:44:38 +01002408 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002409 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002410 break;
2411 }
2412 }
Ben Murdochda12d292016-06-02 14:46:10 +01002413
2414 if (delegating) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002415 return Traits::RewriteYieldStar(generator_object, expression, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002416 }
Ben Murdochda12d292016-06-02 14:46:10 +01002417
2418 expression = Traits::BuildIteratorResult(expression, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002419 // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2420 // TODO(verwaest): Come up with a better solution.
2421 typename Traits::Type::YieldExpression yield =
Ben Murdochda12d292016-06-02 14:46:10 +01002422 factory()->NewYield(generator_object, expression, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002423 return yield;
2424}
2425
Ben Murdochc5610432016-08-08 18:44:38 +01002426template <class Traits>
2427typename ParserBase<Traits>::ExpressionT
2428ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier,
2429 bool* ok) {
2430 // TailCallExpression::
2431 // 'continue' MemberExpression Arguments
2432 // 'continue' CallExpression Arguments
2433 // 'continue' MemberExpression TemplateLiteral
2434 // 'continue' CallExpression TemplateLiteral
2435 Expect(Token::CONTINUE, CHECK_OK);
2436 int pos = position();
2437 int sub_expression_pos = peek_position();
2438 ExpressionT expression =
2439 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2440 CheckNoTailCallExpressions(classifier, CHECK_OK);
2441
2442 Scanner::Location loc(pos, scanner()->location().end_pos);
2443 if (!expression->IsCall()) {
2444 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
2445 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall);
2446 *ok = false;
2447 return Traits::EmptyExpression();
2448 }
2449 if (Traits::IsDirectEvalCall(expression)) {
2450 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
2451 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCallOfEval);
2452 *ok = false;
2453 return Traits::EmptyExpression();
2454 }
2455 if (!is_strict(language_mode())) {
2456 ReportMessageAt(loc, MessageTemplate::kUnexpectedSloppyTailCall);
2457 *ok = false;
2458 return Traits::EmptyExpression();
2459 }
2460 ReturnExprContext return_expr_context =
2461 function_state_->return_expr_context();
2462 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) {
2463 MessageTemplate::Template msg = MessageTemplate::kNone;
2464 switch (return_expr_context) {
2465 case ReturnExprContext::kInsideValidReturnStatement:
2466 UNREACHABLE();
2467 return Traits::EmptyExpression();
2468 case ReturnExprContext::kInsideValidBlock:
2469 msg = MessageTemplate::kUnexpectedTailCall;
2470 break;
2471 case ReturnExprContext::kInsideTryBlock:
2472 msg = MessageTemplate::kUnexpectedTailCallInTryBlock;
2473 break;
2474 case ReturnExprContext::kInsideForInOfBody:
2475 msg = MessageTemplate::kUnexpectedTailCallInForInOf;
2476 break;
2477 }
2478 ReportMessageAt(loc, msg);
2479 *ok = false;
2480 return Traits::EmptyExpression();
2481 }
2482 classifier->RecordTailCallExpressionError(
2483 loc, MessageTemplate::kUnexpectedTailCall);
2484 function_state_->AddExplicitTailCallExpression(expression, loc);
2485 return expression;
2486}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002487
2488// Precedence = 3
2489template <class Traits>
2490typename ParserBase<Traits>::ExpressionT
2491ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
2492 ExpressionClassifier* classifier,
2493 bool* ok) {
2494 // ConditionalExpression ::
2495 // LogicalOrExpression
2496 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2497
2498 int pos = peek_position();
2499 // We start using the binary expression parser for prec >= 4 only!
2500 ExpressionT expression =
2501 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2502 if (peek() != Token::CONDITIONAL) return expression;
Ben Murdochc5610432016-08-08 18:44:38 +01002503 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002504 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002505 ArrowFormalParametersUnexpectedToken(classifier);
2506 BindingPatternUnexpectedToken(classifier);
2507 Consume(Token::CONDITIONAL);
2508 // In parsing the first assignment expression in conditional
2509 // expressions we always accept the 'in' keyword; see ECMA-262,
2510 // section 11.12, page 58.
2511 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002512 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002513 Expect(Token::COLON, CHECK_OK);
2514 ExpressionT right =
2515 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002516 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002517 return factory()->NewConditional(expression, left, right, pos);
2518}
2519
2520
2521// Precedence >= 4
2522template <class Traits>
2523typename ParserBase<Traits>::ExpressionT
2524ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
2525 ExpressionClassifier* classifier,
2526 bool* ok) {
2527 DCHECK(prec >= 4);
2528 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2529 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2530 // prec1 >= 4
2531 while (Precedence(peek(), accept_IN) == prec1) {
Ben Murdochc5610432016-08-08 18:44:38 +01002532 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002533 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002534 BindingPatternUnexpectedToken(classifier);
2535 ArrowFormalParametersUnexpectedToken(classifier);
2536 Token::Value op = Next();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002537 int pos = position();
Ben Murdochda12d292016-06-02 14:46:10 +01002538
2539 const bool is_right_associative = op == Token::EXP;
2540 const int next_prec = is_right_associative ? prec1 : prec1 + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002541 ExpressionT y =
Ben Murdochda12d292016-06-02 14:46:10 +01002542 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002543 if (op != Token::OR && op != Token::AND) {
2544 CheckNoTailCallExpressions(classifier, CHECK_OK);
2545 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002546 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002547
2548 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2549 factory())) {
2550 continue;
2551 }
2552
2553 // For now we distinguish between comparisons and other binary
2554 // operations. (We could combine the two and get rid of this
2555 // code and AST node eventually.)
2556 if (Token::IsCompareOp(op)) {
2557 // We have a comparison.
2558 Token::Value cmp = op;
2559 switch (op) {
2560 case Token::NE: cmp = Token::EQ; break;
2561 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2562 default: break;
2563 }
Ben Murdochc5610432016-08-08 18:44:38 +01002564 x = factory()->NewCompareOperation(cmp, x, y, pos);
2565 if (cmp != op) {
2566 // The comparison was negated - add a NOT.
2567 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002568 }
Ben Murdochda12d292016-06-02 14:46:10 +01002569 } else if (op == Token::EXP) {
2570 x = Traits::RewriteExponentiation(x, y, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002571 } else {
2572 // We have a "normal" binary operation.
2573 x = factory()->NewBinaryOperation(op, x, y, pos);
2574 }
2575 }
2576 }
2577 return x;
2578}
2579
2580
2581template <class Traits>
2582typename ParserBase<Traits>::ExpressionT
2583ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
2584 bool* ok) {
2585 // UnaryExpression ::
2586 // PostfixExpression
2587 // 'delete' UnaryExpression
2588 // 'void' UnaryExpression
2589 // 'typeof' UnaryExpression
2590 // '++' UnaryExpression
2591 // '--' UnaryExpression
2592 // '+' UnaryExpression
2593 // '-' UnaryExpression
2594 // '~' UnaryExpression
2595 // '!' UnaryExpression
Ben Murdochc5610432016-08-08 18:44:38 +01002596 // [+Await] AwaitExpression[?Yield]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002597
2598 Token::Value op = peek();
2599 if (Token::IsUnaryOp(op)) {
2600 BindingPatternUnexpectedToken(classifier);
2601 ArrowFormalParametersUnexpectedToken(classifier);
2602
2603 op = Next();
2604 int pos = position();
2605 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002606 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002607 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002608
2609 if (op == Token::DELETE && is_strict(language_mode())) {
Ben Murdochda12d292016-06-02 14:46:10 +01002610 if (this->IsIdentifier(expression)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002611 // "delete identifier" is a syntax error in strict mode.
2612 ReportMessage(MessageTemplate::kStrictDelete);
2613 *ok = false;
2614 return this->EmptyExpression();
2615 }
2616 }
2617
Ben Murdochda12d292016-06-02 14:46:10 +01002618 if (peek() == Token::EXP) {
2619 ReportUnexpectedToken(Next());
2620 *ok = false;
2621 return this->EmptyExpression();
2622 }
2623
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002624 // Allow Traits do rewrite the expression.
2625 return this->BuildUnaryExpression(expression, op, pos, factory());
2626 } else if (Token::IsCountOp(op)) {
2627 BindingPatternUnexpectedToken(classifier);
2628 ArrowFormalParametersUnexpectedToken(classifier);
2629 op = Next();
2630 int beg_pos = peek_position();
2631 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01002632 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002633 expression = this->CheckAndRewriteReferenceExpression(
2634 expression, beg_pos, scanner()->location().end_pos,
2635 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
2636 this->MarkExpressionAsAssigned(expression);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002637 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002638
2639 return factory()->NewCountOperation(op,
2640 true /* prefix */,
2641 expression,
2642 position());
2643
Ben Murdochc5610432016-08-08 18:44:38 +01002644 } else if (is_async_function() && peek() == Token::AWAIT) {
2645 int beg_pos = peek_position();
2646 switch (PeekAhead()) {
2647 case Token::RPAREN:
2648 case Token::RBRACK:
2649 case Token::RBRACE:
2650 case Token::ASSIGN:
2651 case Token::COMMA: {
2652 Next();
2653 IdentifierT name = this->GetSymbol(scanner());
2654
2655 // Possibly async arrow formals --- record ExpressionError just in case.
2656 ExpressionUnexpectedToken(classifier);
2657 classifier->RecordAsyncBindingPatternError(
2658 Scanner::Location(beg_pos, scanner()->location().end_pos),
2659 MessageTemplate::kAwaitBindingIdentifier);
2660 classifier->RecordAsyncArrowFormalParametersError(
2661 Scanner::Location(beg_pos, scanner()->location().end_pos),
2662 MessageTemplate::kAwaitBindingIdentifier);
2663
2664 return this->ExpressionFromIdentifier(
2665 name, beg_pos, scanner()->location().end_pos, scope_, factory());
2666 }
2667 default:
2668 break;
2669 }
2670 Consume(Token::AWAIT);
2671
2672 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK);
2673
2674 classifier->RecordFormalParameterInitializerError(
2675 Scanner::Location(beg_pos, scanner()->location().end_pos),
2676 MessageTemplate::kAwaitExpressionFormalParameter);
2677 return Traits::RewriteAwaitExpression(value, beg_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002678 } else {
2679 return this->ParsePostfixExpression(classifier, ok);
2680 }
2681}
2682
2683
2684template <class Traits>
2685typename ParserBase<Traits>::ExpressionT
2686ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
2687 bool* ok) {
2688 // PostfixExpression ::
2689 // LeftHandSideExpression ('++' | '--')?
2690
2691 int lhs_beg_pos = peek_position();
2692 ExpressionT expression =
2693 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2694 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2695 Token::IsCountOp(peek())) {
Ben Murdochc5610432016-08-08 18:44:38 +01002696 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002697 BindingPatternUnexpectedToken(classifier);
2698 ArrowFormalParametersUnexpectedToken(classifier);
2699
2700 expression = this->CheckAndRewriteReferenceExpression(
2701 expression, lhs_beg_pos, scanner()->location().end_pos,
2702 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
2703 expression = this->MarkExpressionAsAssigned(expression);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002704 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002705
2706 Token::Value next = Next();
2707 expression =
2708 factory()->NewCountOperation(next,
2709 false /* postfix */,
2710 expression,
2711 position());
2712 }
2713 return expression;
2714}
2715
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002716template <class Traits>
2717typename ParserBase<Traits>::ExpressionT
2718ParserBase<Traits>::ParseLeftHandSideExpression(
2719 ExpressionClassifier* classifier, bool* ok) {
2720 // LeftHandSideExpression ::
2721 // (NewExpression | MemberExpression) ...
2722
Ben Murdochc5610432016-08-08 18:44:38 +01002723 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) {
2724 return this->ParseTailCallExpression(classifier, ok);
2725 }
2726
2727 bool is_async = false;
2728 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(
2729 classifier, &is_async, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002730
2731 while (true) {
2732 switch (peek()) {
2733 case Token::LBRACK: {
Ben Murdochc5610432016-08-08 18:44:38 +01002734 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002735 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002736 BindingPatternUnexpectedToken(classifier);
2737 ArrowFormalParametersUnexpectedToken(classifier);
2738 Consume(Token::LBRACK);
2739 int pos = position();
2740 ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002741 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002742 result = factory()->NewProperty(result, index, pos);
2743 Expect(Token::RBRACK, CHECK_OK);
2744 break;
2745 }
2746
2747 case Token::LPAREN: {
Ben Murdochc5610432016-08-08 18:44:38 +01002748 CheckNoTailCallExpressions(classifier, CHECK_OK);
2749 int pos;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002750 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002751 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002752 if (scanner()->current_token() == Token::IDENTIFIER ||
Ben Murdochc5610432016-08-08 18:44:38 +01002753 scanner()->current_token() == Token::SUPER ||
2754 scanner()->current_token() == Token::ASYNC) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002755 // For call of an identifier we want to report position of
2756 // the identifier as position of the call in the stack trace.
2757 pos = position();
2758 } else {
2759 // For other kinds of calls we record position of the parenthesis as
2760 // position of the call. Note that this is extremely important for
2761 // expressions of the form function(){...}() for which call position
2762 // should not point to the closing brace otherwise it will intersect
2763 // with positions recorded for function literal and confuse debugger.
2764 pos = peek_position();
2765 // Also the trailing parenthesis are a hint that the function will
2766 // be called immediately. If we happen to have parsed a preceding
2767 // function literal eagerly, we can also compile it eagerly.
2768 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2769 result->AsFunctionLiteral()->set_should_eager_compile();
2770 }
2771 }
2772 Scanner::Location spread_pos;
2773 typename Traits::Type::ExpressionList args =
Ben Murdochc5610432016-08-08 18:44:38 +01002774 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK);
2775
2776 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) {
2777 if (args->length()) {
2778 // async ( Arguments ) => ...
2779 return Traits::ExpressionListToExpression(args);
2780 }
2781 // async () => ...
2782 return factory()->NewEmptyParentheses(pos);
2783 }
2784
2785 ArrowFormalParametersUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002786
2787 // Keep track of eval() calls since they disable all local variable
2788 // optimizations.
2789 // The calls that need special treatment are the
2790 // direct eval calls. These calls are all of the form eval(...), with
2791 // no explicit receiver.
2792 // These calls are marked as potentially direct eval calls. Whether
2793 // they are actually direct calls to eval is determined at run time.
2794 this->CheckPossibleEvalCall(result, scope_);
2795
2796 bool is_super_call = result->IsSuperCallReference();
2797 if (spread_pos.IsValid()) {
2798 args = Traits::PrepareSpreadArguments(args);
2799 result = Traits::SpreadCall(result, args, pos);
2800 } else {
2801 result = factory()->NewCall(result, args, pos);
2802 }
2803
2804 // Explicit calls to the super constructor using super() perform an
2805 // implicit binding assignment to the 'this' variable.
2806 if (is_super_call) {
2807 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2808 result =
2809 factory()->NewAssignment(Token::INIT, this_expr, result, pos);
2810 }
2811
2812 if (fni_ != NULL) fni_->RemoveLastFunction();
2813 break;
2814 }
2815
2816 case Token::PERIOD: {
Ben Murdochc5610432016-08-08 18:44:38 +01002817 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002818 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002819 BindingPatternUnexpectedToken(classifier);
2820 ArrowFormalParametersUnexpectedToken(classifier);
2821 Consume(Token::PERIOD);
2822 int pos = position();
2823 IdentifierT name = ParseIdentifierName(CHECK_OK);
2824 result = factory()->NewProperty(
2825 result, factory()->NewStringLiteral(name, pos), pos);
2826 if (fni_ != NULL) this->PushLiteralName(fni_, name);
2827 break;
2828 }
2829
2830 case Token::TEMPLATE_SPAN:
2831 case Token::TEMPLATE_TAIL: {
Ben Murdochc5610432016-08-08 18:44:38 +01002832 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002833 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002834 BindingPatternUnexpectedToken(classifier);
2835 ArrowFormalParametersUnexpectedToken(classifier);
2836 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
2837 break;
2838 }
2839
2840 default:
2841 return result;
2842 }
2843 }
2844}
2845
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002846template <class Traits>
2847typename ParserBase<Traits>::ExpressionT
2848ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
Ben Murdochc5610432016-08-08 18:44:38 +01002849 ExpressionClassifier* classifier, bool* is_async, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002850 // NewExpression ::
2851 // ('new')+ MemberExpression
2852 //
2853 // NewTarget ::
2854 // 'new' '.' 'target'
2855
2856 // The grammar for new expressions is pretty warped. We can have several 'new'
2857 // keywords following each other, and then a MemberExpression. When we see '('
2858 // after the MemberExpression, it's associated with the rightmost unassociated
2859 // 'new' to create a NewExpression with arguments. However, a NewExpression
2860 // can also occur without arguments.
2861
2862 // Examples of new expression:
2863 // new foo.bar().baz means (new (foo.bar)()).baz
2864 // new foo()() means (new foo())()
2865 // new new foo()() means (new (new foo())())
2866 // new new foo means new (new foo)
2867 // new new foo() means new (new foo())
2868 // new new foo().bar().baz means (new (new foo()).bar()).baz
2869
2870 if (peek() == Token::NEW) {
2871 BindingPatternUnexpectedToken(classifier);
2872 ArrowFormalParametersUnexpectedToken(classifier);
2873 Consume(Token::NEW);
2874 int new_pos = position();
2875 ExpressionT result = this->EmptyExpression();
2876 if (peek() == Token::SUPER) {
2877 const bool is_new = true;
2878 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
2879 } else if (peek() == Token::PERIOD) {
2880 return ParseNewTargetExpression(CHECK_OK);
2881 } else {
Ben Murdochc5610432016-08-08 18:44:38 +01002882 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async,
2883 CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002884 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002885 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002886 if (peek() == Token::LPAREN) {
2887 // NewExpression with arguments.
2888 Scanner::Location spread_pos;
2889 typename Traits::Type::ExpressionList args =
2890 this->ParseArguments(&spread_pos, classifier, CHECK_OK);
2891
2892 if (spread_pos.IsValid()) {
2893 args = Traits::PrepareSpreadArguments(args);
2894 result = Traits::SpreadCallNew(result, args, new_pos);
2895 } else {
2896 result = factory()->NewCallNew(result, args, new_pos);
2897 }
2898 // The expression can still continue with . or [ after the arguments.
Ben Murdochc5610432016-08-08 18:44:38 +01002899 result = this->ParseMemberExpressionContinuation(result, is_async,
2900 classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002901 return result;
2902 }
2903 // NewExpression without arguments.
2904 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2905 new_pos);
2906 }
2907 // No 'new' or 'super' keyword.
Ben Murdochc5610432016-08-08 18:44:38 +01002908 return this->ParseMemberExpression(classifier, is_async, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002909}
2910
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002911template <class Traits>
2912typename ParserBase<Traits>::ExpressionT
2913ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
Ben Murdochc5610432016-08-08 18:44:38 +01002914 bool* is_async, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002915 // MemberExpression ::
2916 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
2917 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
2918
2919 // The '[' Expression ']' and '.' Identifier parts are parsed by
2920 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2921 // caller.
2922
2923 // Parse the initial primary or function expression.
2924 ExpressionT result = this->EmptyExpression();
2925 if (peek() == Token::FUNCTION) {
2926 BindingPatternUnexpectedToken(classifier);
2927 ArrowFormalParametersUnexpectedToken(classifier);
2928
2929 Consume(Token::FUNCTION);
2930 int function_token_position = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002931
2932 if (allow_harmony_function_sent() && peek() == Token::PERIOD) {
2933 // function.sent
2934 int pos = position();
2935 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK);
2936
2937 if (!is_generator()) {
2938 // TODO(neis): allow escaping into closures?
2939 ReportMessageAt(scanner()->location(),
2940 MessageTemplate::kUnexpectedFunctionSent);
2941 *ok = false;
2942 return this->EmptyExpression();
2943 }
2944
2945 return this->FunctionSentExpression(scope_, factory(), pos);
2946 }
2947
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002948 bool is_generator = Check(Token::MUL);
2949 IdentifierT name = this->EmptyIdentifier();
2950 bool is_strict_reserved_name = false;
2951 Scanner::Location function_name_location = Scanner::Location::invalid();
2952 FunctionLiteral::FunctionType function_type =
2953 FunctionLiteral::kAnonymousExpression;
2954 if (peek_any_identifier()) {
2955 name = ParseIdentifierOrStrictReservedWord(
2956 is_generator, &is_strict_reserved_name, CHECK_OK);
2957 function_name_location = scanner()->location();
2958 function_type = FunctionLiteral::kNamedExpression;
2959 }
2960 result = this->ParseFunctionLiteral(
2961 name, function_name_location,
2962 is_strict_reserved_name ? kFunctionNameIsStrictReserved
2963 : kFunctionNameValidityUnknown,
2964 is_generator ? FunctionKind::kGeneratorFunction
2965 : FunctionKind::kNormalFunction,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002966 function_token_position, function_type, language_mode(), CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002967 } else if (peek() == Token::SUPER) {
2968 const bool is_new = false;
2969 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
2970 } else {
Ben Murdochc5610432016-08-08 18:44:38 +01002971 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002972 }
2973
Ben Murdochc5610432016-08-08 18:44:38 +01002974 result =
2975 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002976 return result;
2977}
2978
2979
2980template <class Traits>
2981typename ParserBase<Traits>::ExpressionT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002982ParserBase<Traits>::ParseSuperExpression(bool is_new,
2983 ExpressionClassifier* classifier,
2984 bool* ok) {
2985 Expect(Token::SUPER, CHECK_OK);
2986 int pos = position();
2987
2988 Scope* scope = scope_->ReceiverScope();
2989 FunctionKind kind = scope->function_kind();
2990 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
2991 IsClassConstructor(kind)) {
2992 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
2993 scope->RecordSuperPropertyUsage();
2994 return this->SuperPropertyReference(scope_, factory(), pos);
2995 }
2996 // new super() is never allowed.
2997 // super() is only allowed in derived constructor
2998 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002999 // TODO(rossberg): This might not be the correct FunctionState for the
3000 // method here.
3001 function_state_->set_super_location(scanner()->location());
3002 return this->SuperCallReference(scope_, factory(), pos);
3003 }
3004 }
3005
3006 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
3007 *ok = false;
3008 return this->EmptyExpression();
3009}
3010
Ben Murdoch097c5b22016-05-18 11:27:45 +01003011template <class Traits>
3012void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
3013 const char* full_name, int pos,
3014 bool* ok) {
3015 Consume(Token::PERIOD);
3016 ExpectContextualKeyword(property_name, ok);
3017 if (!*ok) return;
3018 if (scanner()->literal_contains_escapes()) {
3019 Traits::ReportMessageAt(
3020 Scanner::Location(pos, scanner()->location().end_pos),
3021 MessageTemplate::kInvalidEscapedMetaProperty, full_name);
3022 *ok = false;
3023 }
3024}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003025
3026template <class Traits>
3027typename ParserBase<Traits>::ExpressionT
3028ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
3029 int pos = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01003030 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003031
3032 if (!scope_->ReceiverScope()->is_function_scope()) {
3033 ReportMessageAt(scanner()->location(),
3034 MessageTemplate::kUnexpectedNewTarget);
3035 *ok = false;
3036 return this->EmptyExpression();
3037 }
3038
3039 return this->NewTargetExpression(scope_, factory(), pos);
3040}
3041
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003042template <class Traits>
3043typename ParserBase<Traits>::ExpressionT
3044ParserBase<Traits>::ParseMemberExpressionContinuation(
Ben Murdochc5610432016-08-08 18:44:38 +01003045 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
3046 bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003047 // Parses this part of MemberExpression:
3048 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3049 while (true) {
3050 switch (peek()) {
3051 case Token::LBRACK: {
Ben Murdochc5610432016-08-08 18:44:38 +01003052 *is_async = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003053 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003054 BindingPatternUnexpectedToken(classifier);
3055 ArrowFormalParametersUnexpectedToken(classifier);
3056
3057 Consume(Token::LBRACK);
3058 int pos = position();
3059 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003060 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003061 expression = factory()->NewProperty(expression, index, pos);
3062 if (fni_ != NULL) {
3063 this->PushPropertyName(fni_, index);
3064 }
3065 Expect(Token::RBRACK, CHECK_OK);
3066 break;
3067 }
3068 case Token::PERIOD: {
Ben Murdochc5610432016-08-08 18:44:38 +01003069 *is_async = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003070 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003071 BindingPatternUnexpectedToken(classifier);
3072 ArrowFormalParametersUnexpectedToken(classifier);
3073
3074 Consume(Token::PERIOD);
3075 int pos = position();
3076 IdentifierT name = ParseIdentifierName(CHECK_OK);
3077 expression = factory()->NewProperty(
3078 expression, factory()->NewStringLiteral(name, pos), pos);
3079 if (fni_ != NULL) {
3080 this->PushLiteralName(fni_, name);
3081 }
3082 break;
3083 }
3084 case Token::TEMPLATE_SPAN:
3085 case Token::TEMPLATE_TAIL: {
Ben Murdochc5610432016-08-08 18:44:38 +01003086 *is_async = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003087 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003088 BindingPatternUnexpectedToken(classifier);
3089 ArrowFormalParametersUnexpectedToken(classifier);
3090 int pos;
3091 if (scanner()->current_token() == Token::IDENTIFIER) {
3092 pos = position();
3093 } else {
3094 pos = peek_position();
3095 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3096 // If the tag function looks like an IIFE, set_parenthesized() to
3097 // force eager compilation.
3098 expression->AsFunctionLiteral()->set_should_eager_compile();
3099 }
3100 }
3101 expression =
3102 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
3103 break;
3104 }
Ben Murdochda12d292016-06-02 14:46:10 +01003105 case Token::ILLEGAL: {
3106 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
3107 *ok = false;
3108 return this->EmptyExpression();
3109 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003110 default:
3111 return expression;
3112 }
3113 }
3114 DCHECK(false);
3115 return this->EmptyExpression();
3116}
3117
3118
3119template <class Traits>
3120void ParserBase<Traits>::ParseFormalParameter(
3121 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3122 // FormalParameter[Yield,GeneratorParameter] :
3123 // BindingElement[?Yield, ?GeneratorParameter]
3124 bool is_rest = parameters->has_rest;
3125
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003126 ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
3127 if (!*ok) return;
3128
3129 ValidateBindingPattern(classifier, ok);
3130 if (!*ok) return;
3131
3132 if (!Traits::IsIdentifier(pattern)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003133 parameters->is_simple = false;
3134 ValidateFormalParameterInitializer(classifier, ok);
3135 if (!*ok) return;
3136 classifier->RecordNonSimpleParameter();
3137 }
3138
3139 ExpressionT initializer = Traits::EmptyExpression();
Ben Murdochda12d292016-06-02 14:46:10 +01003140 if (!is_rest && Check(Token::ASSIGN)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003141 ExpressionClassifier init_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003142 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3143 if (!*ok) return;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003144 Traits::RewriteNonPattern(&init_classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003145 ValidateFormalParameterInitializer(&init_classifier, ok);
3146 if (!*ok) return;
3147 parameters->is_simple = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003148 init_classifier.Discard();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003149 classifier->RecordNonSimpleParameter();
Ben Murdoch097c5b22016-05-18 11:27:45 +01003150
3151 if (allow_harmony_function_name()) {
3152 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
3153 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003154 }
3155
3156 Traits::AddFormalParameter(parameters, pattern, initializer,
3157 scanner()->location().end_pos, is_rest);
3158}
3159
3160
3161template <class Traits>
3162void ParserBase<Traits>::ParseFormalParameterList(
3163 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3164 // FormalParameters[Yield,GeneratorParameter] :
3165 // [empty]
3166 // FormalParameterList[?Yield, ?GeneratorParameter]
3167 //
3168 // FormalParameterList[Yield,GeneratorParameter] :
3169 // FunctionRestParameter[?Yield]
3170 // FormalsList[?Yield, ?GeneratorParameter]
3171 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
3172 //
3173 // FormalsList[Yield,GeneratorParameter] :
3174 // FormalParameter[?Yield, ?GeneratorParameter]
3175 // FormalsList[?Yield, ?GeneratorParameter] ,
3176 // FormalParameter[?Yield,?GeneratorParameter]
3177
3178 DCHECK_EQ(0, parameters->Arity());
3179
3180 if (peek() != Token::RPAREN) {
3181 do {
3182 if (parameters->Arity() > Code::kMaxArguments) {
3183 ReportMessage(MessageTemplate::kTooManyParameters);
3184 *ok = false;
3185 return;
3186 }
3187 parameters->has_rest = Check(Token::ELLIPSIS);
3188 ParseFormalParameter(parameters, classifier, ok);
3189 if (!*ok) return;
3190 } while (!parameters->has_rest && Check(Token::COMMA));
3191
3192 if (parameters->has_rest) {
3193 parameters->is_simple = false;
3194 classifier->RecordNonSimpleParameter();
3195 if (peek() == Token::COMMA) {
3196 ReportMessageAt(scanner()->peek_location(),
3197 MessageTemplate::kParamAfterRest);
3198 *ok = false;
3199 return;
3200 }
3201 }
3202 }
3203
3204 for (int i = 0; i < parameters->Arity(); ++i) {
3205 auto parameter = parameters->at(i);
3206 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
3207 }
3208}
3209
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003210template <class Traits>
Ben Murdoch097c5b22016-05-18 11:27:45 +01003211void ParserBase<Traits>::CheckArityRestrictions(int param_count,
3212 FunctionKind function_kind,
3213 bool has_rest,
3214 int formals_start_pos,
3215 int formals_end_pos, bool* ok) {
3216 if (IsGetterFunction(function_kind)) {
3217 if (param_count != 0) {
3218 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3219 MessageTemplate::kBadGetterArity);
3220 *ok = false;
3221 }
3222 } else if (IsSetterFunction(function_kind)) {
3223 if (param_count != 1) {
3224 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3225 MessageTemplate::kBadSetterArity);
3226 *ok = false;
3227 }
3228 if (has_rest) {
3229 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3230 MessageTemplate::kBadSetterRestParameter);
3231 *ok = false;
3232 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003233 }
3234}
3235
3236
3237template <class Traits>
3238bool ParserBase<Traits>::IsNextLetKeyword() {
3239 DCHECK(peek() == Token::LET);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003240 Token::Value next_next = PeekAhead();
3241 switch (next_next) {
3242 case Token::LBRACE:
3243 case Token::LBRACK:
3244 case Token::IDENTIFIER:
3245 case Token::STATIC:
Ben Murdochc5610432016-08-08 18:44:38 +01003246 case Token::LET: // `let let;` is disallowed by static semantics, but the
3247 // token must be first interpreted as a keyword in order
3248 // for those semantics to apply. This ensures that ASI is
3249 // not honored when a LineTerminator separates the
3250 // tokens.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003251 case Token::YIELD:
Ben Murdochc5610432016-08-08 18:44:38 +01003252 case Token::AWAIT:
3253 case Token::ASYNC:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003254 return true;
Ben Murdochc5610432016-08-08 18:44:38 +01003255 case Token::FUTURE_STRICT_RESERVED_WORD:
3256 return is_sloppy(language_mode());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003257 default:
3258 return false;
3259 }
3260}
3261
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003262template <class Traits>
3263typename ParserBase<Traits>::ExpressionT
3264ParserBase<Traits>::ParseArrowFunctionLiteral(
Ben Murdochc5610432016-08-08 18:44:38 +01003265 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003266 const ExpressionClassifier& formals_classifier, bool* ok) {
3267 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3268 // ASI inserts `;` after arrow parameters if a line terminator is found.
3269 // `=> ...` is never a valid expression, so report as syntax error.
3270 // If next token is not `=>`, it's a syntax error anyways.
3271 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3272 *ok = false;
3273 return this->EmptyExpression();
3274 }
3275
3276 typename Traits::Type::StatementList body;
3277 int num_parameters = formal_parameters.scope->num_parameters();
3278 int materialized_literal_count = -1;
3279 int expected_property_count = -1;
3280 Scanner::Location super_loc;
3281
Ben Murdochc5610432016-08-08 18:44:38 +01003282 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003283 {
3284 typename Traits::Type::Factory function_factory(ast_value_factory());
3285 FunctionState function_state(&function_state_, &scope_,
Ben Murdochc5610432016-08-08 18:44:38 +01003286 formal_parameters.scope, arrow_kind,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003287 &function_factory);
3288
3289 function_state.SkipMaterializedLiterals(
3290 formal_parameters.materialized_literals_count);
3291
3292 this->ReindexLiterals(formal_parameters);
3293
3294 Expect(Token::ARROW, CHECK_OK);
3295
3296 if (peek() == Token::LBRACE) {
3297 // Multiple statement body
3298 Consume(Token::LBRACE);
3299 bool is_lazily_parsed =
3300 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing());
3301 if (is_lazily_parsed) {
3302 body = this->NewStatementList(0, zone());
3303 this->SkipLazyFunctionBody(&materialized_literal_count,
3304 &expected_property_count, CHECK_OK);
3305 if (formal_parameters.materialized_literals_count > 0) {
3306 materialized_literal_count +=
3307 formal_parameters.materialized_literals_count;
3308 }
3309 } else {
3310 body = this->ParseEagerFunctionBody(
3311 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
Ben Murdochc5610432016-08-08 18:44:38 +01003312 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003313 materialized_literal_count =
3314 function_state.materialized_literal_count();
3315 expected_property_count = function_state.expected_property_count();
3316 }
3317 } else {
3318 // Single-expression body
3319 int pos = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01003320 ExpressionClassifier classifier(this);
Ben Murdochc5610432016-08-08 18:44:38 +01003321 DCHECK(ReturnExprContext::kInsideValidBlock ==
3322 function_state_->return_expr_context());
3323 ReturnExprScope allow_tail_calls(
3324 function_state_, ReturnExprContext::kInsideValidReturnStatement);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003325 body = this->NewStatementList(1, zone());
Ben Murdochc5610432016-08-08 18:44:38 +01003326 this->AddParameterInitializationBlock(formal_parameters, body, is_async,
3327 CHECK_OK);
3328 if (is_async) {
3329 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier,
3330 pos, CHECK_OK);
3331 Traits::RewriteNonPattern(&classifier, CHECK_OK);
3332 } else {
3333 ExpressionT expression =
3334 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
3335 Traits::RewriteNonPattern(&classifier, CHECK_OK);
3336 body->Add(factory()->NewReturnStatement(expression, pos), zone());
3337 if (allow_tailcalls() && !is_sloppy(language_mode())) {
3338 // ES6 14.6.1 Static Semantics: IsInTailPosition
3339 this->MarkTailPosition(expression);
3340 }
3341 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003342 materialized_literal_count = function_state.materialized_literal_count();
3343 expected_property_count = function_state.expected_property_count();
Ben Murdochc5610432016-08-08 18:44:38 +01003344 this->MarkCollectedTailCallExpressions();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003345 }
3346 super_loc = function_state.super_location();
3347
3348 formal_parameters.scope->set_end_position(scanner()->location().end_pos);
3349
3350 // Arrow function formal parameters are parsed as StrictFormalParameterList,
3351 // which is not the same as "parameters of a strict function"; it only means
3352 // that duplicates are not allowed. Of course, the arrow function may
3353 // itself be strict as well.
3354 const bool allow_duplicate_parameters = false;
3355 this->ValidateFormalParameters(&formals_classifier, language_mode(),
3356 allow_duplicate_parameters, CHECK_OK);
3357
3358 // Validate strict mode.
3359 if (is_strict(language_mode())) {
3360 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
3361 scanner()->location().end_pos, CHECK_OK);
3362 }
Ben Murdochc5610432016-08-08 18:44:38 +01003363 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003364
3365 Traits::RewriteDestructuringAssignments();
3366 }
3367
3368 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
3369 this->EmptyIdentifierString(), formal_parameters.scope, body,
3370 materialized_literal_count, expected_property_count, num_parameters,
3371 FunctionLiteral::kNoDuplicateParameters,
3372 FunctionLiteral::kAnonymousExpression,
Ben Murdochc5610432016-08-08 18:44:38 +01003373 FunctionLiteral::kShouldLazyCompile, arrow_kind,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003374 formal_parameters.scope->start_position());
3375
3376 function_literal->set_function_token_position(
3377 formal_parameters.scope->start_position());
3378 if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
3379
3380 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
3381
3382 return function_literal;
3383}
3384
3385
3386template <typename Traits>
3387typename ParserBase<Traits>::ExpressionT
3388ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
3389 ExpressionClassifier* classifier,
3390 bool* ok) {
3391 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3392 // text followed by a substitution expression), finalized by a single
3393 // TEMPLATE_TAIL.
3394 //
3395 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3396 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3397 // NoSubstitutionTemplate.
3398 //
3399 // When parsing a TemplateLiteral, we must have scanned either an initial
3400 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
3401 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
3402
3403 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
3404 // In this case we may simply consume the token and build a template with a
3405 // single TEMPLATE_SPAN and no expressions.
3406 if (peek() == Token::TEMPLATE_TAIL) {
3407 Consume(Token::TEMPLATE_TAIL);
3408 int pos = position();
3409 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3410 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3411 Traits::AddTemplateSpan(&ts, true);
3412 return Traits::CloseTemplateLiteral(&ts, start, tag);
3413 }
3414
3415 Consume(Token::TEMPLATE_SPAN);
3416 int pos = position();
3417 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3418 Traits::AddTemplateSpan(&ts, false);
3419 Token::Value next;
3420
3421 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
3422 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
3423 // case, representing a TemplateMiddle).
3424
3425 do {
3426 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3427 next = peek();
3428 if (next == Token::EOS) {
3429 ReportMessageAt(Scanner::Location(start, peek_position()),
3430 MessageTemplate::kUnterminatedTemplate);
3431 *ok = false;
3432 return Traits::EmptyExpression();
3433 } else if (next == Token::ILLEGAL) {
3434 Traits::ReportMessageAt(
3435 Scanner::Location(position() + 1, peek_position()),
3436 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3437 *ok = false;
3438 return Traits::EmptyExpression();
3439 }
3440
3441 int expr_pos = peek_position();
3442 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01003443 CheckNoTailCallExpressions(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003444 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003445 Traits::AddTemplateExpression(&ts, expression);
3446
3447 if (peek() != Token::RBRACE) {
3448 ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
3449 MessageTemplate::kUnterminatedTemplateExpr);
3450 *ok = false;
3451 return Traits::EmptyExpression();
3452 }
3453
3454 // If we didn't die parsing that expression, our next token should be a
3455 // TEMPLATE_SPAN or TEMPLATE_TAIL.
3456 next = scanner()->ScanTemplateContinuation();
3457 Next();
3458 pos = position();
3459
3460 if (next == Token::EOS) {
3461 ReportMessageAt(Scanner::Location(start, pos),
3462 MessageTemplate::kUnterminatedTemplate);
3463 *ok = false;
3464 return Traits::EmptyExpression();
3465 } else if (next == Token::ILLEGAL) {
3466 Traits::ReportMessageAt(
3467 Scanner::Location(position() + 1, peek_position()),
3468 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3469 *ok = false;
3470 return Traits::EmptyExpression();
3471 }
3472
3473 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
3474 } while (next == Token::TEMPLATE_SPAN);
3475
3476 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
3477 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3478 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3479 return Traits::CloseTemplateLiteral(&ts, start, tag);
3480}
3481
3482
3483template <typename Traits>
3484typename ParserBase<Traits>::ExpressionT
3485ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3486 ExpressionT expression, int beg_pos, int end_pos,
3487 MessageTemplate::Template message, bool* ok) {
3488 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
3489 message, kReferenceError, ok);
3490}
3491
3492
3493template <typename Traits>
3494typename ParserBase<Traits>::ExpressionT
3495ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3496 ExpressionT expression, int beg_pos, int end_pos,
3497 MessageTemplate::Template message, ParseErrorType type, bool* ok) {
Ben Murdochda12d292016-06-02 14:46:10 +01003498 if (this->IsIdentifier(expression) && is_strict(language_mode()) &&
3499 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3500 ReportMessageAt(Scanner::Location(beg_pos, end_pos),
3501 MessageTemplate::kStrictEvalArguments, kSyntaxError);
3502 *ok = false;
3503 return this->EmptyExpression();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003504 }
3505 if (expression->IsValidReferenceExpression()) {
3506 return expression;
Ben Murdochda12d292016-06-02 14:46:10 +01003507 }
3508 if (expression->IsCall()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003509 // If it is a call, make it a runtime error for legacy web compatibility.
3510 // Rewrite `expr' to `expr[throw ReferenceError]'.
Ben Murdochda12d292016-06-02 14:46:10 +01003511 ExpressionT error = this->NewThrowReferenceError(message, beg_pos);
3512 return factory()->NewProperty(expression, error, beg_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003513 }
Ben Murdochda12d292016-06-02 14:46:10 +01003514 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
3515 *ok = false;
3516 return this->EmptyExpression();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003517}
3518
3519
3520template <typename Traits>
3521bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) {
3522 return this->IsAssignableIdentifier(expression) || expression->IsProperty();
3523}
3524
3525
3526template <typename Traits>
3527void ParserBase<Traits>::CheckDestructuringElement(
3528 ExpressionT expression, ExpressionClassifier* classifier, int begin,
3529 int end) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003530 if (!IsValidPattern(expression) && !expression->IsAssignment() &&
3531 !IsValidReferenceExpression(expression)) {
3532 classifier->RecordAssignmentPatternError(
3533 Scanner::Location(begin, end),
3534 MessageTemplate::kInvalidDestructuringTarget);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003535 }
3536}
3537
3538
3539#undef CHECK_OK
3540#undef CHECK_OK_CUSTOM
3541
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003542template <typename Traits>
3543void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
Ben Murdochc5610432016-08-08 18:44:38 +01003544 Token::Value property, PropertyKind type, MethodKind method_type,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003545 bool* ok) {
Ben Murdochc5610432016-08-08 18:44:38 +01003546 DCHECK(!IsStaticMethod(method_type));
3547 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003548
3549 if (property == Token::SMI || property == Token::NUMBER) return;
3550
3551 if (type == kValueProperty && IsProto()) {
3552 if (has_seen_proto_) {
3553 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
3554 *ok = false;
3555 return;
3556 }
3557 has_seen_proto_ = true;
3558 return;
3559 }
3560}
3561
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003562template <typename Traits>
3563void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
Ben Murdochc5610432016-08-08 18:44:38 +01003564 Token::Value property, PropertyKind type, MethodKind method_type,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003565 bool* ok) {
3566 DCHECK(type == kMethodProperty || type == kAccessorProperty);
3567
3568 if (property == Token::SMI || property == Token::NUMBER) return;
3569
Ben Murdochc5610432016-08-08 18:44:38 +01003570 if (IsStaticMethod(method_type)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003571 if (IsPrototype()) {
3572 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
3573 *ok = false;
3574 return;
3575 }
3576 } else if (IsConstructor()) {
Ben Murdochc5610432016-08-08 18:44:38 +01003577 const bool is_generator = IsGeneratorMethod(method_type);
3578 const bool is_async = IsAsyncMethod(method_type);
3579 if (is_generator || is_async || type == kAccessorProperty) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003580 MessageTemplate::Template msg =
3581 is_generator ? MessageTemplate::kConstructorIsGenerator
Ben Murdochc5610432016-08-08 18:44:38 +01003582 : is_async ? MessageTemplate::kConstructorIsAsync
3583 : MessageTemplate::kConstructorIsAccessor;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003584 this->parser()->ReportMessage(msg);
3585 *ok = false;
3586 return;
3587 }
3588 if (has_seen_constructor_) {
3589 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
3590 *ok = false;
3591 return;
3592 }
3593 has_seen_constructor_ = true;
3594 return;
3595 }
3596}
Ben Murdoch097c5b22016-05-18 11:27:45 +01003597
3598
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003599} // namespace internal
3600} // namespace v8
3601
3602#endif // V8_PARSING_PARSER_BASE_H