Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(705)

Side by Side Diff: src/preparser.h

Issue 1481613002: Create ast/ and parsing/ subdirectories and move appropriate files (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/preparse-data-format.h ('k') | src/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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_PREPARSER_H
6 #define V8_PREPARSER_H
7
8 #include "src/bailout-reason.h"
9 #include "src/expression-classifier.h"
10 #include "src/func-name-inferrer.h"
11 #include "src/hashmap.h"
12 #include "src/messages.h"
13 #include "src/scanner.h"
14 #include "src/scopes.h"
15 #include "src/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 {
29 explicit FormalParametersBase(Scope* scope) : scope(scope) {}
30 Scope* scope;
31 bool has_rest = false;
32 bool is_simple = true;
33 int materialized_literals_count = 0;
34 mutable int rest_array_literal_index = -1;
35 };
36
37
38 // Common base class shared between parser and pre-parser. Traits encapsulate
39 // the differences between Parser and PreParser:
40
41 // - Return types: For example, Parser functions return Expression* and
42 // PreParser functions return PreParserExpression.
43
44 // - Creating parse tree nodes: Parser generates an AST during the recursive
45 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
46 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
47 // just enough data for the upper layer functions. PreParserFactory is
48 // responsible for creating these dummy objects. It provides a similar kind of
49 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
50 // used.
51
52 // - Miscellaneous other tasks interleaved with the recursive descent. For
53 // example, Parser keeps track of which function literals should be marked as
54 // pretenured, and PreParser doesn't care.
55
56 // The traits are expected to contain the following typedefs:
57 // struct Traits {
58 // // In particular...
59 // struct Type {
60 // // Used by FunctionState and BlockState.
61 // typedef Scope;
62 // typedef GeneratorVariable;
63 // // Return types for traversing functions.
64 // typedef Identifier;
65 // typedef Expression;
66 // typedef FunctionLiteral;
67 // typedef ClassLiteral;
68 // typedef ObjectLiteralProperty;
69 // typedef Literal;
70 // typedef ExpressionList;
71 // typedef PropertyList;
72 // typedef FormalParameter;
73 // typedef FormalParameters;
74 // // For constructing objects returned by the traversing functions.
75 // typedef Factory;
76 // };
77 // // ...
78 // };
79
80 template <typename Traits>
81 class ParserBase : public Traits {
82 public:
83 // Shorten type names defined by Traits.
84 typedef typename Traits::Type::Expression ExpressionT;
85 typedef typename Traits::Type::Identifier IdentifierT;
86 typedef typename Traits::Type::FormalParameter FormalParameterT;
87 typedef typename Traits::Type::FormalParameters FormalParametersT;
88 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
89 typedef typename Traits::Type::Literal LiteralT;
90 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
91 typedef typename Traits::Type::StatementList StatementListT;
92
93 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
94 v8::Extension* extension, AstValueFactory* ast_value_factory,
95 ParserRecorder* log, typename Traits::Type::Parser this_object)
96 : Traits(this_object),
97 parenthesized_function_(false),
98 scope_(NULL),
99 function_state_(NULL),
100 extension_(extension),
101 fni_(NULL),
102 ast_value_factory_(ast_value_factory),
103 log_(log),
104 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
105 stack_limit_(stack_limit),
106 zone_(zone),
107 scanner_(scanner),
108 stack_overflow_(false),
109 allow_lazy_(false),
110 allow_natives_(false),
111 allow_harmony_sloppy_(false),
112 allow_harmony_sloppy_function_(false),
113 allow_harmony_sloppy_let_(false),
114 allow_harmony_rest_parameters_(false),
115 allow_harmony_default_parameters_(false),
116 allow_harmony_destructuring_bind_(false),
117 allow_strong_mode_(false),
118 allow_legacy_const_(true),
119 allow_harmony_do_expressions_(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_rest_parameters);
131 ALLOW_ACCESSORS(harmony_default_parameters);
132 ALLOW_ACCESSORS(harmony_destructuring_bind);
133 ALLOW_ACCESSORS(strong_mode);
134 ALLOW_ACCESSORS(legacy_const);
135 ALLOW_ACCESSORS(harmony_do_expressions);
136 #undef ALLOW_ACCESSORS
137
138 uintptr_t stack_limit() const { return stack_limit_; }
139
140 protected:
141 enum AllowRestrictedIdentifiers {
142 kAllowRestrictedIdentifiers,
143 kDontAllowRestrictedIdentifiers
144 };
145
146 enum Mode {
147 PARSE_LAZILY,
148 PARSE_EAGERLY
149 };
150
151 enum VariableDeclarationContext {
152 kStatementListItem,
153 kStatement,
154 kForStatement
155 };
156
157 class Checkpoint;
158 class ObjectLiteralCheckerBase;
159
160 // ---------------------------------------------------------------------------
161 // FunctionState and BlockState together implement the parser's scope stack.
162 // The parser's current scope is in scope_. BlockState and FunctionState
163 // constructors push on the scope stack and the destructors pop. They are also
164 // used to hold the parser's per-function and per-block state.
165 class BlockState BASE_EMBEDDED {
166 public:
167 BlockState(Scope** scope_stack, Scope* scope)
168 : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
169 *scope_stack_ = scope;
170 }
171 ~BlockState() { *scope_stack_ = outer_scope_; }
172
173 private:
174 Scope** scope_stack_;
175 Scope* outer_scope_;
176 };
177
178 class FunctionState BASE_EMBEDDED {
179 public:
180 FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
181 Scope* scope, FunctionKind kind,
182 typename Traits::Type::Factory* factory);
183 ~FunctionState();
184
185 int NextMaterializedLiteralIndex() {
186 return next_materialized_literal_index_++;
187 }
188 int materialized_literal_count() {
189 return next_materialized_literal_index_;
190 }
191
192 void SkipMaterializedLiterals(int count) {
193 next_materialized_literal_index_ += count;
194 }
195
196 void AddProperty() { expected_property_count_++; }
197 int expected_property_count() { return expected_property_count_; }
198
199 Scanner::Location this_location() const { return this_location_; }
200 Scanner::Location super_location() const { return super_location_; }
201 Scanner::Location return_location() const { return return_location_; }
202 void set_this_location(Scanner::Location location) {
203 this_location_ = location;
204 }
205 void set_super_location(Scanner::Location location) {
206 super_location_ = location;
207 }
208 void set_return_location(Scanner::Location location) {
209 return_location_ = location;
210 }
211
212 bool is_generator() const { return IsGeneratorFunction(kind_); }
213
214 FunctionKind kind() const { return kind_; }
215 FunctionState* outer() const { return outer_function_state_; }
216
217 void set_generator_object_variable(
218 typename Traits::Type::GeneratorVariable* variable) {
219 DCHECK(variable != NULL);
220 DCHECK(is_generator());
221 generator_object_variable_ = variable;
222 }
223 typename Traits::Type::GeneratorVariable* generator_object_variable()
224 const {
225 return generator_object_variable_;
226 }
227
228 typename Traits::Type::Factory* factory() { return factory_; }
229
230 private:
231 // Used to assign an index to each literal that needs materialization in
232 // the function. Includes regexp literals, and boilerplate for object and
233 // array literals.
234 int next_materialized_literal_index_;
235
236 // Properties count estimation.
237 int expected_property_count_;
238
239 // Location of most recent use of 'this' (invalid if none).
240 Scanner::Location this_location_;
241
242 // Location of most recent 'return' statement (invalid if none).
243 Scanner::Location return_location_;
244
245 // Location of call to the "super" constructor (invalid if none).
246 Scanner::Location super_location_;
247
248 FunctionKind kind_;
249 // For generators, this variable may hold the generator object. It variable
250 // is used by yield expressions and return statements. It is not necessary
251 // for generator functions to have this variable set.
252 Variable* generator_object_variable_;
253
254 FunctionState** function_state_stack_;
255 FunctionState* outer_function_state_;
256 Scope** scope_stack_;
257 Scope* outer_scope_;
258 typename Traits::Type::Factory* factory_;
259
260 friend class ParserTraits;
261 friend class Checkpoint;
262 };
263
264 // Annoyingly, arrow functions first parse as comma expressions, then when we
265 // see the => we have to go back and reinterpret the arguments as being formal
266 // parameters. To do so we need to reset some of the parser state back to
267 // what it was before the arguments were first seen.
268 class Checkpoint BASE_EMBEDDED {
269 public:
270 explicit Checkpoint(ParserBase* parser) {
271 function_state_ = parser->function_state_;
272 next_materialized_literal_index_ =
273 function_state_->next_materialized_literal_index_;
274 expected_property_count_ = function_state_->expected_property_count_;
275 }
276
277 void Restore(int* materialized_literal_index_delta) {
278 *materialized_literal_index_delta =
279 function_state_->next_materialized_literal_index_ -
280 next_materialized_literal_index_;
281 function_state_->next_materialized_literal_index_ =
282 next_materialized_literal_index_;
283 function_state_->expected_property_count_ = expected_property_count_;
284 }
285
286 private:
287 FunctionState* function_state_;
288 int next_materialized_literal_index_;
289 int expected_property_count_;
290 };
291
292 class ParsingModeScope BASE_EMBEDDED {
293 public:
294 ParsingModeScope(ParserBase* parser, Mode mode)
295 : parser_(parser),
296 old_mode_(parser->mode()) {
297 parser_->mode_ = mode;
298 }
299 ~ParsingModeScope() {
300 parser_->mode_ = old_mode_;
301 }
302
303 private:
304 ParserBase* parser_;
305 Mode old_mode_;
306 };
307
308 Scope* NewScope(Scope* parent, ScopeType scope_type) {
309 // Must always pass the function kind for FUNCTION_SCOPE.
310 DCHECK(scope_type != FUNCTION_SCOPE);
311 return NewScope(parent, scope_type, kNormalFunction);
312 }
313
314 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
315 DCHECK(ast_value_factory());
316 DCHECK(scope_type != MODULE_SCOPE || FLAG_harmony_modules);
317 Scope* result = new (zone())
318 Scope(zone(), parent, scope_type, ast_value_factory(), kind);
319 result->Initialize();
320 return result;
321 }
322
323 Scanner* scanner() const { return scanner_; }
324 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
325 int position() { return scanner_->location().beg_pos; }
326 int peek_position() { return scanner_->peek_location().beg_pos; }
327 bool stack_overflow() const { return stack_overflow_; }
328 void set_stack_overflow() { stack_overflow_ = true; }
329 Mode mode() const { return mode_; }
330 Zone* zone() const { return zone_; }
331
332 INLINE(Token::Value peek()) {
333 if (stack_overflow_) return Token::ILLEGAL;
334 return scanner()->peek();
335 }
336
337 INLINE(Token::Value PeekAhead()) {
338 if (stack_overflow_) return Token::ILLEGAL;
339 return scanner()->PeekAhead();
340 }
341
342 INLINE(Token::Value Next()) {
343 if (stack_overflow_) return Token::ILLEGAL;
344 {
345 if (GetCurrentStackPosition() < stack_limit_) {
346 // Any further calls to Next or peek will return the illegal token.
347 // The current call must return the next token, which might already
348 // have been peek'ed.
349 stack_overflow_ = true;
350 }
351 }
352 return scanner()->Next();
353 }
354
355 void Consume(Token::Value token) {
356 Token::Value next = Next();
357 USE(next);
358 USE(token);
359 DCHECK(next == token);
360 }
361
362 bool Check(Token::Value token) {
363 Token::Value next = peek();
364 if (next == token) {
365 Consume(next);
366 return true;
367 }
368 return false;
369 }
370
371 void Expect(Token::Value token, bool* ok) {
372 Token::Value next = Next();
373 if (next != token) {
374 ReportUnexpectedToken(next);
375 *ok = false;
376 }
377 }
378
379 void ExpectSemicolon(bool* ok) {
380 // Check for automatic semicolon insertion according to
381 // the rules given in ECMA-262, section 7.9, page 21.
382 Token::Value tok = peek();
383 if (tok == Token::SEMICOLON) {
384 Next();
385 return;
386 }
387 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
388 tok == Token::RBRACE ||
389 tok == Token::EOS) {
390 return;
391 }
392 Expect(Token::SEMICOLON, ok);
393 }
394
395 bool peek_any_identifier() {
396 Token::Value next = peek();
397 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
398 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
399 next == Token::STATIC || next == Token::YIELD;
400 }
401
402 bool CheckContextualKeyword(Vector<const char> keyword) {
403 if (PeekContextualKeyword(keyword)) {
404 Consume(Token::IDENTIFIER);
405 return true;
406 }
407 return false;
408 }
409
410 bool PeekContextualKeyword(Vector<const char> keyword) {
411 return peek() == Token::IDENTIFIER &&
412 scanner()->is_next_contextual_keyword(keyword);
413 }
414
415 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
416 Expect(Token::IDENTIFIER, ok);
417 if (!*ok) return;
418 if (!scanner()->is_literal_contextual_keyword(keyword)) {
419 ReportUnexpectedToken(scanner()->current_token());
420 *ok = false;
421 }
422 }
423
424 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
425 if (Check(Token::IN)) {
426 if (is_strong(language_mode())) {
427 ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn);
428 *ok = false;
429 } else {
430 *visit_mode = ForEachStatement::ENUMERATE;
431 }
432 return true;
433 } else if (CheckContextualKeyword(CStrVector("of"))) {
434 *visit_mode = ForEachStatement::ITERATE;
435 return true;
436 }
437 return false;
438 }
439
440 // Checks whether an octal literal was last seen between beg_pos and end_pos.
441 // If so, reports an error. Only called for strict mode and template strings.
442 void CheckOctalLiteral(int beg_pos, int end_pos,
443 MessageTemplate::Template message, bool* ok) {
444 Scanner::Location octal = scanner()->octal_position();
445 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
446 octal.end_pos <= end_pos) {
447 ReportMessageAt(octal, message);
448 scanner()->clear_octal_position();
449 *ok = false;
450 }
451 }
452
453 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
454 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
455 ok);
456 }
457
458 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
459 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
460 ok);
461 }
462
463 // Checking the name of a function literal. This has to be done after parsing
464 // the function, since the function can declare itself strict.
465 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
466 FunctionNameValidity function_name_validity,
467 const Scanner::Location& function_name_loc, bool* ok) {
468 if (function_name_validity == kSkipFunctionNameCheck) return;
469 // The function name needs to be checked in strict mode.
470 if (is_sloppy(language_mode)) return;
471
472 if (this->IsEvalOrArguments(function_name)) {
473 Traits::ReportMessageAt(function_name_loc,
474 MessageTemplate::kStrictEvalArguments);
475 *ok = false;
476 return;
477 }
478 if (function_name_validity == kFunctionNameIsStrictReserved) {
479 Traits::ReportMessageAt(function_name_loc,
480 MessageTemplate::kUnexpectedStrictReserved);
481 *ok = false;
482 return;
483 }
484 if (is_strong(language_mode) && this->IsUndefined(function_name)) {
485 Traits::ReportMessageAt(function_name_loc,
486 MessageTemplate::kStrongUndefined);
487 *ok = false;
488 return;
489 }
490 }
491
492 // Determine precedence of given token.
493 static int Precedence(Token::Value token, bool accept_IN) {
494 if (token == Token::IN && !accept_IN)
495 return 0; // 0 precedence will terminate binary expression parsing
496 return Token::Precedence(token);
497 }
498
499 typename Traits::Type::Factory* factory() {
500 return function_state_->factory();
501 }
502
503 LanguageMode language_mode() { return scope_->language_mode(); }
504 bool is_generator() const { return function_state_->is_generator(); }
505
506 bool allow_const() {
507 return is_strict(language_mode()) || allow_harmony_sloppy() ||
508 allow_legacy_const();
509 }
510
511 bool allow_let() {
512 return is_strict(language_mode()) || allow_harmony_sloppy_let();
513 }
514
515 // Report syntax errors.
516 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
517 ParseErrorType error_type = kSyntaxError) {
518 Scanner::Location source_location = scanner()->location();
519 Traits::ReportMessageAt(source_location, message, arg, error_type);
520 }
521
522 void ReportMessageAt(Scanner::Location location,
523 MessageTemplate::Template message,
524 ParseErrorType error_type = kSyntaxError) {
525 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
526 error_type);
527 }
528
529 void GetUnexpectedTokenMessage(
530 Token::Value token, MessageTemplate::Template* message, const char** arg,
531 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
532
533 void ReportUnexpectedToken(Token::Value token);
534 void ReportUnexpectedTokenAt(
535 Scanner::Location location, Token::Value token,
536 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
537
538
539 void ReportClassifierError(const ExpressionClassifier::Error& error) {
540 Traits::ReportMessageAt(error.location, error.message, error.arg,
541 kSyntaxError);
542 }
543
544 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
545 if (!classifier->is_valid_expression()) {
546 ReportClassifierError(classifier->expression_error());
547 *ok = false;
548 }
549 }
550
551 void ValidateFormalParameterInitializer(
552 const ExpressionClassifier* classifier, bool* ok) {
553 if (!classifier->is_valid_formal_parameter_initializer()) {
554 ReportClassifierError(classifier->formal_parameter_initializer_error());
555 *ok = false;
556 }
557 }
558
559 void ValidateBindingPattern(const ExpressionClassifier* classifier,
560 bool* ok) {
561 if (!classifier->is_valid_binding_pattern()) {
562 ReportClassifierError(classifier->binding_pattern_error());
563 *ok = false;
564 }
565 }
566
567 void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
568 bool* ok) {
569 if (!classifier->is_valid_assignment_pattern()) {
570 ReportClassifierError(classifier->assignment_pattern_error());
571 *ok = false;
572 }
573 }
574
575 void ValidateFormalParameters(const ExpressionClassifier* classifier,
576 LanguageMode language_mode,
577 bool allow_duplicates, bool* ok) {
578 if (!allow_duplicates &&
579 !classifier->is_valid_formal_parameter_list_without_duplicates()) {
580 ReportClassifierError(classifier->duplicate_formal_parameter_error());
581 *ok = false;
582 } else if (is_strict(language_mode) &&
583 !classifier->is_valid_strict_mode_formal_parameters()) {
584 ReportClassifierError(classifier->strict_mode_formal_parameter_error());
585 *ok = false;
586 } else if (is_strong(language_mode) &&
587 !classifier->is_valid_strong_mode_formal_parameters()) {
588 ReportClassifierError(classifier->strong_mode_formal_parameter_error());
589 *ok = false;
590 }
591 }
592
593 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
594 ExpressionT expr,
595 bool parenthesized_formals, bool* ok) {
596 if (classifier->is_valid_binding_pattern()) {
597 // A simple arrow formal parameter: IDENTIFIER => BODY.
598 if (!this->IsIdentifier(expr)) {
599 Traits::ReportMessageAt(scanner()->location(),
600 MessageTemplate::kUnexpectedToken,
601 Token::String(scanner()->current_token()));
602 *ok = false;
603 }
604 } else if (!classifier->is_valid_arrow_formal_parameters()) {
605 // If after parsing the expr, we see an error but the expression is
606 // neither a valid binding pattern nor a valid parenthesized formal
607 // parameter list, show the "arrow formal parameters" error if the formals
608 // started with a parenthesis, and the binding pattern error otherwise.
609 const ExpressionClassifier::Error& error =
610 parenthesized_formals ? classifier->arrow_formal_parameters_error()
611 : classifier->binding_pattern_error();
612 ReportClassifierError(error);
613 *ok = false;
614 }
615 }
616
617 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) {
618 if (!classifier->is_valid_let_pattern()) {
619 ReportClassifierError(classifier->let_pattern_error());
620 *ok = false;
621 }
622 }
623
624 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
625 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
626 const char* arg;
627 GetUnexpectedTokenMessage(peek(), &message, &arg);
628 classifier->RecordExpressionError(scanner()->peek_location(), message, arg);
629 }
630
631 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
632 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
633 const char* arg;
634 GetUnexpectedTokenMessage(peek(), &message, &arg);
635 classifier->RecordBindingPatternError(scanner()->peek_location(), message,
636 arg);
637 }
638
639 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
640 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
641 const char* arg;
642 GetUnexpectedTokenMessage(peek(), &message, &arg);
643 classifier->RecordArrowFormalParametersError(scanner()->peek_location(),
644 message, arg);
645 }
646
647 void FormalParameterInitializerUnexpectedToken(
648 ExpressionClassifier* classifier) {
649 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
650 const char* arg;
651 GetUnexpectedTokenMessage(peek(), &message, &arg);
652 classifier->RecordFormalParameterInitializerError(
653 scanner()->peek_location(), message, arg);
654 }
655
656 // Recursive descent functions:
657
658 // Parses an identifier that is valid for the current scope, in particular it
659 // fails on strict mode future reserved keywords in a strict scope. If
660 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
661 // "arguments" as identifier even in strict mode (this is needed in cases like
662 // "var foo = eval;").
663 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
664 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
665 bool* ok);
666 // Parses an identifier or a strict mode future reserved word, and indicate
667 // whether it is strict mode future reserved. Allows passing in is_generator
668 // for the case of parsing the identifier in a function expression, where the
669 // relevant "is_generator" bit is of the function being parsed, not the
670 // containing
671 // function.
672 IdentifierT ParseIdentifierOrStrictReservedWord(bool is_generator,
673 bool* is_strict_reserved,
674 bool* ok);
675 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
676 bool* ok) {
677 return ParseIdentifierOrStrictReservedWord(this->is_generator(),
678 is_strict_reserved, ok);
679 }
680
681 IdentifierT ParseIdentifierName(bool* ok);
682 // Parses an identifier and determines whether or not it is 'get' or 'set'.
683 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
684 bool* ok);
685
686
687 ExpressionT ParseRegExpLiteral(bool seen_equal,
688 ExpressionClassifier* classifier, bool* ok);
689
690 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
691 bool* ok);
692 ExpressionT ParseExpression(bool accept_IN, bool* ok);
693 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
694 bool* ok);
695 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
696 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
697 bool* is_static, bool* is_computed_name,
698 bool* is_identifier, bool* is_escaped_keyword,
699 ExpressionClassifier* classifier, bool* ok);
700 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
701 ObjectLiteralPropertyT ParsePropertyDefinition(
702 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
703 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
704 ExpressionClassifier* classifier, bool* ok);
705 typename Traits::Type::ExpressionList ParseArguments(
706 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
707 bool* ok);
708 ExpressionT ParseAssignmentExpression(bool accept_IN,
709 ExpressionClassifier* classifier,
710 bool* ok);
711 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
712 ExpressionT ParseConditionalExpression(bool accept_IN,
713 ExpressionClassifier* classifier,
714 bool* ok);
715 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
716 ExpressionClassifier* classifier, bool* ok);
717 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
718 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
719 bool* ok);
720 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
721 bool* ok);
722 ExpressionT ParseMemberWithNewPrefixesExpression(
723 ExpressionClassifier* classifier, bool* ok);
724 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
725 ExpressionT ParseMemberExpressionContinuation(
726 ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
727 ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
728 const FormalParametersT& parameters,
729 const ExpressionClassifier& classifier,
730 bool* ok);
731 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
732 ExpressionClassifier* classifier, bool* ok);
733 void AddTemplateExpression(ExpressionT);
734 ExpressionT ParseSuperExpression(bool is_new,
735 ExpressionClassifier* classifier, bool* ok);
736 ExpressionT ParseNewTargetExpression(bool* ok);
737 ExpressionT ParseStrongInitializationExpression(
738 ExpressionClassifier* classifier, bool* ok);
739 ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
740 bool* ok);
741
742 void ParseFormalParameter(FormalParametersT* parameters,
743 ExpressionClassifier* classifier, bool* ok);
744 void ParseFormalParameterList(FormalParametersT* parameters,
745 ExpressionClassifier* classifier, bool* ok);
746 void CheckArityRestrictions(
747 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
748 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
749
750 bool IsNextLetKeyword();
751
752 // Checks if the expression is a valid reference expression (e.g., on the
753 // left-hand side of assignments). Although ruled out by ECMA as early errors,
754 // we allow calls for web compatibility and rewrite them to a runtime throw.
755 ExpressionT CheckAndRewriteReferenceExpression(
756 ExpressionT expression, int beg_pos, int end_pos,
757 MessageTemplate::Template message, bool* ok);
758 ExpressionT CheckAndRewriteReferenceExpression(
759 ExpressionT expression, int beg_pos, int end_pos,
760 MessageTemplate::Template message, ParseErrorType type, bool* ok);
761
762 // Used to validate property names in object literals and class literals
763 enum PropertyKind {
764 kAccessorProperty,
765 kValueProperty,
766 kMethodProperty
767 };
768
769 class ObjectLiteralCheckerBase {
770 public:
771 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
772
773 virtual void CheckProperty(Token::Value property, PropertyKind type,
774 bool is_static, bool is_generator, bool* ok) = 0;
775
776 virtual ~ObjectLiteralCheckerBase() {}
777
778 protected:
779 ParserBase* parser() const { return parser_; }
780 Scanner* scanner() const { return parser_->scanner(); }
781
782 private:
783 ParserBase* parser_;
784 };
785
786 // Validation per ES6 object literals.
787 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
788 public:
789 explicit ObjectLiteralChecker(ParserBase* parser)
790 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
791
792 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
793 bool is_generator, bool* ok) override;
794
795 private:
796 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
797
798 bool has_seen_proto_;
799 };
800
801 // Validation per ES6 class literals.
802 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
803 public:
804 explicit ClassLiteralChecker(ParserBase* parser)
805 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
806
807 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
808 bool is_generator, bool* ok) override;
809
810 private:
811 bool IsConstructor() {
812 return this->scanner()->LiteralMatches("constructor", 11);
813 }
814 bool IsPrototype() {
815 return this->scanner()->LiteralMatches("prototype", 9);
816 }
817
818 bool has_seen_constructor_;
819 };
820
821 // If true, the next (and immediately following) function literal is
822 // preceded by a parenthesis.
823 // Heuristically that means that the function will be called immediately,
824 // so never lazily compile it.
825 bool parenthesized_function_;
826
827 Scope* scope_; // Scope stack.
828 FunctionState* function_state_; // Function state stack.
829 v8::Extension* extension_;
830 FuncNameInferrer* fni_;
831 AstValueFactory* ast_value_factory_; // Not owned.
832 ParserRecorder* log_;
833 Mode mode_;
834 uintptr_t stack_limit_;
835
836 private:
837 Zone* zone_;
838
839 Scanner* scanner_;
840 bool stack_overflow_;
841
842 bool allow_lazy_;
843 bool allow_natives_;
844 bool allow_harmony_sloppy_;
845 bool allow_harmony_sloppy_function_;
846 bool allow_harmony_sloppy_let_;
847 bool allow_harmony_rest_parameters_;
848 bool allow_harmony_default_parameters_;
849 bool allow_harmony_destructuring_bind_;
850 bool allow_strong_mode_;
851 bool allow_legacy_const_;
852 bool allow_harmony_do_expressions_;
853 };
854
855
856 class PreParserIdentifier {
857 public:
858 PreParserIdentifier() : type_(kUnknownIdentifier) {}
859 static PreParserIdentifier Default() {
860 return PreParserIdentifier(kUnknownIdentifier);
861 }
862 static PreParserIdentifier Eval() {
863 return PreParserIdentifier(kEvalIdentifier);
864 }
865 static PreParserIdentifier Arguments() {
866 return PreParserIdentifier(kArgumentsIdentifier);
867 }
868 static PreParserIdentifier Undefined() {
869 return PreParserIdentifier(kUndefinedIdentifier);
870 }
871 static PreParserIdentifier FutureReserved() {
872 return PreParserIdentifier(kFutureReservedIdentifier);
873 }
874 static PreParserIdentifier FutureStrictReserved() {
875 return PreParserIdentifier(kFutureStrictReservedIdentifier);
876 }
877 static PreParserIdentifier Let() {
878 return PreParserIdentifier(kLetIdentifier);
879 }
880 static PreParserIdentifier Static() {
881 return PreParserIdentifier(kStaticIdentifier);
882 }
883 static PreParserIdentifier Yield() {
884 return PreParserIdentifier(kYieldIdentifier);
885 }
886 static PreParserIdentifier Prototype() {
887 return PreParserIdentifier(kPrototypeIdentifier);
888 }
889 static PreParserIdentifier Constructor() {
890 return PreParserIdentifier(kConstructorIdentifier);
891 }
892 bool IsEval() const { return type_ == kEvalIdentifier; }
893 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
894 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
895 bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
896 bool IsLet() const { return type_ == kLetIdentifier; }
897 bool IsStatic() const { return type_ == kStaticIdentifier; }
898 bool IsYield() const { return type_ == kYieldIdentifier; }
899 bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
900 bool IsConstructor() const { return type_ == kConstructorIdentifier; }
901 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
902 bool IsFutureStrictReserved() const {
903 return type_ == kFutureStrictReservedIdentifier ||
904 type_ == kLetIdentifier || type_ == kStaticIdentifier ||
905 type_ == kYieldIdentifier;
906 }
907
908 // Allow identifier->name()[->length()] to work. The preparser
909 // does not need the actual positions/lengths of the identifiers.
910 const PreParserIdentifier* operator->() const { return this; }
911 const PreParserIdentifier raw_name() const { return *this; }
912
913 int position() const { return 0; }
914 int length() const { return 0; }
915
916 private:
917 enum Type {
918 kUnknownIdentifier,
919 kFutureReservedIdentifier,
920 kFutureStrictReservedIdentifier,
921 kLetIdentifier,
922 kStaticIdentifier,
923 kYieldIdentifier,
924 kEvalIdentifier,
925 kArgumentsIdentifier,
926 kUndefinedIdentifier,
927 kPrototypeIdentifier,
928 kConstructorIdentifier
929 };
930
931 explicit PreParserIdentifier(Type type) : type_(type) {}
932 Type type_;
933
934 friend class PreParserExpression;
935 };
936
937
938 class PreParserExpression {
939 public:
940 static PreParserExpression Default() {
941 return PreParserExpression(TypeField::encode(kExpression));
942 }
943
944 static PreParserExpression Spread(PreParserExpression expression) {
945 return PreParserExpression(TypeField::encode(kSpreadExpression));
946 }
947
948 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
949 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
950 IdentifierTypeField::encode(id.type_));
951 }
952
953 static PreParserExpression BinaryOperation(PreParserExpression left,
954 Token::Value op,
955 PreParserExpression right) {
956 return PreParserExpression(
957 TypeField::encode(kBinaryOperationExpression) |
958 HasRestField::encode(op == Token::COMMA &&
959 right->IsSpreadExpression()));
960 }
961
962 static PreParserExpression ObjectLiteral() {
963 return PreParserExpression(TypeField::encode(kObjectLiteralExpression));
964 }
965
966 static PreParserExpression ArrayLiteral() {
967 return PreParserExpression(TypeField::encode(kArrayLiteralExpression));
968 }
969
970 static PreParserExpression StringLiteral() {
971 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
972 }
973
974 static PreParserExpression UseStrictStringLiteral() {
975 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
976 IsUseStrictField::encode(true));
977 }
978
979 static PreParserExpression UseStrongStringLiteral() {
980 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
981 IsUseStrongField::encode(true));
982 }
983
984 static PreParserExpression This() {
985 return PreParserExpression(TypeField::encode(kExpression) |
986 ExpressionTypeField::encode(kThisExpression));
987 }
988
989 static PreParserExpression ThisProperty() {
990 return PreParserExpression(
991 TypeField::encode(kExpression) |
992 ExpressionTypeField::encode(kThisPropertyExpression));
993 }
994
995 static PreParserExpression Property() {
996 return PreParserExpression(
997 TypeField::encode(kExpression) |
998 ExpressionTypeField::encode(kPropertyExpression));
999 }
1000
1001 static PreParserExpression Call() {
1002 return PreParserExpression(TypeField::encode(kExpression) |
1003 ExpressionTypeField::encode(kCallExpression));
1004 }
1005
1006 static PreParserExpression SuperCallReference() {
1007 return PreParserExpression(
1008 TypeField::encode(kExpression) |
1009 ExpressionTypeField::encode(kSuperCallReference));
1010 }
1011
1012 static PreParserExpression NoTemplateTag() {
1013 return PreParserExpression(
1014 TypeField::encode(kExpression) |
1015 ExpressionTypeField::encode(kNoTemplateTagExpression));
1016 }
1017
1018 bool IsIdentifier() const {
1019 return TypeField::decode(code_) == kIdentifierExpression;
1020 }
1021
1022 PreParserIdentifier AsIdentifier() const {
1023 DCHECK(IsIdentifier());
1024 return PreParserIdentifier(IdentifierTypeField::decode(code_));
1025 }
1026
1027 bool IsObjectLiteral() const {
1028 return TypeField::decode(code_) == kObjectLiteralExpression;
1029 }
1030
1031 bool IsArrayLiteral() const {
1032 return TypeField::decode(code_) == kArrayLiteralExpression;
1033 }
1034
1035 bool IsStringLiteral() const {
1036 return TypeField::decode(code_) == kStringLiteralExpression;
1037 }
1038
1039 bool IsUseStrictLiteral() const {
1040 return TypeField::decode(code_) == kStringLiteralExpression &&
1041 IsUseStrictField::decode(code_);
1042 }
1043
1044 bool IsUseStrongLiteral() const {
1045 return TypeField::decode(code_) == kStringLiteralExpression &&
1046 IsUseStrongField::decode(code_);
1047 }
1048
1049 bool IsThis() const {
1050 return TypeField::decode(code_) == kExpression &&
1051 ExpressionTypeField::decode(code_) == kThisExpression;
1052 }
1053
1054 bool IsThisProperty() const {
1055 return TypeField::decode(code_) == kExpression &&
1056 ExpressionTypeField::decode(code_) == kThisPropertyExpression;
1057 }
1058
1059 bool IsProperty() const {
1060 return TypeField::decode(code_) == kExpression &&
1061 (ExpressionTypeField::decode(code_) == kPropertyExpression ||
1062 ExpressionTypeField::decode(code_) == kThisPropertyExpression);
1063 }
1064
1065 bool IsCall() const {
1066 return TypeField::decode(code_) == kExpression &&
1067 ExpressionTypeField::decode(code_) == kCallExpression;
1068 }
1069
1070 bool IsSuperCallReference() const {
1071 return TypeField::decode(code_) == kExpression &&
1072 ExpressionTypeField::decode(code_) == kSuperCallReference;
1073 }
1074
1075 bool IsValidReferenceExpression() const {
1076 return IsIdentifier() || IsProperty();
1077 }
1078
1079 // At the moment PreParser doesn't track these expression types.
1080 bool IsFunctionLiteral() const { return false; }
1081 bool IsCallNew() const { return false; }
1082
1083 bool IsNoTemplateTag() const {
1084 return TypeField::decode(code_) == kExpression &&
1085 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
1086 }
1087
1088 bool IsSpreadExpression() const {
1089 return TypeField::decode(code_) == kSpreadExpression;
1090 }
1091
1092 bool IsArrowFunctionFormalParametersWithRestParameter() const {
1093 // Iff the expression classifier has determined that this expression is a
1094 // valid arrow fformal parameter list, return true if the formal parameter
1095 // list ends with a rest parameter.
1096 return IsSpreadExpression() ||
1097 (IsBinaryOperation() && HasRestField::decode(code_));
1098 }
1099
1100 PreParserExpression AsFunctionLiteral() { return *this; }
1101
1102 bool IsBinaryOperation() const {
1103 return TypeField::decode(code_) == kBinaryOperationExpression;
1104 }
1105
1106 // Dummy implementation for making expression->somefunc() work in both Parser
1107 // and PreParser.
1108 PreParserExpression* operator->() { return this; }
1109
1110 // More dummy implementations of things PreParser doesn't need to track:
1111 void set_index(int index) {} // For YieldExpressions
1112 void set_should_eager_compile() {}
1113
1114 int position() const { return RelocInfo::kNoPosition; }
1115 void set_function_token_position(int position) {}
1116
1117 private:
1118 enum Type {
1119 kExpression,
1120 kIdentifierExpression,
1121 kStringLiteralExpression,
1122 kBinaryOperationExpression,
1123 kSpreadExpression,
1124 kObjectLiteralExpression,
1125 kArrayLiteralExpression
1126 };
1127
1128 enum ExpressionType {
1129 kThisExpression,
1130 kThisPropertyExpression,
1131 kPropertyExpression,
1132 kCallExpression,
1133 kSuperCallReference,
1134 kNoTemplateTagExpression
1135 };
1136
1137 explicit PreParserExpression(uint32_t expression_code)
1138 : code_(expression_code) {}
1139
1140 // The first three bits are for the Type.
1141 typedef BitField<Type, 0, 3> TypeField;
1142
1143 // The rest of the bits are interpreted depending on the value
1144 // of the Type field, so they can share the storage.
1145 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
1146 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
1147 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
1148 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
1149 IdentifierTypeField;
1150 typedef BitField<bool, TypeField::kNext, 1> HasRestField;
1151
1152 uint32_t code_;
1153 };
1154
1155
1156 // The pre-parser doesn't need to build lists of expressions, identifiers, or
1157 // the like.
1158 template <typename T>
1159 class PreParserList {
1160 public:
1161 // These functions make list->Add(some_expression) work (and do nothing).
1162 PreParserList() : length_(0) {}
1163 PreParserList* operator->() { return this; }
1164 void Add(T, void*) { ++length_; }
1165 int length() const { return length_; }
1166 private:
1167 int length_;
1168 };
1169
1170
1171 typedef PreParserList<PreParserExpression> PreParserExpressionList;
1172
1173
1174 class PreParserStatement {
1175 public:
1176 static PreParserStatement Default() {
1177 return PreParserStatement(kUnknownStatement);
1178 }
1179
1180 static PreParserStatement Jump() {
1181 return PreParserStatement(kJumpStatement);
1182 }
1183
1184 static PreParserStatement FunctionDeclaration() {
1185 return PreParserStatement(kFunctionDeclaration);
1186 }
1187
1188 // Creates expression statement from expression.
1189 // Preserves being an unparenthesized string literal, possibly
1190 // "use strict".
1191 static PreParserStatement ExpressionStatement(
1192 PreParserExpression expression) {
1193 if (expression.IsUseStrictLiteral()) {
1194 return PreParserStatement(kUseStrictExpressionStatement);
1195 }
1196 if (expression.IsUseStrongLiteral()) {
1197 return PreParserStatement(kUseStrongExpressionStatement);
1198 }
1199 if (expression.IsStringLiteral()) {
1200 return PreParserStatement(kStringLiteralExpressionStatement);
1201 }
1202 return Default();
1203 }
1204
1205 bool IsStringLiteral() {
1206 return code_ == kStringLiteralExpressionStatement;
1207 }
1208
1209 bool IsUseStrictLiteral() {
1210 return code_ == kUseStrictExpressionStatement;
1211 }
1212
1213 bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
1214
1215 bool IsFunctionDeclaration() {
1216 return code_ == kFunctionDeclaration;
1217 }
1218
1219 bool IsJumpStatement() {
1220 return code_ == kJumpStatement;
1221 }
1222
1223 private:
1224 enum Type {
1225 kUnknownStatement,
1226 kJumpStatement,
1227 kStringLiteralExpressionStatement,
1228 kUseStrictExpressionStatement,
1229 kUseStrongExpressionStatement,
1230 kFunctionDeclaration
1231 };
1232
1233 explicit PreParserStatement(Type code) : code_(code) {}
1234 Type code_;
1235 };
1236
1237
1238 typedef PreParserList<PreParserStatement> PreParserStatementList;
1239
1240
1241 class PreParserFactory {
1242 public:
1243 explicit PreParserFactory(void* unused_value_factory) {}
1244 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
1245 int pos) {
1246 return PreParserExpression::Default();
1247 }
1248 PreParserExpression NewNumberLiteral(double number,
1249 int pos) {
1250 return PreParserExpression::Default();
1251 }
1252 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
1253 int js_flags, int literal_index,
1254 bool is_strong, int pos) {
1255 return PreParserExpression::Default();
1256 }
1257 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1258 int literal_index,
1259 bool is_strong,
1260 int pos) {
1261 return PreParserExpression::ArrayLiteral();
1262 }
1263 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1264 int first_spread_index, int literal_index,
1265 bool is_strong, int pos) {
1266 return PreParserExpression::ArrayLiteral();
1267 }
1268 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1269 PreParserExpression value,
1270 ObjectLiteralProperty::Kind kind,
1271 bool is_static,
1272 bool is_computed_name) {
1273 return PreParserExpression::Default();
1274 }
1275 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1276 PreParserExpression value,
1277 bool is_static,
1278 bool is_computed_name) {
1279 return PreParserExpression::Default();
1280 }
1281 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
1282 int literal_index,
1283 int boilerplate_properties,
1284 bool has_function,
1285 bool is_strong,
1286 int pos) {
1287 return PreParserExpression::ObjectLiteral();
1288 }
1289 PreParserExpression NewVariableProxy(void* variable) {
1290 return PreParserExpression::Default();
1291 }
1292 PreParserExpression NewProperty(PreParserExpression obj,
1293 PreParserExpression key,
1294 int pos) {
1295 if (obj.IsThis()) {
1296 return PreParserExpression::ThisProperty();
1297 }
1298 return PreParserExpression::Property();
1299 }
1300 PreParserExpression NewUnaryOperation(Token::Value op,
1301 PreParserExpression expression,
1302 int pos) {
1303 return PreParserExpression::Default();
1304 }
1305 PreParserExpression NewBinaryOperation(Token::Value op,
1306 PreParserExpression left,
1307 PreParserExpression right, int pos) {
1308 return PreParserExpression::BinaryOperation(left, op, right);
1309 }
1310 PreParserExpression NewCompareOperation(Token::Value op,
1311 PreParserExpression left,
1312 PreParserExpression right, int pos) {
1313 return PreParserExpression::Default();
1314 }
1315 PreParserExpression NewAssignment(Token::Value op,
1316 PreParserExpression left,
1317 PreParserExpression right,
1318 int pos) {
1319 return PreParserExpression::Default();
1320 }
1321 PreParserExpression NewYield(PreParserExpression generator_object,
1322 PreParserExpression expression,
1323 Yield::Kind yield_kind,
1324 int pos) {
1325 return PreParserExpression::Default();
1326 }
1327 PreParserExpression NewConditional(PreParserExpression condition,
1328 PreParserExpression then_expression,
1329 PreParserExpression else_expression,
1330 int pos) {
1331 return PreParserExpression::Default();
1332 }
1333 PreParserExpression NewCountOperation(Token::Value op,
1334 bool is_prefix,
1335 PreParserExpression expression,
1336 int pos) {
1337 return PreParserExpression::Default();
1338 }
1339 PreParserExpression NewCall(PreParserExpression expression,
1340 PreParserExpressionList arguments,
1341 int pos) {
1342 return PreParserExpression::Call();
1343 }
1344 PreParserExpression NewCallNew(PreParserExpression expression,
1345 PreParserExpressionList arguments,
1346 int pos) {
1347 return PreParserExpression::Default();
1348 }
1349 PreParserExpression NewCallRuntime(const AstRawString* name,
1350 const Runtime::Function* function,
1351 PreParserExpressionList arguments,
1352 int pos) {
1353 return PreParserExpression::Default();
1354 }
1355 PreParserStatement NewReturnStatement(PreParserExpression expression,
1356 int pos) {
1357 return PreParserStatement::Default();
1358 }
1359 PreParserExpression NewFunctionLiteral(
1360 PreParserIdentifier name, AstValueFactory* ast_value_factory,
1361 Scope* scope, PreParserStatementList body, int materialized_literal_count,
1362 int expected_property_count, int parameter_count,
1363 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1364 FunctionLiteral::FunctionType function_type,
1365 FunctionLiteral::IsFunctionFlag is_function,
1366 FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
1367 int position) {
1368 return PreParserExpression::Default();
1369 }
1370
1371 PreParserExpression NewSpread(PreParserExpression expression, int pos) {
1372 return PreParserExpression::Spread(expression);
1373 }
1374
1375 PreParserExpression NewEmptyParentheses(int pos) {
1376 return PreParserExpression::Default();
1377 }
1378
1379 // Return the object itself as AstVisitor and implement the needed
1380 // dummy method right in this class.
1381 PreParserFactory* visitor() { return this; }
1382 int* ast_properties() {
1383 static int dummy = 42;
1384 return &dummy;
1385 }
1386 };
1387
1388
1389 struct PreParserFormalParameters : FormalParametersBase {
1390 explicit PreParserFormalParameters(Scope* scope)
1391 : FormalParametersBase(scope) {}
1392 int arity = 0;
1393
1394 int Arity() const { return arity; }
1395 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
1396 };
1397
1398
1399 class PreParser;
1400
1401 class PreParserTraits {
1402 public:
1403 struct Type {
1404 // TODO(marja): To be removed. The Traits object should contain all the data
1405 // it needs.
1406 typedef PreParser* Parser;
1407
1408 // PreParser doesn't need to store generator variables.
1409 typedef void GeneratorVariable;
1410
1411 typedef int AstProperties;
1412
1413 // Return types for traversing functions.
1414 typedef PreParserIdentifier Identifier;
1415 typedef PreParserExpression Expression;
1416 typedef PreParserExpression YieldExpression;
1417 typedef PreParserExpression FunctionLiteral;
1418 typedef PreParserExpression ClassLiteral;
1419 typedef PreParserExpression ObjectLiteralProperty;
1420 typedef PreParserExpression Literal;
1421 typedef PreParserExpressionList ExpressionList;
1422 typedef PreParserExpressionList PropertyList;
1423 typedef PreParserIdentifier FormalParameter;
1424 typedef PreParserFormalParameters FormalParameters;
1425 typedef PreParserStatementList StatementList;
1426
1427 // For constructing objects returned by the traversing functions.
1428 typedef PreParserFactory Factory;
1429 };
1430
1431 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
1432
1433 // Helper functions for recursive descent.
1434 static bool IsEval(PreParserIdentifier identifier) {
1435 return identifier.IsEval();
1436 }
1437
1438 static bool IsArguments(PreParserIdentifier identifier) {
1439 return identifier.IsArguments();
1440 }
1441
1442 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
1443 return identifier.IsEvalOrArguments();
1444 }
1445
1446 static bool IsUndefined(PreParserIdentifier identifier) {
1447 return identifier.IsUndefined();
1448 }
1449
1450 static bool IsPrototype(PreParserIdentifier identifier) {
1451 return identifier.IsPrototype();
1452 }
1453
1454 static bool IsConstructor(PreParserIdentifier identifier) {
1455 return identifier.IsConstructor();
1456 }
1457
1458 // Returns true if the expression is of type "this.foo".
1459 static bool IsThisProperty(PreParserExpression expression) {
1460 return expression.IsThisProperty();
1461 }
1462
1463 static bool IsIdentifier(PreParserExpression expression) {
1464 return expression.IsIdentifier();
1465 }
1466
1467 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
1468 return expression.AsIdentifier();
1469 }
1470
1471 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1472 return identifier.IsFutureStrictReserved();
1473 }
1474
1475 static bool IsBoilerplateProperty(PreParserExpression property) {
1476 // PreParser doesn't count boilerplate properties.
1477 return false;
1478 }
1479
1480 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
1481 return false;
1482 }
1483
1484 static PreParserExpression GetPropertyValue(PreParserExpression property) {
1485 return PreParserExpression::Default();
1486 }
1487
1488 // Functions for encapsulating the differences between parsing and preparsing;
1489 // operations interleaved with the recursive descent.
1490 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1491 // PreParser should not use FuncNameInferrer.
1492 UNREACHABLE();
1493 }
1494
1495 static void PushPropertyName(FuncNameInferrer* fni,
1496 PreParserExpression expression) {
1497 // PreParser should not use FuncNameInferrer.
1498 UNREACHABLE();
1499 }
1500
1501 static void InferFunctionName(FuncNameInferrer* fni,
1502 PreParserExpression expression) {
1503 // PreParser should not use FuncNameInferrer.
1504 UNREACHABLE();
1505 }
1506
1507 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
1508 Scope* scope, PreParserExpression property, bool* has_function) {}
1509
1510 static void CheckAssigningFunctionLiteralToProperty(
1511 PreParserExpression left, PreParserExpression right) {}
1512
1513 static void CheckPossibleEvalCall(PreParserExpression expression,
1514 Scope* scope) {
1515 if (IsIdentifier(expression) && IsEval(AsIdentifier(expression))) {
1516 scope->DeclarationScope()->RecordEvalCall();
1517 scope->RecordEvalCall();
1518 }
1519 }
1520
1521 static PreParserExpression MarkExpressionAsAssigned(
1522 PreParserExpression expression) {
1523 // TODO(marja): To be able to produce the same errors, the preparser needs
1524 // to start tracking which expressions are variables and which are assigned.
1525 return expression;
1526 }
1527
1528 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
1529 PreParserExpression y,
1530 Token::Value op,
1531 int pos,
1532 PreParserFactory* factory) {
1533 return false;
1534 }
1535
1536 PreParserExpression BuildUnaryExpression(PreParserExpression expression,
1537 Token::Value op, int pos,
1538 PreParserFactory* factory) {
1539 return PreParserExpression::Default();
1540 }
1541
1542 PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
1543 int pos) {
1544 return PreParserExpression::Default();
1545 }
1546 PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
1547 Handle<Object> arg, int pos) {
1548 return PreParserExpression::Default();
1549 }
1550 PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
1551 Handle<Object> arg, int pos) {
1552 return PreParserExpression::Default();
1553 }
1554
1555 // Reporting errors.
1556 void ReportMessageAt(Scanner::Location location,
1557 MessageTemplate::Template message,
1558 const char* arg = NULL,
1559 ParseErrorType error_type = kSyntaxError);
1560 void ReportMessageAt(int start_pos, int end_pos,
1561 MessageTemplate::Template message,
1562 const char* arg = NULL,
1563 ParseErrorType error_type = kSyntaxError);
1564
1565 // "null" return type creators.
1566 static PreParserIdentifier EmptyIdentifier() {
1567 return PreParserIdentifier::Default();
1568 }
1569 static PreParserIdentifier EmptyIdentifierString() {
1570 return PreParserIdentifier::Default();
1571 }
1572 static PreParserExpression EmptyExpression() {
1573 return PreParserExpression::Default();
1574 }
1575 static PreParserExpression EmptyLiteral() {
1576 return PreParserExpression::Default();
1577 }
1578 static PreParserExpression EmptyObjectLiteralProperty() {
1579 return PreParserExpression::Default();
1580 }
1581 static PreParserExpression EmptyFunctionLiteral() {
1582 return PreParserExpression::Default();
1583 }
1584 static PreParserExpressionList NullExpressionList() {
1585 return PreParserExpressionList();
1586 }
1587
1588 // Odd-ball literal creators.
1589 static PreParserExpression GetLiteralTheHole(int position,
1590 PreParserFactory* factory) {
1591 return PreParserExpression::Default();
1592 }
1593
1594 // Producing data during the recursive descent.
1595 PreParserIdentifier GetSymbol(Scanner* scanner);
1596 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
1597
1598 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1599 return PreParserIdentifier::Default();
1600 }
1601
1602 static PreParserExpression ThisExpression(Scope* scope,
1603 PreParserFactory* factory,
1604 int pos) {
1605 return PreParserExpression::This();
1606 }
1607
1608 static PreParserExpression SuperPropertyReference(Scope* scope,
1609 PreParserFactory* factory,
1610 int pos) {
1611 return PreParserExpression::Default();
1612 }
1613
1614 static PreParserExpression SuperCallReference(Scope* scope,
1615 PreParserFactory* factory,
1616 int pos) {
1617 return PreParserExpression::SuperCallReference();
1618 }
1619
1620 static PreParserExpression NewTargetExpression(Scope* scope,
1621 PreParserFactory* factory,
1622 int pos) {
1623 return PreParserExpression::Default();
1624 }
1625
1626 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
1627 int pos, int end_pos) {
1628 return PreParserExpression::Default();
1629 }
1630
1631 static PreParserExpression ExpressionFromLiteral(
1632 Token::Value token, int pos, Scanner* scanner,
1633 PreParserFactory* factory) {
1634 return PreParserExpression::Default();
1635 }
1636
1637 static PreParserExpression ExpressionFromIdentifier(
1638 PreParserIdentifier name, int start_position, int end_position,
1639 Scope* scope, PreParserFactory* factory) {
1640 return PreParserExpression::FromIdentifier(name);
1641 }
1642
1643 PreParserExpression ExpressionFromString(int pos,
1644 Scanner* scanner,
1645 PreParserFactory* factory = NULL);
1646
1647 PreParserExpression GetIterator(PreParserExpression iterable,
1648 PreParserFactory* factory) {
1649 return PreParserExpression::Default();
1650 }
1651
1652 static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
1653 return PreParserExpressionList();
1654 }
1655
1656 static PreParserStatementList NewStatementList(int size, Zone* zone) {
1657 return PreParserStatementList();
1658 }
1659
1660 static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
1661 return PreParserExpressionList();
1662 }
1663
1664 static void AddParameterInitializationBlock(
1665 const PreParserFormalParameters& parameters,
1666 PreParserStatementList list, bool* ok) {}
1667
1668 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1669 int* expected_property_count, bool* ok) {
1670 UNREACHABLE();
1671 }
1672
1673 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1674 PreParserIdentifier function_name, int pos,
1675 const PreParserFormalParameters& parameters, FunctionKind kind,
1676 FunctionLiteral::FunctionType function_type, bool* ok);
1677
1678 V8_INLINE void ParseArrowFunctionFormalParameterList(
1679 PreParserFormalParameters* parameters,
1680 PreParserExpression expression, const Scanner::Location& params_loc,
1681 Scanner::Location* duplicate_loc, bool* ok);
1682
1683 void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
1684
1685 struct TemplateLiteralState {};
1686
1687 TemplateLiteralState OpenTemplateLiteral(int pos) {
1688 return TemplateLiteralState();
1689 }
1690 void AddTemplateSpan(TemplateLiteralState*, bool) {}
1691 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
1692 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
1693 PreParserExpression tag) {
1694 if (IsTaggedTemplate(tag)) {
1695 // Emulate generation of array literals for tag callsite
1696 // 1st is array of cooked strings, second is array of raw strings
1697 MaterializeTemplateCallsiteLiterals();
1698 }
1699 return EmptyExpression();
1700 }
1701 inline void MaterializeTemplateCallsiteLiterals();
1702 PreParserExpression NoTemplateTag() {
1703 return PreParserExpression::NoTemplateTag();
1704 }
1705 static bool IsTaggedTemplate(const PreParserExpression tag) {
1706 return !tag.IsNoTemplateTag();
1707 }
1708
1709 void AddFormalParameter(PreParserFormalParameters* parameters,
1710 PreParserExpression pattern,
1711 PreParserExpression initializer,
1712 int initializer_end_position, bool is_rest) {
1713 ++parameters->arity;
1714 }
1715 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
1716 ExpressionClassifier* classifier) {
1717 if (!classifier->is_simple_parameter_list()) {
1718 scope->SetHasNonSimpleParameters();
1719 }
1720 }
1721
1722 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
1723
1724 // Temporary glue; these functions will move to ParserBase.
1725 PreParserExpression ParseV8Intrinsic(bool* ok);
1726 V8_INLINE PreParserExpression ParseDoExpression(bool* ok);
1727 PreParserExpression ParseFunctionLiteral(
1728 PreParserIdentifier name, Scanner::Location function_name_location,
1729 FunctionNameValidity function_name_validity, FunctionKind kind,
1730 int function_token_position, FunctionLiteral::FunctionType type,
1731 FunctionLiteral::ArityRestriction arity_restriction,
1732 LanguageMode language_mode, bool* ok);
1733
1734 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1735 Scanner::Location class_name_location,
1736 bool name_is_strict_reserved, int pos,
1737 bool* ok);
1738
1739 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
1740 return list;
1741 }
1742
1743 inline void MaterializeUnspreadArgumentsLiterals(int count);
1744
1745 inline PreParserExpression SpreadCall(PreParserExpression function,
1746 PreParserExpressionList args, int pos);
1747
1748 inline PreParserExpression SpreadCallNew(PreParserExpression function,
1749 PreParserExpressionList args,
1750 int pos);
1751
1752 private:
1753 PreParser* pre_parser_;
1754 };
1755
1756
1757 // Preparsing checks a JavaScript program and emits preparse-data that helps
1758 // a later parsing to be faster.
1759 // See preparse-data-format.h for the data format.
1760
1761 // The PreParser checks that the syntax follows the grammar for JavaScript,
1762 // and collects some information about the program along the way.
1763 // The grammar check is only performed in order to understand the program
1764 // sufficiently to deduce some information about it, that can be used
1765 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
1766 // rather it is to speed up properly written and correct programs.
1767 // That means that contextual checks (like a label being declared where
1768 // it is used) are generally omitted.
1769 class PreParser : public ParserBase<PreParserTraits> {
1770 public:
1771 typedef PreParserIdentifier Identifier;
1772 typedef PreParserExpression Expression;
1773 typedef PreParserStatement Statement;
1774
1775 enum PreParseResult {
1776 kPreParseStackOverflow,
1777 kPreParseSuccess
1778 };
1779
1780 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
1781 ParserRecorder* log, uintptr_t stack_limit)
1782 : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
1783 ast_value_factory, log, this) {}
1784
1785 // Pre-parse the program from the character stream; returns true on
1786 // success (even if parsing failed, the pre-parse data successfully
1787 // captured the syntax error), and false if a stack-overflow happened
1788 // during parsing.
1789 PreParseResult PreParseProgram(int* materialized_literals = 0) {
1790 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1791 PreParserFactory factory(NULL);
1792 FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
1793 &factory);
1794 bool ok = true;
1795 int start_position = scanner()->peek_location().beg_pos;
1796 ParseStatementList(Token::EOS, &ok);
1797 if (stack_overflow()) return kPreParseStackOverflow;
1798 if (!ok) {
1799 ReportUnexpectedToken(scanner()->current_token());
1800 } else if (is_strict(scope_->language_mode())) {
1801 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
1802 &ok);
1803 }
1804 if (materialized_literals) {
1805 *materialized_literals = function_state_->materialized_literal_count();
1806 }
1807 return kPreParseSuccess;
1808 }
1809
1810 // Parses a single function literal, from the opening parentheses before
1811 // parameters to the closing brace after the body.
1812 // Returns a FunctionEntry describing the body of the function in enough
1813 // detail that it can be lazily compiled.
1814 // The scanner is expected to have matched the "function" or "function*"
1815 // keyword and parameters, and have consumed the initial '{'.
1816 // At return, unless an error occurred, the scanner is positioned before the
1817 // the final '}'.
1818 PreParseResult PreParseLazyFunction(
1819 LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
1820 ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr);
1821
1822 private:
1823 friend class PreParserTraits;
1824
1825 static const int kLazyParseTrialLimit = 200;
1826
1827 // These types form an algebra over syntactic categories that is just
1828 // rich enough to let us recognize and propagate the constructs that
1829 // are either being counted in the preparser data, or is important
1830 // to throw the correct syntax error exceptions.
1831
1832 // All ParseXXX functions take as the last argument an *ok parameter
1833 // which is set to false if parsing failed; it is unchanged otherwise.
1834 // By making the 'exception handling' explicit, we are forced to check
1835 // for failure at the call sites.
1836 Statement ParseStatementListItem(bool* ok);
1837 void ParseStatementList(int end_token, bool* ok,
1838 Scanner::BookmarkScope* bookmark = nullptr);
1839 Statement ParseStatement(bool* ok);
1840 Statement ParseSubStatement(bool* ok);
1841 Statement ParseFunctionDeclaration(bool* ok);
1842 Statement ParseClassDeclaration(bool* ok);
1843 Statement ParseBlock(bool* ok);
1844 Statement ParseVariableStatement(VariableDeclarationContext var_context,
1845 bool* ok);
1846 Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1847 int* num_decl, bool* is_lexical,
1848 bool* is_binding_pattern,
1849 Scanner::Location* first_initializer_loc,
1850 Scanner::Location* bindings_loc,
1851 bool* ok);
1852 Statement ParseExpressionOrLabelledStatement(bool* ok);
1853 Statement ParseIfStatement(bool* ok);
1854 Statement ParseContinueStatement(bool* ok);
1855 Statement ParseBreakStatement(bool* ok);
1856 Statement ParseReturnStatement(bool* ok);
1857 Statement ParseWithStatement(bool* ok);
1858 Statement ParseSwitchStatement(bool* ok);
1859 Statement ParseDoWhileStatement(bool* ok);
1860 Statement ParseWhileStatement(bool* ok);
1861 Statement ParseForStatement(bool* ok);
1862 Statement ParseThrowStatement(bool* ok);
1863 Statement ParseTryStatement(bool* ok);
1864 Statement ParseDebuggerStatement(bool* ok);
1865 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1866 Expression ParseObjectLiteral(bool* ok);
1867 Expression ParseV8Intrinsic(bool* ok);
1868 Expression ParseDoExpression(bool* ok);
1869
1870 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1871 int* expected_property_count, bool* ok);
1872 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1873 PreParserIdentifier function_name, int pos,
1874 const PreParserFormalParameters& parameters, FunctionKind kind,
1875 FunctionLiteral::FunctionType function_type, bool* ok);
1876
1877 Expression ParseFunctionLiteral(
1878 Identifier name, Scanner::Location function_name_location,
1879 FunctionNameValidity function_name_validity, FunctionKind kind,
1880 int function_token_pos, FunctionLiteral::FunctionType function_type,
1881 FunctionLiteral::ArityRestriction arity_restriction,
1882 LanguageMode language_mode, bool* ok);
1883 void ParseLazyFunctionLiteralBody(bool* ok,
1884 Scanner::BookmarkScope* bookmark = nullptr);
1885
1886 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1887 Scanner::Location class_name_location,
1888 bool name_is_strict_reserved, int pos,
1889 bool* ok);
1890 };
1891
1892
1893 void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1894 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1895 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1896 }
1897
1898
1899 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
1900 for (int i = 0; i < count; ++i) {
1901 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1902 }
1903 }
1904
1905
1906 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
1907 PreParserExpressionList args,
1908 int pos) {
1909 return pre_parser_->factory()->NewCall(function, args, pos);
1910 }
1911
1912 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1913 PreParserExpressionList args,
1914 int pos) {
1915 return pre_parser_->factory()->NewCallNew(function, args, pos);
1916 }
1917
1918
1919 void PreParserTraits::ParseArrowFunctionFormalParameterList(
1920 PreParserFormalParameters* parameters,
1921 PreParserExpression params, const Scanner::Location& params_loc,
1922 Scanner::Location* duplicate_loc, bool* ok) {
1923 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1924 // lists that are too long.
1925
1926 // Accomodate array literal for rest parameter.
1927 if (params.IsArrowFunctionFormalParametersWithRestParameter()) {
1928 ++parameters->materialized_literals_count;
1929 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1930 }
1931 }
1932
1933
1934 PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
1935 return pre_parser_->ParseDoExpression(ok);
1936 }
1937
1938
1939 PreParserStatementList PreParser::ParseEagerFunctionBody(
1940 PreParserIdentifier function_name, int pos,
1941 const PreParserFormalParameters& parameters, FunctionKind kind,
1942 FunctionLiteral::FunctionType function_type, bool* ok) {
1943 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1944
1945 ParseStatementList(Token::RBRACE, ok);
1946 if (!*ok) return PreParserStatementList();
1947
1948 Expect(Token::RBRACE, ok);
1949 return PreParserStatementList();
1950 }
1951
1952
1953 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1954 PreParserIdentifier function_name, int pos,
1955 const PreParserFormalParameters& parameters, FunctionKind kind,
1956 FunctionLiteral::FunctionType function_type, bool* ok) {
1957 return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
1958 kind, function_type, ok);
1959 }
1960
1961
1962 template <class Traits>
1963 ParserBase<Traits>::FunctionState::FunctionState(
1964 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1965 FunctionKind kind, typename Traits::Type::Factory* factory)
1966 : next_materialized_literal_index_(0),
1967 expected_property_count_(0),
1968 this_location_(Scanner::Location::invalid()),
1969 return_location_(Scanner::Location::invalid()),
1970 super_location_(Scanner::Location::invalid()),
1971 kind_(kind),
1972 generator_object_variable_(NULL),
1973 function_state_stack_(function_state_stack),
1974 outer_function_state_(*function_state_stack),
1975 scope_stack_(scope_stack),
1976 outer_scope_(*scope_stack),
1977 factory_(factory) {
1978 *scope_stack_ = scope;
1979 *function_state_stack = this;
1980 }
1981
1982
1983 template <class Traits>
1984 ParserBase<Traits>::FunctionState::~FunctionState() {
1985 *scope_stack_ = outer_scope_;
1986 *function_state_stack_ = outer_function_state_;
1987 }
1988
1989
1990 template <class Traits>
1991 void ParserBase<Traits>::GetUnexpectedTokenMessage(
1992 Token::Value token, MessageTemplate::Template* message, const char** arg,
1993 MessageTemplate::Template default_) {
1994 // Four of the tokens are treated specially
1995 switch (token) {
1996 case Token::EOS:
1997 *message = MessageTemplate::kUnexpectedEOS;
1998 *arg = nullptr;
1999 break;
2000 case Token::SMI:
2001 case Token::NUMBER:
2002 *message = MessageTemplate::kUnexpectedTokenNumber;
2003 *arg = nullptr;
2004 break;
2005 case Token::STRING:
2006 *message = MessageTemplate::kUnexpectedTokenString;
2007 *arg = nullptr;
2008 break;
2009 case Token::IDENTIFIER:
2010 *message = MessageTemplate::kUnexpectedTokenIdentifier;
2011 *arg = nullptr;
2012 break;
2013 case Token::FUTURE_RESERVED_WORD:
2014 *message = MessageTemplate::kUnexpectedReserved;
2015 *arg = nullptr;
2016 break;
2017 case Token::LET:
2018 case Token::STATIC:
2019 case Token::YIELD:
2020 case Token::FUTURE_STRICT_RESERVED_WORD:
2021 *message = is_strict(language_mode())
2022 ? MessageTemplate::kUnexpectedStrictReserved
2023 : MessageTemplate::kUnexpectedTokenIdentifier;
2024 *arg = nullptr;
2025 break;
2026 case Token::TEMPLATE_SPAN:
2027 case Token::TEMPLATE_TAIL:
2028 *message = MessageTemplate::kUnexpectedTemplateString;
2029 *arg = nullptr;
2030 break;
2031 case Token::ESCAPED_STRICT_RESERVED_WORD:
2032 case Token::ESCAPED_KEYWORD:
2033 *message = MessageTemplate::kInvalidEscapedReservedWord;
2034 *arg = nullptr;
2035 break;
2036 default:
2037 const char* name = Token::String(token);
2038 DCHECK(name != NULL);
2039 *arg = name;
2040 break;
2041 }
2042 }
2043
2044
2045 template <class Traits>
2046 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
2047 return ReportUnexpectedTokenAt(scanner_->location(), token);
2048 }
2049
2050
2051 template <class Traits>
2052 void ParserBase<Traits>::ReportUnexpectedTokenAt(
2053 Scanner::Location source_location, Token::Value token,
2054 MessageTemplate::Template message) {
2055 const char* arg;
2056 GetUnexpectedTokenMessage(token, &message, &arg);
2057 Traits::ReportMessageAt(source_location, message, arg);
2058 }
2059
2060
2061 template <class Traits>
2062 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
2063 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
2064 ExpressionClassifier classifier;
2065 auto result = ParseAndClassifyIdentifier(&classifier, ok);
2066 if (!*ok) return Traits::EmptyIdentifier();
2067
2068 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
2069 ValidateAssignmentPattern(&classifier, ok);
2070 if (!*ok) return Traits::EmptyIdentifier();
2071 ValidateBindingPattern(&classifier, ok);
2072 if (!*ok) return Traits::EmptyIdentifier();
2073 } else {
2074 ValidateExpression(&classifier, ok);
2075 if (!*ok) return Traits::EmptyIdentifier();
2076 }
2077
2078 return result;
2079 }
2080
2081
2082 template <class Traits>
2083 typename ParserBase<Traits>::IdentifierT
2084 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
2085 bool* ok) {
2086 Token::Value next = Next();
2087 if (next == Token::IDENTIFIER) {
2088 IdentifierT name = this->GetSymbol(scanner());
2089 // When this function is used to read a formal parameter, we don't always
2090 // know whether the function is going to be strict or sloppy. Indeed for
2091 // arrow functions we don't always know that the identifier we are reading
2092 // is actually a formal parameter. Therefore besides the errors that we
2093 // must detect because we know we're in strict mode, we also record any
2094 // error that we might make in the future once we know the language mode.
2095 if (this->IsEval(name)) {
2096 classifier->RecordStrictModeFormalParameterError(
2097 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2098 if (is_strict(language_mode())) {
2099 classifier->RecordBindingPatternError(
2100 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2101 }
2102 }
2103 if (this->IsArguments(name)) {
2104 scope_->RecordArgumentsUsage();
2105 classifier->RecordStrictModeFormalParameterError(
2106 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2107 if (is_strict(language_mode())) {
2108 classifier->RecordBindingPatternError(
2109 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2110 }
2111 if (is_strong(language_mode())) {
2112 classifier->RecordExpressionError(scanner()->location(),
2113 MessageTemplate::kStrongArguments);
2114 }
2115 }
2116 if (this->IsUndefined(name)) {
2117 classifier->RecordStrongModeFormalParameterError(
2118 scanner()->location(), MessageTemplate::kStrongUndefined);
2119 if (is_strong(language_mode())) {
2120 // TODO(dslomov): allow 'undefined' in nested patterns.
2121 classifier->RecordBindingPatternError(
2122 scanner()->location(), MessageTemplate::kStrongUndefined);
2123 classifier->RecordAssignmentPatternError(
2124 scanner()->location(), MessageTemplate::kStrongUndefined);
2125 }
2126 }
2127
2128 if (classifier->duplicate_finder() != nullptr &&
2129 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2130 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2131 }
2132 return name;
2133 } else if (is_sloppy(language_mode()) &&
2134 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
2135 next == Token::ESCAPED_STRICT_RESERVED_WORD ||
2136 next == Token::LET || next == Token::STATIC ||
2137 (next == Token::YIELD && !is_generator()))) {
2138 classifier->RecordStrictModeFormalParameterError(
2139 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
2140 if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
2141 is_strict(language_mode())) {
2142 ReportUnexpectedToken(next);
2143 *ok = false;
2144 return Traits::EmptyIdentifier();
2145 }
2146 if (next == Token::LET) {
2147 classifier->RecordLetPatternError(scanner()->location(),
2148 MessageTemplate::kLetInLexicalBinding);
2149 }
2150 return this->GetSymbol(scanner());
2151 } else {
2152 this->ReportUnexpectedToken(next);
2153 *ok = false;
2154 return Traits::EmptyIdentifier();
2155 }
2156 }
2157
2158
2159 template <class Traits>
2160 typename ParserBase<Traits>::IdentifierT
2161 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
2162 bool is_generator, bool* is_strict_reserved, bool* ok) {
2163 Token::Value next = Next();
2164 if (next == Token::IDENTIFIER) {
2165 *is_strict_reserved = false;
2166 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
2167 next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
2168 *is_strict_reserved = true;
2169 } else {
2170 ReportUnexpectedToken(next);
2171 *ok = false;
2172 return Traits::EmptyIdentifier();
2173 }
2174
2175 IdentifierT name = this->GetSymbol(scanner());
2176 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
2177 return name;
2178 }
2179
2180
2181 template <class Traits>
2182 typename ParserBase<Traits>::IdentifierT
2183 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
2184 Token::Value next = Next();
2185 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
2186 next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
2187 next != Token::FUTURE_STRICT_RESERVED_WORD &&
2188 next != Token::ESCAPED_KEYWORD &&
2189 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
2190 this->ReportUnexpectedToken(next);
2191 *ok = false;
2192 return Traits::EmptyIdentifier();
2193 }
2194
2195 IdentifierT name = this->GetSymbol(scanner());
2196 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
2197 return name;
2198 }
2199
2200
2201 template <class Traits>
2202 typename ParserBase<Traits>::IdentifierT
2203 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
2204 bool* is_set,
2205 bool* ok) {
2206 IdentifierT result = ParseIdentifierName(ok);
2207 if (!*ok) return Traits::EmptyIdentifier();
2208 scanner()->IsGetOrSet(is_get, is_set);
2209 return result;
2210 }
2211
2212
2213 template <class Traits>
2214 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
2215 bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
2216 int pos = peek_position();
2217 if (!scanner()->ScanRegExpPattern(seen_equal)) {
2218 Next();
2219 ReportMessage(MessageTemplate::kUnterminatedRegExp);
2220 *ok = false;
2221 return Traits::EmptyExpression();
2222 }
2223
2224 int literal_index = function_state_->NextMaterializedLiteralIndex();
2225
2226 IdentifierT js_pattern = this->GetNextSymbol(scanner());
2227 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
2228 if (flags.IsNothing()) {
2229 Next();
2230 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
2231 *ok = false;
2232 return Traits::EmptyExpression();
2233 }
2234 int js_flags = flags.FromJust();
2235 Next();
2236 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index,
2237 is_strong(language_mode()), pos);
2238 }
2239
2240
2241 #define CHECK_OK ok); \
2242 if (!*ok) return this->EmptyExpression(); \
2243 ((void)0
2244 #define DUMMY ) // to make indentation work
2245 #undef DUMMY
2246
2247 // Used in functions where the return type is not ExpressionT.
2248 #define CHECK_OK_CUSTOM(x) ok); \
2249 if (!*ok) return this->x(); \
2250 ((void)0
2251 #define DUMMY ) // to make indentation work
2252 #undef DUMMY
2253
2254
2255 template <class Traits>
2256 typename ParserBase<Traits>::ExpressionT
2257 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
2258 bool* ok) {
2259 // PrimaryExpression ::
2260 // 'this'
2261 // 'null'
2262 // 'true'
2263 // 'false'
2264 // Identifier
2265 // Number
2266 // String
2267 // ArrayLiteral
2268 // ObjectLiteral
2269 // RegExpLiteral
2270 // ClassLiteral
2271 // '(' Expression ')'
2272 // TemplateLiteral
2273 // do Block
2274
2275 int beg_pos = peek_position();
2276 switch (peek()) {
2277 case Token::THIS: {
2278 BindingPatternUnexpectedToken(classifier);
2279 Consume(Token::THIS);
2280 if (FLAG_strong_this && is_strong(language_mode())) {
2281 // Constructors' usages of 'this' in strong mode are parsed separately.
2282 // TODO(rossberg): this does not work with arrow functions yet.
2283 if (IsClassConstructor(function_state_->kind())) {
2284 ReportMessage(MessageTemplate::kStrongConstructorThis);
2285 *ok = false;
2286 return this->EmptyExpression();
2287 }
2288 }
2289 return this->ThisExpression(scope_, factory(), beg_pos);
2290 }
2291
2292 case Token::NULL_LITERAL:
2293 case Token::TRUE_LITERAL:
2294 case Token::FALSE_LITERAL:
2295 BindingPatternUnexpectedToken(classifier);
2296 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
2297 case Token::SMI:
2298 case Token::NUMBER:
2299 classifier->RecordBindingPatternError(
2300 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
2301 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
2302
2303 case Token::IDENTIFIER:
2304 case Token::LET:
2305 case Token::STATIC:
2306 case Token::YIELD:
2307 case Token::ESCAPED_STRICT_RESERVED_WORD:
2308 case Token::FUTURE_STRICT_RESERVED_WORD: {
2309 // Using eval or arguments in this context is OK even in strict mode.
2310 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
2311 return this->ExpressionFromIdentifier(
2312 name, beg_pos, scanner()->location().end_pos, scope_, factory());
2313 }
2314
2315 case Token::STRING: {
2316 classifier->RecordBindingPatternError(
2317 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString);
2318 Consume(Token::STRING);
2319 return this->ExpressionFromString(beg_pos, scanner(), factory());
2320 }
2321
2322 case Token::ASSIGN_DIV:
2323 classifier->RecordBindingPatternError(
2324 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
2325 return this->ParseRegExpLiteral(true, classifier, ok);
2326
2327 case Token::DIV:
2328 classifier->RecordBindingPatternError(
2329 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
2330 return this->ParseRegExpLiteral(false, classifier, ok);
2331
2332 case Token::LBRACK:
2333 if (!allow_harmony_destructuring_bind()) {
2334 BindingPatternUnexpectedToken(classifier);
2335 }
2336 return this->ParseArrayLiteral(classifier, ok);
2337
2338 case Token::LBRACE:
2339 if (!allow_harmony_destructuring_bind()) {
2340 BindingPatternUnexpectedToken(classifier);
2341 }
2342 return this->ParseObjectLiteral(classifier, ok);
2343
2344 case Token::LPAREN: {
2345 // Arrow function formal parameters are either a single identifier or a
2346 // list of BindingPattern productions enclosed in parentheses.
2347 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
2348 // is_valid_binding_pattern() check to detect multiple levels of
2349 // parenthesization.
2350 if (!classifier->is_valid_binding_pattern()) {
2351 ArrowFormalParametersUnexpectedToken(classifier);
2352 }
2353 BindingPatternUnexpectedToken(classifier);
2354 Consume(Token::LPAREN);
2355 if (Check(Token::RPAREN)) {
2356 // ()=>x. The continuation that looks for the => is in
2357 // ParseAssignmentExpression.
2358 classifier->RecordExpressionError(scanner()->location(),
2359 MessageTemplate::kUnexpectedToken,
2360 Token::String(Token::RPAREN));
2361 classifier->RecordBindingPatternError(scanner()->location(),
2362 MessageTemplate::kUnexpectedToken,
2363 Token::String(Token::RPAREN));
2364 return factory()->NewEmptyParentheses(beg_pos);
2365 } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
2366 // (...x)=>x. The continuation that looks for the => is in
2367 // ParseAssignmentExpression.
2368 int ellipsis_pos = position();
2369 classifier->RecordExpressionError(scanner()->location(),
2370 MessageTemplate::kUnexpectedToken,
2371 Token::String(Token::ELLIPSIS));
2372 classifier->RecordNonSimpleParameter();
2373 Scanner::Location expr_loc = scanner()->peek_location();
2374 Token::Value tok = peek();
2375 ExpressionT expr =
2376 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2377 // Patterns are not allowed as rest parameters. There is no way we can
2378 // succeed so go ahead and use the convenient ReportUnexpectedToken
2379 // interface.
2380 if (!Traits::IsIdentifier(expr)) {
2381 ReportUnexpectedTokenAt(expr_loc, tok);
2382 *ok = false;
2383 return this->EmptyExpression();
2384 }
2385 if (peek() == Token::COMMA) {
2386 ReportMessageAt(scanner()->peek_location(),
2387 MessageTemplate::kParamAfterRest);
2388 *ok = false;
2389 return this->EmptyExpression();
2390 }
2391 Expect(Token::RPAREN, CHECK_OK);
2392 return factory()->NewSpread(expr, ellipsis_pos);
2393 }
2394 // Heuristically try to detect immediately called functions before
2395 // seeing the call parentheses.
2396 parenthesized_function_ = (peek() == Token::FUNCTION);
2397 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
2398 Expect(Token::RPAREN, CHECK_OK);
2399 return expr;
2400 }
2401
2402 case Token::CLASS: {
2403 BindingPatternUnexpectedToken(classifier);
2404 Consume(Token::CLASS);
2405 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2406 ReportMessage(MessageTemplate::kSloppyLexical);
2407 *ok = false;
2408 return this->EmptyExpression();
2409 }
2410 int class_token_position = position();
2411 IdentifierT name = this->EmptyIdentifier();
2412 bool is_strict_reserved_name = false;
2413 Scanner::Location class_name_location = Scanner::Location::invalid();
2414 if (peek_any_identifier()) {
2415 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2416 CHECK_OK);
2417 class_name_location = scanner()->location();
2418 }
2419 return this->ParseClassLiteral(name, class_name_location,
2420 is_strict_reserved_name,
2421 class_token_position, ok);
2422 }
2423
2424 case Token::TEMPLATE_SPAN:
2425 case Token::TEMPLATE_TAIL:
2426 classifier->RecordBindingPatternError(
2427 scanner()->peek_location(),
2428 MessageTemplate::kUnexpectedTemplateString);
2429 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
2430 classifier, ok);
2431
2432 case Token::MOD:
2433 if (allow_natives() || extension_ != NULL) {
2434 BindingPatternUnexpectedToken(classifier);
2435 return this->ParseV8Intrinsic(ok);
2436 }
2437 break;
2438
2439 case Token::DO:
2440 if (allow_harmony_do_expressions()) {
2441 BindingPatternUnexpectedToken(classifier);
2442 return Traits::ParseDoExpression(ok);
2443 }
2444 break;
2445
2446 default:
2447 break;
2448 }
2449
2450 ReportUnexpectedToken(Next());
2451 *ok = false;
2452 return this->EmptyExpression();
2453 }
2454
2455
2456 template <class Traits>
2457 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2458 bool accept_IN, bool* ok) {
2459 ExpressionClassifier classifier;
2460 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
2461 ValidateExpression(&classifier, CHECK_OK);
2462 return result;
2463 }
2464
2465
2466 // Precedence = 1
2467 template <class Traits>
2468 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2469 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2470 // Expression ::
2471 // AssignmentExpression
2472 // Expression ',' AssignmentExpression
2473
2474 ExpressionClassifier binding_classifier;
2475 ExpressionT result =
2476 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
2477 classifier->Accumulate(binding_classifier,
2478 ExpressionClassifier::AllProductions);
2479 bool is_simple_parameter_list = this->IsIdentifier(result);
2480 bool seen_rest = false;
2481 while (peek() == Token::COMMA) {
2482 if (seen_rest) {
2483 // At this point the production can't possibly be valid, but we don't know
2484 // which error to signal.
2485 classifier->RecordArrowFormalParametersError(
2486 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2487 }
2488 Consume(Token::COMMA);
2489 bool is_rest = false;
2490 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) {
2491 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2492 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2493 // valid expression or binding pattern.
2494 ExpressionUnexpectedToken(classifier);
2495 BindingPatternUnexpectedToken(classifier);
2496 Consume(Token::ELLIPSIS);
2497 seen_rest = is_rest = true;
2498 }
2499 int pos = position();
2500 ExpressionT right = this->ParseAssignmentExpression(
2501 accept_IN, &binding_classifier, CHECK_OK);
2502 if (is_rest) right = factory()->NewSpread(right, pos);
2503 is_simple_parameter_list =
2504 is_simple_parameter_list && this->IsIdentifier(right);
2505 classifier->Accumulate(binding_classifier,
2506 ExpressionClassifier::AllProductions);
2507 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2508 }
2509 if (!is_simple_parameter_list || seen_rest) {
2510 classifier->RecordNonSimpleParameter();
2511 }
2512 return result;
2513 }
2514
2515
2516 template <class Traits>
2517 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2518 ExpressionClassifier* classifier, bool* ok) {
2519 // ArrayLiteral ::
2520 // '[' Expression? (',' Expression?)* ']'
2521
2522 int pos = peek_position();
2523 typename Traits::Type::ExpressionList values =
2524 this->NewExpressionList(4, zone_);
2525 int first_spread_index = -1;
2526 Expect(Token::LBRACK, CHECK_OK);
2527 while (peek() != Token::RBRACK) {
2528 bool seen_spread = false;
2529 ExpressionT elem = this->EmptyExpression();
2530 if (peek() == Token::COMMA) {
2531 if (is_strong(language_mode())) {
2532 ReportMessageAt(scanner()->peek_location(),
2533 MessageTemplate::kStrongEllision);
2534 *ok = false;
2535 return this->EmptyExpression();
2536 }
2537 elem = this->GetLiteralTheHole(peek_position(), factory());
2538 } else if (peek() == Token::ELLIPSIS) {
2539 int start_pos = peek_position();
2540 Consume(Token::ELLIPSIS);
2541 ExpressionT argument =
2542 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2543 elem = factory()->NewSpread(argument, start_pos);
2544 seen_spread = true;
2545 if (first_spread_index < 0) {
2546 first_spread_index = values->length();
2547 }
2548 } else {
2549 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2550 }
2551 values->Add(elem, zone_);
2552 if (peek() != Token::RBRACK) {
2553 if (seen_spread) {
2554 BindingPatternUnexpectedToken(classifier);
2555 }
2556 Expect(Token::COMMA, CHECK_OK);
2557 }
2558 }
2559 Expect(Token::RBRACK, CHECK_OK);
2560
2561 // Update the scope information before the pre-parsing bailout.
2562 int literal_index = function_state_->NextMaterializedLiteralIndex();
2563
2564 return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
2565 is_strong(language_mode()), pos);
2566 }
2567
2568
2569 template <class Traits>
2570 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2571 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2572 bool* is_computed_name, bool* is_identifier, bool* is_escaped_keyword,
2573 ExpressionClassifier* classifier, bool* ok) {
2574 Token::Value token = peek();
2575 int pos = peek_position();
2576
2577 // For non computed property names we normalize the name a bit:
2578 //
2579 // "12" -> 12
2580 // 12.3 -> "12.3"
2581 // 12.30 -> "12.3"
2582 // identifier -> "identifier"
2583 //
2584 // This is important because we use the property name as a key in a hash
2585 // table when we compute constant properties.
2586 switch (token) {
2587 case Token::STRING:
2588 Consume(Token::STRING);
2589 *name = this->GetSymbol(scanner());
2590 break;
2591
2592 case Token::SMI:
2593 Consume(Token::SMI);
2594 *name = this->GetNumberAsSymbol(scanner());
2595 break;
2596
2597 case Token::NUMBER:
2598 Consume(Token::NUMBER);
2599 *name = this->GetNumberAsSymbol(scanner());
2600 break;
2601
2602 case Token::LBRACK: {
2603 *is_computed_name = true;
2604 Consume(Token::LBRACK);
2605 ExpressionClassifier computed_name_classifier;
2606 ExpressionT expression =
2607 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
2608 classifier->Accumulate(computed_name_classifier,
2609 ExpressionClassifier::ExpressionProductions);
2610 Expect(Token::RBRACK, CHECK_OK);
2611 return expression;
2612 }
2613
2614 case Token::ESCAPED_KEYWORD:
2615 *is_escaped_keyword = true;
2616 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2617 break;
2618
2619 case Token::STATIC:
2620 *is_static = true;
2621
2622 // Fall through.
2623 default:
2624 *is_identifier = true;
2625 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2626 break;
2627 }
2628
2629 uint32_t index;
2630 return this->IsArrayIndex(*name, &index)
2631 ? factory()->NewNumberLiteral(index, pos)
2632 : factory()->NewStringLiteral(*name, pos);
2633 }
2634
2635
2636 template <class Traits>
2637 typename ParserBase<Traits>::ObjectLiteralPropertyT
2638 ParserBase<Traits>::ParsePropertyDefinition(
2639 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2640 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
2641 ExpressionClassifier* classifier, bool* ok) {
2642 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2643 ExpressionT value = this->EmptyExpression();
2644 IdentifierT name = this->EmptyIdentifier();
2645 bool is_get = false;
2646 bool is_set = false;
2647 bool name_is_static = false;
2648 bool is_generator = Check(Token::MUL);
2649
2650 Token::Value name_token = peek();
2651 int next_beg_pos = scanner()->peek_location().beg_pos;
2652 int next_end_pos = scanner()->peek_location().end_pos;
2653 bool is_identifier = false;
2654 bool is_escaped_keyword = false;
2655 ExpressionT name_expression = ParsePropertyName(
2656 &name, &is_get, &is_set, &name_is_static, is_computed_name,
2657 &is_identifier, &is_escaped_keyword, classifier,
2658 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2659
2660 if (fni_ != nullptr && !*is_computed_name) {
2661 this->PushLiteralName(fni_, name);
2662 }
2663
2664 bool escaped_static =
2665 is_escaped_keyword &&
2666 scanner()->is_literal_contextual_keyword(CStrVector("static"));
2667
2668 if (!in_class && !is_generator) {
2669 DCHECK(!is_static);
2670
2671 if (peek() == Token::COLON) {
2672 // PropertyDefinition
2673 // PropertyName ':' AssignmentExpression
2674 if (!*is_computed_name) {
2675 checker->CheckProperty(name_token, kValueProperty, false, false,
2676 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2677 }
2678 Consume(Token::COLON);
2679 value = this->ParseAssignmentExpression(
2680 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2681 return factory()->NewObjectLiteralProperty(name_expression, value, false,
2682 *is_computed_name);
2683 }
2684
2685 if ((is_identifier || is_escaped_keyword) &&
2686 (peek() == Token::COMMA || peek() == Token::RBRACE ||
2687 peek() == Token::ASSIGN)) {
2688 // PropertyDefinition
2689 // IdentifierReference
2690 // CoverInitializedName
2691 //
2692 // CoverInitializedName
2693 // IdentifierReference Initializer?
2694 if (!Token::IsIdentifier(name_token, language_mode(),
2695 this->is_generator())) {
2696 if (!escaped_static) {
2697 ReportUnexpectedTokenAt(scanner()->location(), name_token);
2698 *ok = false;
2699 return this->EmptyObjectLiteralProperty();
2700 }
2701 }
2702 if (classifier->duplicate_finder() != nullptr &&
2703 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2704 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2705 }
2706 if (name_token == Token::LET) {
2707 classifier->RecordLetPatternError(
2708 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
2709 }
2710
2711 ExpressionT lhs = this->ExpressionFromIdentifier(
2712 name, next_beg_pos, next_end_pos, scope_, factory());
2713
2714 if (peek() == Token::ASSIGN) {
2715 this->ExpressionUnexpectedToken(classifier);
2716 Consume(Token::ASSIGN);
2717 ExpressionClassifier rhs_classifier;
2718 ExpressionT rhs = this->ParseAssignmentExpression(
2719 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2720 classifier->Accumulate(rhs_classifier,
2721 ExpressionClassifier::ExpressionProductions);
2722 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2723 RelocInfo::kNoPosition);
2724 } else {
2725 value = lhs;
2726 }
2727
2728 return factory()->NewObjectLiteralProperty(
2729 name_expression, value, ObjectLiteralProperty::COMPUTED, false,
2730 false);
2731 }
2732 }
2733
2734 if (in_class && escaped_static && !is_static) {
2735 ReportUnexpectedTokenAt(scanner()->location(), name_token);
2736 *ok = false;
2737 return this->EmptyObjectLiteralProperty();
2738 }
2739
2740 if (is_generator || peek() == Token::LPAREN) {
2741 // MethodDefinition
2742 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2743 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2744 if (!*is_computed_name) {
2745 checker->CheckProperty(name_token, kMethodProperty, is_static,
2746 is_generator,
2747 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2748 }
2749
2750 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2751 : FunctionKind::kConciseMethod;
2752
2753 if (in_class && !is_static && this->IsConstructor(name)) {
2754 *has_seen_constructor = true;
2755 kind = has_extends ? FunctionKind::kSubclassConstructor
2756 : FunctionKind::kBaseConstructor;
2757 }
2758
2759 if (!in_class) kind = WithObjectLiteralBit(kind);
2760
2761 value = this->ParseFunctionLiteral(
2762 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2763 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2764 FunctionLiteral::NORMAL_ARITY, language_mode(),
2765 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2766
2767 return factory()->NewObjectLiteralProperty(name_expression, value,
2768 ObjectLiteralProperty::COMPUTED,
2769 is_static, *is_computed_name);
2770 }
2771
2772 if (in_class && name_is_static && !is_static) {
2773 // ClassElement (static)
2774 // 'static' MethodDefinition
2775 return ParsePropertyDefinition(checker, true, has_extends, true,
2776 is_computed_name, nullptr, classifier, ok);
2777 }
2778
2779 if (is_get || is_set) {
2780 // MethodDefinition (Accessors)
2781 // get PropertyName '(' ')' '{' FunctionBody '}'
2782 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2783 name = this->EmptyIdentifier();
2784 bool dont_care = false;
2785 name_token = peek();
2786
2787 name_expression = ParsePropertyName(
2788 &name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care,
2789 &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2790
2791 if (!*is_computed_name) {
2792 checker->CheckProperty(name_token, kAccessorProperty, is_static,
2793 is_generator,
2794 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2795 }
2796
2797 FunctionKind kind = FunctionKind::kAccessorFunction;
2798 if (!in_class) kind = WithObjectLiteralBit(kind);
2799 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2800 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2801 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2802 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2803 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2804
2805 // Make sure the name expression is a string since we need a Name for
2806 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2807 // statically we can skip the extra runtime check.
2808 if (!*is_computed_name) {
2809 name_expression =
2810 factory()->NewStringLiteral(name, name_expression->position());
2811 }
2812
2813 return factory()->NewObjectLiteralProperty(
2814 name_expression, value,
2815 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2816 is_static, *is_computed_name);
2817 }
2818
2819 Token::Value next = Next();
2820 ReportUnexpectedToken(next);
2821 *ok = false;
2822 return this->EmptyObjectLiteralProperty();
2823 }
2824
2825
2826 template <class Traits>
2827 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2828 ExpressionClassifier* classifier, bool* ok) {
2829 // ObjectLiteral ::
2830 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2831
2832 int pos = peek_position();
2833 typename Traits::Type::PropertyList properties =
2834 this->NewPropertyList(4, zone_);
2835 int number_of_boilerplate_properties = 0;
2836 bool has_function = false;
2837 bool has_computed_names = false;
2838 ObjectLiteralChecker checker(this);
2839
2840 Expect(Token::LBRACE, CHECK_OK);
2841
2842 while (peek() != Token::RBRACE) {
2843 if (fni_ != nullptr) fni_->Enter();
2844
2845 const bool in_class = false;
2846 const bool is_static = false;
2847 const bool has_extends = false;
2848 bool is_computed_name = false;
2849 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2850 &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
2851 classifier, CHECK_OK);
2852
2853 if (is_computed_name) {
2854 has_computed_names = true;
2855 }
2856
2857 // Mark top-level object literals that contain function literals and
2858 // pretenure the literal so it can be added as a constant function
2859 // property. (Parser only.)
2860 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2861 &has_function);
2862
2863 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2864 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2865 number_of_boilerplate_properties++;
2866 }
2867 properties->Add(property, zone());
2868
2869 if (peek() != Token::RBRACE) {
2870 // Need {} because of the CHECK_OK macro.
2871 Expect(Token::COMMA, CHECK_OK);
2872 }
2873
2874 if (fni_ != nullptr) {
2875 fni_->Infer();
2876 fni_->Leave();
2877 }
2878 }
2879 Expect(Token::RBRACE, CHECK_OK);
2880
2881 // Computation of literal_index must happen before pre parse bailout.
2882 int literal_index = function_state_->NextMaterializedLiteralIndex();
2883
2884 return factory()->NewObjectLiteral(properties,
2885 literal_index,
2886 number_of_boilerplate_properties,
2887 has_function,
2888 is_strong(language_mode()),
2889 pos);
2890 }
2891
2892
2893 template <class Traits>
2894 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
2895 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier,
2896 bool* ok) {
2897 // Arguments ::
2898 // '(' (AssignmentExpression)*[','] ')'
2899
2900 Scanner::Location spread_arg = Scanner::Location::invalid();
2901 typename Traits::Type::ExpressionList result =
2902 this->NewExpressionList(4, zone_);
2903 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2904 bool done = (peek() == Token::RPAREN);
2905 bool was_unspread = false;
2906 int unspread_sequences_count = 0;
2907 while (!done) {
2908 int start_pos = peek_position();
2909 bool is_spread = Check(Token::ELLIPSIS);
2910
2911 ExpressionT argument = this->ParseAssignmentExpression(
2912 true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
2913 if (is_spread) {
2914 if (!spread_arg.IsValid()) {
2915 spread_arg.beg_pos = start_pos;
2916 spread_arg.end_pos = peek_position();
2917 }
2918 argument = factory()->NewSpread(argument, start_pos);
2919 }
2920 result->Add(argument, zone_);
2921
2922 // unspread_sequences_count is the number of sequences of parameters which
2923 // are not prefixed with a spread '...' operator.
2924 if (is_spread) {
2925 was_unspread = false;
2926 } else if (!was_unspread) {
2927 was_unspread = true;
2928 unspread_sequences_count++;
2929 }
2930
2931 if (result->length() > Code::kMaxArguments) {
2932 ReportMessage(MessageTemplate::kTooManyArguments);
2933 *ok = false;
2934 return this->NullExpressionList();
2935 }
2936 done = (peek() != Token::COMMA);
2937 if (!done) {
2938 Next();
2939 }
2940 }
2941 Scanner::Location location = scanner_->location();
2942 if (Token::RPAREN != Next()) {
2943 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2944 *ok = false;
2945 return this->NullExpressionList();
2946 }
2947 *first_spread_arg_loc = spread_arg;
2948
2949 if (spread_arg.IsValid()) {
2950 // Unspread parameter sequences are translated into array literals in the
2951 // parser. Ensure that the number of materialized literals matches between
2952 // the parser and preparser
2953 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2954 }
2955
2956 return result;
2957 }
2958
2959 // Precedence = 2
2960 template <class Traits>
2961 typename ParserBase<Traits>::ExpressionT
2962 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
2963 ExpressionClassifier* classifier,
2964 bool* ok) {
2965 // AssignmentExpression ::
2966 // ConditionalExpression
2967 // ArrowFunction
2968 // YieldExpression
2969 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2970
2971 int lhs_beg_pos = peek_position();
2972
2973 if (peek() == Token::YIELD && is_generator()) {
2974 return this->ParseYieldExpression(classifier, ok);
2975 }
2976
2977 if (fni_ != NULL) fni_->Enter();
2978 ParserBase<Traits>::Checkpoint checkpoint(this);
2979 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
2980 bool parenthesized_formals = peek() == Token::LPAREN;
2981 if (!parenthesized_formals) {
2982 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2983 }
2984 ExpressionT expression = this->ParseConditionalExpression(
2985 accept_IN, &arrow_formals_classifier, CHECK_OK);
2986 if (peek() == Token::ARROW) {
2987 BindingPatternUnexpectedToken(classifier);
2988 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2989 parenthesized_formals, CHECK_OK);
2990 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2991 Scope* scope =
2992 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
2993 // Because the arrow's parameters were parsed in the outer scope, any
2994 // usage flags that might have been triggered there need to be copied
2995 // to the arrow scope.
2996 scope_->PropagateUsageFlagsToScope(scope);
2997 FormalParametersT parameters(scope);
2998 if (!arrow_formals_classifier.is_simple_parameter_list()) {
2999 scope->SetHasNonSimpleParameters();
3000 parameters.is_simple = false;
3001 }
3002
3003 Scanner::Location duplicate_loc = Scanner::Location::invalid();
3004 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
3005 &duplicate_loc, CHECK_OK);
3006
3007 checkpoint.Restore(&parameters.materialized_literals_count);
3008
3009 scope->set_start_position(lhs_beg_pos);
3010 if (duplicate_loc.IsValid()) {
3011 arrow_formals_classifier.RecordDuplicateFormalParameterError(
3012 duplicate_loc);
3013 }
3014 expression = this->ParseArrowFunctionLiteral(
3015 accept_IN, parameters, arrow_formals_classifier, CHECK_OK);
3016 return expression;
3017 }
3018
3019 // "expression" was not itself an arrow function parameter list, but it might
3020 // form part of one. Propagate speculative formal parameter error locations.
3021 classifier->Accumulate(arrow_formals_classifier,
3022 ExpressionClassifier::StandardProductions |
3023 ExpressionClassifier::FormalParametersProductions);
3024
3025 if (!Token::IsAssignmentOp(peek())) {
3026 if (fni_ != NULL) fni_->Leave();
3027 // Parsed conditional expression only (no assignment).
3028 return expression;
3029 }
3030
3031 if (!(allow_harmony_destructuring_bind() ||
3032 allow_harmony_default_parameters())) {
3033 BindingPatternUnexpectedToken(classifier);
3034 }
3035
3036 expression = this->CheckAndRewriteReferenceExpression(
3037 expression, lhs_beg_pos, scanner()->location().end_pos,
3038 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
3039 expression = this->MarkExpressionAsAssigned(expression);
3040
3041 Token::Value op = Next(); // Get assignment operator.
3042 if (op != Token::ASSIGN) {
3043 classifier->RecordBindingPatternError(scanner()->location(),
3044 MessageTemplate::kUnexpectedToken,
3045 Token::String(op));
3046 }
3047 int pos = position();
3048
3049 ExpressionClassifier rhs_classifier;
3050 ExpressionT right =
3051 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
3052 classifier->Accumulate(rhs_classifier,
3053 ExpressionClassifier::ExpressionProductions);
3054
3055 // TODO(1231235): We try to estimate the set of properties set by
3056 // constructors. We define a new property whenever there is an
3057 // assignment to a property of 'this'. We should probably only add
3058 // properties if we haven't seen them before. Otherwise we'll
3059 // probably overestimate the number of properties.
3060 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
3061 function_state_->AddProperty();
3062 }
3063
3064 this->CheckAssigningFunctionLiteralToProperty(expression, right);
3065
3066 if (fni_ != NULL) {
3067 // Check if the right hand side is a call to avoid inferring a
3068 // name if we're dealing with "a = function(){...}();"-like
3069 // expression.
3070 if ((op == Token::INIT || op == Token::ASSIGN) &&
3071 (!right->IsCall() && !right->IsCallNew())) {
3072 fni_->Infer();
3073 } else {
3074 fni_->RemoveLastFunction();
3075 }
3076 fni_->Leave();
3077 }
3078
3079 return factory()->NewAssignment(op, expression, right, pos);
3080 }
3081
3082 template <class Traits>
3083 typename ParserBase<Traits>::ExpressionT
3084 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
3085 bool* ok) {
3086 // YieldExpression ::
3087 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
3088 int pos = peek_position();
3089 BindingPatternUnexpectedToken(classifier);
3090 FormalParameterInitializerUnexpectedToken(classifier);
3091 Expect(Token::YIELD, CHECK_OK);
3092 ExpressionT generator_object =
3093 factory()->NewVariableProxy(function_state_->generator_object_variable());
3094 ExpressionT expression = Traits::EmptyExpression();
3095 Yield::Kind kind = Yield::kSuspend;
3096 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
3097 if (Check(Token::MUL)) kind = Yield::kDelegating;
3098 switch (peek()) {
3099 case Token::EOS:
3100 case Token::SEMICOLON:
3101 case Token::RBRACE:
3102 case Token::RBRACK:
3103 case Token::RPAREN:
3104 case Token::COLON:
3105 case Token::COMMA:
3106 // The above set of tokens is the complete set of tokens that can appear
3107 // after an AssignmentExpression, and none of them can start an
3108 // AssignmentExpression. This allows us to avoid looking for an RHS for
3109 // a Yield::kSuspend operation, given only one look-ahead token.
3110 if (kind == Yield::kSuspend)
3111 break;
3112 DCHECK_EQ(Yield::kDelegating, kind);
3113 // Delegating yields require an RHS; fall through.
3114 default:
3115 expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
3116 break;
3117 }
3118 }
3119 if (kind == Yield::kDelegating) {
3120 // var iterator = subject[Symbol.iterator]();
3121 expression = this->GetIterator(expression, factory());
3122 }
3123 typename Traits::Type::YieldExpression yield =
3124 factory()->NewYield(generator_object, expression, kind, pos);
3125 return yield;
3126 }
3127
3128
3129 // Precedence = 3
3130 template <class Traits>
3131 typename ParserBase<Traits>::ExpressionT
3132 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
3133 ExpressionClassifier* classifier,
3134 bool* ok) {
3135 // ConditionalExpression ::
3136 // LogicalOrExpression
3137 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3138
3139 int pos = peek_position();
3140 // We start using the binary expression parser for prec >= 4 only!
3141 ExpressionT expression =
3142 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
3143 if (peek() != Token::CONDITIONAL) return expression;
3144 ArrowFormalParametersUnexpectedToken(classifier);
3145 BindingPatternUnexpectedToken(classifier);
3146 Consume(Token::CONDITIONAL);
3147 // In parsing the first assignment expression in conditional
3148 // expressions we always accept the 'in' keyword; see ECMA-262,
3149 // section 11.12, page 58.
3150 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
3151 Expect(Token::COLON, CHECK_OK);
3152 ExpressionT right =
3153 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
3154 return factory()->NewConditional(expression, left, right, pos);
3155 }
3156
3157
3158 // Precedence >= 4
3159 template <class Traits>
3160 typename ParserBase<Traits>::ExpressionT
3161 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
3162 ExpressionClassifier* classifier,
3163 bool* ok) {
3164 DCHECK(prec >= 4);
3165 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
3166 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3167 // prec1 >= 4
3168 while (Precedence(peek(), accept_IN) == prec1) {
3169 BindingPatternUnexpectedToken(classifier);
3170 ArrowFormalParametersUnexpectedToken(classifier);
3171 Token::Value op = Next();
3172 Scanner::Location op_location = scanner()->location();
3173 int pos = position();
3174 ExpressionT y =
3175 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
3176
3177 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
3178 factory())) {
3179 continue;
3180 }
3181
3182 // For now we distinguish between comparisons and other binary
3183 // operations. (We could combine the two and get rid of this
3184 // code and AST node eventually.)
3185 if (Token::IsCompareOp(op)) {
3186 // We have a comparison.
3187 Token::Value cmp = op;
3188 switch (op) {
3189 case Token::NE: cmp = Token::EQ; break;
3190 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
3191 default: break;
3192 }
3193 if (cmp == Token::EQ && is_strong(language_mode())) {
3194 ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
3195 *ok = false;
3196 return this->EmptyExpression();
3197 }
3198 x = factory()->NewCompareOperation(cmp, x, y, pos);
3199 if (cmp != op) {
3200 // The comparison was negated - add a NOT.
3201 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3202 }
3203
3204 } else {
3205 // We have a "normal" binary operation.
3206 x = factory()->NewBinaryOperation(op, x, y, pos);
3207 }
3208 }
3209 }
3210 return x;
3211 }
3212
3213
3214 template <class Traits>
3215 typename ParserBase<Traits>::ExpressionT
3216 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
3217 bool* ok) {
3218 // UnaryExpression ::
3219 // PostfixExpression
3220 // 'delete' UnaryExpression
3221 // 'void' UnaryExpression
3222 // 'typeof' UnaryExpression
3223 // '++' UnaryExpression
3224 // '--' UnaryExpression
3225 // '+' UnaryExpression
3226 // '-' UnaryExpression
3227 // '~' UnaryExpression
3228 // '!' UnaryExpression
3229
3230 Token::Value op = peek();
3231 if (Token::IsUnaryOp(op)) {
3232 BindingPatternUnexpectedToken(classifier);
3233 ArrowFormalParametersUnexpectedToken(classifier);
3234
3235 op = Next();
3236 int pos = position();
3237 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
3238
3239 if (op == Token::DELETE && is_strict(language_mode())) {
3240 if (is_strong(language_mode())) {
3241 ReportMessage(MessageTemplate::kStrongDelete);
3242 *ok = false;
3243 return this->EmptyExpression();
3244 } else if (this->IsIdentifier(expression)) {
3245 // "delete identifier" is a syntax error in strict mode.
3246 ReportMessage(MessageTemplate::kStrictDelete);
3247 *ok = false;
3248 return this->EmptyExpression();
3249 }
3250 }
3251
3252 // Allow Traits do rewrite the expression.
3253 return this->BuildUnaryExpression(expression, op, pos, factory());
3254 } else if (Token::IsCountOp(op)) {
3255 BindingPatternUnexpectedToken(classifier);
3256 ArrowFormalParametersUnexpectedToken(classifier);
3257 op = Next();
3258 int beg_pos = peek_position();
3259 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
3260 expression = this->CheckAndRewriteReferenceExpression(
3261 expression, beg_pos, scanner()->location().end_pos,
3262 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
3263 this->MarkExpressionAsAssigned(expression);
3264
3265 return factory()->NewCountOperation(op,
3266 true /* prefix */,
3267 expression,
3268 position());
3269
3270 } else {
3271 return this->ParsePostfixExpression(classifier, ok);
3272 }
3273 }
3274
3275
3276 template <class Traits>
3277 typename ParserBase<Traits>::ExpressionT
3278 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
3279 bool* ok) {
3280 // PostfixExpression ::
3281 // LeftHandSideExpression ('++' | '--')?
3282
3283 int lhs_beg_pos = peek_position();
3284 ExpressionT expression =
3285 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
3286 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
3287 Token::IsCountOp(peek())) {
3288 BindingPatternUnexpectedToken(classifier);
3289 ArrowFormalParametersUnexpectedToken(classifier);
3290
3291 expression = this->CheckAndRewriteReferenceExpression(
3292 expression, lhs_beg_pos, scanner()->location().end_pos,
3293 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
3294 expression = this->MarkExpressionAsAssigned(expression);
3295
3296 Token::Value next = Next();
3297 expression =
3298 factory()->NewCountOperation(next,
3299 false /* postfix */,
3300 expression,
3301 position());
3302 }
3303 return expression;
3304 }
3305
3306
3307 template <class Traits>
3308 typename ParserBase<Traits>::ExpressionT
3309 ParserBase<Traits>::ParseLeftHandSideExpression(
3310 ExpressionClassifier* classifier, bool* ok) {
3311 // LeftHandSideExpression ::
3312 // (NewExpression | MemberExpression) ...
3313
3314 ExpressionT result =
3315 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3316
3317 while (true) {
3318 switch (peek()) {
3319 case Token::LBRACK: {
3320 BindingPatternUnexpectedToken(classifier);
3321 ArrowFormalParametersUnexpectedToken(classifier);
3322 Consume(Token::LBRACK);
3323 int pos = position();
3324 ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
3325 result = factory()->NewProperty(result, index, pos);
3326 Expect(Token::RBRACK, CHECK_OK);
3327 break;
3328 }
3329
3330 case Token::LPAREN: {
3331 BindingPatternUnexpectedToken(classifier);
3332 ArrowFormalParametersUnexpectedToken(classifier);
3333
3334 if (is_strong(language_mode()) && this->IsIdentifier(result) &&
3335 this->IsEval(this->AsIdentifier(result))) {
3336 ReportMessage(MessageTemplate::kStrongDirectEval);
3337 *ok = false;
3338 return this->EmptyExpression();
3339 }
3340 int pos;
3341 if (scanner()->current_token() == Token::IDENTIFIER ||
3342 scanner()->current_token() == Token::SUPER) {
3343 // For call of an identifier we want to report position of
3344 // the identifier as position of the call in the stack trace.
3345 pos = position();
3346 } else {
3347 // For other kinds of calls we record position of the parenthesis as
3348 // position of the call. Note that this is extremely important for
3349 // expressions of the form function(){...}() for which call position
3350 // should not point to the closing brace otherwise it will intersect
3351 // with positions recorded for function literal and confuse debugger.
3352 pos = peek_position();
3353 // Also the trailing parenthesis are a hint that the function will
3354 // be called immediately. If we happen to have parsed a preceding
3355 // function literal eagerly, we can also compile it eagerly.
3356 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3357 result->AsFunctionLiteral()->set_should_eager_compile();
3358 }
3359 }
3360 Scanner::Location spread_pos;
3361 typename Traits::Type::ExpressionList args =
3362 ParseArguments(&spread_pos, classifier, CHECK_OK);
3363
3364 // Keep track of eval() calls since they disable all local variable
3365 // optimizations.
3366 // The calls that need special treatment are the
3367 // direct eval calls. These calls are all of the form eval(...), with
3368 // no explicit receiver.
3369 // These calls are marked as potentially direct eval calls. Whether
3370 // they are actually direct calls to eval is determined at run time.
3371 this->CheckPossibleEvalCall(result, scope_);
3372
3373 bool is_super_call = result->IsSuperCallReference();
3374 if (spread_pos.IsValid()) {
3375 args = Traits::PrepareSpreadArguments(args);
3376 result = Traits::SpreadCall(result, args, pos);
3377 } else {
3378 result = factory()->NewCall(result, args, pos);
3379 }
3380
3381 // Explicit calls to the super constructor using super() perform an
3382 // implicit binding assignment to the 'this' variable.
3383 if (is_super_call) {
3384 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3385 result =
3386 factory()->NewAssignment(Token::INIT, this_expr, result, pos);
3387 }
3388
3389 if (fni_ != NULL) fni_->RemoveLastFunction();
3390 break;
3391 }
3392
3393 case Token::PERIOD: {
3394 BindingPatternUnexpectedToken(classifier);
3395 ArrowFormalParametersUnexpectedToken(classifier);
3396 Consume(Token::PERIOD);
3397 int pos = position();
3398 IdentifierT name = ParseIdentifierName(CHECK_OK);
3399 result = factory()->NewProperty(
3400 result, factory()->NewStringLiteral(name, pos), pos);
3401 if (fni_ != NULL) this->PushLiteralName(fni_, name);
3402 break;
3403 }
3404
3405 case Token::TEMPLATE_SPAN:
3406 case Token::TEMPLATE_TAIL: {
3407 BindingPatternUnexpectedToken(classifier);
3408 ArrowFormalParametersUnexpectedToken(classifier);
3409 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
3410 break;
3411 }
3412
3413 default:
3414 return result;
3415 }
3416 }
3417 }
3418
3419
3420 template <class Traits>
3421 typename ParserBase<Traits>::ExpressionT
3422 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
3423 ExpressionClassifier* classifier, bool* ok) {
3424 // NewExpression ::
3425 // ('new')+ MemberExpression
3426 //
3427 // NewTarget ::
3428 // 'new' '.' 'target'
3429
3430 // The grammar for new expressions is pretty warped. We can have several 'new'
3431 // keywords following each other, and then a MemberExpression. When we see '('
3432 // after the MemberExpression, it's associated with the rightmost unassociated
3433 // 'new' to create a NewExpression with arguments. However, a NewExpression
3434 // can also occur without arguments.
3435
3436 // Examples of new expression:
3437 // new foo.bar().baz means (new (foo.bar)()).baz
3438 // new foo()() means (new foo())()
3439 // new new foo()() means (new (new foo())())
3440 // new new foo means new (new foo)
3441 // new new foo() means new (new foo())
3442 // new new foo().bar().baz means (new (new foo()).bar()).baz
3443
3444 if (peek() == Token::NEW) {
3445 BindingPatternUnexpectedToken(classifier);
3446 ArrowFormalParametersUnexpectedToken(classifier);
3447 Consume(Token::NEW);
3448 int new_pos = position();
3449 ExpressionT result = this->EmptyExpression();
3450 if (peek() == Token::SUPER) {
3451 const bool is_new = true;
3452 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3453 } else if (peek() == Token::PERIOD) {
3454 return ParseNewTargetExpression(CHECK_OK);
3455 } else {
3456 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3457 }
3458 if (peek() == Token::LPAREN) {
3459 // NewExpression with arguments.
3460 Scanner::Location spread_pos;
3461 typename Traits::Type::ExpressionList args =
3462 this->ParseArguments(&spread_pos, classifier, CHECK_OK);
3463
3464 if (spread_pos.IsValid()) {
3465 args = Traits::PrepareSpreadArguments(args);
3466 result = Traits::SpreadCallNew(result, args, new_pos);
3467 } else {
3468 result = factory()->NewCallNew(result, args, new_pos);
3469 }
3470 // The expression can still continue with . or [ after the arguments.
3471 result =
3472 this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
3473 return result;
3474 }
3475 // NewExpression without arguments.
3476 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
3477 new_pos);
3478 }
3479 // No 'new' or 'super' keyword.
3480 return this->ParseMemberExpression(classifier, ok);
3481 }
3482
3483
3484 template <class Traits>
3485 typename ParserBase<Traits>::ExpressionT
3486 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
3487 bool* ok) {
3488 // MemberExpression ::
3489 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
3490 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3491
3492 // The '[' Expression ']' and '.' Identifier parts are parsed by
3493 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3494 // caller.
3495
3496 // Parse the initial primary or function expression.
3497 ExpressionT result = this->EmptyExpression();
3498 if (peek() == Token::FUNCTION) {
3499 BindingPatternUnexpectedToken(classifier);
3500 ArrowFormalParametersUnexpectedToken(classifier);
3501
3502 Consume(Token::FUNCTION);
3503 int function_token_position = position();
3504 bool is_generator = Check(Token::MUL);
3505 IdentifierT name = this->EmptyIdentifier();
3506 bool is_strict_reserved_name = false;
3507 Scanner::Location function_name_location = Scanner::Location::invalid();
3508 FunctionLiteral::FunctionType function_type =
3509 FunctionLiteral::ANONYMOUS_EXPRESSION;
3510 if (peek_any_identifier()) {
3511 name = ParseIdentifierOrStrictReservedWord(
3512 is_generator, &is_strict_reserved_name, CHECK_OK);
3513 function_name_location = scanner()->location();
3514 function_type = FunctionLiteral::NAMED_EXPRESSION;
3515 }
3516 result = this->ParseFunctionLiteral(
3517 name, function_name_location,
3518 is_strict_reserved_name ? kFunctionNameIsStrictReserved
3519 : kFunctionNameValidityUnknown,
3520 is_generator ? FunctionKind::kGeneratorFunction
3521 : FunctionKind::kNormalFunction,
3522 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
3523 language_mode(), CHECK_OK);
3524 } else if (peek() == Token::SUPER) {
3525 const bool is_new = false;
3526 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3527 } else {
3528 result = ParsePrimaryExpression(classifier, CHECK_OK);
3529 }
3530
3531 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
3532 return result;
3533 }
3534
3535
3536 template <class Traits>
3537 typename ParserBase<Traits>::ExpressionT
3538 ParserBase<Traits>::ParseStrongInitializationExpression(
3539 ExpressionClassifier* classifier, bool* ok) {
3540 // InitializationExpression :: (strong mode)
3541 // 'this' '.' IdentifierName '=' AssignmentExpression
3542 // 'this' '[' Expression ']' '=' AssignmentExpression
3543
3544 if (fni_ != NULL) fni_->Enter();
3545
3546 Consume(Token::THIS);
3547 int pos = position();
3548 function_state_->set_this_location(scanner()->location());
3549 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3550
3551 ExpressionT left = this->EmptyExpression();
3552 switch (peek()) {
3553 case Token::LBRACK: {
3554 Consume(Token::LBRACK);
3555 int pos = position();
3556 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3557 left = factory()->NewProperty(this_expr, index, pos);
3558 if (fni_ != NULL) {
3559 this->PushPropertyName(fni_, index);
3560 }
3561 Expect(Token::RBRACK, CHECK_OK);
3562 break;
3563 }
3564 case Token::PERIOD: {
3565 Consume(Token::PERIOD);
3566 int pos = position();
3567 IdentifierT name = ParseIdentifierName(CHECK_OK);
3568 left = factory()->NewProperty(
3569 this_expr, factory()->NewStringLiteral(name, pos), pos);
3570 if (fni_ != NULL) {
3571 this->PushLiteralName(fni_, name);
3572 }
3573 break;
3574 }
3575 default:
3576 ReportMessage(MessageTemplate::kStrongConstructorThis);
3577 *ok = false;
3578 return this->EmptyExpression();
3579 }
3580
3581 if (peek() != Token::ASSIGN) {
3582 ReportMessageAt(function_state_->this_location(),
3583 MessageTemplate::kStrongConstructorThis);
3584 *ok = false;
3585 return this->EmptyExpression();
3586 }
3587 Consume(Token::ASSIGN);
3588 left = this->MarkExpressionAsAssigned(left);
3589
3590 ExpressionT right =
3591 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
3592 this->CheckAssigningFunctionLiteralToProperty(left, right);
3593 function_state_->AddProperty();
3594 if (fni_ != NULL) {
3595 // Check if the right hand side is a call to avoid inferring a
3596 // name if we're dealing with "this.a = function(){...}();"-like
3597 // expression.
3598 if (!right->IsCall() && !right->IsCallNew()) {
3599 fni_->Infer();
3600 } else {
3601 fni_->RemoveLastFunction();
3602 }
3603 fni_->Leave();
3604 }
3605
3606 if (function_state_->return_location().IsValid()) {
3607 ReportMessageAt(function_state_->return_location(),
3608 MessageTemplate::kStrongConstructorReturnMisplaced);
3609 *ok = false;
3610 return this->EmptyExpression();
3611 }
3612
3613 return factory()->NewAssignment(Token::ASSIGN, left, right, pos);
3614 }
3615
3616
3617 template <class Traits>
3618 typename ParserBase<Traits>::ExpressionT
3619 ParserBase<Traits>::ParseStrongSuperCallExpression(
3620 ExpressionClassifier* classifier, bool* ok) {
3621 // SuperCallExpression :: (strong mode)
3622 // 'super' '(' ExpressionList ')'
3623 BindingPatternUnexpectedToken(classifier);
3624
3625 Consume(Token::SUPER);
3626 int pos = position();
3627 Scanner::Location super_loc = scanner()->location();
3628 ExpressionT expr = this->SuperCallReference(scope_, factory(), pos);
3629
3630 if (peek() != Token::LPAREN) {
3631 ReportMessage(MessageTemplate::kStrongConstructorSuper);
3632 *ok = false;
3633 return this->EmptyExpression();
3634 }
3635
3636 Scanner::Location spread_pos;
3637 typename Traits::Type::ExpressionList args =
3638 ParseArguments(&spread_pos, classifier, CHECK_OK);
3639
3640 // TODO(rossberg): This doesn't work with arrow functions yet.
3641 if (!IsSubclassConstructor(function_state_->kind())) {
3642 ReportMessage(MessageTemplate::kUnexpectedSuper);
3643 *ok = false;
3644 return this->EmptyExpression();
3645 } else if (function_state_->super_location().IsValid()) {
3646 ReportMessageAt(scanner()->location(),
3647 MessageTemplate::kStrongSuperCallDuplicate);
3648 *ok = false;
3649 return this->EmptyExpression();
3650 } else if (function_state_->this_location().IsValid()) {
3651 ReportMessageAt(scanner()->location(),
3652 MessageTemplate::kStrongSuperCallMisplaced);
3653 *ok = false;
3654 return this->EmptyExpression();
3655 } else if (function_state_->return_location().IsValid()) {
3656 ReportMessageAt(function_state_->return_location(),
3657 MessageTemplate::kStrongConstructorReturnMisplaced);
3658 *ok = false;
3659 return this->EmptyExpression();
3660 }
3661
3662 function_state_->set_super_location(super_loc);
3663 if (spread_pos.IsValid()) {
3664 args = Traits::PrepareSpreadArguments(args);
3665 expr = Traits::SpreadCall(expr, args, pos);
3666 } else {
3667 expr = factory()->NewCall(expr, args, pos);
3668 }
3669
3670 // Explicit calls to the super constructor using super() perform an implicit
3671 // binding assignment to the 'this' variable.
3672 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3673 return factory()->NewAssignment(Token::INIT, this_expr, expr, pos);
3674 }
3675
3676
3677 template <class Traits>
3678 typename ParserBase<Traits>::ExpressionT
3679 ParserBase<Traits>::ParseSuperExpression(bool is_new,
3680 ExpressionClassifier* classifier,
3681 bool* ok) {
3682 Expect(Token::SUPER, CHECK_OK);
3683 int pos = position();
3684
3685 Scope* scope = scope_->ReceiverScope();
3686 FunctionKind kind = scope->function_kind();
3687 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3688 IsClassConstructor(kind)) {
3689 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3690 scope->RecordSuperPropertyUsage();
3691 return this->SuperPropertyReference(scope_, factory(), pos);
3692 }
3693 // new super() is never allowed.
3694 // super() is only allowed in derived constructor
3695 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
3696 if (is_strong(language_mode())) {
3697 // Super calls in strong mode are parsed separately.
3698 ReportMessageAt(scanner()->location(),
3699 MessageTemplate::kStrongConstructorSuper);
3700 *ok = false;
3701 return this->EmptyExpression();
3702 }
3703 // TODO(rossberg): This might not be the correct FunctionState for the
3704 // method here.
3705 function_state_->set_super_location(scanner()->location());
3706 return this->SuperCallReference(scope_, factory(), pos);
3707 }
3708 }
3709
3710 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
3711 *ok = false;
3712 return this->EmptyExpression();
3713 }
3714
3715
3716 template <class Traits>
3717 typename ParserBase<Traits>::ExpressionT
3718 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
3719 int pos = position();
3720 Consume(Token::PERIOD);
3721 ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
3722
3723 if (!scope_->ReceiverScope()->is_function_scope()) {
3724 ReportMessageAt(scanner()->location(),
3725 MessageTemplate::kUnexpectedNewTarget);
3726 *ok = false;
3727 return this->EmptyExpression();
3728 }
3729
3730 return this->NewTargetExpression(scope_, factory(), pos);
3731 }
3732
3733
3734 template <class Traits>
3735 typename ParserBase<Traits>::ExpressionT
3736 ParserBase<Traits>::ParseMemberExpressionContinuation(
3737 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
3738 // Parses this part of MemberExpression:
3739 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3740 while (true) {
3741 switch (peek()) {
3742 case Token::LBRACK: {
3743 BindingPatternUnexpectedToken(classifier);
3744 ArrowFormalParametersUnexpectedToken(classifier);
3745
3746 Consume(Token::LBRACK);
3747 int pos = position();
3748 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3749 expression = factory()->NewProperty(expression, index, pos);
3750 if (fni_ != NULL) {
3751 this->PushPropertyName(fni_, index);
3752 }
3753 Expect(Token::RBRACK, CHECK_OK);
3754 break;
3755 }
3756 case Token::PERIOD: {
3757 BindingPatternUnexpectedToken(classifier);
3758 ArrowFormalParametersUnexpectedToken(classifier);
3759
3760 Consume(Token::PERIOD);
3761 int pos = position();
3762 IdentifierT name = ParseIdentifierName(CHECK_OK);
3763 expression = factory()->NewProperty(
3764 expression, factory()->NewStringLiteral(name, pos), pos);
3765 if (fni_ != NULL) {
3766 this->PushLiteralName(fni_, name);
3767 }
3768 break;
3769 }
3770 case Token::TEMPLATE_SPAN:
3771 case Token::TEMPLATE_TAIL: {
3772 BindingPatternUnexpectedToken(classifier);
3773 ArrowFormalParametersUnexpectedToken(classifier);
3774 int pos;
3775 if (scanner()->current_token() == Token::IDENTIFIER) {
3776 pos = position();
3777 } else {
3778 pos = peek_position();
3779 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3780 // If the tag function looks like an IIFE, set_parenthesized() to
3781 // force eager compilation.
3782 expression->AsFunctionLiteral()->set_should_eager_compile();
3783 }
3784 }
3785 expression =
3786 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
3787 break;
3788 }
3789 default:
3790 return expression;
3791 }
3792 }
3793 DCHECK(false);
3794 return this->EmptyExpression();
3795 }
3796
3797
3798 template <class Traits>
3799 void ParserBase<Traits>::ParseFormalParameter(
3800 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3801 // FormalParameter[Yield,GeneratorParameter] :
3802 // BindingElement[?Yield, ?GeneratorParameter]
3803 bool is_rest = parameters->has_rest;
3804
3805 Token::Value next = peek();
3806 ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
3807 if (!*ok) return;
3808
3809 ValidateBindingPattern(classifier, ok);
3810 if (!*ok) return;
3811
3812 if (!Traits::IsIdentifier(pattern)) {
3813 if (is_rest || !allow_harmony_destructuring_bind()) {
3814 ReportUnexpectedToken(next);
3815 *ok = false;
3816 return;
3817 }
3818 parameters->is_simple = false;
3819 ValidateFormalParameterInitializer(classifier, ok);
3820 if (!*ok) return;
3821 classifier->RecordNonSimpleParameter();
3822 }
3823
3824 if (is_rest) {
3825 parameters->rest_array_literal_index =
3826 function_state_->NextMaterializedLiteralIndex();
3827 ++parameters->materialized_literals_count;
3828 }
3829
3830 ExpressionT initializer = Traits::EmptyExpression();
3831 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
3832 ExpressionClassifier init_classifier;
3833 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3834 if (!*ok) return;
3835 ValidateExpression(&init_classifier, ok);
3836 ValidateFormalParameterInitializer(&init_classifier, ok);
3837 if (!*ok) return;
3838 parameters->is_simple = false;
3839 classifier->RecordNonSimpleParameter();
3840 }
3841
3842 Traits::AddFormalParameter(parameters, pattern, initializer,
3843 scanner()->location().end_pos, is_rest);
3844 }
3845
3846
3847 template <class Traits>
3848 void ParserBase<Traits>::ParseFormalParameterList(
3849 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3850 // FormalParameters[Yield,GeneratorParameter] :
3851 // [empty]
3852 // FormalParameterList[?Yield, ?GeneratorParameter]
3853 //
3854 // FormalParameterList[Yield,GeneratorParameter] :
3855 // FunctionRestParameter[?Yield]
3856 // FormalsList[?Yield, ?GeneratorParameter]
3857 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
3858 //
3859 // FormalsList[Yield,GeneratorParameter] :
3860 // FormalParameter[?Yield, ?GeneratorParameter]
3861 // FormalsList[?Yield, ?GeneratorParameter] ,
3862 // FormalParameter[?Yield,?GeneratorParameter]
3863
3864 DCHECK_EQ(0, parameters->Arity());
3865
3866 if (peek() != Token::RPAREN) {
3867 do {
3868 if (parameters->Arity() > Code::kMaxArguments) {
3869 ReportMessage(MessageTemplate::kTooManyParameters);
3870 *ok = false;
3871 return;
3872 }
3873 parameters->has_rest =
3874 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
3875 ParseFormalParameter(parameters, classifier, ok);
3876 if (!*ok) return;
3877 } while (!parameters->has_rest && Check(Token::COMMA));
3878
3879 if (parameters->has_rest) {
3880 parameters->is_simple = false;
3881 classifier->RecordNonSimpleParameter();
3882 if (peek() == Token::COMMA) {
3883 ReportMessageAt(scanner()->peek_location(),
3884 MessageTemplate::kParamAfterRest);
3885 *ok = false;
3886 return;
3887 }
3888 }
3889 }
3890
3891 for (int i = 0; i < parameters->Arity(); ++i) {
3892 auto parameter = parameters->at(i);
3893 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
3894 }
3895 }
3896
3897
3898 template <class Traits>
3899 void ParserBase<Traits>::CheckArityRestrictions(
3900 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
3901 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
3902 switch (arity_restriction) {
3903 case FunctionLiteral::GETTER_ARITY:
3904 if (param_count != 0) {
3905 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3906 MessageTemplate::kBadGetterArity);
3907 *ok = false;
3908 }
3909 break;
3910 case FunctionLiteral::SETTER_ARITY:
3911 if (param_count != 1) {
3912 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3913 MessageTemplate::kBadSetterArity);
3914 *ok = false;
3915 }
3916 if (has_rest) {
3917 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3918 MessageTemplate::kBadSetterRestParameter);
3919 *ok = false;
3920 }
3921 break;
3922 default:
3923 break;
3924 }
3925 }
3926
3927
3928 template <class Traits>
3929 bool ParserBase<Traits>::IsNextLetKeyword() {
3930 DCHECK(peek() == Token::LET);
3931 if (!allow_let()) {
3932 return false;
3933 }
3934 Token::Value next_next = PeekAhead();
3935 switch (next_next) {
3936 case Token::LBRACE:
3937 case Token::LBRACK:
3938 case Token::IDENTIFIER:
3939 case Token::STATIC:
3940 case Token::LET: // Yes, you can do let let = ... in sloppy mode
3941 case Token::YIELD:
3942 return true;
3943 default:
3944 return false;
3945 }
3946 }
3947
3948
3949 template <class Traits>
3950 typename ParserBase<Traits>::ExpressionT
3951 ParserBase<Traits>::ParseArrowFunctionLiteral(
3952 bool accept_IN, const FormalParametersT& formal_parameters,
3953 const ExpressionClassifier& formals_classifier, bool* ok) {
3954 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3955 // ASI inserts `;` after arrow parameters if a line terminator is found.
3956 // `=> ...` is never a valid expression, so report as syntax error.
3957 // If next token is not `=>`, it's a syntax error anyways.
3958 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3959 *ok = false;
3960 return this->EmptyExpression();
3961 }
3962
3963 typename Traits::Type::StatementList body;
3964 int num_parameters = formal_parameters.scope->num_parameters();
3965 int materialized_literal_count = -1;
3966 int expected_property_count = -1;
3967 Scanner::Location super_loc;
3968
3969 {
3970 typename Traits::Type::Factory function_factory(ast_value_factory());
3971 FunctionState function_state(&function_state_, &scope_,
3972 formal_parameters.scope, kArrowFunction,
3973 &function_factory);
3974
3975 function_state.SkipMaterializedLiterals(
3976 formal_parameters.materialized_literals_count);
3977
3978 this->ReindexLiterals(formal_parameters);
3979
3980 Expect(Token::ARROW, CHECK_OK);
3981
3982 if (peek() == Token::LBRACE) {
3983 // Multiple statement body
3984 Consume(Token::LBRACE);
3985 bool is_lazily_parsed =
3986 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
3987 if (is_lazily_parsed) {
3988 body = this->NewStatementList(0, zone());
3989 this->SkipLazyFunctionBody(&materialized_literal_count,
3990 &expected_property_count, CHECK_OK);
3991
3992 if (formal_parameters.materialized_literals_count > 0) {
3993 materialized_literal_count +=
3994 formal_parameters.materialized_literals_count;
3995 }
3996 } else {
3997 body = this->ParseEagerFunctionBody(
3998 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
3999 kArrowFunction, FunctionLiteral::ANONYMOUS_EXPRESSION, CHECK_OK);
4000 materialized_literal_count =
4001 function_state.materialized_literal_count();
4002 expected_property_count = function_state.expected_property_count();
4003 }
4004 } else {
4005 // Single-expression body
4006 int pos = position();
4007 parenthesized_function_ = false;
4008 ExpressionClassifier classifier;
4009 ExpressionT expression =
4010 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
4011 ValidateExpression(&classifier, CHECK_OK);
4012 body = this->NewStatementList(1, zone());
4013 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
4014 body->Add(factory()->NewReturnStatement(expression, pos), zone());
4015 materialized_literal_count = function_state.materialized_literal_count();
4016 expected_property_count = function_state.expected_property_count();
4017 }
4018 super_loc = function_state.super_location();
4019
4020 formal_parameters.scope->set_end_position(scanner()->location().end_pos);
4021
4022 // Arrow function formal parameters are parsed as StrictFormalParameterList,
4023 // which is not the same as "parameters of a strict function"; it only means
4024 // that duplicates are not allowed. Of course, the arrow function may
4025 // itself be strict as well.
4026 const bool allow_duplicate_parameters = false;
4027 this->ValidateFormalParameters(&formals_classifier, language_mode(),
4028 allow_duplicate_parameters, CHECK_OK);
4029
4030 // Validate strict mode.
4031 if (is_strict(language_mode())) {
4032 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
4033 scanner()->location().end_pos, CHECK_OK);
4034 }
4035 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
4036 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
4037 }
4038 }
4039
4040 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
4041 this->EmptyIdentifierString(), ast_value_factory(),
4042 formal_parameters.scope, body, materialized_literal_count,
4043 expected_property_count, num_parameters,
4044 FunctionLiteral::kNoDuplicateParameters,
4045 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
4046 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
4047 formal_parameters.scope->start_position());
4048
4049 function_literal->set_function_token_position(
4050 formal_parameters.scope->start_position());
4051 if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
4052
4053 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
4054
4055 return function_literal;
4056 }
4057
4058
4059 template <typename Traits>
4060 typename ParserBase<Traits>::ExpressionT
4061 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
4062 ExpressionClassifier* classifier,
4063 bool* ok) {
4064 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
4065 // text followed by a substitution expression), finalized by a single
4066 // TEMPLATE_TAIL.
4067 //
4068 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
4069 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
4070 // NoSubstitutionTemplate.
4071 //
4072 // When parsing a TemplateLiteral, we must have scanned either an initial
4073 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
4074 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4075
4076 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
4077 // In this case we may simply consume the token and build a template with a
4078 // single TEMPLATE_SPAN and no expressions.
4079 if (peek() == Token::TEMPLATE_TAIL) {
4080 Consume(Token::TEMPLATE_TAIL);
4081 int pos = position();
4082 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4083 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
4084 Traits::AddTemplateSpan(&ts, true);
4085 return Traits::CloseTemplateLiteral(&ts, start, tag);
4086 }
4087
4088 Consume(Token::TEMPLATE_SPAN);
4089 int pos = position();
4090 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
4091 Traits::AddTemplateSpan(&ts, false);
4092 Token::Value next;
4093
4094 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
4095 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
4096 // case, representing a TemplateMiddle).
4097
4098 do {
4099 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4100 next = peek();
4101 if (next == Token::EOS) {
4102 ReportMessageAt(Scanner::Location(start, peek_position()),
4103 MessageTemplate::kUnterminatedTemplate);
4104 *ok = false;
4105 return Traits::EmptyExpression();
4106 } else if (next == Token::ILLEGAL) {
4107 Traits::ReportMessageAt(
4108 Scanner::Location(position() + 1, peek_position()),
4109 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4110 *ok = false;
4111 return Traits::EmptyExpression();
4112 }
4113
4114 int expr_pos = peek_position();
4115 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
4116 Traits::AddTemplateExpression(&ts, expression);
4117
4118 if (peek() != Token::RBRACE) {
4119 ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
4120 MessageTemplate::kUnterminatedTemplateExpr);
4121 *ok = false;
4122 return Traits::EmptyExpression();
4123 }
4124
4125 // If we didn't die parsing that expression, our next token should be a
4126 // TEMPLATE_SPAN or TEMPLATE_TAIL.
4127 next = scanner()->ScanTemplateContinuation();
4128 Next();
4129 pos = position();
4130
4131 if (next == Token::EOS) {
4132 ReportMessageAt(Scanner::Location(start, pos),
4133 MessageTemplate::kUnterminatedTemplate);
4134 *ok = false;
4135 return Traits::EmptyExpression();
4136 } else if (next == Token::ILLEGAL) {
4137 Traits::ReportMessageAt(
4138 Scanner::Location(position() + 1, peek_position()),
4139 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4140 *ok = false;
4141 return Traits::EmptyExpression();
4142 }
4143
4144 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
4145 } while (next == Token::TEMPLATE_SPAN);
4146
4147 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
4148 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4149 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4150 return Traits::CloseTemplateLiteral(&ts, start, tag);
4151 }
4152
4153
4154 template <typename Traits>
4155 typename ParserBase<Traits>::ExpressionT
4156 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
4157 ExpressionT expression, int beg_pos, int end_pos,
4158 MessageTemplate::Template message, bool* ok) {
4159 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
4160 message, kReferenceError, ok);
4161 }
4162
4163
4164 template <typename Traits>
4165 typename ParserBase<Traits>::ExpressionT
4166 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
4167 ExpressionT expression, int beg_pos, int end_pos,
4168 MessageTemplate::Template message, ParseErrorType type, bool* ok) {
4169 Scanner::Location location(beg_pos, end_pos);
4170 if (this->IsIdentifier(expression)) {
4171 if (is_strict(language_mode()) &&
4172 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
4173 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments,
4174 kSyntaxError);
4175 *ok = false;
4176 return this->EmptyExpression();
4177 }
4178 if (is_strong(language_mode()) &&
4179 this->IsUndefined(this->AsIdentifier(expression))) {
4180 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined,
4181 kSyntaxError);
4182 *ok = false;
4183 return this->EmptyExpression();
4184 }
4185 }
4186 if (expression->IsValidReferenceExpression()) {
4187 return expression;
4188 } else if (expression->IsCall()) {
4189 // If it is a call, make it a runtime error for legacy web compatibility.
4190 // Rewrite `expr' to `expr[throw ReferenceError]'.
4191 int pos = location.beg_pos;
4192 ExpressionT error = this->NewThrowReferenceError(message, pos);
4193 return factory()->NewProperty(expression, error, pos);
4194 } else {
4195 this->ReportMessageAt(location, message, type);
4196 *ok = false;
4197 return this->EmptyExpression();
4198 }
4199 }
4200
4201
4202 #undef CHECK_OK
4203 #undef CHECK_OK_CUSTOM
4204
4205
4206 template <typename Traits>
4207 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
4208 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
4209 bool* ok) {
4210 DCHECK(!is_static);
4211 DCHECK(!is_generator || type == kMethodProperty);
4212
4213 if (property == Token::SMI || property == Token::NUMBER) return;
4214
4215 if (type == kValueProperty && IsProto()) {
4216 if (has_seen_proto_) {
4217 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
4218 *ok = false;
4219 return;
4220 }
4221 has_seen_proto_ = true;
4222 return;
4223 }
4224 }
4225
4226
4227 template <typename Traits>
4228 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
4229 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
4230 bool* ok) {
4231 DCHECK(type == kMethodProperty || type == kAccessorProperty);
4232
4233 if (property == Token::SMI || property == Token::NUMBER) return;
4234
4235 if (is_static) {
4236 if (IsPrototype()) {
4237 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
4238 *ok = false;
4239 return;
4240 }
4241 } else if (IsConstructor()) {
4242 if (is_generator || type == kAccessorProperty) {
4243 MessageTemplate::Template msg =
4244 is_generator ? MessageTemplate::kConstructorIsGenerator
4245 : MessageTemplate::kConstructorIsAccessor;
4246 this->parser()->ReportMessage(msg);
4247 *ok = false;
4248 return;
4249 }
4250 if (has_seen_constructor_) {
4251 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
4252 *ok = false;
4253 return;
4254 }
4255 has_seen_constructor_ = true;
4256 return;
4257 }
4258 }
4259 } // namespace internal
4260 } // namespace v8
4261
4262 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/preparse-data-format.h ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698