blob: dde6b1dd863627db86339e39264fca70dabc99eb [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_PARSING_PARSER_BASE_H
6#define V8_PARSING_PARSER_BASE_H
7
8#include "src/ast/scopes.h"
9#include "src/bailout-reason.h"
10#include "src/hashmap.h"
11#include "src/messages.h"
12#include "src/parsing/expression-classifier.h"
13#include "src/parsing/func-name-inferrer.h"
14#include "src/parsing/scanner.h"
15#include "src/parsing/token.h"
16
17namespace v8 {
18namespace internal {
19
20
21enum FunctionNameValidity {
22 kFunctionNameIsStrictReserved,
23 kSkipFunctionNameCheck,
24 kFunctionNameValidityUnknown
25};
26
Ben Murdochda12d292016-06-02 14:46:10 +010027enum AllowLabelledFunctionStatement {
28 kAllowLabelledFunctionStatement,
29 kDisallowLabelledFunctionStatement,
30};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000031
32struct FormalParametersBase {
33 explicit FormalParametersBase(Scope* scope) : scope(scope) {}
34 Scope* scope;
35 bool has_rest = false;
36 bool is_simple = true;
37 int materialized_literals_count = 0;
38};
39
40
41// Common base class shared between parser and pre-parser. Traits encapsulate
42// the differences between Parser and PreParser:
43
44// - Return types: For example, Parser functions return Expression* and
45// PreParser functions return PreParserExpression.
46
47// - Creating parse tree nodes: Parser generates an AST during the recursive
48// descent. PreParser doesn't create a tree. Instead, it passes around minimal
49// data objects (PreParserExpression, PreParserIdentifier etc.) which contain
50// just enough data for the upper layer functions. PreParserFactory is
51// responsible for creating these dummy objects. It provides a similar kind of
52// interface as AstNodeFactory, so ParserBase doesn't need to care which one is
53// used.
54
55// - Miscellaneous other tasks interleaved with the recursive descent. For
56// example, Parser keeps track of which function literals should be marked as
57// pretenured, and PreParser doesn't care.
58
59// The traits are expected to contain the following typedefs:
60// struct Traits {
61// // In particular...
62// struct Type {
63// // Used by FunctionState and BlockState.
64// typedef Scope;
65// typedef GeneratorVariable;
66// // Return types for traversing functions.
67// typedef Identifier;
68// typedef Expression;
69// typedef FunctionLiteral;
70// typedef ClassLiteral;
71// typedef ObjectLiteralProperty;
72// typedef Literal;
73// typedef ExpressionList;
74// typedef PropertyList;
75// typedef FormalParameter;
76// typedef FormalParameters;
77// // For constructing objects returned by the traversing functions.
78// typedef Factory;
79// };
80// // ...
81// };
82
83template <typename Traits>
84class ParserBase : public Traits {
85 public:
86 // Shorten type names defined by Traits.
87 typedef typename Traits::Type::Expression ExpressionT;
88 typedef typename Traits::Type::Identifier IdentifierT;
89 typedef typename Traits::Type::FormalParameter FormalParameterT;
90 typedef typename Traits::Type::FormalParameters FormalParametersT;
91 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
92 typedef typename Traits::Type::Literal LiteralT;
93 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
94 typedef typename Traits::Type::StatementList StatementListT;
Ben Murdoch097c5b22016-05-18 11:27:45 +010095 typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000096
97 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
98 v8::Extension* extension, AstValueFactory* ast_value_factory,
99 ParserRecorder* log, typename Traits::Type::Parser this_object)
100 : Traits(this_object),
101 parenthesized_function_(false),
102 scope_(NULL),
103 function_state_(NULL),
104 extension_(extension),
105 fni_(NULL),
106 ast_value_factory_(ast_value_factory),
107 log_(log),
108 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
109 stack_limit_(stack_limit),
110 zone_(zone),
111 scanner_(scanner),
112 stack_overflow_(false),
113 allow_lazy_(false),
114 allow_natives_(false),
Ben Murdochda12d292016-06-02 14:46:10 +0100115 allow_tailcalls_(false),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116 allow_harmony_sloppy_(false),
117 allow_harmony_sloppy_function_(false),
118 allow_harmony_sloppy_let_(false),
Ben Murdochda12d292016-06-02 14:46:10 +0100119 allow_harmony_restrictive_declarations_(false),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 allow_harmony_do_expressions_(false),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100121 allow_harmony_function_name_(false),
122 allow_harmony_function_sent_(false) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123
124#define ALLOW_ACCESSORS(name) \
125 bool allow_##name() const { return allow_##name##_; } \
126 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
127
Ben Murdochda12d292016-06-02 14:46:10 +0100128#define SCANNER_ACCESSORS(name) \
129 bool allow_##name() const { return scanner_->allow_##name(); } \
130 void set_allow_##name(bool allow) { \
131 return scanner_->set_allow_##name(allow); \
132 }
133
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 ALLOW_ACCESSORS(lazy);
135 ALLOW_ACCESSORS(natives);
Ben Murdochda12d292016-06-02 14:46:10 +0100136 ALLOW_ACCESSORS(tailcalls);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000137 ALLOW_ACCESSORS(harmony_sloppy);
138 ALLOW_ACCESSORS(harmony_sloppy_function);
139 ALLOW_ACCESSORS(harmony_sloppy_let);
Ben Murdochda12d292016-06-02 14:46:10 +0100140 ALLOW_ACCESSORS(harmony_restrictive_declarations);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141 ALLOW_ACCESSORS(harmony_do_expressions);
142 ALLOW_ACCESSORS(harmony_function_name);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100143 ALLOW_ACCESSORS(harmony_function_sent);
Ben Murdochda12d292016-06-02 14:46:10 +0100144 SCANNER_ACCESSORS(harmony_exponentiation_operator);
145
146#undef SCANNER_ACCESSORS
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147#undef ALLOW_ACCESSORS
148
149 uintptr_t stack_limit() const { return stack_limit_; }
150
151 protected:
152 enum AllowRestrictedIdentifiers {
153 kAllowRestrictedIdentifiers,
154 kDontAllowRestrictedIdentifiers
155 };
156
157 enum Mode {
158 PARSE_LAZILY,
159 PARSE_EAGERLY
160 };
161
162 enum VariableDeclarationContext {
163 kStatementListItem,
164 kStatement,
165 kForStatement
166 };
167
168 class Checkpoint;
169 class ObjectLiteralCheckerBase;
170
171 // ---------------------------------------------------------------------------
172 // FunctionState and BlockState together implement the parser's scope stack.
173 // The parser's current scope is in scope_. BlockState and FunctionState
174 // constructors push on the scope stack and the destructors pop. They are also
175 // used to hold the parser's per-function and per-block state.
176 class BlockState BASE_EMBEDDED {
177 public:
178 BlockState(Scope** scope_stack, Scope* scope)
179 : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
180 *scope_stack_ = scope;
181 }
182 ~BlockState() { *scope_stack_ = outer_scope_; }
183
184 private:
185 Scope** scope_stack_;
186 Scope* outer_scope_;
187 };
188
189 struct DestructuringAssignment {
190 public:
191 DestructuringAssignment(ExpressionT expression, Scope* scope)
192 : assignment(expression), scope(scope) {}
193
194 ExpressionT assignment;
195 Scope* scope;
196 };
197
198 class FunctionState BASE_EMBEDDED {
199 public:
200 FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
201 Scope* scope, FunctionKind kind,
202 typename Traits::Type::Factory* factory);
203 ~FunctionState();
204
205 int NextMaterializedLiteralIndex() {
206 return next_materialized_literal_index_++;
207 }
208 int materialized_literal_count() {
209 return next_materialized_literal_index_;
210 }
211
212 void SkipMaterializedLiterals(int count) {
213 next_materialized_literal_index_ += count;
214 }
215
216 void AddProperty() { expected_property_count_++; }
217 int expected_property_count() { return expected_property_count_; }
218
219 Scanner::Location this_location() const { return this_location_; }
220 Scanner::Location super_location() const { return super_location_; }
221 Scanner::Location return_location() const { return return_location_; }
222 void set_this_location(Scanner::Location location) {
223 this_location_ = location;
224 }
225 void set_super_location(Scanner::Location location) {
226 super_location_ = location;
227 }
228 void set_return_location(Scanner::Location location) {
229 return_location_ = location;
230 }
231
232 bool is_generator() const { return IsGeneratorFunction(kind_); }
233
234 FunctionKind kind() const { return kind_; }
235 FunctionState* outer() const { return outer_function_state_; }
236
237 void set_generator_object_variable(
238 typename Traits::Type::GeneratorVariable* variable) {
239 DCHECK(variable != NULL);
240 DCHECK(is_generator());
241 generator_object_variable_ = variable;
242 }
243 typename Traits::Type::GeneratorVariable* generator_object_variable()
244 const {
245 return generator_object_variable_;
246 }
247
248 typename Traits::Type::Factory* factory() { return factory_; }
249
250 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite()
251 const {
252 return destructuring_assignments_to_rewrite_;
253 }
254
Ben Murdoch097c5b22016-05-18 11:27:45 +0100255 List<ExpressionT>& expressions_in_tail_position() {
256 return expressions_in_tail_position_;
257 }
258 void AddExpressionInTailPosition(ExpressionT expression) {
259 if (collect_expressions_in_tail_position_) {
260 expressions_in_tail_position_.Add(expression);
261 }
262 }
263
264 bool collect_expressions_in_tail_position() const {
265 return collect_expressions_in_tail_position_;
266 }
267 void set_collect_expressions_in_tail_position(bool collect) {
268 collect_expressions_in_tail_position_ = collect;
269 }
270
271 ZoneList<ExpressionT>* non_patterns_to_rewrite() {
272 return &non_patterns_to_rewrite_;
273 }
274
275 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000276 void AddDestructuringAssignment(DestructuringAssignment pair) {
277 destructuring_assignments_to_rewrite_.Add(pair);
278 }
279
Ben Murdoch097c5b22016-05-18 11:27:45 +0100280 V8_INLINE Scope* scope() { return *scope_stack_; }
281
282 void AddNonPatternForRewriting(ExpressionT expr) {
283 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone());
284 }
285
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000286 // Used to assign an index to each literal that needs materialization in
287 // the function. Includes regexp literals, and boilerplate for object and
288 // array literals.
289 int next_materialized_literal_index_;
290
291 // Properties count estimation.
292 int expected_property_count_;
293
294 // Location of most recent use of 'this' (invalid if none).
295 Scanner::Location this_location_;
296
297 // Location of most recent 'return' statement (invalid if none).
298 Scanner::Location return_location_;
299
300 // Location of call to the "super" constructor (invalid if none).
301 Scanner::Location super_location_;
302
303 FunctionKind kind_;
304 // For generators, this variable may hold the generator object. It variable
305 // is used by yield expressions and return statements. It is not necessary
306 // for generator functions to have this variable set.
307 Variable* generator_object_variable_;
308
309 FunctionState** function_state_stack_;
310 FunctionState* outer_function_state_;
311 Scope** scope_stack_;
312 Scope* outer_scope_;
313
314 List<DestructuringAssignment> destructuring_assignments_to_rewrite_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100315 List<ExpressionT> expressions_in_tail_position_;
316 bool collect_expressions_in_tail_position_;
317 ZoneList<ExpressionT> non_patterns_to_rewrite_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000318
319 typename Traits::Type::Factory* factory_;
320
321 friend class ParserTraits;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100322 friend class PreParserTraits;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323 friend class Checkpoint;
324 };
325
326 // Annoyingly, arrow functions first parse as comma expressions, then when we
327 // see the => we have to go back and reinterpret the arguments as being formal
328 // parameters. To do so we need to reset some of the parser state back to
329 // what it was before the arguments were first seen.
330 class Checkpoint BASE_EMBEDDED {
331 public:
332 explicit Checkpoint(ParserBase* parser) {
333 function_state_ = parser->function_state_;
334 next_materialized_literal_index_ =
335 function_state_->next_materialized_literal_index_;
336 expected_property_count_ = function_state_->expected_property_count_;
337 }
338
339 void Restore(int* materialized_literal_index_delta) {
340 *materialized_literal_index_delta =
341 function_state_->next_materialized_literal_index_ -
342 next_materialized_literal_index_;
343 function_state_->next_materialized_literal_index_ =
344 next_materialized_literal_index_;
345 function_state_->expected_property_count_ = expected_property_count_;
346 }
347
348 private:
349 FunctionState* function_state_;
350 int next_materialized_literal_index_;
351 int expected_property_count_;
352 };
353
354 class ParsingModeScope BASE_EMBEDDED {
355 public:
356 ParsingModeScope(ParserBase* parser, Mode mode)
357 : parser_(parser),
358 old_mode_(parser->mode()) {
359 parser_->mode_ = mode;
360 }
361 ~ParsingModeScope() {
362 parser_->mode_ = old_mode_;
363 }
364
365 private:
366 ParserBase* parser_;
367 Mode old_mode_;
368 };
369
370 Scope* NewScope(Scope* parent, ScopeType scope_type) {
371 // Must always pass the function kind for FUNCTION_SCOPE.
372 DCHECK(scope_type != FUNCTION_SCOPE);
373 return NewScope(parent, scope_type, kNormalFunction);
374 }
375
376 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
377 DCHECK(ast_value_factory());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000378 Scope* result = new (zone())
379 Scope(zone(), parent, scope_type, ast_value_factory(), kind);
380 result->Initialize();
381 return result;
382 }
383
384 Scanner* scanner() const { return scanner_; }
385 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
386 int position() { return scanner_->location().beg_pos; }
387 int peek_position() { return scanner_->peek_location().beg_pos; }
388 bool stack_overflow() const { return stack_overflow_; }
389 void set_stack_overflow() { stack_overflow_ = true; }
390 Mode mode() const { return mode_; }
391 Zone* zone() const { return zone_; }
392
393 INLINE(Token::Value peek()) {
394 if (stack_overflow_) return Token::ILLEGAL;
395 return scanner()->peek();
396 }
397
398 INLINE(Token::Value PeekAhead()) {
399 if (stack_overflow_) return Token::ILLEGAL;
400 return scanner()->PeekAhead();
401 }
402
403 INLINE(Token::Value Next()) {
404 if (stack_overflow_) return Token::ILLEGAL;
405 {
406 if (GetCurrentStackPosition() < stack_limit_) {
407 // Any further calls to Next or peek will return the illegal token.
408 // The current call must return the next token, which might already
409 // have been peek'ed.
410 stack_overflow_ = true;
411 }
412 }
413 return scanner()->Next();
414 }
415
416 void Consume(Token::Value token) {
417 Token::Value next = Next();
418 USE(next);
419 USE(token);
420 DCHECK(next == token);
421 }
422
423 bool Check(Token::Value token) {
424 Token::Value next = peek();
425 if (next == token) {
426 Consume(next);
427 return true;
428 }
429 return false;
430 }
431
432 void Expect(Token::Value token, bool* ok) {
433 Token::Value next = Next();
434 if (next != token) {
435 ReportUnexpectedToken(next);
436 *ok = false;
437 }
438 }
439
440 void ExpectSemicolon(bool* ok) {
441 // Check for automatic semicolon insertion according to
442 // the rules given in ECMA-262, section 7.9, page 21.
443 Token::Value tok = peek();
444 if (tok == Token::SEMICOLON) {
445 Next();
446 return;
447 }
448 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
449 tok == Token::RBRACE ||
450 tok == Token::EOS) {
451 return;
452 }
453 Expect(Token::SEMICOLON, ok);
454 }
455
456 bool peek_any_identifier() {
457 Token::Value next = peek();
458 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
459 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
460 next == Token::STATIC || next == Token::YIELD;
461 }
462
463 bool CheckContextualKeyword(Vector<const char> keyword) {
464 if (PeekContextualKeyword(keyword)) {
465 Consume(Token::IDENTIFIER);
466 return true;
467 }
468 return false;
469 }
470
471 bool PeekContextualKeyword(Vector<const char> keyword) {
472 return peek() == Token::IDENTIFIER &&
473 scanner()->is_next_contextual_keyword(keyword);
474 }
475
Ben Murdoch097c5b22016-05-18 11:27:45 +0100476 void ExpectMetaProperty(Vector<const char> property_name,
477 const char* full_name, int pos, bool* ok);
478
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000479 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
480 Expect(Token::IDENTIFIER, ok);
481 if (!*ok) return;
482 if (!scanner()->is_literal_contextual_keyword(keyword)) {
483 ReportUnexpectedToken(scanner()->current_token());
484 *ok = false;
485 }
486 }
487
488 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
489 if (Check(Token::IN)) {
Ben Murdochda12d292016-06-02 14:46:10 +0100490 *visit_mode = ForEachStatement::ENUMERATE;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000491 return true;
492 } else if (CheckContextualKeyword(CStrVector("of"))) {
493 *visit_mode = ForEachStatement::ITERATE;
494 return true;
495 }
496 return false;
497 }
498
Ben Murdoch097c5b22016-05-18 11:27:45 +0100499 bool PeekInOrOf() {
500 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of"));
501 }
502
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000503 // Checks whether an octal literal was last seen between beg_pos and end_pos.
504 // If so, reports an error. Only called for strict mode and template strings.
505 void CheckOctalLiteral(int beg_pos, int end_pos,
506 MessageTemplate::Template message, bool* ok) {
507 Scanner::Location octal = scanner()->octal_position();
508 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
509 octal.end_pos <= end_pos) {
510 ReportMessageAt(octal, message);
511 scanner()->clear_octal_position();
512 *ok = false;
513 }
514 }
515
516 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
517 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
518 ok);
519 }
520
521 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
522 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
523 ok);
524 }
525
526 void CheckDestructuringElement(ExpressionT element,
527 ExpressionClassifier* classifier, int beg_pos,
528 int end_pos);
529
530 // Checking the name of a function literal. This has to be done after parsing
531 // the function, since the function can declare itself strict.
532 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
533 FunctionNameValidity function_name_validity,
534 const Scanner::Location& function_name_loc, bool* ok) {
535 if (function_name_validity == kSkipFunctionNameCheck) return;
536 // The function name needs to be checked in strict mode.
537 if (is_sloppy(language_mode)) return;
538
539 if (this->IsEvalOrArguments(function_name)) {
540 Traits::ReportMessageAt(function_name_loc,
541 MessageTemplate::kStrictEvalArguments);
542 *ok = false;
543 return;
544 }
545 if (function_name_validity == kFunctionNameIsStrictReserved) {
546 Traits::ReportMessageAt(function_name_loc,
547 MessageTemplate::kUnexpectedStrictReserved);
548 *ok = false;
549 return;
550 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000551 }
552
553 // Determine precedence of given token.
554 static int Precedence(Token::Value token, bool accept_IN) {
555 if (token == Token::IN && !accept_IN)
556 return 0; // 0 precedence will terminate binary expression parsing
557 return Token::Precedence(token);
558 }
559
560 typename Traits::Type::Factory* factory() {
561 return function_state_->factory();
562 }
563
564 LanguageMode language_mode() { return scope_->language_mode(); }
565 bool is_generator() const { return function_state_->is_generator(); }
566
567 bool allow_const() {
Ben Murdochda12d292016-06-02 14:46:10 +0100568 return is_strict(language_mode()) || allow_harmony_sloppy();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569 }
570
571 bool allow_let() {
572 return is_strict(language_mode()) || allow_harmony_sloppy_let();
573 }
574
575 // Report syntax errors.
576 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
577 ParseErrorType error_type = kSyntaxError) {
578 Scanner::Location source_location = scanner()->location();
579 Traits::ReportMessageAt(source_location, message, arg, error_type);
580 }
581
582 void ReportMessageAt(Scanner::Location location,
583 MessageTemplate::Template message,
584 ParseErrorType error_type = kSyntaxError) {
585 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
586 error_type);
587 }
588
589 void GetUnexpectedTokenMessage(
Ben Murdochda12d292016-06-02 14:46:10 +0100590 Token::Value token, MessageTemplate::Template* message,
591 Scanner::Location* location, const char** arg,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
593
594 void ReportUnexpectedToken(Token::Value token);
595 void ReportUnexpectedTokenAt(
596 Scanner::Location location, Token::Value token,
597 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
598
Ben Murdoch097c5b22016-05-18 11:27:45 +0100599 void ReportClassifierError(
600 const typename ExpressionClassifier::Error& error) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000601 Traits::ReportMessageAt(error.location, error.message, error.arg,
602 error.type);
603 }
604
605 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
606 if (!classifier->is_valid_expression() ||
607 classifier->has_cover_initialized_name()) {
608 const Scanner::Location& a = classifier->expression_error().location;
609 const Scanner::Location& b =
610 classifier->cover_initialized_name_error().location;
611 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
612 ReportClassifierError(classifier->cover_initialized_name_error());
613 } else {
614 ReportClassifierError(classifier->expression_error());
615 }
616 *ok = false;
617 }
618 }
619
620 void ValidateFormalParameterInitializer(
621 const ExpressionClassifier* classifier, bool* ok) {
622 if (!classifier->is_valid_formal_parameter_initializer()) {
623 ReportClassifierError(classifier->formal_parameter_initializer_error());
624 *ok = false;
625 }
626 }
627
628 void ValidateBindingPattern(const ExpressionClassifier* classifier,
629 bool* ok) {
630 if (!classifier->is_valid_binding_pattern()) {
631 ReportClassifierError(classifier->binding_pattern_error());
632 *ok = false;
633 }
634 }
635
636 void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
637 bool* ok) {
638 if (!classifier->is_valid_assignment_pattern()) {
639 ReportClassifierError(classifier->assignment_pattern_error());
640 *ok = false;
641 }
642 }
643
644 void ValidateFormalParameters(const ExpressionClassifier* classifier,
645 LanguageMode language_mode,
646 bool allow_duplicates, bool* ok) {
647 if (!allow_duplicates &&
648 !classifier->is_valid_formal_parameter_list_without_duplicates()) {
649 ReportClassifierError(classifier->duplicate_formal_parameter_error());
650 *ok = false;
651 } else if (is_strict(language_mode) &&
652 !classifier->is_valid_strict_mode_formal_parameters()) {
653 ReportClassifierError(classifier->strict_mode_formal_parameter_error());
654 *ok = false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000655 }
656 }
657
658 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
659 ExpressionT expr,
660 bool parenthesized_formals, bool* ok) {
661 if (classifier->is_valid_binding_pattern()) {
662 // A simple arrow formal parameter: IDENTIFIER => BODY.
663 if (!this->IsIdentifier(expr)) {
664 Traits::ReportMessageAt(scanner()->location(),
665 MessageTemplate::kUnexpectedToken,
666 Token::String(scanner()->current_token()));
667 *ok = false;
668 }
669 } else if (!classifier->is_valid_arrow_formal_parameters()) {
670 // If after parsing the expr, we see an error but the expression is
671 // neither a valid binding pattern nor a valid parenthesized formal
672 // parameter list, show the "arrow formal parameters" error if the formals
673 // started with a parenthesis, and the binding pattern error otherwise.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100674 const typename ExpressionClassifier::Error& error =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000675 parenthesized_formals ? classifier->arrow_formal_parameters_error()
676 : classifier->binding_pattern_error();
677 ReportClassifierError(error);
678 *ok = false;
679 }
680 }
681
682 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) {
683 if (!classifier->is_valid_let_pattern()) {
684 ReportClassifierError(classifier->let_pattern_error());
685 *ok = false;
686 }
687 }
688
689 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
690 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
691 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100692 Scanner::Location location = scanner()->peek_location();
693 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
694 classifier->RecordExpressionError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000695 }
696
697 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
698 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
699 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100700 Scanner::Location location = scanner()->peek_location();
701 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
702 classifier->RecordBindingPatternError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000703 }
704
705 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
706 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
707 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +0100708 Scanner::Location location = scanner()->peek_location();
709 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
710 classifier->RecordArrowFormalParametersError(location, message, arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000711 }
712
713 // Recursive descent functions:
714
715 // Parses an identifier that is valid for the current scope, in particular it
716 // fails on strict mode future reserved keywords in a strict scope. If
717 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
718 // "arguments" as identifier even in strict mode (this is needed in cases like
719 // "var foo = eval;").
720 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
721 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
722 bool* ok);
723 // Parses an identifier or a strict mode future reserved word, and indicate
724 // whether it is strict mode future reserved. Allows passing in is_generator
725 // for the case of parsing the identifier in a function expression, where the
726 // relevant "is_generator" bit is of the function being parsed, not the
727 // containing
728 // function.
729 IdentifierT ParseIdentifierOrStrictReservedWord(bool is_generator,
730 bool* is_strict_reserved,
731 bool* ok);
732 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
733 bool* ok) {
734 return ParseIdentifierOrStrictReservedWord(this->is_generator(),
735 is_strict_reserved, ok);
736 }
737
738 IdentifierT ParseIdentifierName(bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000739
740 ExpressionT ParseRegExpLiteral(bool seen_equal,
741 ExpressionClassifier* classifier, bool* ok);
742
743 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
744 bool* ok);
745 ExpressionT ParseExpression(bool accept_IN, bool* ok);
746 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
747 bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000748 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
749 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100750 bool* is_computed_name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000751 ExpressionClassifier* classifier, bool* ok);
752 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
753 ObjectLiteralPropertyT ParsePropertyDefinition(
754 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
755 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
756 ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
757 typename Traits::Type::ExpressionList ParseArguments(
758 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
759 bool* ok);
760
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000761 ExpressionT ParseAssignmentExpression(bool accept_IN,
762 ExpressionClassifier* classifier,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100763 bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000764 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
765 ExpressionT ParseConditionalExpression(bool accept_IN,
766 ExpressionClassifier* classifier,
767 bool* ok);
768 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
769 ExpressionClassifier* classifier, bool* ok);
770 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
771 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
772 bool* ok);
773 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
774 bool* ok);
775 ExpressionT ParseMemberWithNewPrefixesExpression(
776 ExpressionClassifier* classifier, bool* ok);
777 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
778 ExpressionT ParseMemberExpressionContinuation(
779 ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
780 ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
781 const FormalParametersT& parameters,
782 const ExpressionClassifier& classifier,
783 bool* ok);
784 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
785 ExpressionClassifier* classifier, bool* ok);
786 void AddTemplateExpression(ExpressionT);
787 ExpressionT ParseSuperExpression(bool is_new,
788 ExpressionClassifier* classifier, bool* ok);
789 ExpressionT ParseNewTargetExpression(bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000790
791 void ParseFormalParameter(FormalParametersT* parameters,
792 ExpressionClassifier* classifier, bool* ok);
793 void ParseFormalParameterList(FormalParametersT* parameters,
794 ExpressionClassifier* classifier, bool* ok);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100795 void CheckArityRestrictions(int param_count, FunctionKind function_type,
796 bool has_rest, int formals_start_pos,
797 int formals_end_pos, bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000798
799 bool IsNextLetKeyword();
800
801 // Checks if the expression is a valid reference expression (e.g., on the
802 // left-hand side of assignments). Although ruled out by ECMA as early errors,
803 // we allow calls for web compatibility and rewrite them to a runtime throw.
804 ExpressionT CheckAndRewriteReferenceExpression(
805 ExpressionT expression, int beg_pos, int end_pos,
806 MessageTemplate::Template message, bool* ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000807 ExpressionT CheckAndRewriteReferenceExpression(
808 ExpressionT expression, int beg_pos, int end_pos,
809 MessageTemplate::Template message, ParseErrorType type, bool* ok);
810
811 bool IsValidReferenceExpression(ExpressionT expression);
812
813 bool IsAssignableIdentifier(ExpressionT expression) {
814 if (!Traits::IsIdentifier(expression)) return false;
815 if (is_strict(language_mode()) &&
816 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
817 return false;
818 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000819 return true;
820 }
821
Ben Murdoch097c5b22016-05-18 11:27:45 +0100822 bool IsValidPattern(ExpressionT expression) {
823 return expression->IsObjectLiteral() || expression->IsArrayLiteral();
824 }
825
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000826 // Keep track of eval() calls since they disable all local variable
827 // optimizations. This checks if expression is an eval call, and if yes,
828 // forwards the information to scope.
829 void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) {
830 if (Traits::IsIdentifier(expression) &&
831 Traits::IsEval(Traits::AsIdentifier(expression))) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000832 scope->RecordEvalCall();
Ben Murdochda12d292016-06-02 14:46:10 +0100833 if (is_sloppy(scope->language_mode())) {
834 // For sloppy scopes we also have to record the call at function level,
835 // in case it includes declarations that will be hoisted.
836 scope->DeclarationScope()->RecordEvalCall();
837 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000838 }
839 }
840
841 // Used to validate property names in object literals and class literals
842 enum PropertyKind {
843 kAccessorProperty,
844 kValueProperty,
845 kMethodProperty
846 };
847
848 class ObjectLiteralCheckerBase {
849 public:
850 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
851
852 virtual void CheckProperty(Token::Value property, PropertyKind type,
853 bool is_static, bool is_generator, bool* ok) = 0;
854
855 virtual ~ObjectLiteralCheckerBase() {}
856
857 protected:
858 ParserBase* parser() const { return parser_; }
859 Scanner* scanner() const { return parser_->scanner(); }
860
861 private:
862 ParserBase* parser_;
863 };
864
865 // Validation per ES6 object literals.
866 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
867 public:
868 explicit ObjectLiteralChecker(ParserBase* parser)
869 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
870
871 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
872 bool is_generator, bool* ok) override;
873
874 private:
875 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
876
877 bool has_seen_proto_;
878 };
879
880 // Validation per ES6 class literals.
881 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
882 public:
883 explicit ClassLiteralChecker(ParserBase* parser)
884 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
885
886 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
887 bool is_generator, bool* ok) override;
888
889 private:
890 bool IsConstructor() {
891 return this->scanner()->LiteralMatches("constructor", 11);
892 }
893 bool IsPrototype() {
894 return this->scanner()->LiteralMatches("prototype", 9);
895 }
896
897 bool has_seen_constructor_;
898 };
899
900 // If true, the next (and immediately following) function literal is
901 // preceded by a parenthesis.
902 // Heuristically that means that the function will be called immediately,
903 // so never lazily compile it.
904 bool parenthesized_function_;
905
906 Scope* scope_; // Scope stack.
907 FunctionState* function_state_; // Function state stack.
908 v8::Extension* extension_;
909 FuncNameInferrer* fni_;
910 AstValueFactory* ast_value_factory_; // Not owned.
911 ParserRecorder* log_;
912 Mode mode_;
913 uintptr_t stack_limit_;
914
915 private:
916 Zone* zone_;
917
918 Scanner* scanner_;
919 bool stack_overflow_;
920
921 bool allow_lazy_;
922 bool allow_natives_;
Ben Murdochda12d292016-06-02 14:46:10 +0100923 bool allow_tailcalls_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924 bool allow_harmony_sloppy_;
925 bool allow_harmony_sloppy_function_;
926 bool allow_harmony_sloppy_let_;
Ben Murdochda12d292016-06-02 14:46:10 +0100927 bool allow_harmony_restrictive_declarations_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000928 bool allow_harmony_do_expressions_;
929 bool allow_harmony_function_name_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100930 bool allow_harmony_function_sent_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000931};
932
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000933template <class Traits>
934ParserBase<Traits>::FunctionState::FunctionState(
935 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
936 FunctionKind kind, typename Traits::Type::Factory* factory)
937 : next_materialized_literal_index_(0),
938 expected_property_count_(0),
939 this_location_(Scanner::Location::invalid()),
940 return_location_(Scanner::Location::invalid()),
941 super_location_(Scanner::Location::invalid()),
942 kind_(kind),
943 generator_object_variable_(NULL),
944 function_state_stack_(function_state_stack),
945 outer_function_state_(*function_state_stack),
946 scope_stack_(scope_stack),
947 outer_scope_(*scope_stack),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100948 collect_expressions_in_tail_position_(true),
949 non_patterns_to_rewrite_(0, scope->zone()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 factory_(factory) {
951 *scope_stack_ = scope;
952 *function_state_stack = this;
953}
954
955
956template <class Traits>
957ParserBase<Traits>::FunctionState::~FunctionState() {
958 *scope_stack_ = outer_scope_;
959 *function_state_stack_ = outer_function_state_;
960}
961
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000962template <class Traits>
963void ParserBase<Traits>::GetUnexpectedTokenMessage(
Ben Murdochda12d292016-06-02 14:46:10 +0100964 Token::Value token, MessageTemplate::Template* message,
965 Scanner::Location* location, const char** arg,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000966 MessageTemplate::Template default_) {
Ben Murdochda12d292016-06-02 14:46:10 +0100967 *arg = nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000968 switch (token) {
969 case Token::EOS:
970 *message = MessageTemplate::kUnexpectedEOS;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000971 break;
972 case Token::SMI:
973 case Token::NUMBER:
974 *message = MessageTemplate::kUnexpectedTokenNumber;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000975 break;
976 case Token::STRING:
977 *message = MessageTemplate::kUnexpectedTokenString;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000978 break;
979 case Token::IDENTIFIER:
980 *message = MessageTemplate::kUnexpectedTokenIdentifier;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000981 break;
982 case Token::FUTURE_RESERVED_WORD:
983 *message = MessageTemplate::kUnexpectedReserved;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000984 break;
985 case Token::LET:
986 case Token::STATIC:
987 case Token::YIELD:
988 case Token::FUTURE_STRICT_RESERVED_WORD:
989 *message = is_strict(language_mode())
990 ? MessageTemplate::kUnexpectedStrictReserved
991 : MessageTemplate::kUnexpectedTokenIdentifier;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000992 break;
993 case Token::TEMPLATE_SPAN:
994 case Token::TEMPLATE_TAIL:
995 *message = MessageTemplate::kUnexpectedTemplateString;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000996 break;
997 case Token::ESCAPED_STRICT_RESERVED_WORD:
998 case Token::ESCAPED_KEYWORD:
999 *message = MessageTemplate::kInvalidEscapedReservedWord;
Ben Murdochda12d292016-06-02 14:46:10 +01001000 break;
1001 case Token::ILLEGAL:
1002 if (scanner()->has_error()) {
1003 *message = scanner()->error();
1004 *location = scanner()->error_location();
1005 } else {
1006 *message = MessageTemplate::kInvalidOrUnexpectedToken;
1007 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001008 break;
1009 default:
1010 const char* name = Token::String(token);
1011 DCHECK(name != NULL);
1012 *arg = name;
1013 break;
1014 }
1015}
1016
1017
1018template <class Traits>
1019void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1020 return ReportUnexpectedTokenAt(scanner_->location(), token);
1021}
1022
1023
1024template <class Traits>
1025void ParserBase<Traits>::ReportUnexpectedTokenAt(
1026 Scanner::Location source_location, Token::Value token,
1027 MessageTemplate::Template message) {
1028 const char* arg;
Ben Murdochda12d292016-06-02 14:46:10 +01001029 GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001030 Traits::ReportMessageAt(source_location, message, arg);
1031}
1032
1033
1034template <class Traits>
1035typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1036 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001037 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001038 auto result = ParseAndClassifyIdentifier(&classifier, ok);
1039 if (!*ok) return Traits::EmptyIdentifier();
1040
1041 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1042 ValidateAssignmentPattern(&classifier, ok);
1043 if (!*ok) return Traits::EmptyIdentifier();
1044 ValidateBindingPattern(&classifier, ok);
1045 if (!*ok) return Traits::EmptyIdentifier();
1046 }
1047
1048 return result;
1049}
1050
1051
1052template <class Traits>
1053typename ParserBase<Traits>::IdentifierT
1054ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1055 bool* ok) {
1056 Token::Value next = Next();
1057 if (next == Token::IDENTIFIER) {
1058 IdentifierT name = this->GetSymbol(scanner());
1059 // When this function is used to read a formal parameter, we don't always
1060 // know whether the function is going to be strict or sloppy. Indeed for
1061 // arrow functions we don't always know that the identifier we are reading
1062 // is actually a formal parameter. Therefore besides the errors that we
1063 // must detect because we know we're in strict mode, we also record any
1064 // error that we might make in the future once we know the language mode.
1065 if (this->IsEval(name)) {
1066 classifier->RecordStrictModeFormalParameterError(
1067 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1068 if (is_strict(language_mode())) {
1069 classifier->RecordBindingPatternError(
1070 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1071 }
1072 }
1073 if (this->IsArguments(name)) {
1074 scope_->RecordArgumentsUsage();
1075 classifier->RecordStrictModeFormalParameterError(
1076 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1077 if (is_strict(language_mode())) {
1078 classifier->RecordBindingPatternError(
1079 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1080 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001081 }
1082
1083 if (classifier->duplicate_finder() != nullptr &&
1084 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1085 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1086 }
1087 return name;
1088 } else if (is_sloppy(language_mode()) &&
1089 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1090 next == Token::ESCAPED_STRICT_RESERVED_WORD ||
1091 next == Token::LET || next == Token::STATIC ||
1092 (next == Token::YIELD && !is_generator()))) {
1093 classifier->RecordStrictModeFormalParameterError(
1094 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1095 if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1096 is_strict(language_mode())) {
1097 ReportUnexpectedToken(next);
1098 *ok = false;
1099 return Traits::EmptyIdentifier();
1100 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001101 if (next == Token::LET ||
1102 (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1103 scanner()->is_literal_contextual_keyword(CStrVector("let")))) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001104 classifier->RecordLetPatternError(scanner()->location(),
1105 MessageTemplate::kLetInLexicalBinding);
1106 }
1107 return this->GetSymbol(scanner());
1108 } else {
1109 this->ReportUnexpectedToken(next);
1110 *ok = false;
1111 return Traits::EmptyIdentifier();
1112 }
1113}
1114
1115
1116template <class Traits>
1117typename ParserBase<Traits>::IdentifierT
1118ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
1119 bool is_generator, bool* is_strict_reserved, bool* ok) {
1120 Token::Value next = Next();
1121 if (next == Token::IDENTIFIER) {
1122 *is_strict_reserved = false;
1123 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1124 next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
1125 *is_strict_reserved = true;
1126 } else {
1127 ReportUnexpectedToken(next);
1128 *ok = false;
1129 return Traits::EmptyIdentifier();
1130 }
1131
1132 IdentifierT name = this->GetSymbol(scanner());
1133 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1134 return name;
1135}
1136
1137
1138template <class Traits>
1139typename ParserBase<Traits>::IdentifierT
1140ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1141 Token::Value next = Next();
1142 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
1143 next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
1144 next != Token::FUTURE_STRICT_RESERVED_WORD &&
1145 next != Token::ESCAPED_KEYWORD &&
1146 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1147 this->ReportUnexpectedToken(next);
1148 *ok = false;
1149 return Traits::EmptyIdentifier();
1150 }
1151
1152 IdentifierT name = this->GetSymbol(scanner());
1153 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1154 return name;
1155}
1156
1157
1158template <class Traits>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001159typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1160 bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
1161 int pos = peek_position();
1162 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1163 Next();
1164 ReportMessage(MessageTemplate::kUnterminatedRegExp);
1165 *ok = false;
1166 return Traits::EmptyExpression();
1167 }
1168
1169 int literal_index = function_state_->NextMaterializedLiteralIndex();
1170
1171 IdentifierT js_pattern = this->GetNextSymbol(scanner());
1172 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
1173 if (flags.IsNothing()) {
1174 Next();
1175 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1176 *ok = false;
1177 return Traits::EmptyExpression();
1178 }
1179 int js_flags = flags.FromJust();
1180 Next();
Ben Murdochda12d292016-06-02 14:46:10 +01001181 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001182}
1183
1184
1185#define CHECK_OK ok); \
1186 if (!*ok) return this->EmptyExpression(); \
1187 ((void)0
1188#define DUMMY ) // to make indentation work
1189#undef DUMMY
1190
1191// Used in functions where the return type is not ExpressionT.
1192#define CHECK_OK_CUSTOM(x) ok); \
1193 if (!*ok) return this->x(); \
1194 ((void)0
1195#define DUMMY ) // to make indentation work
1196#undef DUMMY
1197
1198
1199template <class Traits>
1200typename ParserBase<Traits>::ExpressionT
1201ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
1202 bool* ok) {
1203 // PrimaryExpression ::
1204 // 'this'
1205 // 'null'
1206 // 'true'
1207 // 'false'
1208 // Identifier
1209 // Number
1210 // String
1211 // ArrayLiteral
1212 // ObjectLiteral
1213 // RegExpLiteral
1214 // ClassLiteral
1215 // '(' Expression ')'
1216 // TemplateLiteral
1217 // do Block
1218
1219 int beg_pos = peek_position();
1220 switch (peek()) {
1221 case Token::THIS: {
1222 BindingPatternUnexpectedToken(classifier);
1223 Consume(Token::THIS);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224 return this->ThisExpression(scope_, factory(), beg_pos);
1225 }
1226
1227 case Token::NULL_LITERAL:
1228 case Token::TRUE_LITERAL:
1229 case Token::FALSE_LITERAL:
1230 BindingPatternUnexpectedToken(classifier);
1231 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1232 case Token::SMI:
1233 case Token::NUMBER:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001234 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001235 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1236
1237 case Token::IDENTIFIER:
1238 case Token::LET:
1239 case Token::STATIC:
1240 case Token::YIELD:
1241 case Token::ESCAPED_STRICT_RESERVED_WORD:
1242 case Token::FUTURE_STRICT_RESERVED_WORD: {
1243 // Using eval or arguments in this context is OK even in strict mode.
1244 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
1245 return this->ExpressionFromIdentifier(
1246 name, beg_pos, scanner()->location().end_pos, scope_, factory());
1247 }
1248
1249 case Token::STRING: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001250 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001251 Consume(Token::STRING);
1252 return this->ExpressionFromString(beg_pos, scanner(), factory());
1253 }
1254
1255 case Token::ASSIGN_DIV:
1256 classifier->RecordBindingPatternError(
1257 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1258 return this->ParseRegExpLiteral(true, classifier, ok);
1259
1260 case Token::DIV:
1261 classifier->RecordBindingPatternError(
1262 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1263 return this->ParseRegExpLiteral(false, classifier, ok);
1264
1265 case Token::LBRACK:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001266 return this->ParseArrayLiteral(classifier, ok);
1267
1268 case Token::LBRACE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001269 return this->ParseObjectLiteral(classifier, ok);
1270
1271 case Token::LPAREN: {
1272 // Arrow function formal parameters are either a single identifier or a
1273 // list of BindingPattern productions enclosed in parentheses.
1274 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
1275 // is_valid_binding_pattern() check to detect multiple levels of
1276 // parenthesization.
1277 if (!classifier->is_valid_binding_pattern()) {
1278 ArrowFormalParametersUnexpectedToken(classifier);
1279 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001280 classifier->RecordPatternError(scanner()->peek_location(),
1281 MessageTemplate::kUnexpectedToken,
1282 Token::String(Token::LPAREN));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001283 Consume(Token::LPAREN);
1284 if (Check(Token::RPAREN)) {
1285 // ()=>x. The continuation that looks for the => is in
1286 // ParseAssignmentExpression.
1287 classifier->RecordExpressionError(scanner()->location(),
1288 MessageTemplate::kUnexpectedToken,
1289 Token::String(Token::RPAREN));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001290 return factory()->NewEmptyParentheses(beg_pos);
1291 } else if (Check(Token::ELLIPSIS)) {
1292 // (...x)=>x. The continuation that looks for the => is in
1293 // ParseAssignmentExpression.
1294 int ellipsis_pos = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001295 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001296 classifier->RecordExpressionError(scanner()->location(),
1297 MessageTemplate::kUnexpectedToken,
1298 Token::String(Token::ELLIPSIS));
1299 classifier->RecordNonSimpleParameter();
1300 ExpressionT expr =
1301 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001302 if (!this->IsIdentifier(expr) && !IsValidPattern(expr)) {
1303 classifier->RecordArrowFormalParametersError(
1304 Scanner::Location(ellipsis_pos, scanner()->location().end_pos),
1305 MessageTemplate::kInvalidRestParameter);
1306 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001307 if (peek() == Token::COMMA) {
1308 ReportMessageAt(scanner()->peek_location(),
1309 MessageTemplate::kParamAfterRest);
1310 *ok = false;
1311 return this->EmptyExpression();
1312 }
1313 Expect(Token::RPAREN, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001314 return factory()->NewSpread(expr, ellipsis_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001315 }
1316 // Heuristically try to detect immediately called functions before
1317 // seeing the call parentheses.
1318 parenthesized_function_ = (peek() == Token::FUNCTION);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001319 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001320 Expect(Token::RPAREN, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001321 return expr;
1322 }
1323
1324 case Token::CLASS: {
1325 BindingPatternUnexpectedToken(classifier);
1326 Consume(Token::CLASS);
1327 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
1328 ReportMessage(MessageTemplate::kSloppyLexical);
1329 *ok = false;
1330 return this->EmptyExpression();
1331 }
1332 int class_token_position = position();
1333 IdentifierT name = this->EmptyIdentifier();
1334 bool is_strict_reserved_name = false;
1335 Scanner::Location class_name_location = Scanner::Location::invalid();
1336 if (peek_any_identifier()) {
1337 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1338 CHECK_OK);
1339 class_name_location = scanner()->location();
1340 }
Ben Murdochda12d292016-06-02 14:46:10 +01001341 return this->ParseClassLiteral(classifier, name, class_name_location,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001342 is_strict_reserved_name,
1343 class_token_position, ok);
1344 }
1345
1346 case Token::TEMPLATE_SPAN:
1347 case Token::TEMPLATE_TAIL:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001348 BindingPatternUnexpectedToken(classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001349 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
1350 classifier, ok);
1351
1352 case Token::MOD:
1353 if (allow_natives() || extension_ != NULL) {
1354 BindingPatternUnexpectedToken(classifier);
1355 return this->ParseV8Intrinsic(ok);
1356 }
1357 break;
1358
1359 case Token::DO:
1360 if (allow_harmony_do_expressions()) {
1361 BindingPatternUnexpectedToken(classifier);
1362 return Traits::ParseDoExpression(ok);
1363 }
1364 break;
1365
1366 default:
1367 break;
1368 }
1369
1370 ReportUnexpectedToken(Next());
1371 *ok = false;
1372 return this->EmptyExpression();
1373}
1374
1375
1376template <class Traits>
1377typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1378 bool accept_IN, bool* ok) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001379 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001380 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001381 Traits::RewriteNonPattern(&classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001382 return result;
1383}
1384
1385
1386template <class Traits>
1387typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1388 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001389 // Expression ::
1390 // AssignmentExpression
1391 // Expression ',' AssignmentExpression
1392
Ben Murdoch097c5b22016-05-18 11:27:45 +01001393 ExpressionClassifier binding_classifier(this);
1394 ExpressionT result =
1395 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
1396 classifier->Accumulate(&binding_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001397 ExpressionClassifier::AllProductions);
1398 bool is_simple_parameter_list = this->IsIdentifier(result);
1399 bool seen_rest = false;
1400 while (peek() == Token::COMMA) {
1401 if (seen_rest) {
1402 // At this point the production can't possibly be valid, but we don't know
1403 // which error to signal.
1404 classifier->RecordArrowFormalParametersError(
1405 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
1406 }
1407 Consume(Token::COMMA);
1408 bool is_rest = false;
1409 if (peek() == Token::ELLIPSIS) {
1410 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1411 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1412 // valid expression or binding pattern.
1413 ExpressionUnexpectedToken(classifier);
1414 BindingPatternUnexpectedToken(classifier);
1415 Consume(Token::ELLIPSIS);
1416 seen_rest = is_rest = true;
1417 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001418 int pos = position(), expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001419 ExpressionT right = this->ParseAssignmentExpression(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001420 accept_IN, &binding_classifier, CHECK_OK);
1421 classifier->Accumulate(&binding_classifier,
1422 ExpressionClassifier::AllProductions);
1423 if (is_rest) {
1424 if (!this->IsIdentifier(right) && !IsValidPattern(right)) {
1425 classifier->RecordArrowFormalParametersError(
1426 Scanner::Location(pos, scanner()->location().end_pos),
1427 MessageTemplate::kInvalidRestParameter);
1428 }
1429 right = factory()->NewSpread(right, pos, expr_pos);
1430 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001431 is_simple_parameter_list =
1432 is_simple_parameter_list && this->IsIdentifier(right);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001433 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1434 }
1435 if (!is_simple_parameter_list || seen_rest) {
1436 classifier->RecordNonSimpleParameter();
1437 }
1438
1439 return result;
1440}
1441
1442
1443template <class Traits>
1444typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
1445 ExpressionClassifier* classifier, bool* ok) {
1446 // ArrayLiteral ::
1447 // '[' Expression? (',' Expression?)* ']'
1448
1449 int pos = peek_position();
1450 typename Traits::Type::ExpressionList values =
1451 this->NewExpressionList(4, zone_);
1452 int first_spread_index = -1;
1453 Expect(Token::LBRACK, CHECK_OK);
1454 while (peek() != Token::RBRACK) {
1455 ExpressionT elem = this->EmptyExpression();
1456 if (peek() == Token::COMMA) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001457 elem = this->GetLiteralTheHole(peek_position(), factory());
1458 } else if (peek() == Token::ELLIPSIS) {
1459 int start_pos = peek_position();
1460 Consume(Token::ELLIPSIS);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001461 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001462 ExpressionT argument =
1463 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001464 elem = factory()->NewSpread(argument, start_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001465
1466 if (first_spread_index < 0) {
1467 first_spread_index = values->length();
1468 }
1469
1470 if (argument->IsAssignment()) {
1471 classifier->RecordPatternError(
1472 Scanner::Location(start_pos, scanner()->location().end_pos),
1473 MessageTemplate::kInvalidDestructuringTarget);
1474 } else {
1475 CheckDestructuringElement(argument, classifier, start_pos,
1476 scanner()->location().end_pos);
1477 }
1478
1479 if (peek() == Token::COMMA) {
1480 classifier->RecordPatternError(
1481 Scanner::Location(start_pos, scanner()->location().end_pos),
1482 MessageTemplate::kElementAfterRest);
1483 }
1484 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001485 int beg_pos = peek_position();
1486 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
1487 CheckDestructuringElement(elem, classifier, beg_pos,
1488 scanner()->location().end_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001489 }
1490 values->Add(elem, zone_);
1491 if (peek() != Token::RBRACK) {
1492 Expect(Token::COMMA, CHECK_OK);
1493 }
1494 }
1495 Expect(Token::RBRACK, CHECK_OK);
1496
1497 // Update the scope information before the pre-parsing bailout.
1498 int literal_index = function_state_->NextMaterializedLiteralIndex();
1499
Ben Murdochda12d292016-06-02 14:46:10 +01001500 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index,
1501 literal_index, pos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001502 if (first_spread_index >= 0) {
1503 result = factory()->NewRewritableExpression(result);
1504 Traits::QueueNonPatternForRewriting(result);
1505 }
1506 return result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001507}
1508
1509
1510template <class Traits>
1511typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001512 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001513 ExpressionClassifier* classifier, bool* ok) {
1514 Token::Value token = peek();
1515 int pos = peek_position();
1516
1517 // For non computed property names we normalize the name a bit:
1518 //
1519 // "12" -> 12
1520 // 12.3 -> "12.3"
1521 // 12.30 -> "12.3"
1522 // identifier -> "identifier"
1523 //
1524 // This is important because we use the property name as a key in a hash
1525 // table when we compute constant properties.
1526 switch (token) {
1527 case Token::STRING:
1528 Consume(Token::STRING);
1529 *name = this->GetSymbol(scanner());
1530 break;
1531
1532 case Token::SMI:
1533 Consume(Token::SMI);
1534 *name = this->GetNumberAsSymbol(scanner());
1535 break;
1536
1537 case Token::NUMBER:
1538 Consume(Token::NUMBER);
1539 *name = this->GetNumberAsSymbol(scanner());
1540 break;
1541
1542 case Token::LBRACK: {
1543 *is_computed_name = true;
1544 Consume(Token::LBRACK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001545 ExpressionClassifier computed_name_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001546 ExpressionT expression =
1547 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001548 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK);
1549 classifier->Accumulate(&computed_name_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001550 ExpressionClassifier::ExpressionProductions);
1551 Expect(Token::RBRACK, CHECK_OK);
1552 return expression;
1553 }
1554
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001555 default:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001556 *name = ParseIdentifierName(CHECK_OK);
1557 scanner()->IsGetOrSet(is_get, is_set);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001558 break;
1559 }
1560
1561 uint32_t index;
1562 return this->IsArrayIndex(*name, &index)
1563 ? factory()->NewNumberLiteral(index, pos)
1564 : factory()->NewStringLiteral(*name, pos);
1565}
1566
1567
1568template <class Traits>
1569typename ParserBase<Traits>::ObjectLiteralPropertyT
1570ParserBase<Traits>::ParsePropertyDefinition(
1571 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
1572 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
1573 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
1574 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
1575 ExpressionT value = this->EmptyExpression();
1576 bool is_get = false;
1577 bool is_set = false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001578 bool is_generator = Check(Token::MUL);
1579
1580 Token::Value name_token = peek();
1581 int next_beg_pos = scanner()->peek_location().beg_pos;
1582 int next_end_pos = scanner()->peek_location().end_pos;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001583 ExpressionT name_expression =
1584 ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier,
1585 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001586
1587 if (fni_ != nullptr && !*is_computed_name) {
1588 this->PushLiteralName(fni_, *name);
1589 }
1590
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001591 if (!in_class && !is_generator) {
1592 DCHECK(!is_static);
1593
1594 if (peek() == Token::COLON) {
1595 // PropertyDefinition
1596 // PropertyName ':' AssignmentExpression
1597 if (!*is_computed_name) {
1598 checker->CheckProperty(name_token, kValueProperty, false, false,
1599 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1600 }
1601 Consume(Token::COLON);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001602 int beg_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001603 value = this->ParseAssignmentExpression(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001604 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1605 CheckDestructuringElement(value, classifier, beg_pos,
1606 scanner()->location().end_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001607
1608 return factory()->NewObjectLiteralProperty(name_expression, value, false,
1609 *is_computed_name);
1610 }
1611
Ben Murdoch097c5b22016-05-18 11:27:45 +01001612 if (Token::IsIdentifier(name_token, language_mode(),
1613 this->is_generator()) &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001614 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1615 peek() == Token::ASSIGN)) {
1616 // PropertyDefinition
1617 // IdentifierReference
1618 // CoverInitializedName
1619 //
1620 // CoverInitializedName
1621 // IdentifierReference Initializer?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001622 if (classifier->duplicate_finder() != nullptr &&
1623 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1624 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1625 }
1626 if (name_token == Token::LET) {
1627 classifier->RecordLetPatternError(
1628 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1629 }
1630
1631 ExpressionT lhs = this->ExpressionFromIdentifier(
1632 *name, next_beg_pos, next_end_pos, scope_, factory());
1633 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos);
1634
1635 if (peek() == Token::ASSIGN) {
1636 Consume(Token::ASSIGN);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001637 ExpressionClassifier rhs_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001638 ExpressionT rhs = this->ParseAssignmentExpression(
1639 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001640 Traits::RewriteNonPattern(&rhs_classifier,
1641 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1642 classifier->Accumulate(&rhs_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001643 ExpressionClassifier::ExpressionProductions);
1644 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
1645 RelocInfo::kNoPosition);
1646 classifier->RecordCoverInitializedNameError(
1647 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1648 MessageTemplate::kInvalidCoverInitializedName);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001649
1650 if (allow_harmony_function_name()) {
1651 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs);
1652 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001653 } else {
1654 value = lhs;
1655 }
1656
1657 return factory()->NewObjectLiteralProperty(
1658 name_expression, value, ObjectLiteralProperty::COMPUTED, false,
1659 false);
1660 }
1661 }
1662
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001663 // Method definitions are never valid in patterns.
1664 classifier->RecordPatternError(
1665 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1666 MessageTemplate::kInvalidDestructuringTarget);
1667
1668 if (is_generator || peek() == Token::LPAREN) {
1669 // MethodDefinition
1670 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1671 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1672 if (!*is_computed_name) {
1673 checker->CheckProperty(name_token, kMethodProperty, is_static,
1674 is_generator,
1675 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1676 }
1677
1678 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
1679 : FunctionKind::kConciseMethod;
1680
1681 if (in_class && !is_static && this->IsConstructor(*name)) {
1682 *has_seen_constructor = true;
1683 kind = has_extends ? FunctionKind::kSubclassConstructor
1684 : FunctionKind::kBaseConstructor;
1685 }
1686
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001687 value = this->ParseFunctionLiteral(
1688 *name, scanner()->location(), kSkipFunctionNameCheck, kind,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001689 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
1690 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001691
1692 return factory()->NewObjectLiteralProperty(name_expression, value,
1693 ObjectLiteralProperty::COMPUTED,
1694 is_static, *is_computed_name);
1695 }
1696
Ben Murdoch097c5b22016-05-18 11:27:45 +01001697 if (in_class && name_token == Token::STATIC && !is_static) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001698 // ClassElement (static)
1699 // 'static' MethodDefinition
1700 *name = this->EmptyIdentifier();
1701 ObjectLiteralPropertyT property = ParsePropertyDefinition(
1702 checker, true, has_extends, true, is_computed_name, nullptr, classifier,
1703 name, ok);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001704 Traits::RewriteNonPattern(classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001705 return property;
1706 }
1707
1708 if (is_get || is_set) {
1709 // MethodDefinition (Accessors)
1710 // get PropertyName '(' ')' '{' FunctionBody '}'
1711 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
1712 *name = this->EmptyIdentifier();
1713 bool dont_care = false;
1714 name_token = peek();
1715
1716 name_expression = ParsePropertyName(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001717 name, &dont_care, &dont_care, is_computed_name, classifier,
1718 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001719
1720 if (!*is_computed_name) {
1721 checker->CheckProperty(name_token, kAccessorProperty, is_static,
1722 is_generator,
1723 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1724 }
1725
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001726 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001727 *name, scanner()->location(), kSkipFunctionNameCheck,
1728 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction,
1729 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001730 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1731
1732 // Make sure the name expression is a string since we need a Name for
1733 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
1734 // statically we can skip the extra runtime check.
1735 if (!*is_computed_name) {
1736 name_expression =
1737 factory()->NewStringLiteral(*name, name_expression->position());
1738 }
1739
1740 return factory()->NewObjectLiteralProperty(
1741 name_expression, value,
1742 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
1743 is_static, *is_computed_name);
1744 }
1745
1746 Token::Value next = Next();
1747 ReportUnexpectedToken(next);
1748 *ok = false;
1749 return this->EmptyObjectLiteralProperty();
1750}
1751
1752
1753template <class Traits>
1754typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
1755 ExpressionClassifier* classifier, bool* ok) {
1756 // ObjectLiteral ::
1757 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
1758
1759 int pos = peek_position();
1760 typename Traits::Type::PropertyList properties =
1761 this->NewPropertyList(4, zone_);
1762 int number_of_boilerplate_properties = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001763 bool has_computed_names = false;
1764 ObjectLiteralChecker checker(this);
1765
1766 Expect(Token::LBRACE, CHECK_OK);
1767
1768 while (peek() != Token::RBRACE) {
1769 FuncNameInferrer::State fni_state(fni_);
1770
1771 const bool in_class = false;
1772 const bool is_static = false;
1773 const bool has_extends = false;
1774 bool is_computed_name = false;
1775 IdentifierT name = this->EmptyIdentifier();
1776 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
1777 &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
1778 classifier, &name, CHECK_OK);
1779
1780 if (is_computed_name) {
1781 has_computed_names = true;
1782 }
1783
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001784 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
1785 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
1786 number_of_boilerplate_properties++;
1787 }
1788 properties->Add(property, zone());
1789
1790 if (peek() != Token::RBRACE) {
1791 // Need {} because of the CHECK_OK macro.
1792 Expect(Token::COMMA, CHECK_OK);
1793 }
1794
1795 if (fni_ != nullptr) fni_->Infer();
1796
1797 if (allow_harmony_function_name()) {
1798 Traits::SetFunctionNameFromPropertyName(property, name);
1799 }
1800 }
1801 Expect(Token::RBRACE, CHECK_OK);
1802
1803 // Computation of literal_index must happen before pre parse bailout.
1804 int literal_index = function_state_->NextMaterializedLiteralIndex();
1805
1806 return factory()->NewObjectLiteral(properties,
1807 literal_index,
1808 number_of_boilerplate_properties,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001809 pos);
1810}
1811
1812
1813template <class Traits>
1814typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
1815 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier,
1816 bool* ok) {
1817 // Arguments ::
1818 // '(' (AssignmentExpression)*[','] ')'
1819
1820 Scanner::Location spread_arg = Scanner::Location::invalid();
1821 typename Traits::Type::ExpressionList result =
1822 this->NewExpressionList(4, zone_);
1823 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1824 bool done = (peek() == Token::RPAREN);
1825 bool was_unspread = false;
1826 int unspread_sequences_count = 0;
1827 while (!done) {
1828 int start_pos = peek_position();
1829 bool is_spread = Check(Token::ELLIPSIS);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001830 int expr_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001831
1832 ExpressionT argument = this->ParseAssignmentExpression(
1833 true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001834 Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001835 if (is_spread) {
1836 if (!spread_arg.IsValid()) {
1837 spread_arg.beg_pos = start_pos;
1838 spread_arg.end_pos = peek_position();
1839 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001840 argument = factory()->NewSpread(argument, start_pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001841 }
1842 result->Add(argument, zone_);
1843
1844 // unspread_sequences_count is the number of sequences of parameters which
1845 // are not prefixed with a spread '...' operator.
1846 if (is_spread) {
1847 was_unspread = false;
1848 } else if (!was_unspread) {
1849 was_unspread = true;
1850 unspread_sequences_count++;
1851 }
1852
1853 if (result->length() > Code::kMaxArguments) {
1854 ReportMessage(MessageTemplate::kTooManyArguments);
1855 *ok = false;
1856 return this->NullExpressionList();
1857 }
1858 done = (peek() != Token::COMMA);
1859 if (!done) {
1860 Next();
1861 }
1862 }
1863 Scanner::Location location = scanner_->location();
1864 if (Token::RPAREN != Next()) {
1865 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
1866 *ok = false;
1867 return this->NullExpressionList();
1868 }
1869 *first_spread_arg_loc = spread_arg;
1870
1871 if (spread_arg.IsValid()) {
1872 // Unspread parameter sequences are translated into array literals in the
1873 // parser. Ensure that the number of materialized literals matches between
1874 // the parser and preparser
1875 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
1876 }
1877
1878 return result;
1879}
1880
1881// Precedence = 2
1882template <class Traits>
1883typename ParserBase<Traits>::ExpressionT
Ben Murdoch097c5b22016-05-18 11:27:45 +01001884ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001885 ExpressionClassifier* classifier,
1886 bool* ok) {
1887 // AssignmentExpression ::
1888 // ConditionalExpression
1889 // ArrowFunction
1890 // YieldExpression
1891 // LeftHandSideExpression AssignmentOperator AssignmentExpression
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001892 bool is_destructuring_assignment = false;
1893 int lhs_beg_pos = peek_position();
1894
1895 if (peek() == Token::YIELD && is_generator()) {
1896 return this->ParseYieldExpression(classifier, ok);
1897 }
1898
1899 FuncNameInferrer::State fni_state(fni_);
1900 ParserBase<Traits>::Checkpoint checkpoint(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001901 ExpressionClassifier arrow_formals_classifier(this,
1902 classifier->duplicate_finder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001903 bool parenthesized_formals = peek() == Token::LPAREN;
1904 if (!parenthesized_formals) {
1905 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
1906 }
1907 ExpressionT expression = this->ParseConditionalExpression(
1908 accept_IN, &arrow_formals_classifier, CHECK_OK);
1909 if (peek() == Token::ARROW) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001910 classifier->RecordPatternError(scanner()->peek_location(),
1911 MessageTemplate::kUnexpectedToken,
1912 Token::String(Token::ARROW));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001913 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
1914 parenthesized_formals, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01001915 // This reads strangely, but is correct: it checks whether any
1916 // sub-expression of the parameter list failed to be a valid formal
1917 // parameter initializer. Since YieldExpressions are banned anywhere
1918 // in an arrow parameter list, this is correct.
1919 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
1920 // "YieldExpression", which is its only use.
1921 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001922 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
1923 Scope* scope =
1924 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
1925 // Because the arrow's parameters were parsed in the outer scope, any
1926 // usage flags that might have been triggered there need to be copied
1927 // to the arrow scope.
1928 scope_->PropagateUsageFlagsToScope(scope);
1929 FormalParametersT parameters(scope);
1930 if (!arrow_formals_classifier.is_simple_parameter_list()) {
1931 scope->SetHasNonSimpleParameters();
1932 parameters.is_simple = false;
1933 }
1934
1935 checkpoint.Restore(&parameters.materialized_literals_count);
1936
1937 scope->set_start_position(lhs_beg_pos);
1938 Scanner::Location duplicate_loc = Scanner::Location::invalid();
1939 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
1940 &duplicate_loc, CHECK_OK);
1941 if (duplicate_loc.IsValid()) {
1942 arrow_formals_classifier.RecordDuplicateFormalParameterError(
1943 duplicate_loc);
1944 }
1945 expression = this->ParseArrowFunctionLiteral(
1946 accept_IN, parameters, arrow_formals_classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001947
1948 if (fni_ != nullptr) fni_->Infer();
1949
1950 return expression;
1951 }
1952
1953 if (this->IsValidReferenceExpression(expression)) {
1954 arrow_formals_classifier.ForgiveAssignmentPatternError();
1955 }
1956
1957 // "expression" was not itself an arrow function parameter list, but it might
1958 // form part of one. Propagate speculative formal parameter error locations.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001959 // Do not merge pending non-pattern expressions yet!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001960 classifier->Accumulate(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001961 &arrow_formals_classifier,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001962 ExpressionClassifier::StandardProductions |
Ben Murdoch097c5b22016-05-18 11:27:45 +01001963 ExpressionClassifier::FormalParametersProductions |
1964 ExpressionClassifier::CoverInitializedNameProduction,
1965 false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001966
1967 if (!Token::IsAssignmentOp(peek())) {
1968 // Parsed conditional expression only (no assignment).
Ben Murdoch097c5b22016-05-18 11:27:45 +01001969 // Now pending non-pattern expressions must be merged.
1970 classifier->MergeNonPatterns(&arrow_formals_classifier);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001971 return expression;
1972 }
1973
Ben Murdoch097c5b22016-05-18 11:27:45 +01001974 // Now pending non-pattern expressions must be discarded.
1975 arrow_formals_classifier.Discard();
1976
Ben Murdochda12d292016-06-02 14:46:10 +01001977 if (IsValidPattern(expression) && peek() == Token::ASSIGN) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001978 classifier->ForgiveCoverInitializedNameError();
1979 ValidateAssignmentPattern(classifier, CHECK_OK);
1980 is_destructuring_assignment = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001981 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001982 expression = this->CheckAndRewriteReferenceExpression(
1983 expression, lhs_beg_pos, scanner()->location().end_pos,
1984 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
1985 }
1986
1987 expression = this->MarkExpressionAsAssigned(expression);
1988
1989 Token::Value op = Next(); // Get assignment operator.
1990 if (op != Token::ASSIGN) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001991 classifier->RecordPatternError(scanner()->location(),
1992 MessageTemplate::kUnexpectedToken,
1993 Token::String(op));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001994 }
1995 int pos = position();
1996
Ben Murdoch097c5b22016-05-18 11:27:45 +01001997 ExpressionClassifier rhs_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001998
1999 ExpressionT right =
2000 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002001 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002002 classifier->Accumulate(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002003 &rhs_classifier, ExpressionClassifier::ExpressionProductions |
2004 ExpressionClassifier::CoverInitializedNameProduction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002005
2006 // TODO(1231235): We try to estimate the set of properties set by
2007 // constructors. We define a new property whenever there is an
2008 // assignment to a property of 'this'. We should probably only add
2009 // properties if we haven't seen them before. Otherwise we'll
2010 // probably overestimate the number of properties.
2011 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2012 function_state_->AddProperty();
2013 }
2014
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002015 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2016
2017 if (fni_ != NULL) {
2018 // Check if the right hand side is a call to avoid inferring a
2019 // name if we're dealing with "a = function(){...}();"-like
2020 // expression.
2021 if ((op == Token::INIT || op == Token::ASSIGN) &&
2022 (!right->IsCall() && !right->IsCallNew())) {
2023 fni_->Infer();
2024 } else {
2025 fni_->RemoveLastFunction();
2026 }
2027 }
2028
2029 if (op == Token::ASSIGN && allow_harmony_function_name()) {
2030 Traits::SetFunctionNameFromIdentifierRef(right, expression);
2031 }
2032
Ben Murdochda12d292016-06-02 14:46:10 +01002033 if (op == Token::ASSIGN_EXP) {
2034 DCHECK(!is_destructuring_assignment);
2035 return Traits::RewriteAssignExponentiation(expression, right, pos);
2036 }
2037
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002038 ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2039
2040 if (is_destructuring_assignment) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002041 result = factory()->NewRewritableExpression(result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002042 Traits::QueueDestructuringAssignmentForRewriting(result);
2043 }
2044
2045 return result;
2046}
2047
2048template <class Traits>
2049typename ParserBase<Traits>::ExpressionT
2050ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
2051 bool* ok) {
2052 // YieldExpression ::
2053 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2054 int pos = peek_position();
2055 classifier->RecordPatternError(scanner()->peek_location(),
2056 MessageTemplate::kInvalidDestructuringTarget);
Ben Murdochda12d292016-06-02 14:46:10 +01002057 classifier->RecordFormalParameterInitializerError(
2058 scanner()->peek_location(), MessageTemplate::kYieldInParameter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002059 Expect(Token::YIELD, CHECK_OK);
2060 ExpressionT generator_object =
2061 factory()->NewVariableProxy(function_state_->generator_object_variable());
2062 ExpressionT expression = Traits::EmptyExpression();
Ben Murdochda12d292016-06-02 14:46:10 +01002063 bool delegating = false; // yield*
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002064 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
Ben Murdochda12d292016-06-02 14:46:10 +01002065 if (Check(Token::MUL)) delegating = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002066 switch (peek()) {
2067 case Token::EOS:
2068 case Token::SEMICOLON:
2069 case Token::RBRACE:
2070 case Token::RBRACK:
2071 case Token::RPAREN:
2072 case Token::COLON:
2073 case Token::COMMA:
2074 // The above set of tokens is the complete set of tokens that can appear
2075 // after an AssignmentExpression, and none of them can start an
2076 // AssignmentExpression. This allows us to avoid looking for an RHS for
Ben Murdochda12d292016-06-02 14:46:10 +01002077 // a regular yield, given only one look-ahead token.
2078 if (!delegating) break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002079 // Delegating yields require an RHS; fall through.
2080 default:
2081 expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002082 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002083 break;
2084 }
2085 }
Ben Murdochda12d292016-06-02 14:46:10 +01002086
2087 if (delegating) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002088 return Traits::RewriteYieldStar(generator_object, expression, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002089 }
Ben Murdochda12d292016-06-02 14:46:10 +01002090
2091 expression = Traits::BuildIteratorResult(expression, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002092 // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2093 // TODO(verwaest): Come up with a better solution.
2094 typename Traits::Type::YieldExpression yield =
Ben Murdochda12d292016-06-02 14:46:10 +01002095 factory()->NewYield(generator_object, expression, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002096 return yield;
2097}
2098
2099
2100// Precedence = 3
2101template <class Traits>
2102typename ParserBase<Traits>::ExpressionT
2103ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
2104 ExpressionClassifier* classifier,
2105 bool* ok) {
2106 // ConditionalExpression ::
2107 // LogicalOrExpression
2108 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2109
2110 int pos = peek_position();
2111 // We start using the binary expression parser for prec >= 4 only!
2112 ExpressionT expression =
2113 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2114 if (peek() != Token::CONDITIONAL) return expression;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002115 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002116 ArrowFormalParametersUnexpectedToken(classifier);
2117 BindingPatternUnexpectedToken(classifier);
2118 Consume(Token::CONDITIONAL);
2119 // In parsing the first assignment expression in conditional
2120 // expressions we always accept the 'in' keyword; see ECMA-262,
2121 // section 11.12, page 58.
2122 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002123 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002124 Expect(Token::COLON, CHECK_OK);
2125 ExpressionT right =
2126 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002127 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002128 return factory()->NewConditional(expression, left, right, pos);
2129}
2130
2131
2132// Precedence >= 4
2133template <class Traits>
2134typename ParserBase<Traits>::ExpressionT
2135ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
2136 ExpressionClassifier* classifier,
2137 bool* ok) {
2138 DCHECK(prec >= 4);
2139 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2140 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2141 // prec1 >= 4
2142 while (Precedence(peek(), accept_IN) == prec1) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002143 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002144 BindingPatternUnexpectedToken(classifier);
2145 ArrowFormalParametersUnexpectedToken(classifier);
2146 Token::Value op = Next();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002147 int pos = position();
Ben Murdochda12d292016-06-02 14:46:10 +01002148
2149 const bool is_right_associative = op == Token::EXP;
2150 const int next_prec = is_right_associative ? prec1 : prec1 + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002151 ExpressionT y =
Ben Murdochda12d292016-06-02 14:46:10 +01002152 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002153 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002154
2155 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2156 factory())) {
2157 continue;
2158 }
2159
2160 // For now we distinguish between comparisons and other binary
2161 // operations. (We could combine the two and get rid of this
2162 // code and AST node eventually.)
2163 if (Token::IsCompareOp(op)) {
2164 // We have a comparison.
2165 Token::Value cmp = op;
2166 switch (op) {
2167 case Token::NE: cmp = Token::EQ; break;
2168 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2169 default: break;
2170 }
Ben Murdochda12d292016-06-02 14:46:10 +01002171 if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002172 x = Traits::RewriteInstanceof(x, y, pos);
2173 } else {
2174 x = factory()->NewCompareOperation(cmp, x, y, pos);
2175 if (cmp != op) {
2176 // The comparison was negated - add a NOT.
2177 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2178 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002179 }
Ben Murdochda12d292016-06-02 14:46:10 +01002180
2181 } else if (op == Token::EXP) {
2182 x = Traits::RewriteExponentiation(x, y, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002183 } else {
2184 // We have a "normal" binary operation.
2185 x = factory()->NewBinaryOperation(op, x, y, pos);
2186 }
2187 }
2188 }
2189 return x;
2190}
2191
2192
2193template <class Traits>
2194typename ParserBase<Traits>::ExpressionT
2195ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
2196 bool* ok) {
2197 // UnaryExpression ::
2198 // PostfixExpression
2199 // 'delete' UnaryExpression
2200 // 'void' UnaryExpression
2201 // 'typeof' UnaryExpression
2202 // '++' UnaryExpression
2203 // '--' UnaryExpression
2204 // '+' UnaryExpression
2205 // '-' UnaryExpression
2206 // '~' UnaryExpression
2207 // '!' UnaryExpression
2208
2209 Token::Value op = peek();
2210 if (Token::IsUnaryOp(op)) {
2211 BindingPatternUnexpectedToken(classifier);
2212 ArrowFormalParametersUnexpectedToken(classifier);
2213
2214 op = Next();
2215 int pos = position();
2216 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002217 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002218
2219 if (op == Token::DELETE && is_strict(language_mode())) {
Ben Murdochda12d292016-06-02 14:46:10 +01002220 if (this->IsIdentifier(expression)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002221 // "delete identifier" is a syntax error in strict mode.
2222 ReportMessage(MessageTemplate::kStrictDelete);
2223 *ok = false;
2224 return this->EmptyExpression();
2225 }
2226 }
2227
Ben Murdochda12d292016-06-02 14:46:10 +01002228 if (peek() == Token::EXP) {
2229 ReportUnexpectedToken(Next());
2230 *ok = false;
2231 return this->EmptyExpression();
2232 }
2233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002234 // Allow Traits do rewrite the expression.
2235 return this->BuildUnaryExpression(expression, op, pos, factory());
2236 } else if (Token::IsCountOp(op)) {
2237 BindingPatternUnexpectedToken(classifier);
2238 ArrowFormalParametersUnexpectedToken(classifier);
2239 op = Next();
2240 int beg_pos = peek_position();
2241 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
2242 expression = this->CheckAndRewriteReferenceExpression(
2243 expression, beg_pos, scanner()->location().end_pos,
2244 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
2245 this->MarkExpressionAsAssigned(expression);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002246 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002247
2248 return factory()->NewCountOperation(op,
2249 true /* prefix */,
2250 expression,
2251 position());
2252
2253 } else {
2254 return this->ParsePostfixExpression(classifier, ok);
2255 }
2256}
2257
2258
2259template <class Traits>
2260typename ParserBase<Traits>::ExpressionT
2261ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
2262 bool* ok) {
2263 // PostfixExpression ::
2264 // LeftHandSideExpression ('++' | '--')?
2265
2266 int lhs_beg_pos = peek_position();
2267 ExpressionT expression =
2268 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2269 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2270 Token::IsCountOp(peek())) {
2271 BindingPatternUnexpectedToken(classifier);
2272 ArrowFormalParametersUnexpectedToken(classifier);
2273
2274 expression = this->CheckAndRewriteReferenceExpression(
2275 expression, lhs_beg_pos, scanner()->location().end_pos,
2276 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
2277 expression = this->MarkExpressionAsAssigned(expression);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002278 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002279
2280 Token::Value next = Next();
2281 expression =
2282 factory()->NewCountOperation(next,
2283 false /* postfix */,
2284 expression,
2285 position());
2286 }
2287 return expression;
2288}
2289
2290
2291template <class Traits>
2292typename ParserBase<Traits>::ExpressionT
2293ParserBase<Traits>::ParseLeftHandSideExpression(
2294 ExpressionClassifier* classifier, bool* ok) {
2295 // LeftHandSideExpression ::
2296 // (NewExpression | MemberExpression) ...
2297
2298 ExpressionT result =
2299 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
2300
2301 while (true) {
2302 switch (peek()) {
2303 case Token::LBRACK: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002304 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002305 BindingPatternUnexpectedToken(classifier);
2306 ArrowFormalParametersUnexpectedToken(classifier);
2307 Consume(Token::LBRACK);
2308 int pos = position();
2309 ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002310 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002311 result = factory()->NewProperty(result, index, pos);
2312 Expect(Token::RBRACK, CHECK_OK);
2313 break;
2314 }
2315
2316 case Token::LPAREN: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002317 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002318 BindingPatternUnexpectedToken(classifier);
2319 ArrowFormalParametersUnexpectedToken(classifier);
2320
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002321 int pos;
2322 if (scanner()->current_token() == Token::IDENTIFIER ||
2323 scanner()->current_token() == Token::SUPER) {
2324 // For call of an identifier we want to report position of
2325 // the identifier as position of the call in the stack trace.
2326 pos = position();
2327 } else {
2328 // For other kinds of calls we record position of the parenthesis as
2329 // position of the call. Note that this is extremely important for
2330 // expressions of the form function(){...}() for which call position
2331 // should not point to the closing brace otherwise it will intersect
2332 // with positions recorded for function literal and confuse debugger.
2333 pos = peek_position();
2334 // Also the trailing parenthesis are a hint that the function will
2335 // be called immediately. If we happen to have parsed a preceding
2336 // function literal eagerly, we can also compile it eagerly.
2337 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2338 result->AsFunctionLiteral()->set_should_eager_compile();
2339 }
2340 }
2341 Scanner::Location spread_pos;
2342 typename Traits::Type::ExpressionList args =
2343 ParseArguments(&spread_pos, classifier, CHECK_OK);
2344
2345 // Keep track of eval() calls since they disable all local variable
2346 // optimizations.
2347 // The calls that need special treatment are the
2348 // direct eval calls. These calls are all of the form eval(...), with
2349 // no explicit receiver.
2350 // These calls are marked as potentially direct eval calls. Whether
2351 // they are actually direct calls to eval is determined at run time.
2352 this->CheckPossibleEvalCall(result, scope_);
2353
2354 bool is_super_call = result->IsSuperCallReference();
2355 if (spread_pos.IsValid()) {
2356 args = Traits::PrepareSpreadArguments(args);
2357 result = Traits::SpreadCall(result, args, pos);
2358 } else {
2359 result = factory()->NewCall(result, args, pos);
2360 }
2361
2362 // Explicit calls to the super constructor using super() perform an
2363 // implicit binding assignment to the 'this' variable.
2364 if (is_super_call) {
2365 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2366 result =
2367 factory()->NewAssignment(Token::INIT, this_expr, result, pos);
2368 }
2369
2370 if (fni_ != NULL) fni_->RemoveLastFunction();
2371 break;
2372 }
2373
2374 case Token::PERIOD: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002375 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002376 BindingPatternUnexpectedToken(classifier);
2377 ArrowFormalParametersUnexpectedToken(classifier);
2378 Consume(Token::PERIOD);
2379 int pos = position();
2380 IdentifierT name = ParseIdentifierName(CHECK_OK);
2381 result = factory()->NewProperty(
2382 result, factory()->NewStringLiteral(name, pos), pos);
2383 if (fni_ != NULL) this->PushLiteralName(fni_, name);
2384 break;
2385 }
2386
2387 case Token::TEMPLATE_SPAN:
2388 case Token::TEMPLATE_TAIL: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002389 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002390 BindingPatternUnexpectedToken(classifier);
2391 ArrowFormalParametersUnexpectedToken(classifier);
2392 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
2393 break;
2394 }
2395
2396 default:
2397 return result;
2398 }
2399 }
2400}
2401
2402
2403template <class Traits>
2404typename ParserBase<Traits>::ExpressionT
2405ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
2406 ExpressionClassifier* classifier, bool* ok) {
2407 // NewExpression ::
2408 // ('new')+ MemberExpression
2409 //
2410 // NewTarget ::
2411 // 'new' '.' 'target'
2412
2413 // The grammar for new expressions is pretty warped. We can have several 'new'
2414 // keywords following each other, and then a MemberExpression. When we see '('
2415 // after the MemberExpression, it's associated with the rightmost unassociated
2416 // 'new' to create a NewExpression with arguments. However, a NewExpression
2417 // can also occur without arguments.
2418
2419 // Examples of new expression:
2420 // new foo.bar().baz means (new (foo.bar)()).baz
2421 // new foo()() means (new foo())()
2422 // new new foo()() means (new (new foo())())
2423 // new new foo means new (new foo)
2424 // new new foo() means new (new foo())
2425 // new new foo().bar().baz means (new (new foo()).bar()).baz
2426
2427 if (peek() == Token::NEW) {
2428 BindingPatternUnexpectedToken(classifier);
2429 ArrowFormalParametersUnexpectedToken(classifier);
2430 Consume(Token::NEW);
2431 int new_pos = position();
2432 ExpressionT result = this->EmptyExpression();
2433 if (peek() == Token::SUPER) {
2434 const bool is_new = true;
2435 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
2436 } else if (peek() == Token::PERIOD) {
2437 return ParseNewTargetExpression(CHECK_OK);
2438 } else {
2439 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
2440 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002441 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002442 if (peek() == Token::LPAREN) {
2443 // NewExpression with arguments.
2444 Scanner::Location spread_pos;
2445 typename Traits::Type::ExpressionList args =
2446 this->ParseArguments(&spread_pos, classifier, CHECK_OK);
2447
2448 if (spread_pos.IsValid()) {
2449 args = Traits::PrepareSpreadArguments(args);
2450 result = Traits::SpreadCallNew(result, args, new_pos);
2451 } else {
2452 result = factory()->NewCallNew(result, args, new_pos);
2453 }
2454 // The expression can still continue with . or [ after the arguments.
2455 result =
2456 this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
2457 return result;
2458 }
2459 // NewExpression without arguments.
2460 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2461 new_pos);
2462 }
2463 // No 'new' or 'super' keyword.
2464 return this->ParseMemberExpression(classifier, ok);
2465}
2466
2467
2468template <class Traits>
2469typename ParserBase<Traits>::ExpressionT
2470ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
2471 bool* ok) {
2472 // MemberExpression ::
2473 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
2474 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
2475
2476 // The '[' Expression ']' and '.' Identifier parts are parsed by
2477 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2478 // caller.
2479
2480 // Parse the initial primary or function expression.
2481 ExpressionT result = this->EmptyExpression();
2482 if (peek() == Token::FUNCTION) {
2483 BindingPatternUnexpectedToken(classifier);
2484 ArrowFormalParametersUnexpectedToken(classifier);
2485
2486 Consume(Token::FUNCTION);
2487 int function_token_position = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002488
2489 if (allow_harmony_function_sent() && peek() == Token::PERIOD) {
2490 // function.sent
2491 int pos = position();
2492 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK);
2493
2494 if (!is_generator()) {
2495 // TODO(neis): allow escaping into closures?
2496 ReportMessageAt(scanner()->location(),
2497 MessageTemplate::kUnexpectedFunctionSent);
2498 *ok = false;
2499 return this->EmptyExpression();
2500 }
2501
2502 return this->FunctionSentExpression(scope_, factory(), pos);
2503 }
2504
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002505 bool is_generator = Check(Token::MUL);
2506 IdentifierT name = this->EmptyIdentifier();
2507 bool is_strict_reserved_name = false;
2508 Scanner::Location function_name_location = Scanner::Location::invalid();
2509 FunctionLiteral::FunctionType function_type =
2510 FunctionLiteral::kAnonymousExpression;
2511 if (peek_any_identifier()) {
2512 name = ParseIdentifierOrStrictReservedWord(
2513 is_generator, &is_strict_reserved_name, CHECK_OK);
2514 function_name_location = scanner()->location();
2515 function_type = FunctionLiteral::kNamedExpression;
2516 }
2517 result = this->ParseFunctionLiteral(
2518 name, function_name_location,
2519 is_strict_reserved_name ? kFunctionNameIsStrictReserved
2520 : kFunctionNameValidityUnknown,
2521 is_generator ? FunctionKind::kGeneratorFunction
2522 : FunctionKind::kNormalFunction,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002523 function_token_position, function_type, language_mode(), CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002524 } else if (peek() == Token::SUPER) {
2525 const bool is_new = false;
2526 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
2527 } else {
2528 result = ParsePrimaryExpression(classifier, CHECK_OK);
2529 }
2530
2531 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
2532 return result;
2533}
2534
2535
2536template <class Traits>
2537typename ParserBase<Traits>::ExpressionT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002538ParserBase<Traits>::ParseSuperExpression(bool is_new,
2539 ExpressionClassifier* classifier,
2540 bool* ok) {
2541 Expect(Token::SUPER, CHECK_OK);
2542 int pos = position();
2543
2544 Scope* scope = scope_->ReceiverScope();
2545 FunctionKind kind = scope->function_kind();
2546 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
2547 IsClassConstructor(kind)) {
2548 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
2549 scope->RecordSuperPropertyUsage();
2550 return this->SuperPropertyReference(scope_, factory(), pos);
2551 }
2552 // new super() is never allowed.
2553 // super() is only allowed in derived constructor
2554 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002555 // TODO(rossberg): This might not be the correct FunctionState for the
2556 // method here.
2557 function_state_->set_super_location(scanner()->location());
2558 return this->SuperCallReference(scope_, factory(), pos);
2559 }
2560 }
2561
2562 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
2563 *ok = false;
2564 return this->EmptyExpression();
2565}
2566
Ben Murdoch097c5b22016-05-18 11:27:45 +01002567template <class Traits>
2568void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
2569 const char* full_name, int pos,
2570 bool* ok) {
2571 Consume(Token::PERIOD);
2572 ExpectContextualKeyword(property_name, ok);
2573 if (!*ok) return;
2574 if (scanner()->literal_contains_escapes()) {
2575 Traits::ReportMessageAt(
2576 Scanner::Location(pos, scanner()->location().end_pos),
2577 MessageTemplate::kInvalidEscapedMetaProperty, full_name);
2578 *ok = false;
2579 }
2580}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002581
2582template <class Traits>
2583typename ParserBase<Traits>::ExpressionT
2584ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
2585 int pos = position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002586 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002587
2588 if (!scope_->ReceiverScope()->is_function_scope()) {
2589 ReportMessageAt(scanner()->location(),
2590 MessageTemplate::kUnexpectedNewTarget);
2591 *ok = false;
2592 return this->EmptyExpression();
2593 }
2594
2595 return this->NewTargetExpression(scope_, factory(), pos);
2596}
2597
2598
2599template <class Traits>
2600typename ParserBase<Traits>::ExpressionT
2601ParserBase<Traits>::ParseMemberExpressionContinuation(
2602 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
2603 // Parses this part of MemberExpression:
2604 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
2605 while (true) {
2606 switch (peek()) {
2607 case Token::LBRACK: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002608 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002609 BindingPatternUnexpectedToken(classifier);
2610 ArrowFormalParametersUnexpectedToken(classifier);
2611
2612 Consume(Token::LBRACK);
2613 int pos = position();
2614 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002615 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002616 expression = factory()->NewProperty(expression, index, pos);
2617 if (fni_ != NULL) {
2618 this->PushPropertyName(fni_, index);
2619 }
2620 Expect(Token::RBRACK, CHECK_OK);
2621 break;
2622 }
2623 case Token::PERIOD: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002624 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002625 BindingPatternUnexpectedToken(classifier);
2626 ArrowFormalParametersUnexpectedToken(classifier);
2627
2628 Consume(Token::PERIOD);
2629 int pos = position();
2630 IdentifierT name = ParseIdentifierName(CHECK_OK);
2631 expression = factory()->NewProperty(
2632 expression, factory()->NewStringLiteral(name, pos), pos);
2633 if (fni_ != NULL) {
2634 this->PushLiteralName(fni_, name);
2635 }
2636 break;
2637 }
2638 case Token::TEMPLATE_SPAN:
2639 case Token::TEMPLATE_TAIL: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002640 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002641 BindingPatternUnexpectedToken(classifier);
2642 ArrowFormalParametersUnexpectedToken(classifier);
2643 int pos;
2644 if (scanner()->current_token() == Token::IDENTIFIER) {
2645 pos = position();
2646 } else {
2647 pos = peek_position();
2648 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2649 // If the tag function looks like an IIFE, set_parenthesized() to
2650 // force eager compilation.
2651 expression->AsFunctionLiteral()->set_should_eager_compile();
2652 }
2653 }
2654 expression =
2655 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
2656 break;
2657 }
Ben Murdochda12d292016-06-02 14:46:10 +01002658 case Token::ILLEGAL: {
2659 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
2660 *ok = false;
2661 return this->EmptyExpression();
2662 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002663 default:
2664 return expression;
2665 }
2666 }
2667 DCHECK(false);
2668 return this->EmptyExpression();
2669}
2670
2671
2672template <class Traits>
2673void ParserBase<Traits>::ParseFormalParameter(
2674 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
2675 // FormalParameter[Yield,GeneratorParameter] :
2676 // BindingElement[?Yield, ?GeneratorParameter]
2677 bool is_rest = parameters->has_rest;
2678
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002679 ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
2680 if (!*ok) return;
2681
2682 ValidateBindingPattern(classifier, ok);
2683 if (!*ok) return;
2684
2685 if (!Traits::IsIdentifier(pattern)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002686 parameters->is_simple = false;
2687 ValidateFormalParameterInitializer(classifier, ok);
2688 if (!*ok) return;
2689 classifier->RecordNonSimpleParameter();
2690 }
2691
2692 ExpressionT initializer = Traits::EmptyExpression();
Ben Murdochda12d292016-06-02 14:46:10 +01002693 if (!is_rest && Check(Token::ASSIGN)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002694 ExpressionClassifier init_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002695 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
2696 if (!*ok) return;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002697 Traits::RewriteNonPattern(&init_classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002698 ValidateFormalParameterInitializer(&init_classifier, ok);
2699 if (!*ok) return;
2700 parameters->is_simple = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002701 init_classifier.Discard();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002702 classifier->RecordNonSimpleParameter();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002703
2704 if (allow_harmony_function_name()) {
2705 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
2706 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002707 }
2708
2709 Traits::AddFormalParameter(parameters, pattern, initializer,
2710 scanner()->location().end_pos, is_rest);
2711}
2712
2713
2714template <class Traits>
2715void ParserBase<Traits>::ParseFormalParameterList(
2716 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
2717 // FormalParameters[Yield,GeneratorParameter] :
2718 // [empty]
2719 // FormalParameterList[?Yield, ?GeneratorParameter]
2720 //
2721 // FormalParameterList[Yield,GeneratorParameter] :
2722 // FunctionRestParameter[?Yield]
2723 // FormalsList[?Yield, ?GeneratorParameter]
2724 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
2725 //
2726 // FormalsList[Yield,GeneratorParameter] :
2727 // FormalParameter[?Yield, ?GeneratorParameter]
2728 // FormalsList[?Yield, ?GeneratorParameter] ,
2729 // FormalParameter[?Yield,?GeneratorParameter]
2730
2731 DCHECK_EQ(0, parameters->Arity());
2732
2733 if (peek() != Token::RPAREN) {
2734 do {
2735 if (parameters->Arity() > Code::kMaxArguments) {
2736 ReportMessage(MessageTemplate::kTooManyParameters);
2737 *ok = false;
2738 return;
2739 }
2740 parameters->has_rest = Check(Token::ELLIPSIS);
2741 ParseFormalParameter(parameters, classifier, ok);
2742 if (!*ok) return;
2743 } while (!parameters->has_rest && Check(Token::COMMA));
2744
2745 if (parameters->has_rest) {
2746 parameters->is_simple = false;
2747 classifier->RecordNonSimpleParameter();
2748 if (peek() == Token::COMMA) {
2749 ReportMessageAt(scanner()->peek_location(),
2750 MessageTemplate::kParamAfterRest);
2751 *ok = false;
2752 return;
2753 }
2754 }
2755 }
2756
2757 for (int i = 0; i < parameters->Arity(); ++i) {
2758 auto parameter = parameters->at(i);
2759 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
2760 }
2761}
2762
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002763template <class Traits>
Ben Murdoch097c5b22016-05-18 11:27:45 +01002764void ParserBase<Traits>::CheckArityRestrictions(int param_count,
2765 FunctionKind function_kind,
2766 bool has_rest,
2767 int formals_start_pos,
2768 int formals_end_pos, bool* ok) {
2769 if (IsGetterFunction(function_kind)) {
2770 if (param_count != 0) {
2771 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
2772 MessageTemplate::kBadGetterArity);
2773 *ok = false;
2774 }
2775 } else if (IsSetterFunction(function_kind)) {
2776 if (param_count != 1) {
2777 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
2778 MessageTemplate::kBadSetterArity);
2779 *ok = false;
2780 }
2781 if (has_rest) {
2782 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
2783 MessageTemplate::kBadSetterRestParameter);
2784 *ok = false;
2785 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002786 }
2787}
2788
2789
2790template <class Traits>
2791bool ParserBase<Traits>::IsNextLetKeyword() {
2792 DCHECK(peek() == Token::LET);
2793 if (!allow_let()) {
2794 return false;
2795 }
2796 Token::Value next_next = PeekAhead();
2797 switch (next_next) {
2798 case Token::LBRACE:
2799 case Token::LBRACK:
2800 case Token::IDENTIFIER:
2801 case Token::STATIC:
2802 case Token::LET: // Yes, you can do let let = ... in sloppy mode
2803 case Token::YIELD:
2804 return true;
2805 default:
2806 return false;
2807 }
2808}
2809
2810
2811template <class Traits>
2812typename ParserBase<Traits>::ExpressionT
2813ParserBase<Traits>::ParseArrowFunctionLiteral(
2814 bool accept_IN, const FormalParametersT& formal_parameters,
2815 const ExpressionClassifier& formals_classifier, bool* ok) {
2816 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
2817 // ASI inserts `;` after arrow parameters if a line terminator is found.
2818 // `=> ...` is never a valid expression, so report as syntax error.
2819 // If next token is not `=>`, it's a syntax error anyways.
2820 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
2821 *ok = false;
2822 return this->EmptyExpression();
2823 }
2824
2825 typename Traits::Type::StatementList body;
2826 int num_parameters = formal_parameters.scope->num_parameters();
2827 int materialized_literal_count = -1;
2828 int expected_property_count = -1;
2829 Scanner::Location super_loc;
2830
2831 {
2832 typename Traits::Type::Factory function_factory(ast_value_factory());
2833 FunctionState function_state(&function_state_, &scope_,
2834 formal_parameters.scope, kArrowFunction,
2835 &function_factory);
2836
2837 function_state.SkipMaterializedLiterals(
2838 formal_parameters.materialized_literals_count);
2839
2840 this->ReindexLiterals(formal_parameters);
2841
2842 Expect(Token::ARROW, CHECK_OK);
2843
2844 if (peek() == Token::LBRACE) {
2845 // Multiple statement body
2846 Consume(Token::LBRACE);
2847 bool is_lazily_parsed =
2848 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing());
2849 if (is_lazily_parsed) {
2850 body = this->NewStatementList(0, zone());
2851 this->SkipLazyFunctionBody(&materialized_literal_count,
2852 &expected_property_count, CHECK_OK);
2853 if (formal_parameters.materialized_literals_count > 0) {
2854 materialized_literal_count +=
2855 formal_parameters.materialized_literals_count;
2856 }
2857 } else {
2858 body = this->ParseEagerFunctionBody(
2859 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
2860 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK);
2861 materialized_literal_count =
2862 function_state.materialized_literal_count();
2863 expected_property_count = function_state.expected_property_count();
2864 }
2865 } else {
2866 // Single-expression body
2867 int pos = position();
2868 parenthesized_function_ = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002869 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002870 ExpressionT expression =
2871 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002872 Traits::RewriteNonPattern(&classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002873 body = this->NewStatementList(1, zone());
2874 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
2875 body->Add(factory()->NewReturnStatement(expression, pos), zone());
2876 materialized_literal_count = function_state.materialized_literal_count();
2877 expected_property_count = function_state.expected_property_count();
Ben Murdochda12d292016-06-02 14:46:10 +01002878 // ES6 14.6.1 Static Semantics: IsInTailPosition
2879 if (allow_tailcalls() && !is_sloppy(language_mode())) {
2880 this->MarkTailPosition(expression);
2881 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002882 }
2883 super_loc = function_state.super_location();
2884
2885 formal_parameters.scope->set_end_position(scanner()->location().end_pos);
2886
2887 // Arrow function formal parameters are parsed as StrictFormalParameterList,
2888 // which is not the same as "parameters of a strict function"; it only means
2889 // that duplicates are not allowed. Of course, the arrow function may
2890 // itself be strict as well.
2891 const bool allow_duplicate_parameters = false;
2892 this->ValidateFormalParameters(&formals_classifier, language_mode(),
2893 allow_duplicate_parameters, CHECK_OK);
2894
2895 // Validate strict mode.
2896 if (is_strict(language_mode())) {
2897 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
2898 scanner()->location().end_pos, CHECK_OK);
2899 }
2900 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
2901 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
2902 }
2903
2904 Traits::RewriteDestructuringAssignments();
2905 }
2906
2907 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
2908 this->EmptyIdentifierString(), formal_parameters.scope, body,
2909 materialized_literal_count, expected_property_count, num_parameters,
2910 FunctionLiteral::kNoDuplicateParameters,
2911 FunctionLiteral::kAnonymousExpression,
2912 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
2913 formal_parameters.scope->start_position());
2914
2915 function_literal->set_function_token_position(
2916 formal_parameters.scope->start_position());
2917 if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
2918
2919 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
2920
2921 return function_literal;
2922}
2923
2924
2925template <typename Traits>
2926typename ParserBase<Traits>::ExpressionT
2927ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
2928 ExpressionClassifier* classifier,
2929 bool* ok) {
2930 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
2931 // text followed by a substitution expression), finalized by a single
2932 // TEMPLATE_TAIL.
2933 //
2934 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
2935 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
2936 // NoSubstitutionTemplate.
2937 //
2938 // When parsing a TemplateLiteral, we must have scanned either an initial
2939 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
2940 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
2941
2942 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
2943 // In this case we may simply consume the token and build a template with a
2944 // single TEMPLATE_SPAN and no expressions.
2945 if (peek() == Token::TEMPLATE_TAIL) {
2946 Consume(Token::TEMPLATE_TAIL);
2947 int pos = position();
2948 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
2949 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
2950 Traits::AddTemplateSpan(&ts, true);
2951 return Traits::CloseTemplateLiteral(&ts, start, tag);
2952 }
2953
2954 Consume(Token::TEMPLATE_SPAN);
2955 int pos = position();
2956 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
2957 Traits::AddTemplateSpan(&ts, false);
2958 Token::Value next;
2959
2960 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
2961 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
2962 // case, representing a TemplateMiddle).
2963
2964 do {
2965 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
2966 next = peek();
2967 if (next == Token::EOS) {
2968 ReportMessageAt(Scanner::Location(start, peek_position()),
2969 MessageTemplate::kUnterminatedTemplate);
2970 *ok = false;
2971 return Traits::EmptyExpression();
2972 } else if (next == Token::ILLEGAL) {
2973 Traits::ReportMessageAt(
2974 Scanner::Location(position() + 1, peek_position()),
2975 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
2976 *ok = false;
2977 return Traits::EmptyExpression();
2978 }
2979
2980 int expr_pos = peek_position();
2981 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002982 Traits::RewriteNonPattern(classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002983 Traits::AddTemplateExpression(&ts, expression);
2984
2985 if (peek() != Token::RBRACE) {
2986 ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
2987 MessageTemplate::kUnterminatedTemplateExpr);
2988 *ok = false;
2989 return Traits::EmptyExpression();
2990 }
2991
2992 // If we didn't die parsing that expression, our next token should be a
2993 // TEMPLATE_SPAN or TEMPLATE_TAIL.
2994 next = scanner()->ScanTemplateContinuation();
2995 Next();
2996 pos = position();
2997
2998 if (next == Token::EOS) {
2999 ReportMessageAt(Scanner::Location(start, pos),
3000 MessageTemplate::kUnterminatedTemplate);
3001 *ok = false;
3002 return Traits::EmptyExpression();
3003 } else if (next == Token::ILLEGAL) {
3004 Traits::ReportMessageAt(
3005 Scanner::Location(position() + 1, peek_position()),
3006 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3007 *ok = false;
3008 return Traits::EmptyExpression();
3009 }
3010
3011 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
3012 } while (next == Token::TEMPLATE_SPAN);
3013
3014 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
3015 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3016 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3017 return Traits::CloseTemplateLiteral(&ts, start, tag);
3018}
3019
3020
3021template <typename Traits>
3022typename ParserBase<Traits>::ExpressionT
3023ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3024 ExpressionT expression, int beg_pos, int end_pos,
3025 MessageTemplate::Template message, bool* ok) {
3026 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
3027 message, kReferenceError, ok);
3028}
3029
3030
3031template <typename Traits>
3032typename ParserBase<Traits>::ExpressionT
3033ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3034 ExpressionT expression, int beg_pos, int end_pos,
3035 MessageTemplate::Template message, ParseErrorType type, bool* ok) {
Ben Murdochda12d292016-06-02 14:46:10 +01003036 if (this->IsIdentifier(expression) && is_strict(language_mode()) &&
3037 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3038 ReportMessageAt(Scanner::Location(beg_pos, end_pos),
3039 MessageTemplate::kStrictEvalArguments, kSyntaxError);
3040 *ok = false;
3041 return this->EmptyExpression();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003042 }
3043 if (expression->IsValidReferenceExpression()) {
3044 return expression;
Ben Murdochda12d292016-06-02 14:46:10 +01003045 }
3046 if (expression->IsCall()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003047 // If it is a call, make it a runtime error for legacy web compatibility.
3048 // Rewrite `expr' to `expr[throw ReferenceError]'.
Ben Murdochda12d292016-06-02 14:46:10 +01003049 ExpressionT error = this->NewThrowReferenceError(message, beg_pos);
3050 return factory()->NewProperty(expression, error, beg_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003051 }
Ben Murdochda12d292016-06-02 14:46:10 +01003052 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
3053 *ok = false;
3054 return this->EmptyExpression();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003055}
3056
3057
3058template <typename Traits>
3059bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) {
3060 return this->IsAssignableIdentifier(expression) || expression->IsProperty();
3061}
3062
3063
3064template <typename Traits>
3065void ParserBase<Traits>::CheckDestructuringElement(
3066 ExpressionT expression, ExpressionClassifier* classifier, int begin,
3067 int end) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003068 if (!IsValidPattern(expression) && !expression->IsAssignment() &&
3069 !IsValidReferenceExpression(expression)) {
3070 classifier->RecordAssignmentPatternError(
3071 Scanner::Location(begin, end),
3072 MessageTemplate::kInvalidDestructuringTarget);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003073 }
3074}
3075
3076
3077#undef CHECK_OK
3078#undef CHECK_OK_CUSTOM
3079
3080
3081template <typename Traits>
3082void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
3083 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3084 bool* ok) {
3085 DCHECK(!is_static);
3086 DCHECK(!is_generator || type == kMethodProperty);
3087
3088 if (property == Token::SMI || property == Token::NUMBER) return;
3089
3090 if (type == kValueProperty && IsProto()) {
3091 if (has_seen_proto_) {
3092 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
3093 *ok = false;
3094 return;
3095 }
3096 has_seen_proto_ = true;
3097 return;
3098 }
3099}
3100
3101
3102template <typename Traits>
3103void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
3104 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3105 bool* ok) {
3106 DCHECK(type == kMethodProperty || type == kAccessorProperty);
3107
3108 if (property == Token::SMI || property == Token::NUMBER) return;
3109
3110 if (is_static) {
3111 if (IsPrototype()) {
3112 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
3113 *ok = false;
3114 return;
3115 }
3116 } else if (IsConstructor()) {
3117 if (is_generator || type == kAccessorProperty) {
3118 MessageTemplate::Template msg =
3119 is_generator ? MessageTemplate::kConstructorIsGenerator
3120 : MessageTemplate::kConstructorIsAccessor;
3121 this->parser()->ReportMessage(msg);
3122 *ok = false;
3123 return;
3124 }
3125 if (has_seen_constructor_) {
3126 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
3127 *ok = false;
3128 return;
3129 }
3130 has_seen_constructor_ = true;
3131 return;
3132 }
3133}
Ben Murdoch097c5b22016-05-18 11:27:45 +01003134
3135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003136} // namespace internal
3137} // namespace v8
3138
3139#endif // V8_PARSING_PARSER_BASE_H