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