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

Side by Side Diff: src/preparser.h

Issue 1233913008: Split off ParserBase into src/parser-base.h (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Copy whole ParserBase, not just the class Created 5 years, 5 months 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/parser-base.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
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/bailout-reason.h"
11 #include "src/expression-classifier.h" 10 #include "src/expression-classifier.h"
12 #include "src/func-name-inferrer.h" 11 #include "src/func-name-inferrer.h"
13 #include "src/hashmap.h"
14 #include "src/messages.h" 12 #include "src/messages.h"
13 #include "src/parser-base.h"
15 #include "src/scanner.h" 14 #include "src/scanner.h"
16 #include "src/scopes.h" 15 #include "src/scopes.h"
17 #include "src/token.h" 16 #include "src/token.h"
18 17
19 namespace v8 { 18 namespace v8 {
20 namespace internal { 19 namespace internal {
21 20
22
23 enum FunctionNameValidity {
24 kFunctionNameIsStrictReserved,
25 kSkipFunctionNameCheck,
26 kFunctionNameValidityUnknown
27 };
28
29
30 // Common base class shared between parser and pre-parser. Traits encapsulate
31 // the differences between Parser and PreParser:
32
33 // - Return types: For example, Parser functions return Expression* and
34 // PreParser functions return PreParserExpression.
35
36 // - Creating parse tree nodes: Parser generates an AST during the recursive
37 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
38 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
39 // just enough data for the upper layer functions. PreParserFactory is
40 // responsible for creating these dummy objects. It provides a similar kind of
41 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
42 // used.
43
44 // - Miscellaneous other tasks interleaved with the recursive descent. For
45 // example, Parser keeps track of which function literals should be marked as
46 // pretenured, and PreParser doesn't care.
47
48 // The traits are expected to contain the following typedefs:
49 // struct Traits {
50 // // In particular...
51 // struct Type {
52 // // Used by FunctionState and BlockState.
53 // typedef Scope;
54 // typedef GeneratorVariable;
55 // // Return types for traversing functions.
56 // typedef Identifier;
57 // typedef Expression;
58 // typedef FunctionLiteral;
59 // typedef ClassLiteral;
60 // typedef ObjectLiteralProperty;
61 // typedef Literal;
62 // typedef ExpressionList;
63 // typedef PropertyList;
64 // typedef FormalParameter;
65 // // For constructing objects returned by the traversing functions.
66 // typedef Factory;
67 // };
68 // // ...
69 // };
70
71 template <typename Traits>
72 class ParserBase : public Traits {
73 public:
74 // Shorten type names defined by Traits.
75 typedef typename Traits::Type::Expression ExpressionT;
76 typedef typename Traits::Type::Identifier IdentifierT;
77 typedef typename Traits::Type::FormalParameter FormalParameterT;
78 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
79 typedef typename Traits::Type::Literal LiteralT;
80 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
81 typedef typename Traits::Type::FormalParameterParsingState
82 FormalParameterParsingStateT;
83
84 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
85 v8::Extension* extension, AstValueFactory* ast_value_factory,
86 ParserRecorder* log, typename Traits::Type::Parser this_object)
87 : Traits(this_object),
88 parenthesized_function_(false),
89 scope_(NULL),
90 function_state_(NULL),
91 extension_(extension),
92 fni_(NULL),
93 ast_value_factory_(ast_value_factory),
94 log_(log),
95 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
96 stack_limit_(stack_limit),
97 zone_(zone),
98 scanner_(scanner),
99 stack_overflow_(false),
100 allow_lazy_(false),
101 allow_natives_(false),
102 allow_harmony_arrow_functions_(false),
103 allow_harmony_sloppy_(false),
104 allow_harmony_computed_property_names_(false),
105 allow_harmony_rest_params_(false),
106 allow_harmony_spreadcalls_(false),
107 allow_harmony_destructuring_(false),
108 allow_harmony_spread_arrays_(false),
109 allow_harmony_new_target_(false),
110 allow_strong_mode_(false),
111 allow_legacy_const_(true) {}
112
113 #define ALLOW_ACCESSORS(name) \
114 bool allow_##name() const { return allow_##name##_; } \
115 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
116
117 ALLOW_ACCESSORS(lazy);
118 ALLOW_ACCESSORS(natives);
119 ALLOW_ACCESSORS(harmony_arrow_functions);
120 ALLOW_ACCESSORS(harmony_sloppy);
121 ALLOW_ACCESSORS(harmony_computed_property_names);
122 ALLOW_ACCESSORS(harmony_rest_params);
123 ALLOW_ACCESSORS(harmony_spreadcalls);
124 ALLOW_ACCESSORS(harmony_destructuring);
125 ALLOW_ACCESSORS(harmony_spread_arrays);
126 ALLOW_ACCESSORS(harmony_new_target);
127 ALLOW_ACCESSORS(strong_mode);
128 ALLOW_ACCESSORS(legacy_const);
129 #undef ALLOW_ACCESSORS
130
131 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); }
132 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
133
134 void set_allow_harmony_modules(bool a) { scanner()->SetHarmonyModules(a); }
135 void set_allow_harmony_unicode(bool a) { scanner()->SetHarmonyUnicode(a); }
136
137 protected:
138 enum AllowRestrictedIdentifiers {
139 kAllowRestrictedIdentifiers,
140 kDontAllowRestrictedIdentifiers
141 };
142
143 enum Mode {
144 PARSE_LAZILY,
145 PARSE_EAGERLY
146 };
147
148 enum VariableDeclarationContext {
149 kStatementListItem,
150 kStatement,
151 kForStatement
152 };
153
154 class Checkpoint;
155 class ObjectLiteralCheckerBase;
156
157 // ---------------------------------------------------------------------------
158 // FunctionState and BlockState together implement the parser's scope stack.
159 // The parser's current scope is in scope_. BlockState and FunctionState
160 // constructors push on the scope stack and the destructors pop. They are also
161 // used to hold the parser's per-function and per-block state.
162 class BlockState BASE_EMBEDDED {
163 public:
164 BlockState(Scope** scope_stack, Scope* scope)
165 : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
166 *scope_stack_ = scope;
167 }
168 ~BlockState() { *scope_stack_ = outer_scope_; }
169
170 private:
171 Scope** scope_stack_;
172 Scope* outer_scope_;
173 };
174
175 class FunctionState BASE_EMBEDDED {
176 public:
177 FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
178 Scope* scope, FunctionKind kind,
179 typename Traits::Type::Factory* factory);
180 ~FunctionState();
181
182 int NextMaterializedLiteralIndex() {
183 return next_materialized_literal_index_++;
184 }
185 int materialized_literal_count() {
186 return next_materialized_literal_index_;
187 }
188
189 void SkipMaterializedLiterals(int count) {
190 next_materialized_literal_index_ += count;
191 }
192
193 void AddProperty() { expected_property_count_++; }
194 int expected_property_count() { return expected_property_count_; }
195
196 Scanner::Location this_location() const { return this_location_; }
197 Scanner::Location super_location() const { return super_location_; }
198 Scanner::Location return_location() const { return return_location_; }
199 void set_this_location(Scanner::Location location) {
200 this_location_ = location;
201 }
202 void set_super_location(Scanner::Location location) {
203 super_location_ = location;
204 }
205 void set_return_location(Scanner::Location location) {
206 return_location_ = location;
207 }
208
209 bool is_generator() const { return IsGeneratorFunction(kind_); }
210
211 FunctionKind kind() const { return kind_; }
212 FunctionState* outer() const { return outer_function_state_; }
213
214 void set_generator_object_variable(
215 typename Traits::Type::GeneratorVariable* variable) {
216 DCHECK(variable != NULL);
217 DCHECK(is_generator());
218 generator_object_variable_ = variable;
219 }
220 typename Traits::Type::GeneratorVariable* generator_object_variable()
221 const {
222 return generator_object_variable_;
223 }
224
225 typename Traits::Type::Factory* factory() { return factory_; }
226
227 private:
228 // Used to assign an index to each literal that needs materialization in
229 // the function. Includes regexp literals, and boilerplate for object and
230 // array literals.
231 int next_materialized_literal_index_;
232
233 // Properties count estimation.
234 int expected_property_count_;
235
236 // Location of most recent use of 'this' (invalid if none).
237 Scanner::Location this_location_;
238
239 // Location of most recent 'return' statement (invalid if none).
240 Scanner::Location return_location_;
241
242 // Location of call to the "super" constructor (invalid if none).
243 Scanner::Location super_location_;
244
245 FunctionKind kind_;
246 // For generators, this variable may hold the generator object. It variable
247 // is used by yield expressions and return statements. It is not necessary
248 // for generator functions to have this variable set.
249 Variable* generator_object_variable_;
250
251 FunctionState** function_state_stack_;
252 FunctionState* outer_function_state_;
253 Scope** scope_stack_;
254 Scope* outer_scope_;
255 typename Traits::Type::Factory* factory_;
256
257 friend class ParserTraits;
258 friend class Checkpoint;
259 };
260
261 // Annoyingly, arrow functions first parse as comma expressions, then when we
262 // see the => we have to go back and reinterpret the arguments as being formal
263 // parameters. To do so we need to reset some of the parser state back to
264 // what it was before the arguments were first seen.
265 class Checkpoint BASE_EMBEDDED {
266 public:
267 explicit Checkpoint(ParserBase* parser) {
268 function_state_ = parser->function_state_;
269 next_materialized_literal_index_ =
270 function_state_->next_materialized_literal_index_;
271 expected_property_count_ = function_state_->expected_property_count_;
272 }
273
274 void Restore(int* materialized_literal_index_delta) {
275 *materialized_literal_index_delta =
276 function_state_->next_materialized_literal_index_ -
277 next_materialized_literal_index_;
278 function_state_->next_materialized_literal_index_ =
279 next_materialized_literal_index_;
280 function_state_->expected_property_count_ = expected_property_count_;
281 }
282
283 private:
284 FunctionState* function_state_;
285 int next_materialized_literal_index_;
286 int expected_property_count_;
287 };
288
289 class ParsingModeScope BASE_EMBEDDED {
290 public:
291 ParsingModeScope(ParserBase* parser, Mode mode)
292 : parser_(parser),
293 old_mode_(parser->mode()) {
294 parser_->mode_ = mode;
295 }
296 ~ParsingModeScope() {
297 parser_->mode_ = old_mode_;
298 }
299
300 private:
301 ParserBase* parser_;
302 Mode old_mode_;
303 };
304
305 Scope* NewScope(Scope* parent, ScopeType scope_type) {
306 // Must always pass the function kind for FUNCTION_SCOPE and ARROW_SCOPE.
307 DCHECK(scope_type != FUNCTION_SCOPE);
308 DCHECK(scope_type != ARROW_SCOPE);
309 return NewScope(parent, scope_type, kNormalFunction);
310 }
311
312 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
313 DCHECK(ast_value_factory());
314 DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules());
315 DCHECK(!IsArrowFunction(kind) || scope_type == ARROW_SCOPE);
316 Scope* result = new (zone())
317 Scope(zone(), parent, scope_type, ast_value_factory(), kind);
318 result->Initialize();
319 return result;
320 }
321
322 Scanner* scanner() const { return scanner_; }
323 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
324 int position() { return scanner_->location().beg_pos; }
325 int peek_position() { return scanner_->peek_location().beg_pos; }
326 bool stack_overflow() const { return stack_overflow_; }
327 void set_stack_overflow() { stack_overflow_ = true; }
328 Mode mode() const { return mode_; }
329 Zone* zone() const { return zone_; }
330
331 INLINE(Token::Value peek()) {
332 if (stack_overflow_) return Token::ILLEGAL;
333 return scanner()->peek();
334 }
335
336 INLINE(Token::Value Next()) {
337 if (stack_overflow_) return Token::ILLEGAL;
338 {
339 if (GetCurrentStackPosition() < stack_limit_) {
340 // Any further calls to Next or peek will return the illegal token.
341 // The current call must return the next token, which might already
342 // have been peek'ed.
343 stack_overflow_ = true;
344 }
345 }
346 return scanner()->Next();
347 }
348
349 void Consume(Token::Value token) {
350 Token::Value next = Next();
351 USE(next);
352 USE(token);
353 DCHECK(next == token);
354 }
355
356 bool Check(Token::Value token) {
357 Token::Value next = peek();
358 if (next == token) {
359 Consume(next);
360 return true;
361 }
362 return false;
363 }
364
365 void Expect(Token::Value token, bool* ok) {
366 Token::Value next = Next();
367 if (next != token) {
368 ReportUnexpectedToken(next);
369 *ok = false;
370 }
371 }
372
373 void ExpectSemicolon(bool* ok) {
374 // Check for automatic semicolon insertion according to
375 // the rules given in ECMA-262, section 7.9, page 21.
376 Token::Value tok = peek();
377 if (tok == Token::SEMICOLON) {
378 Next();
379 return;
380 }
381 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
382 tok == Token::RBRACE ||
383 tok == Token::EOS) {
384 return;
385 }
386 Expect(Token::SEMICOLON, ok);
387 }
388
389 bool peek_any_identifier() {
390 Token::Value next = peek();
391 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
392 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
393 next == Token::STATIC || next == Token::YIELD;
394 }
395
396 bool CheckContextualKeyword(Vector<const char> keyword) {
397 if (PeekContextualKeyword(keyword)) {
398 Consume(Token::IDENTIFIER);
399 return true;
400 }
401 return false;
402 }
403
404 bool PeekContextualKeyword(Vector<const char> keyword) {
405 return peek() == Token::IDENTIFIER &&
406 scanner()->is_next_contextual_keyword(keyword);
407 }
408
409 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
410 Expect(Token::IDENTIFIER, ok);
411 if (!*ok) return;
412 if (!scanner()->is_literal_contextual_keyword(keyword)) {
413 ReportUnexpectedToken(scanner()->current_token());
414 *ok = false;
415 }
416 }
417
418 bool CheckInOrOf(
419 bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) {
420 if (Check(Token::IN)) {
421 if (is_strong(language_mode())) {
422 ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn);
423 *ok = false;
424 } else {
425 *visit_mode = ForEachStatement::ENUMERATE;
426 }
427 return true;
428 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
429 *visit_mode = ForEachStatement::ITERATE;
430 return true;
431 }
432 return false;
433 }
434
435 // Checks whether an octal literal was last seen between beg_pos and end_pos.
436 // If so, reports an error. Only called for strict mode and template strings.
437 void CheckOctalLiteral(int beg_pos, int end_pos,
438 MessageTemplate::Template message, bool* ok) {
439 Scanner::Location octal = scanner()->octal_position();
440 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
441 octal.end_pos <= end_pos) {
442 ReportMessageAt(octal, message);
443 scanner()->clear_octal_position();
444 *ok = false;
445 }
446 }
447
448 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
449 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
450 ok);
451 }
452
453 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
454 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
455 ok);
456 }
457
458 // Checking the name of a function literal. This has to be done after parsing
459 // the function, since the function can declare itself strict.
460 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
461 FunctionNameValidity function_name_validity,
462 const Scanner::Location& function_name_loc, bool* ok) {
463 if (function_name_validity == kSkipFunctionNameCheck) return;
464 // The function name needs to be checked in strict mode.
465 if (is_sloppy(language_mode)) return;
466
467 if (this->IsEvalOrArguments(function_name)) {
468 Traits::ReportMessageAt(function_name_loc,
469 MessageTemplate::kStrictEvalArguments);
470 *ok = false;
471 return;
472 }
473 if (function_name_validity == kFunctionNameIsStrictReserved) {
474 Traits::ReportMessageAt(function_name_loc,
475 MessageTemplate::kUnexpectedStrictReserved);
476 *ok = false;
477 return;
478 }
479 if (is_strong(language_mode) && this->IsUndefined(function_name)) {
480 Traits::ReportMessageAt(function_name_loc,
481 MessageTemplate::kStrongUndefined);
482 *ok = false;
483 return;
484 }
485 }
486
487 // Determine precedence of given token.
488 static int Precedence(Token::Value token, bool accept_IN) {
489 if (token == Token::IN && !accept_IN)
490 return 0; // 0 precedence will terminate binary expression parsing
491 return Token::Precedence(token);
492 }
493
494 typename Traits::Type::Factory* factory() {
495 return function_state_->factory();
496 }
497
498 LanguageMode language_mode() { return scope_->language_mode(); }
499 bool is_generator() const { return function_state_->is_generator(); }
500
501 bool allow_const() {
502 return is_strict(language_mode()) || allow_harmony_sloppy() ||
503 allow_legacy_const();
504 }
505
506 bool allow_let() {
507 return is_strict(language_mode()) || allow_harmony_sloppy();
508 }
509
510 // Report syntax errors.
511 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
512 ParseErrorType error_type = kSyntaxError) {
513 Scanner::Location source_location = scanner()->location();
514 Traits::ReportMessageAt(source_location, message, arg, error_type);
515 }
516
517 void ReportMessageAt(Scanner::Location location,
518 MessageTemplate::Template message,
519 ParseErrorType error_type = kSyntaxError) {
520 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
521 error_type);
522 }
523
524 void GetUnexpectedTokenMessage(
525 Token::Value token, MessageTemplate::Template* message, const char** arg,
526 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
527
528 void ReportUnexpectedToken(Token::Value token);
529 void ReportUnexpectedTokenAt(
530 Scanner::Location location, Token::Value token,
531 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
532
533
534 void ReportClassifierError(const ExpressionClassifier::Error& error) {
535 Traits::ReportMessageAt(error.location, error.message, error.arg,
536 kSyntaxError);
537 }
538
539 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
540 if (!classifier->is_valid_expression()) {
541 ReportClassifierError(classifier->expression_error());
542 *ok = false;
543 }
544 }
545
546 void ValidateBindingPattern(const ExpressionClassifier* classifier,
547 bool* ok) {
548 if (!classifier->is_valid_binding_pattern()) {
549 ReportClassifierError(classifier->binding_pattern_error());
550 *ok = false;
551 }
552 }
553
554 void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
555 bool* ok) {
556 if (!classifier->is_valid_assignment_pattern()) {
557 ReportClassifierError(classifier->assignment_pattern_error());
558 *ok = false;
559 }
560 }
561
562 void ValidateFormalParameters(const ExpressionClassifier* classifier,
563 LanguageMode language_mode,
564 bool allow_duplicates, bool* ok) {
565 if (!allow_duplicates &&
566 !classifier->is_valid_formal_parameter_list_without_duplicates()) {
567 ReportClassifierError(classifier->duplicate_formal_parameter_error());
568 *ok = false;
569 } else if (is_strict(language_mode) &&
570 !classifier->is_valid_strict_mode_formal_parameters()) {
571 ReportClassifierError(classifier->strict_mode_formal_parameter_error());
572 *ok = false;
573 } else if (is_strong(language_mode) &&
574 !classifier->is_valid_strong_mode_formal_parameters()) {
575 ReportClassifierError(classifier->strong_mode_formal_parameter_error());
576 *ok = false;
577 }
578 }
579
580 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
581 ExpressionT expr,
582 bool parenthesized_formals, bool* ok) {
583 if (classifier->is_valid_binding_pattern()) {
584 // A simple arrow formal parameter: IDENTIFIER => BODY.
585 if (!this->IsIdentifier(expr)) {
586 Traits::ReportMessageAt(scanner()->location(),
587 MessageTemplate::kUnexpectedToken,
588 Token::String(scanner()->current_token()));
589 *ok = false;
590 }
591 } else if (!classifier->is_valid_arrow_formal_parameters()) {
592 // If after parsing the expr, we see an error but the expression is
593 // neither a valid binding pattern nor a valid parenthesized formal
594 // parameter list, show the "arrow formal parameters" error if the formals
595 // started with a parenthesis, and the binding pattern error otherwise.
596 const ExpressionClassifier::Error& error =
597 parenthesized_formals ? classifier->arrow_formal_parameters_error()
598 : classifier->binding_pattern_error();
599 ReportClassifierError(error);
600 *ok = false;
601 }
602 }
603
604 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
605 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
606 const char* arg;
607 GetUnexpectedTokenMessage(peek(), &message, &arg);
608 classifier->RecordExpressionError(scanner()->peek_location(), message, arg);
609 }
610
611 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
612 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
613 const char* arg;
614 GetUnexpectedTokenMessage(peek(), &message, &arg);
615 classifier->RecordBindingPatternError(scanner()->peek_location(), message,
616 arg);
617 }
618
619 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
620 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
621 const char* arg;
622 GetUnexpectedTokenMessage(peek(), &message, &arg);
623 classifier->RecordArrowFormalParametersError(scanner()->peek_location(),
624 message, arg);
625 }
626
627 // Recursive descent functions:
628
629 // Parses an identifier that is valid for the current scope, in particular it
630 // fails on strict mode future reserved keywords in a strict scope. If
631 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
632 // "arguments" as identifier even in strict mode (this is needed in cases like
633 // "var foo = eval;").
634 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
635 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
636 bool* ok);
637 // Parses an identifier or a strict mode future reserved word, and indicate
638 // whether it is strict mode future reserved.
639 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
640 bool* ok);
641 IdentifierT ParseIdentifierName(bool* ok);
642 // Parses an identifier and determines whether or not it is 'get' or 'set'.
643 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
644 bool* ok);
645
646
647 ExpressionT ParseRegExpLiteral(bool seen_equal,
648 ExpressionClassifier* classifier, bool* ok);
649
650 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
651 bool* ok);
652 ExpressionT ParseExpression(bool accept_IN, bool* ok);
653 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
654 bool* ok);
655 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
656 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
657 bool* is_static, bool* is_computed_name,
658 ExpressionClassifier* classifier, bool* ok);
659 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
660 ObjectLiteralPropertyT ParsePropertyDefinition(
661 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
662 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
663 ExpressionClassifier* classifier, bool* ok);
664 typename Traits::Type::ExpressionList ParseArguments(
665 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
666 bool* ok);
667 ExpressionT ParseAssignmentExpression(bool accept_IN,
668 ExpressionClassifier* classifier,
669 bool* ok);
670 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
671 ExpressionT ParseConditionalExpression(bool accept_IN,
672 ExpressionClassifier* classifier,
673 bool* ok);
674 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
675 ExpressionClassifier* classifier, bool* ok);
676 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
677 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
678 bool* ok);
679 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
680 bool* ok);
681 ExpressionT ParseMemberWithNewPrefixesExpression(
682 ExpressionClassifier* classifier, bool* ok);
683 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
684 ExpressionT ParseMemberExpressionContinuation(
685 ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
686 ExpressionT ParseArrowFunctionLiteral(
687 const FormalParameterParsingStateT& parsing_state,
688 const ExpressionClassifier& classifier, bool* ok);
689 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
690 ExpressionClassifier* classifier, bool* ok);
691 void AddTemplateExpression(ExpressionT);
692 ExpressionT ParseSuperExpression(bool is_new,
693 ExpressionClassifier* classifier, bool* ok);
694 ExpressionT ParseNewTargetExpression(bool* ok);
695 ExpressionT ParseStrongInitializationExpression(
696 ExpressionClassifier* classifier, bool* ok);
697 ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
698 bool* ok);
699
700 void ParseFormalParameter(bool is_rest,
701 FormalParameterParsingStateT* parsing_result,
702 ExpressionClassifier* classifier, bool* ok);
703 int ParseFormalParameterList(FormalParameterParsingStateT* parsing_state,
704 ExpressionClassifier* classifier, bool* ok);
705 void CheckArityRestrictions(
706 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
707 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
708
709 // Checks if the expression is a valid reference expression (e.g., on the
710 // left-hand side of assignments). Although ruled out by ECMA as early errors,
711 // we allow calls for web compatibility and rewrite them to a runtime throw.
712 ExpressionT CheckAndRewriteReferenceExpression(
713 ExpressionT expression, Scanner::Location location,
714 MessageTemplate::Template message, bool* ok);
715
716 // Used to validate property names in object literals and class literals
717 enum PropertyKind {
718 kAccessorProperty,
719 kValueProperty,
720 kMethodProperty
721 };
722
723 class ObjectLiteralCheckerBase {
724 public:
725 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
726
727 virtual void CheckProperty(Token::Value property, PropertyKind type,
728 bool is_static, bool is_generator, bool* ok) = 0;
729
730 virtual ~ObjectLiteralCheckerBase() {}
731
732 protected:
733 ParserBase* parser() const { return parser_; }
734 Scanner* scanner() const { return parser_->scanner(); }
735
736 private:
737 ParserBase* parser_;
738 };
739
740 // Validation per ES6 object literals.
741 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
742 public:
743 explicit ObjectLiteralChecker(ParserBase* parser)
744 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
745
746 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
747 bool is_generator, bool* ok) override;
748
749 private:
750 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
751
752 bool has_seen_proto_;
753 };
754
755 // Validation per ES6 class literals.
756 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
757 public:
758 explicit ClassLiteralChecker(ParserBase* parser)
759 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
760
761 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
762 bool is_generator, bool* ok) override;
763
764 private:
765 bool IsConstructor() {
766 return this->scanner()->LiteralMatches("constructor", 11);
767 }
768 bool IsPrototype() {
769 return this->scanner()->LiteralMatches("prototype", 9);
770 }
771
772 bool has_seen_constructor_;
773 };
774
775 // If true, the next (and immediately following) function literal is
776 // preceded by a parenthesis.
777 // Heuristically that means that the function will be called immediately,
778 // so never lazily compile it.
779 bool parenthesized_function_;
780
781 Scope* scope_; // Scope stack.
782 FunctionState* function_state_; // Function state stack.
783 v8::Extension* extension_;
784 FuncNameInferrer* fni_;
785 AstValueFactory* ast_value_factory_; // Not owned.
786 ParserRecorder* log_;
787 Mode mode_;
788 uintptr_t stack_limit_;
789
790 private:
791 Zone* zone_;
792
793 Scanner* scanner_;
794 bool stack_overflow_;
795
796 bool allow_lazy_;
797 bool allow_natives_;
798 bool allow_harmony_arrow_functions_;
799 bool allow_harmony_sloppy_;
800 bool allow_harmony_computed_property_names_;
801 bool allow_harmony_rest_params_;
802 bool allow_harmony_spreadcalls_;
803 bool allow_harmony_destructuring_;
804 bool allow_harmony_spread_arrays_;
805 bool allow_harmony_new_target_;
806 bool allow_strong_mode_;
807 bool allow_legacy_const_;
808 };
809
810
811 class PreParserIdentifier { 21 class PreParserIdentifier {
812 public: 22 public:
813 PreParserIdentifier() : type_(kUnknownIdentifier) {} 23 PreParserIdentifier() : type_(kUnknownIdentifier) {}
814 static PreParserIdentifier Default() { 24 static PreParserIdentifier Default() {
815 return PreParserIdentifier(kUnknownIdentifier); 25 return PreParserIdentifier(kUnknownIdentifier);
816 } 26 }
817 static PreParserIdentifier Eval() { 27 static PreParserIdentifier Eval() {
818 return PreParserIdentifier(kEvalIdentifier); 28 return PreParserIdentifier(kEvalIdentifier);
819 } 29 }
820 static PreParserIdentifier Arguments() { 30 static PreParserIdentifier Arguments() {
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 } 1045 }
1836 1046
1837 1047
1838 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( 1048 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1839 PreParserIdentifier function_name, int pos, 1049 PreParserIdentifier function_name, int pos,
1840 const PreParserFormalParameterParsingState& formal_parameters, 1050 const PreParserFormalParameterParsingState& formal_parameters,
1841 Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok) { 1051 Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
1842 return pre_parser_->ParseEagerFunctionBody( 1052 return pre_parser_->ParseEagerFunctionBody(
1843 function_name, pos, formal_parameters, fvar, fvar_init_op, kind, ok); 1053 function_name, pos, formal_parameters, fvar, fvar_init_op, kind, ok);
1844 } 1054 }
1845
1846
1847 template <class Traits>
1848 ParserBase<Traits>::FunctionState::FunctionState(
1849 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1850 FunctionKind kind, typename Traits::Type::Factory* factory)
1851 : next_materialized_literal_index_(0),
1852 expected_property_count_(0),
1853 this_location_(Scanner::Location::invalid()),
1854 return_location_(Scanner::Location::invalid()),
1855 super_location_(Scanner::Location::invalid()),
1856 kind_(kind),
1857 generator_object_variable_(NULL),
1858 function_state_stack_(function_state_stack),
1859 outer_function_state_(*function_state_stack),
1860 scope_stack_(scope_stack),
1861 outer_scope_(*scope_stack),
1862 factory_(factory) {
1863 *scope_stack_ = scope;
1864 *function_state_stack = this;
1865 }
1866
1867
1868 template <class Traits>
1869 ParserBase<Traits>::FunctionState::~FunctionState() {
1870 *scope_stack_ = outer_scope_;
1871 *function_state_stack_ = outer_function_state_;
1872 }
1873
1874
1875 template <class Traits>
1876 void ParserBase<Traits>::GetUnexpectedTokenMessage(
1877 Token::Value token, MessageTemplate::Template* message, const char** arg,
1878 MessageTemplate::Template default_) {
1879 // Four of the tokens are treated specially
1880 switch (token) {
1881 case Token::EOS:
1882 *message = MessageTemplate::kUnexpectedEOS;
1883 *arg = nullptr;
1884 break;
1885 case Token::SMI:
1886 case Token::NUMBER:
1887 *message = MessageTemplate::kUnexpectedTokenNumber;
1888 *arg = nullptr;
1889 break;
1890 case Token::STRING:
1891 *message = MessageTemplate::kUnexpectedTokenString;
1892 *arg = nullptr;
1893 break;
1894 case Token::IDENTIFIER:
1895 *message = MessageTemplate::kUnexpectedTokenIdentifier;
1896 *arg = nullptr;
1897 break;
1898 case Token::FUTURE_RESERVED_WORD:
1899 *message = MessageTemplate::kUnexpectedReserved;
1900 *arg = nullptr;
1901 break;
1902 case Token::LET:
1903 case Token::STATIC:
1904 case Token::YIELD:
1905 case Token::FUTURE_STRICT_RESERVED_WORD:
1906 *message = is_strict(language_mode())
1907 ? MessageTemplate::kUnexpectedStrictReserved
1908 : MessageTemplate::kUnexpectedTokenIdentifier;
1909 *arg = nullptr;
1910 break;
1911 case Token::TEMPLATE_SPAN:
1912 case Token::TEMPLATE_TAIL:
1913 *message = MessageTemplate::kUnexpectedTemplateString;
1914 *arg = nullptr;
1915 break;
1916 default:
1917 const char* name = Token::String(token);
1918 DCHECK(name != NULL);
1919 *arg = name;
1920 break;
1921 }
1922 }
1923
1924
1925 template <class Traits>
1926 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1927 return ReportUnexpectedTokenAt(scanner_->location(), token);
1928 }
1929
1930
1931 template <class Traits>
1932 void ParserBase<Traits>::ReportUnexpectedTokenAt(
1933 Scanner::Location source_location, Token::Value token,
1934 MessageTemplate::Template message) {
1935 const char* arg;
1936 GetUnexpectedTokenMessage(token, &message, &arg);
1937 Traits::ReportMessageAt(source_location, message, arg);
1938 }
1939
1940
1941 template <class Traits>
1942 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1943 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1944 ExpressionClassifier classifier;
1945 auto result = ParseAndClassifyIdentifier(&classifier, ok);
1946 if (!*ok) return Traits::EmptyIdentifier();
1947
1948 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1949 ValidateAssignmentPattern(&classifier, ok);
1950 if (!*ok) return Traits::EmptyIdentifier();
1951 ValidateBindingPattern(&classifier, ok);
1952 if (!*ok) return Traits::EmptyIdentifier();
1953 } else {
1954 ValidateExpression(&classifier, ok);
1955 if (!*ok) return Traits::EmptyIdentifier();
1956 }
1957
1958 return result;
1959 }
1960
1961
1962 template <class Traits>
1963 typename ParserBase<Traits>::IdentifierT
1964 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1965 bool* ok) {
1966 Token::Value next = Next();
1967 if (next == Token::IDENTIFIER) {
1968 IdentifierT name = this->GetSymbol(scanner());
1969 // When this function is used to read a formal parameter, we don't always
1970 // know whether the function is going to be strict or sloppy. Indeed for
1971 // arrow functions we don't always know that the identifier we are reading
1972 // is actually a formal parameter. Therefore besides the errors that we
1973 // must detect because we know we're in strict mode, we also record any
1974 // error that we might make in the future once we know the language mode.
1975 if (this->IsEval(name)) {
1976 classifier->RecordStrictModeFormalParameterError(
1977 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1978 if (is_strict(language_mode())) {
1979 classifier->RecordBindingPatternError(
1980 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1981 }
1982 }
1983 if (this->IsArguments(name)) {
1984 scope_->RecordArgumentsUsage();
1985 classifier->RecordStrictModeFormalParameterError(
1986 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1987 if (is_strict(language_mode())) {
1988 classifier->RecordBindingPatternError(
1989 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1990 }
1991 if (is_strong(language_mode())) {
1992 classifier->RecordExpressionError(scanner()->location(),
1993 MessageTemplate::kStrongArguments);
1994 }
1995 }
1996 if (this->IsUndefined(name)) {
1997 classifier->RecordStrongModeFormalParameterError(
1998 scanner()->location(), MessageTemplate::kStrongUndefined);
1999 if (is_strong(language_mode())) {
2000 // TODO(dslomov): allow 'undefined' in nested patterns.
2001 classifier->RecordBindingPatternError(
2002 scanner()->location(), MessageTemplate::kStrongUndefined);
2003 classifier->RecordAssignmentPatternError(
2004 scanner()->location(), MessageTemplate::kStrongUndefined);
2005 }
2006 }
2007
2008 if (classifier->duplicate_finder() != nullptr &&
2009 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2010 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2011 }
2012 return name;
2013 } else if (is_sloppy(language_mode()) &&
2014 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
2015 next == Token::LET || next == Token::STATIC ||
2016 (next == Token::YIELD && !is_generator()))) {
2017 classifier->RecordStrictModeFormalParameterError(
2018 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
2019 return this->GetSymbol(scanner());
2020 } else {
2021 this->ReportUnexpectedToken(next);
2022 *ok = false;
2023 return Traits::EmptyIdentifier();
2024 }
2025 }
2026
2027
2028 template <class Traits>
2029 typename ParserBase<Traits>::IdentifierT ParserBase<
2030 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
2031 bool* ok) {
2032 Token::Value next = Next();
2033 if (next == Token::IDENTIFIER) {
2034 *is_strict_reserved = false;
2035 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
2036 next == Token::STATIC ||
2037 (next == Token::YIELD && !this->is_generator())) {
2038 *is_strict_reserved = true;
2039 } else {
2040 ReportUnexpectedToken(next);
2041 *ok = false;
2042 return Traits::EmptyIdentifier();
2043 }
2044
2045 IdentifierT name = this->GetSymbol(scanner());
2046 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
2047 return name;
2048 }
2049
2050
2051 template <class Traits>
2052 typename ParserBase<Traits>::IdentifierT
2053 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
2054 Token::Value next = Next();
2055 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
2056 next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
2057 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
2058 this->ReportUnexpectedToken(next);
2059 *ok = false;
2060 return Traits::EmptyIdentifier();
2061 }
2062
2063 IdentifierT name = this->GetSymbol(scanner());
2064 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
2065 return name;
2066 }
2067
2068
2069 template <class Traits>
2070 typename ParserBase<Traits>::IdentifierT
2071 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
2072 bool* is_set,
2073 bool* ok) {
2074 IdentifierT result = ParseIdentifierName(ok);
2075 if (!*ok) return Traits::EmptyIdentifier();
2076 scanner()->IsGetOrSet(is_get, is_set);
2077 return result;
2078 }
2079
2080
2081 template <class Traits>
2082 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
2083 bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
2084 int pos = peek_position();
2085 if (!scanner()->ScanRegExpPattern(seen_equal)) {
2086 Next();
2087 ReportMessage(MessageTemplate::kUnterminatedRegExp);
2088 *ok = false;
2089 return Traits::EmptyExpression();
2090 }
2091
2092 int literal_index = function_state_->NextMaterializedLiteralIndex();
2093
2094 IdentifierT js_pattern = this->GetNextSymbol(scanner());
2095 if (!scanner()->ScanRegExpFlags()) {
2096 Next();
2097 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
2098 *ok = false;
2099 return Traits::EmptyExpression();
2100 }
2101 IdentifierT js_flags = this->GetNextSymbol(scanner());
2102 Next();
2103 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index,
2104 is_strong(language_mode()), pos);
2105 }
2106
2107
2108 #define CHECK_OK ok); \
2109 if (!*ok) return this->EmptyExpression(); \
2110 ((void)0
2111 #define DUMMY ) // to make indentation work
2112 #undef DUMMY
2113
2114 // Used in functions where the return type is not ExpressionT.
2115 #define CHECK_OK_CUSTOM(x) ok); \
2116 if (!*ok) return this->x(); \
2117 ((void)0
2118 #define DUMMY ) // to make indentation work
2119 #undef DUMMY
2120
2121
2122 template <class Traits>
2123 typename ParserBase<Traits>::ExpressionT
2124 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
2125 bool* ok) {
2126 // PrimaryExpression ::
2127 // 'this'
2128 // 'null'
2129 // 'true'
2130 // 'false'
2131 // Identifier
2132 // Number
2133 // String
2134 // ArrayLiteral
2135 // ObjectLiteral
2136 // RegExpLiteral
2137 // ClassLiteral
2138 // '(' Expression ')'
2139 // TemplateLiteral
2140
2141 int beg_pos = scanner()->peek_location().beg_pos;
2142 int end_pos = scanner()->peek_location().end_pos;
2143 ExpressionT result = this->EmptyExpression();
2144 Token::Value token = peek();
2145 switch (token) {
2146 case Token::THIS: {
2147 BindingPatternUnexpectedToken(classifier);
2148 Consume(Token::THIS);
2149 if (FLAG_strong_this && is_strong(language_mode())) {
2150 // Constructors' usages of 'this' in strong mode are parsed separately.
2151 // TODO(rossberg): this does not work with arrow functions yet.
2152 if (i::IsConstructor(function_state_->kind())) {
2153 ReportMessage(MessageTemplate::kStrongConstructorThis);
2154 *ok = false;
2155 break;
2156 }
2157 }
2158 result = this->ThisExpression(scope_, factory(), beg_pos);
2159 break;
2160 }
2161
2162 case Token::NULL_LITERAL:
2163 case Token::TRUE_LITERAL:
2164 case Token::FALSE_LITERAL:
2165 BindingPatternUnexpectedToken(classifier);
2166 Next();
2167 result =
2168 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2169 break;
2170 case Token::SMI:
2171 case Token::NUMBER:
2172 classifier->RecordBindingPatternError(
2173 scanner()->location(), MessageTemplate::kUnexpectedTokenNumber);
2174 Next();
2175 result =
2176 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2177 break;
2178
2179 case Token::IDENTIFIER:
2180 case Token::LET:
2181 case Token::STATIC:
2182 case Token::YIELD:
2183 case Token::FUTURE_STRICT_RESERVED_WORD: {
2184 // Using eval or arguments in this context is OK even in strict mode.
2185 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
2186 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
2187 factory());
2188 break;
2189 }
2190
2191 case Token::STRING: {
2192 classifier->RecordBindingPatternError(
2193 scanner()->location(), MessageTemplate::kUnexpectedTokenString);
2194 Consume(Token::STRING);
2195 result = this->ExpressionFromString(beg_pos, scanner(), factory());
2196 break;
2197 }
2198
2199 case Token::ASSIGN_DIV:
2200 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK);
2201 break;
2202
2203 case Token::DIV:
2204 result = this->ParseRegExpLiteral(false, classifier, CHECK_OK);
2205 break;
2206
2207 case Token::LBRACK:
2208 if (!allow_harmony_destructuring()) {
2209 BindingPatternUnexpectedToken(classifier);
2210 }
2211 result = this->ParseArrayLiteral(classifier, CHECK_OK);
2212 break;
2213
2214 case Token::LBRACE:
2215 if (!allow_harmony_destructuring()) {
2216 BindingPatternUnexpectedToken(classifier);
2217 }
2218 result = this->ParseObjectLiteral(classifier, CHECK_OK);
2219 break;
2220
2221 case Token::LPAREN:
2222 // Arrow function formal parameters are either a single identifier or a
2223 // list of BindingPattern productions enclosed in parentheses.
2224 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
2225 // is_valid_binding_pattern() check to detect multiple levels of
2226 // parenthesization.
2227 if (!classifier->is_valid_binding_pattern()) {
2228 ArrowFormalParametersUnexpectedToken(classifier);
2229 }
2230 BindingPatternUnexpectedToken(classifier);
2231 Consume(Token::LPAREN);
2232 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) {
2233 // As a primary expression, the only thing that can follow "()" is "=>".
2234 classifier->RecordBindingPatternError(scanner()->location(),
2235 MessageTemplate::kUnexpectedToken,
2236 Token::String(Token::RPAREN));
2237 // Give a good error to the user who might have typed e.g. "return();".
2238 if (peek() != Token::ARROW) {
2239 ReportUnexpectedTokenAt(scanner_->peek_location(), peek(),
2240 MessageTemplate::kMissingArrow);
2241 *ok = false;
2242 return this->EmptyExpression();
2243 }
2244 Scope* scope =
2245 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2246 FormalParameterParsingStateT parsing_state(scope);
2247 scope->set_start_position(beg_pos);
2248 ExpressionClassifier args_classifier;
2249 result = this->ParseArrowFunctionLiteral(parsing_state, args_classifier,
2250 CHECK_OK);
2251 } else if (allow_harmony_arrow_functions() &&
2252 allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
2253 // (...x) => y
2254 Scope* scope =
2255 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2256 FormalParameterParsingStateT parsing_state(scope);
2257 scope->set_start_position(beg_pos);
2258 ExpressionClassifier args_classifier;
2259 const bool is_rest = true;
2260 this->ParseFormalParameter(is_rest, &parsing_state, &args_classifier,
2261 CHECK_OK);
2262 if (peek() == Token::COMMA) {
2263 ReportMessageAt(scanner()->peek_location(),
2264 MessageTemplate::kParamAfterRest);
2265 *ok = false;
2266 return this->EmptyExpression();
2267 }
2268 Expect(Token::RPAREN, CHECK_OK);
2269 result = this->ParseArrowFunctionLiteral(parsing_state, args_classifier,
2270 CHECK_OK);
2271 } else {
2272 // Heuristically try to detect immediately called functions before
2273 // seeing the call parentheses.
2274 parenthesized_function_ = (peek() == Token::FUNCTION);
2275 result = this->ParseExpression(true, classifier, CHECK_OK);
2276 Expect(Token::RPAREN, CHECK_OK);
2277 }
2278 break;
2279
2280 case Token::CLASS: {
2281 BindingPatternUnexpectedToken(classifier);
2282 Consume(Token::CLASS);
2283 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2284 ReportMessage(MessageTemplate::kSloppyLexical);
2285 *ok = false;
2286 break;
2287 }
2288 int class_token_position = position();
2289 IdentifierT name = this->EmptyIdentifier();
2290 bool is_strict_reserved_name = false;
2291 Scanner::Location class_name_location = Scanner::Location::invalid();
2292 if (peek_any_identifier()) {
2293 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2294 CHECK_OK);
2295 class_name_location = scanner()->location();
2296 }
2297 result = this->ParseClassLiteral(name, class_name_location,
2298 is_strict_reserved_name,
2299 class_token_position, CHECK_OK);
2300 break;
2301 }
2302
2303 case Token::TEMPLATE_SPAN:
2304 case Token::TEMPLATE_TAIL:
2305 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
2306 classifier, CHECK_OK);
2307 break;
2308
2309 case Token::MOD:
2310 if (allow_natives() || extension_ != NULL) {
2311 result = this->ParseV8Intrinsic(CHECK_OK);
2312 break;
2313 }
2314 // If we're not allowing special syntax we fall-through to the
2315 // default case.
2316
2317 default: {
2318 Next();
2319 ReportUnexpectedToken(token);
2320 *ok = false;
2321 }
2322 }
2323
2324 return result;
2325 }
2326
2327
2328 template <class Traits>
2329 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2330 bool accept_IN, bool* ok) {
2331 ExpressionClassifier classifier;
2332 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
2333 ValidateExpression(&classifier, CHECK_OK);
2334 return result;
2335 }
2336
2337
2338 // Precedence = 1
2339 template <class Traits>
2340 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2341 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2342 // Expression ::
2343 // AssignmentExpression
2344 // Expression ',' AssignmentExpression
2345
2346 ExpressionClassifier binding_classifier;
2347 ExpressionT result =
2348 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
2349 classifier->Accumulate(binding_classifier,
2350 ExpressionClassifier::AllProductions);
2351 bool seen_rest = false;
2352 while (peek() == Token::COMMA) {
2353 if (seen_rest) {
2354 // At this point the production can't possibly be valid, but we don't know
2355 // which error to signal.
2356 classifier->RecordArrowFormalParametersError(
2357 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2358 }
2359 Consume(Token::COMMA);
2360 bool is_rest = false;
2361 if (allow_harmony_rest_params() && peek() == Token::ELLIPSIS) {
2362 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2363 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2364 // valid expression or binding pattern.
2365 ExpressionUnexpectedToken(classifier);
2366 BindingPatternUnexpectedToken(classifier);
2367 Consume(Token::ELLIPSIS);
2368 seen_rest = is_rest = true;
2369 }
2370 int pos = position();
2371 ExpressionT right = this->ParseAssignmentExpression(
2372 accept_IN, &binding_classifier, CHECK_OK);
2373 if (is_rest) right = factory()->NewSpread(right, pos);
2374 classifier->Accumulate(binding_classifier,
2375 ExpressionClassifier::AllProductions);
2376 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2377 }
2378 return result;
2379 }
2380
2381
2382 template <class Traits>
2383 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2384 ExpressionClassifier* classifier, bool* ok) {
2385 // ArrayLiteral ::
2386 // '[' Expression? (',' Expression?)* ']'
2387
2388 int pos = peek_position();
2389 typename Traits::Type::ExpressionList values =
2390 this->NewExpressionList(4, zone_);
2391 Expect(Token::LBRACK, CHECK_OK);
2392 while (peek() != Token::RBRACK) {
2393 bool seen_spread = false;
2394 ExpressionT elem = this->EmptyExpression();
2395 if (peek() == Token::COMMA) {
2396 if (is_strong(language_mode())) {
2397 ReportMessageAt(scanner()->peek_location(),
2398 MessageTemplate::kStrongEllision);
2399 *ok = false;
2400 return this->EmptyExpression();
2401 }
2402 elem = this->GetLiteralTheHole(peek_position(), factory());
2403 } else if (peek() == Token::ELLIPSIS) {
2404 if (!allow_harmony_spread_arrays()) {
2405 ExpressionUnexpectedToken(classifier);
2406 }
2407 int start_pos = peek_position();
2408 Consume(Token::ELLIPSIS);
2409 ExpressionT argument =
2410 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2411 elem = factory()->NewSpread(argument, start_pos);
2412 seen_spread = true;
2413 } else {
2414 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2415 }
2416 values->Add(elem, zone_);
2417 if (peek() != Token::RBRACK) {
2418 if (seen_spread) {
2419 BindingPatternUnexpectedToken(classifier);
2420 }
2421 Expect(Token::COMMA, CHECK_OK);
2422 }
2423 }
2424 Expect(Token::RBRACK, CHECK_OK);
2425
2426 // Update the scope information before the pre-parsing bailout.
2427 int literal_index = function_state_->NextMaterializedLiteralIndex();
2428
2429 return factory()->NewArrayLiteral(values, literal_index,
2430 is_strong(language_mode()), pos);
2431 }
2432
2433
2434 template <class Traits>
2435 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2436 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2437 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
2438 Token::Value token = peek();
2439 int pos = peek_position();
2440
2441 // For non computed property names we normalize the name a bit:
2442 //
2443 // "12" -> 12
2444 // 12.3 -> "12.3"
2445 // 12.30 -> "12.3"
2446 // identifier -> "identifier"
2447 //
2448 // This is important because we use the property name as a key in a hash
2449 // table when we compute constant properties.
2450 switch (token) {
2451 case Token::STRING:
2452 Consume(Token::STRING);
2453 *name = this->GetSymbol(scanner());
2454 break;
2455
2456 case Token::SMI:
2457 Consume(Token::SMI);
2458 *name = this->GetNumberAsSymbol(scanner());
2459 break;
2460
2461 case Token::NUMBER:
2462 Consume(Token::NUMBER);
2463 *name = this->GetNumberAsSymbol(scanner());
2464 break;
2465
2466 case Token::LBRACK:
2467 if (allow_harmony_computed_property_names_) {
2468 *is_computed_name = true;
2469 Consume(Token::LBRACK);
2470 ExpressionClassifier computed_name_classifier;
2471 ExpressionT expression = ParseAssignmentExpression(
2472 true, &computed_name_classifier, CHECK_OK);
2473 classifier->AccumulateReclassifyingAsPattern(computed_name_classifier);
2474 Expect(Token::RBRACK, CHECK_OK);
2475 return expression;
2476 }
2477
2478 // Fall through.
2479 case Token::STATIC:
2480 *is_static = true;
2481
2482 // Fall through.
2483 default:
2484 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2485 break;
2486 }
2487
2488 uint32_t index;
2489 return this->IsArrayIndex(*name, &index)
2490 ? factory()->NewNumberLiteral(index, pos)
2491 : factory()->NewStringLiteral(*name, pos);
2492 }
2493
2494
2495 template <class Traits>
2496 typename ParserBase<Traits>::ObjectLiteralPropertyT
2497 ParserBase<Traits>::ParsePropertyDefinition(
2498 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2499 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
2500 ExpressionClassifier* classifier, bool* ok) {
2501 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2502 ExpressionT value = this->EmptyExpression();
2503 IdentifierT name = this->EmptyIdentifier();
2504 bool is_get = false;
2505 bool is_set = false;
2506 bool name_is_static = false;
2507 bool is_generator = Check(Token::MUL);
2508
2509 Token::Value name_token = peek();
2510 int next_beg_pos = scanner()->peek_location().beg_pos;
2511 int next_end_pos = scanner()->peek_location().end_pos;
2512 ExpressionT name_expression = ParsePropertyName(
2513 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier,
2514 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2515
2516 if (fni_ != nullptr && !*is_computed_name) {
2517 this->PushLiteralName(fni_, name);
2518 }
2519
2520 if (!in_class && !is_generator && peek() == Token::COLON) {
2521 // PropertyDefinition : PropertyName ':' AssignmentExpression
2522 if (!*is_computed_name) {
2523 checker->CheckProperty(name_token, kValueProperty, is_static,
2524 is_generator,
2525 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2526 }
2527 Consume(Token::COLON);
2528 value = this->ParseAssignmentExpression(
2529 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2530
2531 } else if (is_generator || peek() == Token::LPAREN) {
2532 // Concise Method
2533 if (!*is_computed_name) {
2534 checker->CheckProperty(name_token, kMethodProperty, is_static,
2535 is_generator,
2536 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2537 }
2538
2539 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2540 : FunctionKind::kConciseMethod;
2541
2542 if (in_class && !is_static && this->IsConstructor(name)) {
2543 *has_seen_constructor = true;
2544 kind = has_extends ? FunctionKind::kSubclassConstructor
2545 : FunctionKind::kBaseConstructor;
2546 }
2547
2548 if (!in_class) kind = WithObjectLiteralBit(kind);
2549
2550 value = this->ParseFunctionLiteral(
2551 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2552 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2553 FunctionLiteral::NORMAL_ARITY,
2554 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2555
2556 return factory()->NewObjectLiteralProperty(name_expression, value,
2557 ObjectLiteralProperty::COMPUTED,
2558 is_static, *is_computed_name);
2559
2560 } else if (in_class && name_is_static && !is_static) {
2561 // static MethodDefinition
2562 return ParsePropertyDefinition(checker, true, has_extends, true,
2563 is_computed_name, nullptr, classifier, ok);
2564 } else if (is_get || is_set) {
2565 // Accessor
2566 name = this->EmptyIdentifier();
2567 bool dont_care = false;
2568 name_token = peek();
2569
2570 name_expression = ParsePropertyName(
2571 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2572 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2573
2574 if (!*is_computed_name) {
2575 checker->CheckProperty(name_token, kAccessorProperty, is_static,
2576 is_generator,
2577 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2578 }
2579
2580 FunctionKind kind = FunctionKind::kAccessorFunction;
2581 if (!in_class) kind = WithObjectLiteralBit(kind);
2582 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2583 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2584 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2585 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2586 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2587
2588 // Make sure the name expression is a string since we need a Name for
2589 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2590 // statically we can skip the extra runtime check.
2591 if (!*is_computed_name) {
2592 name_expression =
2593 factory()->NewStringLiteral(name, name_expression->position());
2594 }
2595
2596 return factory()->NewObjectLiteralProperty(
2597 name_expression, value,
2598 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2599 is_static, *is_computed_name);
2600
2601 } else if (!in_class && Token::IsIdentifier(name_token, language_mode(),
2602 this->is_generator())) {
2603 DCHECK(!*is_computed_name);
2604 DCHECK(!is_static);
2605
2606 if (classifier->duplicate_finder() != nullptr &&
2607 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2608 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2609 }
2610
2611 ExpressionT lhs = this->ExpressionFromIdentifier(
2612 name, next_beg_pos, next_end_pos, scope_, factory());
2613 if (peek() == Token::ASSIGN) {
2614 this->ExpressionUnexpectedToken(classifier);
2615 Consume(Token::ASSIGN);
2616 ExpressionClassifier rhs_classifier;
2617 ExpressionT rhs = this->ParseAssignmentExpression(
2618 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2619 classifier->AccumulateReclassifyingAsPattern(rhs_classifier);
2620 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2621 RelocInfo::kNoPosition);
2622 } else {
2623 value = lhs;
2624 }
2625 return factory()->NewObjectLiteralProperty(
2626 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false);
2627
2628 } else {
2629 Token::Value next = Next();
2630 ReportUnexpectedToken(next);
2631 *ok = false;
2632 return this->EmptyObjectLiteralProperty();
2633 }
2634
2635 return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
2636 *is_computed_name);
2637 }
2638
2639
2640 template <class Traits>
2641 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2642 ExpressionClassifier* classifier, bool* ok) {
2643 // ObjectLiteral ::
2644 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2645
2646 int pos = peek_position();
2647 typename Traits::Type::PropertyList properties =
2648 this->NewPropertyList(4, zone_);
2649 int number_of_boilerplate_properties = 0;
2650 bool has_function = false;
2651 bool has_computed_names = false;
2652 ObjectLiteralChecker checker(this);
2653
2654 Expect(Token::LBRACE, CHECK_OK);
2655
2656 while (peek() != Token::RBRACE) {
2657 if (fni_ != nullptr) fni_->Enter();
2658
2659 const bool in_class = false;
2660 const bool is_static = false;
2661 const bool has_extends = false;
2662 bool is_computed_name = false;
2663 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2664 &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
2665 classifier, CHECK_OK);
2666
2667 if (is_computed_name) {
2668 has_computed_names = true;
2669 }
2670
2671 // Mark top-level object literals that contain function literals and
2672 // pretenure the literal so it can be added as a constant function
2673 // property. (Parser only.)
2674 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2675 &has_function);
2676
2677 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2678 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2679 number_of_boilerplate_properties++;
2680 }
2681 properties->Add(property, zone());
2682
2683 if (peek() != Token::RBRACE) {
2684 // Need {} because of the CHECK_OK macro.
2685 Expect(Token::COMMA, CHECK_OK);
2686 }
2687
2688 if (fni_ != nullptr) {
2689 fni_->Infer();
2690 fni_->Leave();
2691 }
2692 }
2693 Expect(Token::RBRACE, CHECK_OK);
2694
2695 // Computation of literal_index must happen before pre parse bailout.
2696 int literal_index = function_state_->NextMaterializedLiteralIndex();
2697
2698 return factory()->NewObjectLiteral(properties,
2699 literal_index,
2700 number_of_boilerplate_properties,
2701 has_function,
2702 is_strong(language_mode()),
2703 pos);
2704 }
2705
2706
2707 template <class Traits>
2708 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
2709 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier,
2710 bool* ok) {
2711 // Arguments ::
2712 // '(' (AssignmentExpression)*[','] ')'
2713
2714 Scanner::Location spread_arg = Scanner::Location::invalid();
2715 typename Traits::Type::ExpressionList result =
2716 this->NewExpressionList(4, zone_);
2717 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2718 bool done = (peek() == Token::RPAREN);
2719 bool was_unspread = false;
2720 int unspread_sequences_count = 0;
2721 while (!done) {
2722 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS);
2723 int start_pos = peek_position();
2724 if (is_spread) Consume(Token::ELLIPSIS);
2725
2726 ExpressionT argument = this->ParseAssignmentExpression(
2727 true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
2728 if (is_spread) {
2729 if (!spread_arg.IsValid()) {
2730 spread_arg.beg_pos = start_pos;
2731 spread_arg.end_pos = peek_position();
2732 }
2733 argument = factory()->NewSpread(argument, start_pos);
2734 }
2735 result->Add(argument, zone_);
2736
2737 // unspread_sequences_count is the number of sequences of parameters which
2738 // are not prefixed with a spread '...' operator.
2739 if (is_spread) {
2740 was_unspread = false;
2741 } else if (!was_unspread) {
2742 was_unspread = true;
2743 unspread_sequences_count++;
2744 }
2745
2746 if (result->length() > Code::kMaxArguments) {
2747 ReportMessage(MessageTemplate::kTooManyArguments);
2748 *ok = false;
2749 return this->NullExpressionList();
2750 }
2751 done = (peek() != Token::COMMA);
2752 if (!done) {
2753 Next();
2754 }
2755 }
2756 Scanner::Location location = scanner_->location();
2757 if (Token::RPAREN != Next()) {
2758 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2759 *ok = false;
2760 return this->NullExpressionList();
2761 }
2762 *first_spread_arg_loc = spread_arg;
2763
2764 if (spread_arg.IsValid()) {
2765 // Unspread parameter sequences are translated into array literals in the
2766 // parser. Ensure that the number of materialized literals matches between
2767 // the parser and preparser
2768 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2769 }
2770
2771 return result;
2772 }
2773
2774 // Precedence = 2
2775 template <class Traits>
2776 typename ParserBase<Traits>::ExpressionT
2777 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
2778 ExpressionClassifier* classifier,
2779 bool* ok) {
2780 // AssignmentExpression ::
2781 // ConditionalExpression
2782 // ArrowFunction
2783 // YieldExpression
2784 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2785
2786 Scanner::Location lhs_location = scanner()->peek_location();
2787
2788 if (peek() == Token::YIELD && is_generator()) {
2789 return this->ParseYieldExpression(classifier, ok);
2790 }
2791
2792 if (fni_ != NULL) fni_->Enter();
2793 ParserBase<Traits>::Checkpoint checkpoint(this);
2794 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
2795 bool parenthesized_formals = peek() == Token::LPAREN;
2796 if (!parenthesized_formals) {
2797 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2798 }
2799 ExpressionT expression = this->ParseConditionalExpression(
2800 accept_IN, &arrow_formals_classifier, CHECK_OK);
2801
2802 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2803 BindingPatternUnexpectedToken(classifier);
2804 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2805 parenthesized_formals, CHECK_OK);
2806 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
2807 Scope* scope =
2808 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2809 FormalParameterParsingStateT parsing_state(scope);
2810 checkpoint.Restore(&parsing_state.materialized_literals_count);
2811
2812 scope->set_start_position(lhs_location.beg_pos);
2813 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2814 this->ParseArrowFunctionFormalParameters(&parsing_state, expression, loc,
2815 &duplicate_loc, CHECK_OK);
2816 if (duplicate_loc.IsValid()) {
2817 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2818 duplicate_loc);
2819 }
2820 expression = this->ParseArrowFunctionLiteral(
2821 parsing_state, arrow_formals_classifier, CHECK_OK);
2822 return expression;
2823 }
2824
2825 // "expression" was not itself an arrow function parameter list, but it might
2826 // form part of one. Propagate speculative formal parameter error locations.
2827 classifier->Accumulate(arrow_formals_classifier,
2828 ExpressionClassifier::StandardProductions |
2829 ExpressionClassifier::FormalParametersProductions);
2830
2831 if (!Token::IsAssignmentOp(peek())) {
2832 if (fni_ != NULL) fni_->Leave();
2833 // Parsed conditional expression only (no assignment).
2834 return expression;
2835 }
2836
2837 if (!allow_harmony_destructuring()) {
2838 BindingPatternUnexpectedToken(classifier);
2839 }
2840
2841 expression = this->CheckAndRewriteReferenceExpression(
2842 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment,
2843 CHECK_OK);
2844 expression = this->MarkExpressionAsAssigned(expression);
2845
2846 Token::Value op = Next(); // Get assignment operator.
2847 if (op != Token::ASSIGN) {
2848 classifier->RecordBindingPatternError(scanner()->location(),
2849 MessageTemplate::kUnexpectedToken,
2850 Token::String(op));
2851 }
2852 int pos = position();
2853
2854 ExpressionClassifier rhs_classifier;
2855 ExpressionT right =
2856 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
2857 classifier->AccumulateReclassifyingAsPattern(rhs_classifier);
2858
2859 // TODO(1231235): We try to estimate the set of properties set by
2860 // constructors. We define a new property whenever there is an
2861 // assignment to a property of 'this'. We should probably only add
2862 // properties if we haven't seen them before. Otherwise we'll
2863 // probably overestimate the number of properties.
2864 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2865 function_state_->AddProperty();
2866 }
2867
2868 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2869
2870 if (fni_ != NULL) {
2871 // Check if the right hand side is a call to avoid inferring a
2872 // name if we're dealing with "a = function(){...}();"-like
2873 // expression.
2874 if ((op == Token::INIT_VAR
2875 || op == Token::INIT_CONST_LEGACY
2876 || op == Token::ASSIGN)
2877 && (!right->IsCall() && !right->IsCallNew())) {
2878 fni_->Infer();
2879 } else {
2880 fni_->RemoveLastFunction();
2881 }
2882 fni_->Leave();
2883 }
2884
2885 return factory()->NewAssignment(op, expression, right, pos);
2886 }
2887
2888 template <class Traits>
2889 typename ParserBase<Traits>::ExpressionT
2890 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
2891 bool* ok) {
2892 // YieldExpression ::
2893 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2894 int pos = peek_position();
2895 Expect(Token::YIELD, CHECK_OK);
2896 ExpressionT generator_object =
2897 factory()->NewVariableProxy(function_state_->generator_object_variable());
2898 ExpressionT expression = Traits::EmptyExpression();
2899 Yield::Kind kind = Yield::kSuspend;
2900 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2901 if (Check(Token::MUL)) kind = Yield::kDelegating;
2902 switch (peek()) {
2903 case Token::EOS:
2904 case Token::SEMICOLON:
2905 case Token::RBRACE:
2906 case Token::RBRACK:
2907 case Token::RPAREN:
2908 case Token::COLON:
2909 case Token::COMMA:
2910 // The above set of tokens is the complete set of tokens that can appear
2911 // after an AssignmentExpression, and none of them can start an
2912 // AssignmentExpression. This allows us to avoid looking for an RHS for
2913 // a Yield::kSuspend operation, given only one look-ahead token.
2914 if (kind == Yield::kSuspend)
2915 break;
2916 DCHECK_EQ(Yield::kDelegating, kind);
2917 // Delegating yields require an RHS; fall through.
2918 default:
2919 expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
2920 break;
2921 }
2922 }
2923 if (kind == Yield::kDelegating) {
2924 // var iterator = subject[Symbol.iterator]();
2925 expression = this->GetIterator(expression, factory());
2926 }
2927 typename Traits::Type::YieldExpression yield =
2928 factory()->NewYield(generator_object, expression, kind, pos);
2929 return yield;
2930 }
2931
2932
2933 // Precedence = 3
2934 template <class Traits>
2935 typename ParserBase<Traits>::ExpressionT
2936 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
2937 ExpressionClassifier* classifier,
2938 bool* ok) {
2939 // ConditionalExpression ::
2940 // LogicalOrExpression
2941 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2942
2943 int pos = peek_position();
2944 // We start using the binary expression parser for prec >= 4 only!
2945 ExpressionT expression =
2946 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2947 if (peek() != Token::CONDITIONAL) return expression;
2948 BindingPatternUnexpectedToken(classifier);
2949 Consume(Token::CONDITIONAL);
2950 // In parsing the first assignment expression in conditional
2951 // expressions we always accept the 'in' keyword; see ECMA-262,
2952 // section 11.12, page 58.
2953 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
2954 Expect(Token::COLON, CHECK_OK);
2955 ExpressionT right =
2956 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
2957 return factory()->NewConditional(expression, left, right, pos);
2958 }
2959
2960
2961 // Precedence >= 4
2962 template <class Traits>
2963 typename ParserBase<Traits>::ExpressionT
2964 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
2965 ExpressionClassifier* classifier,
2966 bool* ok) {
2967 DCHECK(prec >= 4);
2968 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2969 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2970 // prec1 >= 4
2971 while (Precedence(peek(), accept_IN) == prec1) {
2972 BindingPatternUnexpectedToken(classifier);
2973 Token::Value op = Next();
2974 Scanner::Location op_location = scanner()->location();
2975 int pos = position();
2976 ExpressionT y =
2977 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
2978
2979 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2980 factory())) {
2981 continue;
2982 }
2983
2984 // For now we distinguish between comparisons and other binary
2985 // operations. (We could combine the two and get rid of this
2986 // code and AST node eventually.)
2987 if (Token::IsCompareOp(op)) {
2988 // We have a comparison.
2989 Token::Value cmp = op;
2990 switch (op) {
2991 case Token::NE: cmp = Token::EQ; break;
2992 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2993 default: break;
2994 }
2995 if (cmp == Token::EQ && is_strong(language_mode())) {
2996 ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
2997 *ok = false;
2998 return this->EmptyExpression();
2999 }
3000 x = factory()->NewCompareOperation(cmp, x, y, pos);
3001 if (cmp != op) {
3002 // The comparison was negated - add a NOT.
3003 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3004 }
3005
3006 } else {
3007 // We have a "normal" binary operation.
3008 x = factory()->NewBinaryOperation(op, x, y, pos);
3009 }
3010 }
3011 }
3012 return x;
3013 }
3014
3015
3016 template <class Traits>
3017 typename ParserBase<Traits>::ExpressionT
3018 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
3019 bool* ok) {
3020 // UnaryExpression ::
3021 // PostfixExpression
3022 // 'delete' UnaryExpression
3023 // 'void' UnaryExpression
3024 // 'typeof' UnaryExpression
3025 // '++' UnaryExpression
3026 // '--' UnaryExpression
3027 // '+' UnaryExpression
3028 // '-' UnaryExpression
3029 // '~' UnaryExpression
3030 // '!' UnaryExpression
3031
3032 Token::Value op = peek();
3033 if (Token::IsUnaryOp(op)) {
3034 BindingPatternUnexpectedToken(classifier);
3035
3036 op = Next();
3037 int pos = position();
3038 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
3039
3040 if (op == Token::DELETE && is_strict(language_mode())) {
3041 if (is_strong(language_mode())) {
3042 ReportMessage(MessageTemplate::kStrongDelete);
3043 *ok = false;
3044 return this->EmptyExpression();
3045 } else if (this->IsIdentifier(expression)) {
3046 // "delete identifier" is a syntax error in strict mode.
3047 ReportMessage(MessageTemplate::kStrictDelete);
3048 *ok = false;
3049 return this->EmptyExpression();
3050 }
3051 }
3052
3053 // Allow Traits do rewrite the expression.
3054 return this->BuildUnaryExpression(expression, op, pos, factory());
3055 } else if (Token::IsCountOp(op)) {
3056 BindingPatternUnexpectedToken(classifier);
3057 op = Next();
3058 Scanner::Location lhs_location = scanner()->peek_location();
3059 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
3060 expression = this->CheckAndRewriteReferenceExpression(
3061 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp,
3062 CHECK_OK);
3063 this->MarkExpressionAsAssigned(expression);
3064
3065 return factory()->NewCountOperation(op,
3066 true /* prefix */,
3067 expression,
3068 position());
3069
3070 } else {
3071 return this->ParsePostfixExpression(classifier, ok);
3072 }
3073 }
3074
3075
3076 template <class Traits>
3077 typename ParserBase<Traits>::ExpressionT
3078 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
3079 bool* ok) {
3080 // PostfixExpression ::
3081 // LeftHandSideExpression ('++' | '--')?
3082
3083 Scanner::Location lhs_location = scanner()->peek_location();
3084 ExpressionT expression =
3085 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
3086 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
3087 Token::IsCountOp(peek())) {
3088 BindingPatternUnexpectedToken(classifier);
3089
3090 expression = this->CheckAndRewriteReferenceExpression(
3091 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp,
3092 CHECK_OK);
3093 expression = this->MarkExpressionAsAssigned(expression);
3094
3095 Token::Value next = Next();
3096 expression =
3097 factory()->NewCountOperation(next,
3098 false /* postfix */,
3099 expression,
3100 position());
3101 }
3102 return expression;
3103 }
3104
3105
3106 template <class Traits>
3107 typename ParserBase<Traits>::ExpressionT
3108 ParserBase<Traits>::ParseLeftHandSideExpression(
3109 ExpressionClassifier* classifier, bool* ok) {
3110 // LeftHandSideExpression ::
3111 // (NewExpression | MemberExpression) ...
3112
3113 ExpressionT result =
3114 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3115
3116 while (true) {
3117 switch (peek()) {
3118 case Token::LBRACK: {
3119 BindingPatternUnexpectedToken(classifier);
3120 Consume(Token::LBRACK);
3121 int pos = position();
3122 ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
3123 result = factory()->NewProperty(result, index, pos);
3124 Expect(Token::RBRACK, CHECK_OK);
3125 break;
3126 }
3127
3128 case Token::LPAREN: {
3129 BindingPatternUnexpectedToken(classifier);
3130
3131 if (is_strong(language_mode()) && this->IsIdentifier(result) &&
3132 this->IsEval(this->AsIdentifier(result))) {
3133 ReportMessage(MessageTemplate::kStrongDirectEval);
3134 *ok = false;
3135 return this->EmptyExpression();
3136 }
3137 int pos;
3138 if (scanner()->current_token() == Token::IDENTIFIER) {
3139 // For call of an identifier we want to report position of
3140 // the identifier as position of the call in the stack trace.
3141 pos = position();
3142 } else {
3143 // For other kinds of calls we record position of the parenthesis as
3144 // position of the call. Note that this is extremely important for
3145 // expressions of the form function(){...}() for which call position
3146 // should not point to the closing brace otherwise it will intersect
3147 // with positions recorded for function literal and confuse debugger.
3148 pos = peek_position();
3149 // Also the trailing parenthesis are a hint that the function will
3150 // be called immediately. If we happen to have parsed a preceding
3151 // function literal eagerly, we can also compile it eagerly.
3152 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3153 result->AsFunctionLiteral()->set_should_eager_compile();
3154 }
3155 }
3156 Scanner::Location spread_pos;
3157 typename Traits::Type::ExpressionList args =
3158 ParseArguments(&spread_pos, classifier, CHECK_OK);
3159
3160 // Keep track of eval() calls since they disable all local variable
3161 // optimizations.
3162 // The calls that need special treatment are the
3163 // direct eval calls. These calls are all of the form eval(...), with
3164 // no explicit receiver.
3165 // These calls are marked as potentially direct eval calls. Whether
3166 // they are actually direct calls to eval is determined at run time.
3167 this->CheckPossibleEvalCall(result, scope_);
3168
3169 if (spread_pos.IsValid()) {
3170 args = Traits::PrepareSpreadArguments(args);
3171 result = Traits::SpreadCall(result, args, pos);
3172 } else {
3173 result = factory()->NewCall(result, args, pos);
3174 }
3175 if (fni_ != NULL) fni_->RemoveLastFunction();
3176 break;
3177 }
3178
3179 case Token::PERIOD: {
3180 BindingPatternUnexpectedToken(classifier);
3181 Consume(Token::PERIOD);
3182 int pos = position();
3183 IdentifierT name = ParseIdentifierName(CHECK_OK);
3184 result = factory()->NewProperty(
3185 result, factory()->NewStringLiteral(name, pos), pos);
3186 if (fni_ != NULL) this->PushLiteralName(fni_, name);
3187 break;
3188 }
3189
3190 case Token::TEMPLATE_SPAN:
3191 case Token::TEMPLATE_TAIL: {
3192 BindingPatternUnexpectedToken(classifier);
3193 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
3194 break;
3195 }
3196
3197 default:
3198 return result;
3199 }
3200 }
3201 }
3202
3203
3204 template <class Traits>
3205 typename ParserBase<Traits>::ExpressionT
3206 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
3207 ExpressionClassifier* classifier, bool* ok) {
3208 // NewExpression ::
3209 // ('new')+ MemberExpression
3210 //
3211 // NewTarget ::
3212 // 'new' '.' 'target'
3213
3214 // The grammar for new expressions is pretty warped. We can have several 'new'
3215 // keywords following each other, and then a MemberExpression. When we see '('
3216 // after the MemberExpression, it's associated with the rightmost unassociated
3217 // 'new' to create a NewExpression with arguments. However, a NewExpression
3218 // can also occur without arguments.
3219
3220 // Examples of new expression:
3221 // new foo.bar().baz means (new (foo.bar)()).baz
3222 // new foo()() means (new foo())()
3223 // new new foo()() means (new (new foo())())
3224 // new new foo means new (new foo)
3225 // new new foo() means new (new foo())
3226 // new new foo().bar().baz means (new (new foo()).bar()).baz
3227
3228 if (peek() == Token::NEW) {
3229 BindingPatternUnexpectedToken(classifier);
3230 Consume(Token::NEW);
3231 int new_pos = position();
3232 ExpressionT result = this->EmptyExpression();
3233 if (peek() == Token::SUPER) {
3234 const bool is_new = true;
3235 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3236 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) {
3237 return ParseNewTargetExpression(CHECK_OK);
3238 } else {
3239 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3240 }
3241 if (peek() == Token::LPAREN) {
3242 // NewExpression with arguments.
3243 Scanner::Location spread_pos;
3244 typename Traits::Type::ExpressionList args =
3245 this->ParseArguments(&spread_pos, classifier, CHECK_OK);
3246
3247 if (spread_pos.IsValid()) {
3248 args = Traits::PrepareSpreadArguments(args);
3249 result = Traits::SpreadCallNew(result, args, new_pos);
3250 } else {
3251 result = factory()->NewCallNew(result, args, new_pos);
3252 }
3253 // The expression can still continue with . or [ after the arguments.
3254 result =
3255 this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
3256 return result;
3257 }
3258 // NewExpression without arguments.
3259 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
3260 new_pos);
3261 }
3262 // No 'new' or 'super' keyword.
3263 return this->ParseMemberExpression(classifier, ok);
3264 }
3265
3266
3267 template <class Traits>
3268 typename ParserBase<Traits>::ExpressionT
3269 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
3270 bool* ok) {
3271 // MemberExpression ::
3272 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
3273 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3274
3275 // The '[' Expression ']' and '.' Identifier parts are parsed by
3276 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3277 // caller.
3278
3279 // Parse the initial primary or function expression.
3280 ExpressionT result = this->EmptyExpression();
3281 if (peek() == Token::FUNCTION) {
3282 BindingPatternUnexpectedToken(classifier);
3283
3284 Consume(Token::FUNCTION);
3285 int function_token_position = position();
3286 bool is_generator = Check(Token::MUL);
3287 IdentifierT name = this->EmptyIdentifier();
3288 bool is_strict_reserved_name = false;
3289 Scanner::Location function_name_location = Scanner::Location::invalid();
3290 FunctionLiteral::FunctionType function_type =
3291 FunctionLiteral::ANONYMOUS_EXPRESSION;
3292 if (peek_any_identifier()) {
3293 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3294 CHECK_OK);
3295 function_name_location = scanner()->location();
3296 function_type = FunctionLiteral::NAMED_EXPRESSION;
3297 }
3298 result = this->ParseFunctionLiteral(
3299 name, function_name_location,
3300 is_strict_reserved_name ? kFunctionNameIsStrictReserved
3301 : kFunctionNameValidityUnknown,
3302 is_generator ? FunctionKind::kGeneratorFunction
3303 : FunctionKind::kNormalFunction,
3304 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
3305 CHECK_OK);
3306 } else if (peek() == Token::SUPER) {
3307 const bool is_new = false;
3308 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3309 } else {
3310 result = ParsePrimaryExpression(classifier, CHECK_OK);
3311 }
3312
3313 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
3314 return result;
3315 }
3316
3317
3318 template <class Traits>
3319 typename ParserBase<Traits>::ExpressionT
3320 ParserBase<Traits>::ParseStrongInitializationExpression(
3321 ExpressionClassifier* classifier, bool* ok) {
3322 // InitializationExpression :: (strong mode)
3323 // 'this' '.' IdentifierName '=' AssignmentExpression
3324 // 'this' '[' Expression ']' '=' AssignmentExpression
3325
3326 if (fni_ != NULL) fni_->Enter();
3327
3328 Consume(Token::THIS);
3329 int pos = position();
3330 function_state_->set_this_location(scanner()->location());
3331 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
3332
3333 ExpressionT left = this->EmptyExpression();
3334 switch (peek()) {
3335 case Token::LBRACK: {
3336 Consume(Token::LBRACK);
3337 int pos = position();
3338 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3339 left = factory()->NewProperty(this_expr, index, pos);
3340 if (fni_ != NULL) {
3341 this->PushPropertyName(fni_, index);
3342 }
3343 Expect(Token::RBRACK, CHECK_OK);
3344 break;
3345 }
3346 case Token::PERIOD: {
3347 Consume(Token::PERIOD);
3348 int pos = position();
3349 IdentifierT name = ParseIdentifierName(CHECK_OK);
3350 left = factory()->NewProperty(
3351 this_expr, factory()->NewStringLiteral(name, pos), pos);
3352 if (fni_ != NULL) {
3353 this->PushLiteralName(fni_, name);
3354 }
3355 break;
3356 }
3357 default:
3358 ReportMessage(MessageTemplate::kStrongConstructorThis);
3359 *ok = false;
3360 return this->EmptyExpression();
3361 }
3362
3363 if (peek() != Token::ASSIGN) {
3364 ReportMessageAt(function_state_->this_location(),
3365 MessageTemplate::kStrongConstructorThis);
3366 *ok = false;
3367 return this->EmptyExpression();
3368 }
3369 Consume(Token::ASSIGN);
3370 left = this->MarkExpressionAsAssigned(left);
3371
3372 ExpressionT right =
3373 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
3374 this->CheckAssigningFunctionLiteralToProperty(left, right);
3375 function_state_->AddProperty();
3376 if (fni_ != NULL) {
3377 // Check if the right hand side is a call to avoid inferring a
3378 // name if we're dealing with "this.a = function(){...}();"-like
3379 // expression.
3380 if (!right->IsCall() && !right->IsCallNew()) {
3381 fni_->Infer();
3382 } else {
3383 fni_->RemoveLastFunction();
3384 }
3385 fni_->Leave();
3386 }
3387
3388 if (function_state_->return_location().IsValid()) {
3389 ReportMessageAt(function_state_->return_location(),
3390 MessageTemplate::kStrongConstructorReturnMisplaced);
3391 *ok = false;
3392 return this->EmptyExpression();
3393 }
3394
3395 return factory()->NewAssignment(Token::ASSIGN, left, right, pos);
3396 }
3397
3398
3399 template <class Traits>
3400 typename ParserBase<Traits>::ExpressionT
3401 ParserBase<Traits>::ParseStrongSuperCallExpression(
3402 ExpressionClassifier* classifier, bool* ok) {
3403 // SuperCallExpression :: (strong mode)
3404 // 'super' '(' ExpressionList ')'
3405 BindingPatternUnexpectedToken(classifier);
3406
3407 Consume(Token::SUPER);
3408 int pos = position();
3409 Scanner::Location super_loc = scanner()->location();
3410 ExpressionT expr = this->SuperCallReference(scope_, factory(), pos);
3411
3412 if (peek() != Token::LPAREN) {
3413 ReportMessage(MessageTemplate::kStrongConstructorSuper);
3414 *ok = false;
3415 return this->EmptyExpression();
3416 }
3417
3418 Scanner::Location spread_pos;
3419 typename Traits::Type::ExpressionList args =
3420 ParseArguments(&spread_pos, classifier, CHECK_OK);
3421
3422 // TODO(rossberg): This doesn't work with arrow functions yet.
3423 if (!IsSubclassConstructor(function_state_->kind())) {
3424 ReportMessage(MessageTemplate::kUnexpectedSuper);
3425 *ok = false;
3426 return this->EmptyExpression();
3427 } else if (function_state_->super_location().IsValid()) {
3428 ReportMessageAt(scanner()->location(),
3429 MessageTemplate::kStrongSuperCallDuplicate);
3430 *ok = false;
3431 return this->EmptyExpression();
3432 } else if (function_state_->this_location().IsValid()) {
3433 ReportMessageAt(scanner()->location(),
3434 MessageTemplate::kStrongSuperCallMisplaced);
3435 *ok = false;
3436 return this->EmptyExpression();
3437 } else if (function_state_->return_location().IsValid()) {
3438 ReportMessageAt(function_state_->return_location(),
3439 MessageTemplate::kStrongConstructorReturnMisplaced);
3440 *ok = false;
3441 return this->EmptyExpression();
3442 }
3443
3444 function_state_->set_super_location(super_loc);
3445 if (spread_pos.IsValid()) {
3446 args = Traits::PrepareSpreadArguments(args);
3447 return Traits::SpreadCall(expr, args, pos);
3448 } else {
3449 return factory()->NewCall(expr, args, pos);
3450 }
3451 }
3452
3453
3454 template <class Traits>
3455 typename ParserBase<Traits>::ExpressionT
3456 ParserBase<Traits>::ParseSuperExpression(bool is_new,
3457 ExpressionClassifier* classifier,
3458 bool* ok) {
3459 int pos = position();
3460 Expect(Token::SUPER, CHECK_OK);
3461
3462 Scope* scope = scope_->DeclarationScope();
3463 while (scope->is_eval_scope() || scope->is_arrow_scope()) {
3464 scope = scope->outer_scope();
3465 DCHECK_NOT_NULL(scope);
3466 scope = scope->DeclarationScope();
3467 }
3468
3469 FunctionKind kind = scope->function_kind();
3470 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3471 i::IsConstructor(kind)) {
3472 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3473 scope->RecordSuperPropertyUsage();
3474 return this->SuperPropertyReference(scope_, factory(), pos);
3475 }
3476 // new super() is never allowed.
3477 // super() is only allowed in derived constructor
3478 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
3479 if (is_strong(language_mode())) {
3480 // Super calls in strong mode are parsed separately.
3481 ReportMessageAt(scanner()->location(),
3482 MessageTemplate::kStrongConstructorSuper);
3483 *ok = false;
3484 return this->EmptyExpression();
3485 }
3486 // TODO(rossberg): This might not be the correct FunctionState for the
3487 // method here.
3488 function_state_->set_super_location(scanner()->location());
3489 return this->SuperCallReference(scope_, factory(), pos);
3490 }
3491 }
3492
3493 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
3494 *ok = false;
3495 return this->EmptyExpression();
3496 }
3497
3498
3499 template <class Traits>
3500 typename ParserBase<Traits>::ExpressionT
3501 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
3502 int pos = position();
3503 Consume(Token::PERIOD);
3504 ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
3505
3506 Scope* scope = scope_->DeclarationScope();
3507 while (scope->is_eval_scope() || scope->is_arrow_scope()) {
3508 scope = scope->outer_scope();
3509 DCHECK_NOT_NULL(scope);
3510 scope = scope->DeclarationScope();
3511 }
3512
3513 if (!scope->is_function_scope()) {
3514 ReportMessageAt(scanner()->location(),
3515 MessageTemplate::kUnexpectedNewTarget);
3516 *ok = false;
3517 return this->EmptyExpression();
3518 }
3519
3520 return this->NewTargetExpression(scope_, factory(), pos);
3521 }
3522
3523
3524 template <class Traits>
3525 typename ParserBase<Traits>::ExpressionT
3526 ParserBase<Traits>::ParseMemberExpressionContinuation(
3527 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
3528 // Parses this part of MemberExpression:
3529 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3530 while (true) {
3531 switch (peek()) {
3532 case Token::LBRACK: {
3533 BindingPatternUnexpectedToken(classifier);
3534
3535 Consume(Token::LBRACK);
3536 int pos = position();
3537 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3538 expression = factory()->NewProperty(expression, index, pos);
3539 if (fni_ != NULL) {
3540 this->PushPropertyName(fni_, index);
3541 }
3542 Expect(Token::RBRACK, CHECK_OK);
3543 break;
3544 }
3545 case Token::PERIOD: {
3546 BindingPatternUnexpectedToken(classifier);
3547
3548 Consume(Token::PERIOD);
3549 int pos = position();
3550 IdentifierT name = ParseIdentifierName(CHECK_OK);
3551 expression = factory()->NewProperty(
3552 expression, factory()->NewStringLiteral(name, pos), pos);
3553 if (fni_ != NULL) {
3554 this->PushLiteralName(fni_, name);
3555 }
3556 break;
3557 }
3558 case Token::TEMPLATE_SPAN:
3559 case Token::TEMPLATE_TAIL: {
3560 BindingPatternUnexpectedToken(classifier);
3561 int pos;
3562 if (scanner()->current_token() == Token::IDENTIFIER) {
3563 pos = position();
3564 } else {
3565 pos = peek_position();
3566 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3567 // If the tag function looks like an IIFE, set_parenthesized() to
3568 // force eager compilation.
3569 expression->AsFunctionLiteral()->set_should_eager_compile();
3570 }
3571 }
3572 expression =
3573 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
3574 break;
3575 }
3576 default:
3577 return expression;
3578 }
3579 }
3580 DCHECK(false);
3581 return this->EmptyExpression();
3582 }
3583
3584
3585 template <class Traits>
3586 void ParserBase<Traits>::ParseFormalParameter(
3587 bool is_rest, FormalParameterParsingStateT* parsing_state,
3588 ExpressionClassifier* classifier, bool* ok) {
3589 // FormalParameter[Yield,GeneratorParameter] :
3590 // BindingElement[?Yield, ?GeneratorParameter]
3591
3592 Token::Value next = peek();
3593 ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
3594 if (!*ok) return;
3595
3596 ValidateBindingPattern(classifier, ok);
3597 if (!*ok) return;
3598
3599 if (!allow_harmony_destructuring() && !Traits::IsIdentifier(pattern)) {
3600 ReportUnexpectedToken(next);
3601 *ok = false;
3602 return;
3603 }
3604
3605 if (parsing_state->is_simple_parameter_list) {
3606 parsing_state->is_simple_parameter_list =
3607 !is_rest && Traits::IsIdentifier(pattern);
3608 }
3609 parsing_state->has_rest = is_rest;
3610 if (is_rest && !Traits::IsIdentifier(pattern)) {
3611 ReportUnexpectedToken(next);
3612 *ok = false;
3613 return;
3614 }
3615 Traits::DeclareFormalParameter(parsing_state, pattern, classifier, is_rest);
3616 }
3617
3618
3619 template <class Traits>
3620 int ParserBase<Traits>::ParseFormalParameterList(
3621 FormalParameterParsingStateT* parsing_state,
3622 ExpressionClassifier* classifier, bool* ok) {
3623 // FormalParameters[Yield,GeneratorParameter] :
3624 // [empty]
3625 // FormalParameterList[?Yield, ?GeneratorParameter]
3626 //
3627 // FormalParameterList[Yield,GeneratorParameter] :
3628 // FunctionRestParameter[?Yield]
3629 // FormalsList[?Yield, ?GeneratorParameter]
3630 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
3631 //
3632 // FormalsList[Yield,GeneratorParameter] :
3633 // FormalParameter[?Yield, ?GeneratorParameter]
3634 // FormalsList[?Yield, ?GeneratorParameter] ,
3635 // FormalParameter[?Yield,?GeneratorParameter]
3636
3637 int parameter_count = 0;
3638
3639 if (peek() != Token::RPAREN) {
3640 do {
3641 if (++parameter_count > Code::kMaxArguments) {
3642 ReportMessage(MessageTemplate::kTooManyParameters);
3643 *ok = false;
3644 return -1;
3645 }
3646 bool is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
3647 ParseFormalParameter(is_rest, parsing_state, classifier, ok);
3648 if (!*ok) return -1;
3649 } while (!parsing_state->has_rest && Check(Token::COMMA));
3650
3651 if (parsing_state->has_rest && peek() == Token::COMMA) {
3652 ReportMessageAt(scanner()->peek_location(),
3653 MessageTemplate::kParamAfterRest);
3654 *ok = false;
3655 return -1;
3656 }
3657 }
3658
3659 return parameter_count;
3660 }
3661
3662
3663 template <class Traits>
3664 void ParserBase<Traits>::CheckArityRestrictions(
3665 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
3666 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
3667 switch (arity_restriction) {
3668 case FunctionLiteral::GETTER_ARITY:
3669 if (param_count != 0) {
3670 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3671 MessageTemplate::kBadGetterArity);
3672 *ok = false;
3673 }
3674 break;
3675 case FunctionLiteral::SETTER_ARITY:
3676 if (param_count != 1) {
3677 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3678 MessageTemplate::kBadSetterArity);
3679 *ok = false;
3680 }
3681 if (has_rest) {
3682 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3683 MessageTemplate::kBadSetterRestParameter);
3684 *ok = false;
3685 }
3686 break;
3687 default:
3688 break;
3689 }
3690 }
3691
3692
3693 template <class Traits>
3694 typename ParserBase<Traits>::ExpressionT
3695 ParserBase<Traits>::ParseArrowFunctionLiteral(
3696 const FormalParameterParsingStateT& formal_parameters,
3697 const ExpressionClassifier& formals_classifier, bool* ok) {
3698 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3699 // ASI inserts `;` after arrow parameters if a line terminator is found.
3700 // `=> ...` is never a valid expression, so report as syntax error.
3701 // If next token is not `=>`, it's a syntax error anyways.
3702 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3703 *ok = false;
3704 return this->EmptyExpression();
3705 }
3706
3707 typename Traits::Type::StatementList body;
3708 int num_parameters = formal_parameters.scope->num_parameters();
3709 int materialized_literal_count = -1;
3710 int expected_property_count = -1;
3711 Scanner::Location super_loc;
3712
3713 {
3714 typename Traits::Type::Factory function_factory(ast_value_factory());
3715 FunctionState function_state(&function_state_, &scope_,
3716 formal_parameters.scope, kArrowFunction,
3717 &function_factory);
3718
3719 function_state.SkipMaterializedLiterals(
3720 formal_parameters.materialized_literals_count);
3721
3722 this->ReindexLiterals(formal_parameters);
3723
3724 Expect(Token::ARROW, CHECK_OK);
3725
3726 if (peek() == Token::LBRACE) {
3727 // Multiple statement body
3728 Consume(Token::LBRACE);
3729 bool is_lazily_parsed =
3730 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
3731 if (is_lazily_parsed) {
3732 body = this->NewStatementList(0, zone());
3733 this->SkipLazyFunctionBody(&materialized_literal_count,
3734 &expected_property_count, CHECK_OK);
3735 } else {
3736 body = this->ParseEagerFunctionBody(
3737 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
3738 NULL, Token::INIT_VAR, kArrowFunction, CHECK_OK);
3739 materialized_literal_count =
3740 function_state.materialized_literal_count();
3741 expected_property_count = function_state.expected_property_count();
3742 }
3743 } else {
3744 // Single-expression body
3745 int pos = position();
3746 parenthesized_function_ = false;
3747 ExpressionClassifier classifier;
3748 ExpressionT expression =
3749 ParseAssignmentExpression(true, &classifier, CHECK_OK);
3750 ValidateExpression(&classifier, CHECK_OK);
3751 body = this->NewStatementList(1, zone());
3752 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
3753 body->Add(factory()->NewReturnStatement(expression, pos), zone());
3754 materialized_literal_count = function_state.materialized_literal_count();
3755 expected_property_count = function_state.expected_property_count();
3756 }
3757 super_loc = function_state.super_location();
3758
3759 formal_parameters.scope->set_end_position(scanner()->location().end_pos);
3760
3761 // Arrow function formal parameters are parsed as StrictFormalParameterList,
3762 // which is not the same as "parameters of a strict function"; it only means
3763 // that duplicates are not allowed. Of course, the arrow function may
3764 // itself be strict as well.
3765 const bool allow_duplicate_parameters = false;
3766 this->ValidateFormalParameters(&formals_classifier, language_mode(),
3767 allow_duplicate_parameters, CHECK_OK);
3768
3769 // Validate strict mode.
3770 if (is_strict(language_mode())) {
3771 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
3772 scanner()->location().end_pos, CHECK_OK);
3773 }
3774 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
3775 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
3776 }
3777 }
3778
3779 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
3780 this->EmptyIdentifierString(), ast_value_factory(),
3781 formal_parameters.scope, body, materialized_literal_count,
3782 expected_property_count, num_parameters,
3783 FunctionLiteral::kNoDuplicateParameters,
3784 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
3785 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
3786 formal_parameters.scope->start_position());
3787
3788 function_literal->set_function_token_position(
3789 formal_parameters.scope->start_position());
3790 if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
3791
3792 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
3793
3794 return function_literal;
3795 }
3796
3797
3798 template <typename Traits>
3799 typename ParserBase<Traits>::ExpressionT
3800 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
3801 ExpressionClassifier* classifier,
3802 bool* ok) {
3803 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3804 // text followed by a substitution expression), finalized by a single
3805 // TEMPLATE_TAIL.
3806 //
3807 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3808 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3809 // NoSubstitutionTemplate.
3810 //
3811 // When parsing a TemplateLiteral, we must have scanned either an initial
3812 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
3813 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
3814
3815 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
3816 // In this case we may simply consume the token and build a template with a
3817 // single TEMPLATE_SPAN and no expressions.
3818 if (peek() == Token::TEMPLATE_TAIL) {
3819 Consume(Token::TEMPLATE_TAIL);
3820 int pos = position();
3821 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3822 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3823 Traits::AddTemplateSpan(&ts, true);
3824 return Traits::CloseTemplateLiteral(&ts, start, tag);
3825 }
3826
3827 Consume(Token::TEMPLATE_SPAN);
3828 int pos = position();
3829 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3830 Traits::AddTemplateSpan(&ts, false);
3831 Token::Value next;
3832
3833 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
3834 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
3835 // case, representing a TemplateMiddle).
3836
3837 do {
3838 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3839 next = peek();
3840 if (next == Token::EOS) {
3841 ReportMessageAt(Scanner::Location(start, peek_position()),
3842 MessageTemplate::kUnterminatedTemplate);
3843 *ok = false;
3844 return Traits::EmptyExpression();
3845 } else if (next == Token::ILLEGAL) {
3846 Traits::ReportMessageAt(
3847 Scanner::Location(position() + 1, peek_position()),
3848 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3849 *ok = false;
3850 return Traits::EmptyExpression();
3851 }
3852
3853 int expr_pos = peek_position();
3854 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
3855 Traits::AddTemplateExpression(&ts, expression);
3856
3857 if (peek() != Token::RBRACE) {
3858 ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
3859 MessageTemplate::kUnterminatedTemplateExpr);
3860 *ok = false;
3861 return Traits::EmptyExpression();
3862 }
3863
3864 // If we didn't die parsing that expression, our next token should be a
3865 // TEMPLATE_SPAN or TEMPLATE_TAIL.
3866 next = scanner()->ScanTemplateContinuation();
3867 Next();
3868 pos = position();
3869
3870 if (next == Token::EOS) {
3871 ReportMessageAt(Scanner::Location(start, pos),
3872 MessageTemplate::kUnterminatedTemplate);
3873 *ok = false;
3874 return Traits::EmptyExpression();
3875 } else if (next == Token::ILLEGAL) {
3876 Traits::ReportMessageAt(
3877 Scanner::Location(position() + 1, peek_position()),
3878 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3879 *ok = false;
3880 return Traits::EmptyExpression();
3881 }
3882
3883 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
3884 } while (next == Token::TEMPLATE_SPAN);
3885
3886 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
3887 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3888 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3889 return Traits::CloseTemplateLiteral(&ts, start, tag);
3890 }
3891
3892
3893 template <typename Traits>
3894 typename ParserBase<Traits>::ExpressionT
3895 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3896 ExpressionT expression, Scanner::Location location,
3897 MessageTemplate::Template message, bool* ok) {
3898 if (this->IsIdentifier(expression)) {
3899 if (is_strict(language_mode()) &&
3900 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3901 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments,
3902 kSyntaxError);
3903 *ok = false;
3904 return this->EmptyExpression();
3905 }
3906 if (is_strong(language_mode()) &&
3907 this->IsUndefined(this->AsIdentifier(expression))) {
3908 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined,
3909 kSyntaxError);
3910 *ok = false;
3911 return this->EmptyExpression();
3912 }
3913 }
3914 if (expression->IsValidReferenceExpression()) {
3915 return expression;
3916 } else if (expression->IsCall()) {
3917 // If it is a call, make it a runtime error for legacy web compatibility.
3918 // Rewrite `expr' to `expr[throw ReferenceError]'.
3919 int pos = location.beg_pos;
3920 ExpressionT error = this->NewThrowReferenceError(message, pos);
3921 return factory()->NewProperty(expression, error, pos);
3922 } else {
3923 this->ReportMessageAt(location, message, kReferenceError);
3924 *ok = false;
3925 return this->EmptyExpression();
3926 }
3927 }
3928
3929
3930 #undef CHECK_OK
3931 #undef CHECK_OK_CUSTOM
3932
3933
3934 template <typename Traits>
3935 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
3936 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3937 bool* ok) {
3938 DCHECK(!is_static);
3939 DCHECK(!is_generator || type == kMethodProperty);
3940
3941 if (property == Token::SMI || property == Token::NUMBER) return;
3942
3943 if (type == kValueProperty && IsProto()) {
3944 if (has_seen_proto_) {
3945 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
3946 *ok = false;
3947 return;
3948 }
3949 has_seen_proto_ = true;
3950 return;
3951 }
3952 }
3953
3954
3955 template <typename Traits>
3956 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
3957 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3958 bool* ok) {
3959 DCHECK(type == kMethodProperty || type == kAccessorProperty);
3960
3961 if (property == Token::SMI || property == Token::NUMBER) return;
3962
3963 if (is_static) {
3964 if (IsPrototype()) {
3965 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
3966 *ok = false;
3967 return;
3968 }
3969 } else if (IsConstructor()) {
3970 if (is_generator || type == kAccessorProperty) {
3971 MessageTemplate::Template msg =
3972 is_generator ? MessageTemplate::kConstructorIsGenerator
3973 : MessageTemplate::kConstructorIsAccessor;
3974 this->parser()->ReportMessage(msg);
3975 *ok = false;
3976 return;
3977 }
3978 if (has_seen_constructor_) {
3979 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
3980 *ok = false;
3981 return;
3982 }
3983 has_seen_constructor_ = true;
3984 return;
3985 }
3986 }
3987 } } // v8::internal 1055 } } // v8::internal
3988 1056
3989 #endif // V8_PREPARSER_H 1057 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser-base.h ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698