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