OLD | NEW |
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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 public: | 81 public: |
82 // Shorten type names defined by Traits. | 82 // Shorten type names defined by Traits. |
83 typedef typename Traits::Type::Expression ExpressionT; | 83 typedef typename Traits::Type::Expression ExpressionT; |
84 typedef typename Traits::Type::Identifier IdentifierT; | 84 typedef typename Traits::Type::Identifier IdentifierT; |
85 typedef typename Traits::Type::FormalParameter FormalParameterT; | 85 typedef typename Traits::Type::FormalParameter FormalParameterT; |
86 typedef typename Traits::Type::FormalParameters FormalParametersT; | 86 typedef typename Traits::Type::FormalParameters FormalParametersT; |
87 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | 87 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
88 typedef typename Traits::Type::Literal LiteralT; | 88 typedef typename Traits::Type::Literal LiteralT; |
89 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; | 89 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
90 typedef typename Traits::Type::StatementList StatementListT; | 90 typedef typename Traits::Type::StatementList StatementListT; |
91 typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier; | |
92 | 91 |
93 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 92 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
94 v8::Extension* extension, AstValueFactory* ast_value_factory, | 93 v8::Extension* extension, AstValueFactory* ast_value_factory, |
95 ParserRecorder* log, typename Traits::Type::Parser this_object) | 94 ParserRecorder* log, typename Traits::Type::Parser this_object) |
96 : Traits(this_object), | 95 : Traits(this_object), |
97 parenthesized_function_(false), | 96 parenthesized_function_(false), |
98 scope_(NULL), | 97 scope_(NULL), |
99 function_state_(NULL), | 98 function_state_(NULL), |
100 extension_(extension), | 99 extension_(extension), |
101 fni_(NULL), | 100 fni_(NULL), |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 return generator_object_variable_; | 237 return generator_object_variable_; |
239 } | 238 } |
240 | 239 |
241 typename Traits::Type::Factory* factory() { return factory_; } | 240 typename Traits::Type::Factory* factory() { return factory_; } |
242 | 241 |
243 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 242 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
244 const { | 243 const { |
245 return destructuring_assignments_to_rewrite_; | 244 return destructuring_assignments_to_rewrite_; |
246 } | 245 } |
247 | 246 |
| 247 void AddDestructuringAssignment(DestructuringAssignment pair) { |
| 248 destructuring_assignments_to_rewrite_.Add(pair); |
| 249 } |
| 250 |
248 List<ExpressionT>& expressions_in_tail_position() { | 251 List<ExpressionT>& expressions_in_tail_position() { |
249 return expressions_in_tail_position_; | 252 return expressions_in_tail_position_; |
250 } | 253 } |
251 void AddExpressionInTailPosition(ExpressionT expression) { | 254 void AddExpressionInTailPosition(ExpressionT expression) { |
252 if (collect_expressions_in_tail_position_) { | 255 if (collect_expressions_in_tail_position_) { |
253 expressions_in_tail_position_.Add(expression); | 256 expressions_in_tail_position_.Add(expression); |
254 } | 257 } |
255 } | 258 } |
256 | 259 |
257 bool collect_expressions_in_tail_position() const { | 260 bool collect_expressions_in_tail_position() const { |
258 return collect_expressions_in_tail_position_; | 261 return collect_expressions_in_tail_position_; |
259 } | 262 } |
260 void set_collect_expressions_in_tail_position(bool collect) { | 263 void set_collect_expressions_in_tail_position(bool collect) { |
261 collect_expressions_in_tail_position_ = collect; | 264 collect_expressions_in_tail_position_ = collect; |
262 } | 265 } |
263 | 266 |
264 ZoneList<ExpressionT>* non_patterns_to_rewrite() { | |
265 return &non_patterns_to_rewrite_; | |
266 } | |
267 | |
268 private: | 267 private: |
269 void AddDestructuringAssignment(DestructuringAssignment pair) { | |
270 destructuring_assignments_to_rewrite_.Add(pair); | |
271 } | |
272 | |
273 V8_INLINE Scope* scope() { return *scope_stack_; } | |
274 | |
275 void AddNonPatternForRewriting(ExpressionT expr) { | |
276 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone()); | |
277 } | |
278 | |
279 // Used to assign an index to each literal that needs materialization in | 268 // Used to assign an index to each literal that needs materialization in |
280 // the function. Includes regexp literals, and boilerplate for object and | 269 // the function. Includes regexp literals, and boilerplate for object and |
281 // array literals. | 270 // array literals. |
282 int next_materialized_literal_index_; | 271 int next_materialized_literal_index_; |
283 | 272 |
284 // Properties count estimation. | 273 // Properties count estimation. |
285 int expected_property_count_; | 274 int expected_property_count_; |
286 | 275 |
287 // Location of most recent use of 'this' (invalid if none). | 276 // Location of most recent use of 'this' (invalid if none). |
288 Scanner::Location this_location_; | 277 Scanner::Location this_location_; |
(...skipping 11 matching lines...) Expand all Loading... |
300 Variable* generator_object_variable_; | 289 Variable* generator_object_variable_; |
301 | 290 |
302 FunctionState** function_state_stack_; | 291 FunctionState** function_state_stack_; |
303 FunctionState* outer_function_state_; | 292 FunctionState* outer_function_state_; |
304 Scope** scope_stack_; | 293 Scope** scope_stack_; |
305 Scope* outer_scope_; | 294 Scope* outer_scope_; |
306 | 295 |
307 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; | 296 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
308 List<ExpressionT> expressions_in_tail_position_; | 297 List<ExpressionT> expressions_in_tail_position_; |
309 bool collect_expressions_in_tail_position_; | 298 bool collect_expressions_in_tail_position_; |
310 ZoneList<ExpressionT> non_patterns_to_rewrite_; | 299 |
| 300 void RewriteDestructuringAssignments(); |
311 | 301 |
312 typename Traits::Type::Factory* factory_; | 302 typename Traits::Type::Factory* factory_; |
313 | 303 |
314 friend class ParserTraits; | 304 friend class ParserTraits; |
315 friend class PreParserTraits; | |
316 friend class Checkpoint; | 305 friend class Checkpoint; |
317 }; | 306 }; |
318 | 307 |
319 // Annoyingly, arrow functions first parse as comma expressions, then when we | 308 // Annoyingly, arrow functions first parse as comma expressions, then when we |
320 // see the => we have to go back and reinterpret the arguments as being formal | 309 // see the => we have to go back and reinterpret the arguments as being formal |
321 // parameters. To do so we need to reset some of the parser state back to | 310 // parameters. To do so we need to reset some of the parser state back to |
322 // what it was before the arguments were first seen. | 311 // what it was before the arguments were first seen. |
323 class Checkpoint BASE_EMBEDDED { | 312 class Checkpoint BASE_EMBEDDED { |
324 public: | 313 public: |
325 explicit Checkpoint(ParserBase* parser) { | 314 explicit Checkpoint(ParserBase* parser) { |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 | 583 |
595 void GetUnexpectedTokenMessage( | 584 void GetUnexpectedTokenMessage( |
596 Token::Value token, MessageTemplate::Template* message, const char** arg, | 585 Token::Value token, MessageTemplate::Template* message, const char** arg, |
597 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); | 586 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); |
598 | 587 |
599 void ReportUnexpectedToken(Token::Value token); | 588 void ReportUnexpectedToken(Token::Value token); |
600 void ReportUnexpectedTokenAt( | 589 void ReportUnexpectedTokenAt( |
601 Scanner::Location location, Token::Value token, | 590 Scanner::Location location, Token::Value token, |
602 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 591 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
603 | 592 |
604 void ReportClassifierError( | 593 |
605 const typename ExpressionClassifier::Error& error) { | 594 void ReportClassifierError(const ExpressionClassifier::Error& error) { |
606 Traits::ReportMessageAt(error.location, error.message, error.arg, | 595 Traits::ReportMessageAt(error.location, error.message, error.arg, |
607 error.type); | 596 error.type); |
608 } | 597 } |
609 | 598 |
610 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 599 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
611 if (!classifier->is_valid_expression() || | 600 if (!classifier->is_valid_expression() || |
612 classifier->has_cover_initialized_name()) { | 601 classifier->has_cover_initialized_name()) { |
613 const Scanner::Location& a = classifier->expression_error().location; | 602 const Scanner::Location& a = classifier->expression_error().location; |
614 const Scanner::Location& b = | 603 const Scanner::Location& b = |
615 classifier->cover_initialized_name_error().location; | 604 classifier->cover_initialized_name_error().location; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 Traits::ReportMessageAt(scanner()->location(), | 662 Traits::ReportMessageAt(scanner()->location(), |
674 MessageTemplate::kUnexpectedToken, | 663 MessageTemplate::kUnexpectedToken, |
675 Token::String(scanner()->current_token())); | 664 Token::String(scanner()->current_token())); |
676 *ok = false; | 665 *ok = false; |
677 } | 666 } |
678 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 667 } else if (!classifier->is_valid_arrow_formal_parameters()) { |
679 // If after parsing the expr, we see an error but the expression is | 668 // If after parsing the expr, we see an error but the expression is |
680 // neither a valid binding pattern nor a valid parenthesized formal | 669 // neither a valid binding pattern nor a valid parenthesized formal |
681 // parameter list, show the "arrow formal parameters" error if the formals | 670 // parameter list, show the "arrow formal parameters" error if the formals |
682 // started with a parenthesis, and the binding pattern error otherwise. | 671 // started with a parenthesis, and the binding pattern error otherwise. |
683 const typename ExpressionClassifier::Error& error = | 672 const ExpressionClassifier::Error& error = |
684 parenthesized_formals ? classifier->arrow_formal_parameters_error() | 673 parenthesized_formals ? classifier->arrow_formal_parameters_error() |
685 : classifier->binding_pattern_error(); | 674 : classifier->binding_pattern_error(); |
686 ReportClassifierError(error); | 675 ReportClassifierError(error); |
687 *ok = false; | 676 *ok = false; |
688 } | 677 } |
689 } | 678 } |
690 | 679 |
691 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 680 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
692 if (!classifier->is_valid_let_pattern()) { | 681 if (!classifier->is_valid_let_pattern()) { |
693 ReportClassifierError(classifier->let_pattern_error()); | 682 ReportClassifierError(classifier->let_pattern_error()); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { | 830 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { |
842 return false; | 831 return false; |
843 } | 832 } |
844 if (is_strong(language_mode()) && | 833 if (is_strong(language_mode()) && |
845 Traits::IsUndefined(Traits::AsIdentifier(expression))) { | 834 Traits::IsUndefined(Traits::AsIdentifier(expression))) { |
846 return false; | 835 return false; |
847 } | 836 } |
848 return true; | 837 return true; |
849 } | 838 } |
850 | 839 |
| 840 bool IsAssignmentExpression(ExpressionT expression) { |
| 841 return expression->IsAssignment() || |
| 842 expression->IsRewritableAssignmentExpression(); |
| 843 } |
| 844 |
851 bool IsValidPattern(ExpressionT expression) { | 845 bool IsValidPattern(ExpressionT expression) { |
852 return expression->IsObjectLiteral() || expression->IsArrayLiteral(); | 846 return expression->IsObjectLiteral() || expression->IsArrayLiteral(); |
853 } | 847 } |
854 | 848 |
855 // Keep track of eval() calls since they disable all local variable | 849 // Keep track of eval() calls since they disable all local variable |
856 // optimizations. This checks if expression is an eval call, and if yes, | 850 // optimizations. This checks if expression is an eval call, and if yes, |
857 // forwards the information to scope. | 851 // forwards the information to scope. |
858 void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) { | 852 void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) { |
859 if (Traits::IsIdentifier(expression) && | 853 if (Traits::IsIdentifier(expression) && |
860 Traits::IsEval(Traits::AsIdentifier(expression))) { | 854 Traits::IsEval(Traits::AsIdentifier(expression))) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 this_location_(Scanner::Location::invalid()), | 961 this_location_(Scanner::Location::invalid()), |
968 return_location_(Scanner::Location::invalid()), | 962 return_location_(Scanner::Location::invalid()), |
969 super_location_(Scanner::Location::invalid()), | 963 super_location_(Scanner::Location::invalid()), |
970 kind_(kind), | 964 kind_(kind), |
971 generator_object_variable_(NULL), | 965 generator_object_variable_(NULL), |
972 function_state_stack_(function_state_stack), | 966 function_state_stack_(function_state_stack), |
973 outer_function_state_(*function_state_stack), | 967 outer_function_state_(*function_state_stack), |
974 scope_stack_(scope_stack), | 968 scope_stack_(scope_stack), |
975 outer_scope_(*scope_stack), | 969 outer_scope_(*scope_stack), |
976 collect_expressions_in_tail_position_(true), | 970 collect_expressions_in_tail_position_(true), |
977 non_patterns_to_rewrite_(0, scope->zone()), | |
978 factory_(factory) { | 971 factory_(factory) { |
979 *scope_stack_ = scope; | 972 *scope_stack_ = scope; |
980 *function_state_stack = this; | 973 *function_state_stack = this; |
981 } | 974 } |
982 | 975 |
983 | 976 |
984 template <class Traits> | 977 template <class Traits> |
985 ParserBase<Traits>::FunctionState::~FunctionState() { | 978 ParserBase<Traits>::FunctionState::~FunctionState() { |
986 *scope_stack_ = outer_scope_; | 979 *scope_stack_ = outer_scope_; |
987 *function_state_stack_ = outer_function_state_; | 980 *function_state_stack_ = outer_function_state_; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 MessageTemplate::Template message) { | 1047 MessageTemplate::Template message) { |
1055 const char* arg; | 1048 const char* arg; |
1056 GetUnexpectedTokenMessage(token, &message, &arg); | 1049 GetUnexpectedTokenMessage(token, &message, &arg); |
1057 Traits::ReportMessageAt(source_location, message, arg); | 1050 Traits::ReportMessageAt(source_location, message, arg); |
1058 } | 1051 } |
1059 | 1052 |
1060 | 1053 |
1061 template <class Traits> | 1054 template <class Traits> |
1062 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | 1055 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
1063 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { | 1056 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
1064 ExpressionClassifier classifier(this); | 1057 ExpressionClassifier classifier; |
1065 auto result = ParseAndClassifyIdentifier(&classifier, ok); | 1058 auto result = ParseAndClassifyIdentifier(&classifier, ok); |
1066 if (!*ok) return Traits::EmptyIdentifier(); | 1059 if (!*ok) return Traits::EmptyIdentifier(); |
1067 | 1060 |
1068 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { | 1061 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { |
1069 ValidateAssignmentPattern(&classifier, ok); | 1062 ValidateAssignmentPattern(&classifier, ok); |
1070 if (!*ok) return Traits::EmptyIdentifier(); | 1063 if (!*ok) return Traits::EmptyIdentifier(); |
1071 ValidateBindingPattern(&classifier, ok); | 1064 ValidateBindingPattern(&classifier, ok); |
1072 if (!*ok) return Traits::EmptyIdentifier(); | 1065 if (!*ok) return Traits::EmptyIdentifier(); |
1073 } | 1066 } |
1074 | 1067 |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1425 | 1418 |
1426 ReportUnexpectedToken(Next()); | 1419 ReportUnexpectedToken(Next()); |
1427 *ok = false; | 1420 *ok = false; |
1428 return this->EmptyExpression(); | 1421 return this->EmptyExpression(); |
1429 } | 1422 } |
1430 | 1423 |
1431 | 1424 |
1432 template <class Traits> | 1425 template <class Traits> |
1433 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1426 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1434 bool accept_IN, bool* ok) { | 1427 bool accept_IN, bool* ok) { |
1435 ExpressionClassifier classifier(this); | 1428 ExpressionClassifier classifier; |
1436 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1429 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
1437 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 1430 result = Traits::RewriteNonPattern(result, &classifier, CHECK_OK); |
1438 return result; | 1431 return result; |
1439 } | 1432 } |
1440 | 1433 |
1441 | 1434 |
1442 template <class Traits> | 1435 template <class Traits> |
1443 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1436 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1444 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1437 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
1445 // Expression :: | 1438 // Expression :: |
1446 // AssignmentExpression | 1439 // AssignmentExpression |
1447 // Expression ',' AssignmentExpression | 1440 // Expression ',' AssignmentExpression |
1448 | 1441 |
1449 ExpressionClassifier binding_classifier(this); | 1442 ExpressionClassifier binding_classifier; |
1450 ExpressionT result = | 1443 ExpressionT result = |
1451 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 1444 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
1452 classifier->Accumulate(&binding_classifier, | 1445 classifier->Accumulate(binding_classifier, |
1453 ExpressionClassifier::AllProductions); | 1446 ExpressionClassifier::AllProductions); |
1454 bool is_simple_parameter_list = this->IsIdentifier(result); | 1447 bool is_simple_parameter_list = this->IsIdentifier(result); |
1455 bool seen_rest = false; | 1448 bool seen_rest = false; |
1456 while (peek() == Token::COMMA) { | 1449 while (peek() == Token::COMMA) { |
1457 if (seen_rest) { | 1450 if (seen_rest) { |
1458 // At this point the production can't possibly be valid, but we don't know | 1451 // At this point the production can't possibly be valid, but we don't know |
1459 // which error to signal. | 1452 // which error to signal. |
1460 classifier->RecordArrowFormalParametersError( | 1453 classifier->RecordArrowFormalParametersError( |
1461 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 1454 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
1462 } | 1455 } |
1463 Consume(Token::COMMA); | 1456 Consume(Token::COMMA); |
1464 bool is_rest = false; | 1457 bool is_rest = false; |
1465 if (peek() == Token::ELLIPSIS) { | 1458 if (peek() == Token::ELLIPSIS) { |
1466 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1459 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
1467 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 1460 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
1468 // valid expression or binding pattern. | 1461 // valid expression or binding pattern. |
1469 ExpressionUnexpectedToken(classifier); | 1462 ExpressionUnexpectedToken(classifier); |
1470 BindingPatternUnexpectedToken(classifier); | 1463 BindingPatternUnexpectedToken(classifier); |
1471 Consume(Token::ELLIPSIS); | 1464 Consume(Token::ELLIPSIS); |
1472 seen_rest = is_rest = true; | 1465 seen_rest = is_rest = true; |
1473 } | 1466 } |
1474 int pos = position(), expr_pos = peek_position(); | 1467 int pos = position(), expr_pos = peek_position(); |
1475 ExpressionT right = this->ParseAssignmentExpression( | 1468 ExpressionT right = this->ParseAssignmentExpression( |
1476 accept_IN, &binding_classifier, CHECK_OK); | 1469 accept_IN, &binding_classifier, CHECK_OK); |
1477 classifier->Accumulate(&binding_classifier, | |
1478 ExpressionClassifier::AllProductions); | |
1479 if (is_rest) { | 1470 if (is_rest) { |
1480 if (!this->IsIdentifier(right) && !IsValidPattern(right)) { | 1471 if (!this->IsIdentifier(right) && !IsValidPattern(right)) { |
1481 classifier->RecordArrowFormalParametersError( | 1472 classifier->RecordArrowFormalParametersError( |
1482 Scanner::Location(pos, scanner()->location().end_pos), | 1473 Scanner::Location(pos, scanner()->location().end_pos), |
1483 MessageTemplate::kInvalidRestParameter); | 1474 MessageTemplate::kInvalidRestParameter); |
1484 } | 1475 } |
1485 right = factory()->NewSpread(right, pos, expr_pos); | 1476 right = factory()->NewSpread(right, pos, expr_pos); |
1486 } | 1477 } |
1487 is_simple_parameter_list = | 1478 is_simple_parameter_list = |
1488 is_simple_parameter_list && this->IsIdentifier(right); | 1479 is_simple_parameter_list && this->IsIdentifier(right); |
| 1480 classifier->Accumulate(binding_classifier, |
| 1481 ExpressionClassifier::AllProductions); |
1489 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 1482 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
1490 } | 1483 } |
1491 if (!is_simple_parameter_list || seen_rest) { | 1484 if (!is_simple_parameter_list || seen_rest) { |
1492 classifier->RecordNonSimpleParameter(); | 1485 classifier->RecordNonSimpleParameter(); |
1493 } | 1486 } |
1494 | 1487 |
1495 return result; | 1488 return result; |
1496 } | 1489 } |
1497 | 1490 |
1498 | 1491 |
(...skipping 23 matching lines...) Expand all Loading... |
1522 Consume(Token::ELLIPSIS); | 1515 Consume(Token::ELLIPSIS); |
1523 int expr_pos = peek_position(); | 1516 int expr_pos = peek_position(); |
1524 ExpressionT argument = | 1517 ExpressionT argument = |
1525 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1518 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
1526 elem = factory()->NewSpread(argument, start_pos, expr_pos); | 1519 elem = factory()->NewSpread(argument, start_pos, expr_pos); |
1527 | 1520 |
1528 if (first_spread_index < 0) { | 1521 if (first_spread_index < 0) { |
1529 first_spread_index = values->length(); | 1522 first_spread_index = values->length(); |
1530 } | 1523 } |
1531 | 1524 |
1532 if (argument->IsAssignment()) { | 1525 if (IsAssignmentExpression(argument)) { |
1533 classifier->RecordPatternError( | 1526 classifier->RecordPatternError( |
1534 Scanner::Location(start_pos, scanner()->location().end_pos), | 1527 Scanner::Location(start_pos, scanner()->location().end_pos), |
1535 MessageTemplate::kInvalidDestructuringTarget); | 1528 MessageTemplate::kInvalidDestructuringTarget); |
1536 } else { | 1529 } else { |
1537 CheckDestructuringElement(argument, classifier, start_pos, | 1530 CheckDestructuringElement(argument, classifier, start_pos, |
1538 scanner()->location().end_pos); | 1531 scanner()->location().end_pos); |
1539 } | 1532 } |
1540 | 1533 |
1541 if (peek() == Token::COMMA) { | 1534 if (peek() == Token::COMMA) { |
1542 classifier->RecordPatternError( | 1535 classifier->RecordPatternError( |
1543 Scanner::Location(start_pos, scanner()->location().end_pos), | 1536 Scanner::Location(start_pos, scanner()->location().end_pos), |
1544 MessageTemplate::kElementAfterRest); | 1537 MessageTemplate::kElementAfterRest); |
1545 } | 1538 } |
1546 } else { | 1539 } else { |
1547 int beg_pos = peek_position(); | 1540 int beg_pos = peek_position(); |
1548 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1541 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
1549 CheckDestructuringElement(elem, classifier, beg_pos, | 1542 CheckDestructuringElement(elem, classifier, beg_pos, |
1550 scanner()->location().end_pos); | 1543 scanner()->location().end_pos); |
1551 } | 1544 } |
1552 values->Add(elem, zone_); | 1545 values->Add(elem, zone_); |
1553 if (peek() != Token::RBRACK) { | 1546 if (peek() != Token::RBRACK) { |
1554 Expect(Token::COMMA, CHECK_OK); | 1547 Expect(Token::COMMA, CHECK_OK); |
1555 } | 1548 } |
1556 } | 1549 } |
1557 Expect(Token::RBRACK, CHECK_OK); | 1550 Expect(Token::RBRACK, CHECK_OK); |
1558 | 1551 |
1559 // Update the scope information before the pre-parsing bailout. | 1552 // Update the scope information before the pre-parsing bailout. |
1560 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1553 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1561 | 1554 |
1562 ExpressionT result = | 1555 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, |
1563 factory()->NewArrayLiteral(values, first_spread_index, literal_index, | 1556 is_strong(language_mode()), pos); |
1564 is_strong(language_mode()), pos); | |
1565 if (first_spread_index >= 0) { | |
1566 result = factory()->NewRewritableExpression(result); | |
1567 Traits::QueueNonPatternForRewriting(result); | |
1568 } | |
1569 return result; | |
1570 } | 1557 } |
1571 | 1558 |
1572 | 1559 |
1573 template <class Traits> | 1560 template <class Traits> |
1574 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 1561 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
1575 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, | 1562 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, |
1576 ExpressionClassifier* classifier, bool* ok) { | 1563 ExpressionClassifier* classifier, bool* ok) { |
1577 Token::Value token = peek(); | 1564 Token::Value token = peek(); |
1578 int pos = peek_position(); | 1565 int pos = peek_position(); |
1579 | 1566 |
(...skipping 18 matching lines...) Expand all Loading... |
1598 break; | 1585 break; |
1599 | 1586 |
1600 case Token::NUMBER: | 1587 case Token::NUMBER: |
1601 Consume(Token::NUMBER); | 1588 Consume(Token::NUMBER); |
1602 *name = this->GetNumberAsSymbol(scanner()); | 1589 *name = this->GetNumberAsSymbol(scanner()); |
1603 break; | 1590 break; |
1604 | 1591 |
1605 case Token::LBRACK: { | 1592 case Token::LBRACK: { |
1606 *is_computed_name = true; | 1593 *is_computed_name = true; |
1607 Consume(Token::LBRACK); | 1594 Consume(Token::LBRACK); |
1608 ExpressionClassifier computed_name_classifier(this); | 1595 ExpressionClassifier computed_name_classifier; |
1609 ExpressionT expression = | 1596 ExpressionT expression = |
1610 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); | 1597 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); |
1611 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 1598 expression = Traits::RewriteNonPattern( |
1612 classifier->Accumulate(&computed_name_classifier, | 1599 expression, &computed_name_classifier, CHECK_OK); |
| 1600 classifier->Accumulate(computed_name_classifier, |
1613 ExpressionClassifier::ExpressionProductions); | 1601 ExpressionClassifier::ExpressionProductions); |
1614 Expect(Token::RBRACK, CHECK_OK); | 1602 Expect(Token::RBRACK, CHECK_OK); |
1615 return expression; | 1603 return expression; |
1616 } | 1604 } |
1617 | 1605 |
1618 default: | 1606 default: |
1619 *name = ParseIdentifierName(CHECK_OK); | 1607 *name = ParseIdentifierName(CHECK_OK); |
1620 scanner()->IsGetOrSet(is_get, is_set); | 1608 scanner()->IsGetOrSet(is_get, is_set); |
1621 break; | 1609 break; |
1622 } | 1610 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 classifier->RecordLetPatternError( | 1678 classifier->RecordLetPatternError( |
1691 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 1679 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
1692 } | 1680 } |
1693 | 1681 |
1694 ExpressionT lhs = this->ExpressionFromIdentifier( | 1682 ExpressionT lhs = this->ExpressionFromIdentifier( |
1695 *name, next_beg_pos, next_end_pos, scope_, factory()); | 1683 *name, next_beg_pos, next_end_pos, scope_, factory()); |
1696 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 1684 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
1697 | 1685 |
1698 if (peek() == Token::ASSIGN) { | 1686 if (peek() == Token::ASSIGN) { |
1699 Consume(Token::ASSIGN); | 1687 Consume(Token::ASSIGN); |
1700 ExpressionClassifier rhs_classifier(this); | 1688 ExpressionClassifier rhs_classifier; |
1701 ExpressionT rhs = this->ParseAssignmentExpression( | 1689 ExpressionT rhs = this->ParseAssignmentExpression( |
1702 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1690 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1703 Traits::RewriteNonPattern(&rhs_classifier, | 1691 rhs = Traits::RewriteNonPattern( |
1704 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1692 rhs, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1705 classifier->Accumulate(&rhs_classifier, | 1693 classifier->Accumulate(rhs_classifier, |
1706 ExpressionClassifier::ExpressionProductions); | 1694 ExpressionClassifier::ExpressionProductions); |
1707 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 1695 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
1708 RelocInfo::kNoPosition); | 1696 RelocInfo::kNoPosition); |
1709 classifier->RecordCoverInitializedNameError( | 1697 classifier->RecordCoverInitializedNameError( |
1710 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 1698 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
1711 MessageTemplate::kInvalidCoverInitializedName); | 1699 MessageTemplate::kInvalidCoverInitializedName); |
1712 | 1700 |
1713 if (allow_harmony_function_name()) { | 1701 if (allow_harmony_function_name()) { |
1714 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs); | 1702 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs); |
1715 } | 1703 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1757 is_static, *is_computed_name); | 1745 is_static, *is_computed_name); |
1758 } | 1746 } |
1759 | 1747 |
1760 if (in_class && name_token == Token::STATIC && !is_static) { | 1748 if (in_class && name_token == Token::STATIC && !is_static) { |
1761 // ClassElement (static) | 1749 // ClassElement (static) |
1762 // 'static' MethodDefinition | 1750 // 'static' MethodDefinition |
1763 *name = this->EmptyIdentifier(); | 1751 *name = this->EmptyIdentifier(); |
1764 ObjectLiteralPropertyT property = ParsePropertyDefinition( | 1752 ObjectLiteralPropertyT property = ParsePropertyDefinition( |
1765 checker, true, has_extends, true, is_computed_name, nullptr, classifier, | 1753 checker, true, has_extends, true, is_computed_name, nullptr, classifier, |
1766 name, ok); | 1754 name, ok); |
1767 Traits::RewriteNonPattern(classifier, ok); | 1755 property = Traits::RewriteNonPatternObjectLiteralProperty(property, |
| 1756 classifier, ok); |
1768 return property; | 1757 return property; |
1769 } | 1758 } |
1770 | 1759 |
1771 if (is_get || is_set) { | 1760 if (is_get || is_set) { |
1772 // MethodDefinition (Accessors) | 1761 // MethodDefinition (Accessors) |
1773 // get PropertyName '(' ')' '{' FunctionBody '}' | 1762 // get PropertyName '(' ')' '{' FunctionBody '}' |
1774 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 1763 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
1775 *name = this->EmptyIdentifier(); | 1764 *name = this->EmptyIdentifier(); |
1776 bool dont_care = false; | 1765 bool dont_care = false; |
1777 name_token = peek(); | 1766 name_token = peek(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1896 bool done = (peek() == Token::RPAREN); | 1885 bool done = (peek() == Token::RPAREN); |
1897 bool was_unspread = false; | 1886 bool was_unspread = false; |
1898 int unspread_sequences_count = 0; | 1887 int unspread_sequences_count = 0; |
1899 while (!done) { | 1888 while (!done) { |
1900 int start_pos = peek_position(); | 1889 int start_pos = peek_position(); |
1901 bool is_spread = Check(Token::ELLIPSIS); | 1890 bool is_spread = Check(Token::ELLIPSIS); |
1902 int expr_pos = peek_position(); | 1891 int expr_pos = peek_position(); |
1903 | 1892 |
1904 ExpressionT argument = this->ParseAssignmentExpression( | 1893 ExpressionT argument = this->ParseAssignmentExpression( |
1905 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 1894 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
1906 Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 1895 argument = Traits::RewriteNonPattern(argument, classifier, |
| 1896 CHECK_OK_CUSTOM(NullExpressionList)); |
1907 if (is_spread) { | 1897 if (is_spread) { |
1908 if (!spread_arg.IsValid()) { | 1898 if (!spread_arg.IsValid()) { |
1909 spread_arg.beg_pos = start_pos; | 1899 spread_arg.beg_pos = start_pos; |
1910 spread_arg.end_pos = peek_position(); | 1900 spread_arg.end_pos = peek_position(); |
1911 } | 1901 } |
1912 argument = factory()->NewSpread(argument, start_pos, expr_pos); | 1902 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
1913 } | 1903 } |
1914 result->Add(argument, zone_); | 1904 result->Add(argument, zone_); |
1915 | 1905 |
1916 // unspread_sequences_count is the number of sequences of parameters which | 1906 // unspread_sequences_count is the number of sequences of parameters which |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1953 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1964 bool is_destructuring_assignment = false; | 1954 bool is_destructuring_assignment = false; |
1965 int lhs_beg_pos = peek_position(); | 1955 int lhs_beg_pos = peek_position(); |
1966 | 1956 |
1967 if (peek() == Token::YIELD && is_generator()) { | 1957 if (peek() == Token::YIELD && is_generator()) { |
1968 return this->ParseYieldExpression(classifier, ok); | 1958 return this->ParseYieldExpression(classifier, ok); |
1969 } | 1959 } |
1970 | 1960 |
1971 FuncNameInferrer::State fni_state(fni_); | 1961 FuncNameInferrer::State fni_state(fni_); |
1972 ParserBase<Traits>::Checkpoint checkpoint(this); | 1962 ParserBase<Traits>::Checkpoint checkpoint(this); |
1973 ExpressionClassifier arrow_formals_classifier(this, | 1963 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); |
1974 classifier->duplicate_finder()); | |
1975 bool parenthesized_formals = peek() == Token::LPAREN; | 1964 bool parenthesized_formals = peek() == Token::LPAREN; |
1976 if (!parenthesized_formals) { | 1965 if (!parenthesized_formals) { |
1977 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 1966 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); |
1978 } | 1967 } |
1979 ExpressionT expression = this->ParseConditionalExpression( | 1968 ExpressionT expression = this->ParseConditionalExpression( |
1980 accept_IN, &arrow_formals_classifier, CHECK_OK); | 1969 accept_IN, &arrow_formals_classifier, CHECK_OK); |
1981 if (peek() == Token::ARROW) { | 1970 if (peek() == Token::ARROW) { |
1982 classifier->RecordPatternError(scanner()->peek_location(), | 1971 classifier->RecordPatternError(scanner()->peek_location(), |
1983 MessageTemplate::kUnexpectedToken, | 1972 MessageTemplate::kUnexpectedToken, |
1984 Token::String(Token::ARROW)); | 1973 Token::String(Token::ARROW)); |
(...skipping 29 matching lines...) Expand all Loading... |
2014 | 2003 |
2015 return expression; | 2004 return expression; |
2016 } | 2005 } |
2017 | 2006 |
2018 if (this->IsValidReferenceExpression(expression)) { | 2007 if (this->IsValidReferenceExpression(expression)) { |
2019 arrow_formals_classifier.ForgiveAssignmentPatternError(); | 2008 arrow_formals_classifier.ForgiveAssignmentPatternError(); |
2020 } | 2009 } |
2021 | 2010 |
2022 // "expression" was not itself an arrow function parameter list, but it might | 2011 // "expression" was not itself an arrow function parameter list, but it might |
2023 // form part of one. Propagate speculative formal parameter error locations. | 2012 // form part of one. Propagate speculative formal parameter error locations. |
2024 // Do not merge pending non-pattern expressions yet! | |
2025 classifier->Accumulate( | 2013 classifier->Accumulate( |
2026 &arrow_formals_classifier, | 2014 arrow_formals_classifier, |
2027 ExpressionClassifier::StandardProductions | | 2015 ExpressionClassifier::StandardProductions | |
2028 ExpressionClassifier::FormalParametersProductions | | 2016 ExpressionClassifier::FormalParametersProductions | |
2029 ExpressionClassifier::CoverInitializedNameProduction, | 2017 ExpressionClassifier::CoverInitializedNameProduction); |
2030 false); | |
2031 | 2018 |
2032 if (!Token::IsAssignmentOp(peek())) { | 2019 if (!Token::IsAssignmentOp(peek())) { |
2033 // Parsed conditional expression only (no assignment). | 2020 // Parsed conditional expression only (no assignment). |
2034 // Now pending non-pattern expressions must be merged. | |
2035 classifier->MergeNonPatterns(&arrow_formals_classifier); | |
2036 return expression; | 2021 return expression; |
2037 } | 2022 } |
2038 | 2023 |
2039 // Now pending non-pattern expressions must be discarded. | |
2040 arrow_formals_classifier.Discard(); | |
2041 | |
2042 if (!(allow_harmony_destructuring_bind() || | 2024 if (!(allow_harmony_destructuring_bind() || |
2043 allow_harmony_default_parameters())) { | 2025 allow_harmony_default_parameters())) { |
2044 BindingPatternUnexpectedToken(classifier); | 2026 BindingPatternUnexpectedToken(classifier); |
2045 } | 2027 } |
2046 | 2028 |
2047 if (allow_harmony_destructuring_assignment() && IsValidPattern(expression) && | 2029 if (allow_harmony_destructuring_assignment() && IsValidPattern(expression) && |
2048 peek() == Token::ASSIGN) { | 2030 peek() == Token::ASSIGN) { |
2049 classifier->ForgiveCoverInitializedNameError(); | 2031 classifier->ForgiveCoverInitializedNameError(); |
2050 ValidateAssignmentPattern(classifier, CHECK_OK); | 2032 ValidateAssignmentPattern(classifier, CHECK_OK); |
2051 is_destructuring_assignment = true; | 2033 is_destructuring_assignment = true; |
(...skipping 13 matching lines...) Expand all Loading... |
2065 expression = this->MarkExpressionAsAssigned(expression); | 2047 expression = this->MarkExpressionAsAssigned(expression); |
2066 | 2048 |
2067 Token::Value op = Next(); // Get assignment operator. | 2049 Token::Value op = Next(); // Get assignment operator. |
2068 if (op != Token::ASSIGN) { | 2050 if (op != Token::ASSIGN) { |
2069 classifier->RecordPatternError(scanner()->location(), | 2051 classifier->RecordPatternError(scanner()->location(), |
2070 MessageTemplate::kUnexpectedToken, | 2052 MessageTemplate::kUnexpectedToken, |
2071 Token::String(op)); | 2053 Token::String(op)); |
2072 } | 2054 } |
2073 int pos = position(); | 2055 int pos = position(); |
2074 | 2056 |
2075 ExpressionClassifier rhs_classifier(this); | 2057 ExpressionClassifier rhs_classifier; |
2076 | 2058 |
2077 ExpressionT right = | 2059 ExpressionT right = |
2078 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2060 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
2079 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); | 2061 right = Traits::RewriteNonPattern(right, &rhs_classifier, CHECK_OK); |
2080 classifier->Accumulate( | 2062 classifier->Accumulate( |
2081 &rhs_classifier, ExpressionClassifier::ExpressionProductions | | 2063 rhs_classifier, ExpressionClassifier::ExpressionProductions | |
2082 ExpressionClassifier::CoverInitializedNameProduction); | 2064 ExpressionClassifier::CoverInitializedNameProduction); |
2083 | 2065 |
2084 // TODO(1231235): We try to estimate the set of properties set by | 2066 // TODO(1231235): We try to estimate the set of properties set by |
2085 // constructors. We define a new property whenever there is an | 2067 // constructors. We define a new property whenever there is an |
2086 // assignment to a property of 'this'. We should probably only add | 2068 // assignment to a property of 'this'. We should probably only add |
2087 // properties if we haven't seen them before. Otherwise we'll | 2069 // properties if we haven't seen them before. Otherwise we'll |
2088 // probably overestimate the number of properties. | 2070 // probably overestimate the number of properties. |
2089 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 2071 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
2090 function_state_->AddProperty(); | 2072 function_state_->AddProperty(); |
2091 } | 2073 } |
2092 | 2074 |
(...skipping 11 matching lines...) Expand all Loading... |
2104 } | 2086 } |
2105 } | 2087 } |
2106 | 2088 |
2107 if (op == Token::ASSIGN && allow_harmony_function_name()) { | 2089 if (op == Token::ASSIGN && allow_harmony_function_name()) { |
2108 Traits::SetFunctionNameFromIdentifierRef(right, expression); | 2090 Traits::SetFunctionNameFromIdentifierRef(right, expression); |
2109 } | 2091 } |
2110 | 2092 |
2111 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); | 2093 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
2112 | 2094 |
2113 if (is_destructuring_assignment) { | 2095 if (is_destructuring_assignment) { |
2114 result = factory()->NewRewritableExpression(result); | 2096 result = factory()->NewRewritableAssignmentExpression(result); |
2115 Traits::QueueDestructuringAssignmentForRewriting(result); | 2097 Traits::QueueDestructuringAssignmentForRewriting(result); |
2116 } | 2098 } |
2117 | 2099 |
2118 return result; | 2100 return result; |
2119 } | 2101 } |
2120 | 2102 |
2121 template <class Traits> | 2103 template <class Traits> |
2122 typename ParserBase<Traits>::ExpressionT | 2104 typename ParserBase<Traits>::ExpressionT |
2123 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 2105 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
2124 bool* ok) { | 2106 bool* ok) { |
(...skipping 21 matching lines...) Expand all Loading... |
2146 // The above set of tokens is the complete set of tokens that can appear | 2128 // The above set of tokens is the complete set of tokens that can appear |
2147 // after an AssignmentExpression, and none of them can start an | 2129 // after an AssignmentExpression, and none of them can start an |
2148 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2130 // AssignmentExpression. This allows us to avoid looking for an RHS for |
2149 // a Yield::kSuspend operation, given only one look-ahead token. | 2131 // a Yield::kSuspend operation, given only one look-ahead token. |
2150 if (kind == Yield::kSuspend) | 2132 if (kind == Yield::kSuspend) |
2151 break; | 2133 break; |
2152 DCHECK_EQ(Yield::kDelegating, kind); | 2134 DCHECK_EQ(Yield::kDelegating, kind); |
2153 // Delegating yields require an RHS; fall through. | 2135 // Delegating yields require an RHS; fall through. |
2154 default: | 2136 default: |
2155 expression = ParseAssignmentExpression(false, classifier, CHECK_OK); | 2137 expression = ParseAssignmentExpression(false, classifier, CHECK_OK); |
2156 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2138 expression = |
| 2139 Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
2157 break; | 2140 break; |
2158 } | 2141 } |
2159 } | 2142 } |
2160 if (kind == Yield::kDelegating) { | 2143 if (kind == Yield::kDelegating) { |
2161 return Traits::RewriteYieldStar(generator_object, expression, pos); | 2144 return Traits::RewriteYieldStar(generator_object, expression, pos); |
2162 } | 2145 } |
2163 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2146 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
2164 // TODO(verwaest): Come up with a better solution. | 2147 // TODO(verwaest): Come up with a better solution. |
2165 typename Traits::Type::YieldExpression yield = | 2148 typename Traits::Type::YieldExpression yield = |
2166 factory()->NewYield(generator_object, expression, kind, pos); | 2149 factory()->NewYield(generator_object, expression, kind, pos); |
2167 return yield; | 2150 return yield; |
2168 } | 2151 } |
2169 | 2152 |
2170 | 2153 |
2171 // Precedence = 3 | 2154 // Precedence = 3 |
2172 template <class Traits> | 2155 template <class Traits> |
2173 typename ParserBase<Traits>::ExpressionT | 2156 typename ParserBase<Traits>::ExpressionT |
2174 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, | 2157 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
2175 ExpressionClassifier* classifier, | 2158 ExpressionClassifier* classifier, |
2176 bool* ok) { | 2159 bool* ok) { |
2177 // ConditionalExpression :: | 2160 // ConditionalExpression :: |
2178 // LogicalOrExpression | 2161 // LogicalOrExpression |
2179 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2162 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2180 | 2163 |
2181 int pos = peek_position(); | 2164 int pos = peek_position(); |
2182 // We start using the binary expression parser for prec >= 4 only! | 2165 // We start using the binary expression parser for prec >= 4 only! |
2183 ExpressionT expression = | 2166 ExpressionT expression = |
2184 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | 2167 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
2185 if (peek() != Token::CONDITIONAL) return expression; | 2168 if (peek() != Token::CONDITIONAL) return expression; |
2186 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2169 expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
2187 ArrowFormalParametersUnexpectedToken(classifier); | 2170 ArrowFormalParametersUnexpectedToken(classifier); |
2188 BindingPatternUnexpectedToken(classifier); | 2171 BindingPatternUnexpectedToken(classifier); |
2189 Consume(Token::CONDITIONAL); | 2172 Consume(Token::CONDITIONAL); |
2190 // In parsing the first assignment expression in conditional | 2173 // In parsing the first assignment expression in conditional |
2191 // expressions we always accept the 'in' keyword; see ECMA-262, | 2174 // expressions we always accept the 'in' keyword; see ECMA-262, |
2192 // section 11.12, page 58. | 2175 // section 11.12, page 58. |
2193 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 2176 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
2194 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2177 left = Traits::RewriteNonPattern(left, classifier, CHECK_OK); |
2195 Expect(Token::COLON, CHECK_OK); | 2178 Expect(Token::COLON, CHECK_OK); |
2196 ExpressionT right = | 2179 ExpressionT right = |
2197 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2180 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2198 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2181 right = Traits::RewriteNonPattern(right, classifier, CHECK_OK); |
2199 return factory()->NewConditional(expression, left, right, pos); | 2182 return factory()->NewConditional(expression, left, right, pos); |
2200 } | 2183 } |
2201 | 2184 |
2202 | 2185 |
2203 // Precedence >= 4 | 2186 // Precedence >= 4 |
2204 template <class Traits> | 2187 template <class Traits> |
2205 typename ParserBase<Traits>::ExpressionT | 2188 typename ParserBase<Traits>::ExpressionT |
2206 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, | 2189 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
2207 ExpressionClassifier* classifier, | 2190 ExpressionClassifier* classifier, |
2208 bool* ok) { | 2191 bool* ok) { |
2209 DCHECK(prec >= 4); | 2192 DCHECK(prec >= 4); |
2210 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 2193 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
2211 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2194 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2212 // prec1 >= 4 | 2195 // prec1 >= 4 |
2213 while (Precedence(peek(), accept_IN) == prec1) { | 2196 while (Precedence(peek(), accept_IN) == prec1) { |
2214 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2197 x = Traits::RewriteNonPattern(x, classifier, CHECK_OK); |
2215 BindingPatternUnexpectedToken(classifier); | 2198 BindingPatternUnexpectedToken(classifier); |
2216 ArrowFormalParametersUnexpectedToken(classifier); | 2199 ArrowFormalParametersUnexpectedToken(classifier); |
2217 Token::Value op = Next(); | 2200 Token::Value op = Next(); |
2218 Scanner::Location op_location = scanner()->location(); | 2201 Scanner::Location op_location = scanner()->location(); |
2219 int pos = position(); | 2202 int pos = position(); |
2220 ExpressionT y = | 2203 ExpressionT y = |
2221 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); | 2204 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); |
2222 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2205 y = Traits::RewriteNonPattern(y, classifier, CHECK_OK); |
2223 | 2206 |
2224 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2207 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
2225 factory())) { | 2208 factory())) { |
2226 continue; | 2209 continue; |
2227 } | 2210 } |
2228 | 2211 |
2229 // For now we distinguish between comparisons and other binary | 2212 // For now we distinguish between comparisons and other binary |
2230 // operations. (We could combine the two and get rid of this | 2213 // operations. (We could combine the two and get rid of this |
2231 // code and AST node eventually.) | 2214 // code and AST node eventually.) |
2232 if (Token::IsCompareOp(op)) { | 2215 if (Token::IsCompareOp(op)) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2275 // '!' UnaryExpression | 2258 // '!' UnaryExpression |
2276 | 2259 |
2277 Token::Value op = peek(); | 2260 Token::Value op = peek(); |
2278 if (Token::IsUnaryOp(op)) { | 2261 if (Token::IsUnaryOp(op)) { |
2279 BindingPatternUnexpectedToken(classifier); | 2262 BindingPatternUnexpectedToken(classifier); |
2280 ArrowFormalParametersUnexpectedToken(classifier); | 2263 ArrowFormalParametersUnexpectedToken(classifier); |
2281 | 2264 |
2282 op = Next(); | 2265 op = Next(); |
2283 int pos = position(); | 2266 int pos = position(); |
2284 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2267 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
2285 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2268 expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
2286 | 2269 |
2287 if (op == Token::DELETE && is_strict(language_mode())) { | 2270 if (op == Token::DELETE && is_strict(language_mode())) { |
2288 if (is_strong(language_mode())) { | 2271 if (is_strong(language_mode())) { |
2289 ReportMessage(MessageTemplate::kStrongDelete); | 2272 ReportMessage(MessageTemplate::kStrongDelete); |
2290 *ok = false; | 2273 *ok = false; |
2291 return this->EmptyExpression(); | 2274 return this->EmptyExpression(); |
2292 } else if (this->IsIdentifier(expression)) { | 2275 } else if (this->IsIdentifier(expression)) { |
2293 // "delete identifier" is a syntax error in strict mode. | 2276 // "delete identifier" is a syntax error in strict mode. |
2294 ReportMessage(MessageTemplate::kStrictDelete); | 2277 ReportMessage(MessageTemplate::kStrictDelete); |
2295 *ok = false; | 2278 *ok = false; |
2296 return this->EmptyExpression(); | 2279 return this->EmptyExpression(); |
2297 } | 2280 } |
2298 } | 2281 } |
2299 | 2282 |
2300 // Allow Traits do rewrite the expression. | 2283 // Allow Traits do rewrite the expression. |
2301 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2284 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2302 } else if (Token::IsCountOp(op)) { | 2285 } else if (Token::IsCountOp(op)) { |
2303 BindingPatternUnexpectedToken(classifier); | 2286 BindingPatternUnexpectedToken(classifier); |
2304 ArrowFormalParametersUnexpectedToken(classifier); | 2287 ArrowFormalParametersUnexpectedToken(classifier); |
2305 op = Next(); | 2288 op = Next(); |
2306 int beg_pos = peek_position(); | 2289 int beg_pos = peek_position(); |
2307 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 2290 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
2308 expression = this->CheckAndRewriteReferenceExpression( | 2291 expression = this->CheckAndRewriteReferenceExpression( |
2309 expression, beg_pos, scanner()->location().end_pos, | 2292 expression, beg_pos, scanner()->location().end_pos, |
2310 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2293 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
2311 this->MarkExpressionAsAssigned(expression); | 2294 this->MarkExpressionAsAssigned(expression); |
2312 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2295 expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
2313 | 2296 |
2314 return factory()->NewCountOperation(op, | 2297 return factory()->NewCountOperation(op, |
2315 true /* prefix */, | 2298 true /* prefix */, |
2316 expression, | 2299 expression, |
2317 position()); | 2300 position()); |
2318 | 2301 |
2319 } else { | 2302 } else { |
2320 return this->ParsePostfixExpression(classifier, ok); | 2303 return this->ParsePostfixExpression(classifier, ok); |
2321 } | 2304 } |
2322 } | 2305 } |
(...skipping 11 matching lines...) Expand all Loading... |
2334 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 2317 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
2335 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2318 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2336 Token::IsCountOp(peek())) { | 2319 Token::IsCountOp(peek())) { |
2337 BindingPatternUnexpectedToken(classifier); | 2320 BindingPatternUnexpectedToken(classifier); |
2338 ArrowFormalParametersUnexpectedToken(classifier); | 2321 ArrowFormalParametersUnexpectedToken(classifier); |
2339 | 2322 |
2340 expression = this->CheckAndRewriteReferenceExpression( | 2323 expression = this->CheckAndRewriteReferenceExpression( |
2341 expression, lhs_beg_pos, scanner()->location().end_pos, | 2324 expression, lhs_beg_pos, scanner()->location().end_pos, |
2342 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); | 2325 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
2343 expression = this->MarkExpressionAsAssigned(expression); | 2326 expression = this->MarkExpressionAsAssigned(expression); |
2344 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2327 expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
2345 | 2328 |
2346 Token::Value next = Next(); | 2329 Token::Value next = Next(); |
2347 expression = | 2330 expression = |
2348 factory()->NewCountOperation(next, | 2331 factory()->NewCountOperation(next, |
2349 false /* postfix */, | 2332 false /* postfix */, |
2350 expression, | 2333 expression, |
2351 position()); | 2334 position()); |
2352 } | 2335 } |
2353 return expression; | 2336 return expression; |
2354 } | 2337 } |
2355 | 2338 |
2356 | 2339 |
2357 template <class Traits> | 2340 template <class Traits> |
2358 typename ParserBase<Traits>::ExpressionT | 2341 typename ParserBase<Traits>::ExpressionT |
2359 ParserBase<Traits>::ParseLeftHandSideExpression( | 2342 ParserBase<Traits>::ParseLeftHandSideExpression( |
2360 ExpressionClassifier* classifier, bool* ok) { | 2343 ExpressionClassifier* classifier, bool* ok) { |
2361 // LeftHandSideExpression :: | 2344 // LeftHandSideExpression :: |
2362 // (NewExpression | MemberExpression) ... | 2345 // (NewExpression | MemberExpression) ... |
2363 | 2346 |
2364 ExpressionT result = | 2347 ExpressionT result = |
2365 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2348 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
2366 | 2349 |
2367 while (true) { | 2350 while (true) { |
2368 switch (peek()) { | 2351 switch (peek()) { |
2369 case Token::LBRACK: { | 2352 case Token::LBRACK: { |
2370 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2353 result = Traits::RewriteNonPattern(result, classifier, CHECK_OK); |
2371 BindingPatternUnexpectedToken(classifier); | 2354 BindingPatternUnexpectedToken(classifier); |
2372 ArrowFormalParametersUnexpectedToken(classifier); | 2355 ArrowFormalParametersUnexpectedToken(classifier); |
2373 Consume(Token::LBRACK); | 2356 Consume(Token::LBRACK); |
2374 int pos = position(); | 2357 int pos = position(); |
2375 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2358 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
2376 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2359 index = Traits::RewriteNonPattern(index, classifier, CHECK_OK); |
2377 result = factory()->NewProperty(result, index, pos); | 2360 result = factory()->NewProperty(result, index, pos); |
2378 Expect(Token::RBRACK, CHECK_OK); | 2361 Expect(Token::RBRACK, CHECK_OK); |
2379 break; | 2362 break; |
2380 } | 2363 } |
2381 | 2364 |
2382 case Token::LPAREN: { | 2365 case Token::LPAREN: { |
2383 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2366 result = Traits::RewriteNonPattern(result, classifier, CHECK_OK); |
2384 BindingPatternUnexpectedToken(classifier); | 2367 BindingPatternUnexpectedToken(classifier); |
2385 ArrowFormalParametersUnexpectedToken(classifier); | 2368 ArrowFormalParametersUnexpectedToken(classifier); |
2386 | 2369 |
2387 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 2370 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
2388 this->IsEval(this->AsIdentifier(result))) { | 2371 this->IsEval(this->AsIdentifier(result))) { |
2389 ReportMessage(MessageTemplate::kStrongDirectEval); | 2372 ReportMessage(MessageTemplate::kStrongDirectEval); |
2390 *ok = false; | 2373 *ok = false; |
2391 return this->EmptyExpression(); | 2374 return this->EmptyExpression(); |
2392 } | 2375 } |
2393 int pos; | 2376 int pos; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2437 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | 2420 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); |
2438 result = | 2421 result = |
2439 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 2422 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
2440 } | 2423 } |
2441 | 2424 |
2442 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2425 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2443 break; | 2426 break; |
2444 } | 2427 } |
2445 | 2428 |
2446 case Token::PERIOD: { | 2429 case Token::PERIOD: { |
2447 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2430 result = Traits::RewriteNonPattern(result, classifier, CHECK_OK); |
2448 BindingPatternUnexpectedToken(classifier); | 2431 BindingPatternUnexpectedToken(classifier); |
2449 ArrowFormalParametersUnexpectedToken(classifier); | 2432 ArrowFormalParametersUnexpectedToken(classifier); |
2450 Consume(Token::PERIOD); | 2433 Consume(Token::PERIOD); |
2451 int pos = position(); | 2434 int pos = position(); |
2452 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2435 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2453 result = factory()->NewProperty( | 2436 result = factory()->NewProperty( |
2454 result, factory()->NewStringLiteral(name, pos), pos); | 2437 result, factory()->NewStringLiteral(name, pos), pos); |
2455 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2438 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
2456 break; | 2439 break; |
2457 } | 2440 } |
2458 | 2441 |
2459 case Token::TEMPLATE_SPAN: | 2442 case Token::TEMPLATE_SPAN: |
2460 case Token::TEMPLATE_TAIL: { | 2443 case Token::TEMPLATE_TAIL: { |
2461 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2444 result = Traits::RewriteNonPattern(result, classifier, CHECK_OK); |
2462 BindingPatternUnexpectedToken(classifier); | 2445 BindingPatternUnexpectedToken(classifier); |
2463 ArrowFormalParametersUnexpectedToken(classifier); | 2446 ArrowFormalParametersUnexpectedToken(classifier); |
2464 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2447 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
2465 break; | 2448 break; |
2466 } | 2449 } |
2467 | 2450 |
2468 default: | 2451 default: |
2469 return result; | 2452 return result; |
2470 } | 2453 } |
2471 } | 2454 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 int new_pos = position(); | 2486 int new_pos = position(); |
2504 ExpressionT result = this->EmptyExpression(); | 2487 ExpressionT result = this->EmptyExpression(); |
2505 if (peek() == Token::SUPER) { | 2488 if (peek() == Token::SUPER) { |
2506 const bool is_new = true; | 2489 const bool is_new = true; |
2507 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 2490 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
2508 } else if (peek() == Token::PERIOD) { | 2491 } else if (peek() == Token::PERIOD) { |
2509 return ParseNewTargetExpression(CHECK_OK); | 2492 return ParseNewTargetExpression(CHECK_OK); |
2510 } else { | 2493 } else { |
2511 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2494 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
2512 } | 2495 } |
2513 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2496 result = Traits::RewriteNonPattern(result, classifier, CHECK_OK); |
2514 if (peek() == Token::LPAREN) { | 2497 if (peek() == Token::LPAREN) { |
2515 // NewExpression with arguments. | 2498 // NewExpression with arguments. |
2516 Scanner::Location spread_pos; | 2499 Scanner::Location spread_pos; |
2517 typename Traits::Type::ExpressionList args = | 2500 typename Traits::Type::ExpressionList args = |
2518 this->ParseArguments(&spread_pos, classifier, CHECK_OK); | 2501 this->ParseArguments(&spread_pos, classifier, CHECK_OK); |
2519 | 2502 |
2520 if (spread_pos.IsValid()) { | 2503 if (spread_pos.IsValid()) { |
2521 args = Traits::PrepareSpreadArguments(args); | 2504 args = Traits::PrepareSpreadArguments(args); |
2522 result = Traits::SpreadCallNew(result, args, new_pos); | 2505 result = Traits::SpreadCallNew(result, args, new_pos); |
2523 } else { | 2506 } else { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 int pos = position(); | 2602 int pos = position(); |
2620 function_state_->set_this_location(scanner()->location()); | 2603 function_state_->set_this_location(scanner()->location()); |
2621 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | 2604 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); |
2622 | 2605 |
2623 ExpressionT left = this->EmptyExpression(); | 2606 ExpressionT left = this->EmptyExpression(); |
2624 switch (peek()) { | 2607 switch (peek()) { |
2625 case Token::LBRACK: { | 2608 case Token::LBRACK: { |
2626 Consume(Token::LBRACK); | 2609 Consume(Token::LBRACK); |
2627 int pos = position(); | 2610 int pos = position(); |
2628 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 2611 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
2629 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2612 index = Traits::RewriteNonPattern(index, classifier, CHECK_OK); |
2630 left = factory()->NewProperty(this_expr, index, pos); | 2613 left = factory()->NewProperty(this_expr, index, pos); |
2631 if (fni_ != NULL) { | 2614 if (fni_ != NULL) { |
2632 this->PushPropertyName(fni_, index); | 2615 this->PushPropertyName(fni_, index); |
2633 } | 2616 } |
2634 Expect(Token::RBRACK, CHECK_OK); | 2617 Expect(Token::RBRACK, CHECK_OK); |
2635 break; | 2618 break; |
2636 } | 2619 } |
2637 case Token::PERIOD: { | 2620 case Token::PERIOD: { |
2638 Consume(Token::PERIOD); | 2621 Consume(Token::PERIOD); |
2639 int pos = position(); | 2622 int pos = position(); |
(...skipping 15 matching lines...) Expand all Loading... |
2655 ReportMessageAt(function_state_->this_location(), | 2638 ReportMessageAt(function_state_->this_location(), |
2656 MessageTemplate::kStrongConstructorThis); | 2639 MessageTemplate::kStrongConstructorThis); |
2657 *ok = false; | 2640 *ok = false; |
2658 return this->EmptyExpression(); | 2641 return this->EmptyExpression(); |
2659 } | 2642 } |
2660 Consume(Token::ASSIGN); | 2643 Consume(Token::ASSIGN); |
2661 left = this->MarkExpressionAsAssigned(left); | 2644 left = this->MarkExpressionAsAssigned(left); |
2662 | 2645 |
2663 ExpressionT right = | 2646 ExpressionT right = |
2664 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2647 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
2665 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2648 right = Traits::RewriteNonPattern(right, classifier, CHECK_OK); |
2666 this->CheckAssigningFunctionLiteralToProperty(left, right); | 2649 this->CheckAssigningFunctionLiteralToProperty(left, right); |
2667 function_state_->AddProperty(); | 2650 function_state_->AddProperty(); |
2668 if (fni_ != NULL) { | 2651 if (fni_ != NULL) { |
2669 // Check if the right hand side is a call to avoid inferring a | 2652 // Check if the right hand side is a call to avoid inferring a |
2670 // name if we're dealing with "this.a = function(){...}();"-like | 2653 // name if we're dealing with "this.a = function(){...}();"-like |
2671 // expression. | 2654 // expression. |
2672 if (!right->IsCall() && !right->IsCallNew()) { | 2655 if (!right->IsCall() && !right->IsCallNew()) { |
2673 fni_->Infer(); | 2656 fni_->Infer(); |
2674 } else { | 2657 } else { |
2675 fni_->RemoveLastFunction(); | 2658 fni_->RemoveLastFunction(); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2819 | 2802 |
2820 template <class Traits> | 2803 template <class Traits> |
2821 typename ParserBase<Traits>::ExpressionT | 2804 typename ParserBase<Traits>::ExpressionT |
2822 ParserBase<Traits>::ParseMemberExpressionContinuation( | 2805 ParserBase<Traits>::ParseMemberExpressionContinuation( |
2823 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 2806 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
2824 // Parses this part of MemberExpression: | 2807 // Parses this part of MemberExpression: |
2825 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 2808 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
2826 while (true) { | 2809 while (true) { |
2827 switch (peek()) { | 2810 switch (peek()) { |
2828 case Token::LBRACK: { | 2811 case Token::LBRACK: { |
2829 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2812 expression = |
| 2813 Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
2830 BindingPatternUnexpectedToken(classifier); | 2814 BindingPatternUnexpectedToken(classifier); |
2831 ArrowFormalParametersUnexpectedToken(classifier); | 2815 ArrowFormalParametersUnexpectedToken(classifier); |
2832 | 2816 |
2833 Consume(Token::LBRACK); | 2817 Consume(Token::LBRACK); |
2834 int pos = position(); | 2818 int pos = position(); |
2835 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 2819 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
2836 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2820 index = Traits::RewriteNonPattern(index, classifier, CHECK_OK); |
2837 expression = factory()->NewProperty(expression, index, pos); | 2821 expression = factory()->NewProperty(expression, index, pos); |
2838 if (fni_ != NULL) { | 2822 if (fni_ != NULL) { |
2839 this->PushPropertyName(fni_, index); | 2823 this->PushPropertyName(fni_, index); |
2840 } | 2824 } |
2841 Expect(Token::RBRACK, CHECK_OK); | 2825 Expect(Token::RBRACK, CHECK_OK); |
2842 break; | 2826 break; |
2843 } | 2827 } |
2844 case Token::PERIOD: { | 2828 case Token::PERIOD: { |
2845 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2829 expression = |
| 2830 Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
2846 BindingPatternUnexpectedToken(classifier); | 2831 BindingPatternUnexpectedToken(classifier); |
2847 ArrowFormalParametersUnexpectedToken(classifier); | 2832 ArrowFormalParametersUnexpectedToken(classifier); |
2848 | 2833 |
2849 Consume(Token::PERIOD); | 2834 Consume(Token::PERIOD); |
2850 int pos = position(); | 2835 int pos = position(); |
2851 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2836 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2852 expression = factory()->NewProperty( | 2837 expression = factory()->NewProperty( |
2853 expression, factory()->NewStringLiteral(name, pos), pos); | 2838 expression, factory()->NewStringLiteral(name, pos), pos); |
2854 if (fni_ != NULL) { | 2839 if (fni_ != NULL) { |
2855 this->PushLiteralName(fni_, name); | 2840 this->PushLiteralName(fni_, name); |
2856 } | 2841 } |
2857 break; | 2842 break; |
2858 } | 2843 } |
2859 case Token::TEMPLATE_SPAN: | 2844 case Token::TEMPLATE_SPAN: |
2860 case Token::TEMPLATE_TAIL: { | 2845 case Token::TEMPLATE_TAIL: { |
2861 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2846 expression = |
| 2847 Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
2862 BindingPatternUnexpectedToken(classifier); | 2848 BindingPatternUnexpectedToken(classifier); |
2863 ArrowFormalParametersUnexpectedToken(classifier); | 2849 ArrowFormalParametersUnexpectedToken(classifier); |
2864 int pos; | 2850 int pos; |
2865 if (scanner()->current_token() == Token::IDENTIFIER) { | 2851 if (scanner()->current_token() == Token::IDENTIFIER) { |
2866 pos = position(); | 2852 pos = position(); |
2867 } else { | 2853 } else { |
2868 pos = peek_position(); | 2854 pos = peek_position(); |
2869 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2855 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2870 // If the tag function looks like an IIFE, set_parenthesized() to | 2856 // If the tag function looks like an IIFE, set_parenthesized() to |
2871 // force eager compilation. | 2857 // force eager compilation. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2906 return; | 2892 return; |
2907 } | 2893 } |
2908 parameters->is_simple = false; | 2894 parameters->is_simple = false; |
2909 ValidateFormalParameterInitializer(classifier, ok); | 2895 ValidateFormalParameterInitializer(classifier, ok); |
2910 if (!*ok) return; | 2896 if (!*ok) return; |
2911 classifier->RecordNonSimpleParameter(); | 2897 classifier->RecordNonSimpleParameter(); |
2912 } | 2898 } |
2913 | 2899 |
2914 ExpressionT initializer = Traits::EmptyExpression(); | 2900 ExpressionT initializer = Traits::EmptyExpression(); |
2915 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { | 2901 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { |
2916 ExpressionClassifier init_classifier(this); | 2902 ExpressionClassifier init_classifier; |
2917 initializer = ParseAssignmentExpression(true, &init_classifier, ok); | 2903 initializer = ParseAssignmentExpression(true, &init_classifier, ok); |
2918 if (!*ok) return; | 2904 if (!*ok) return; |
2919 Traits::RewriteNonPattern(&init_classifier, ok); | 2905 initializer = Traits::RewriteNonPattern(initializer, &init_classifier, ok); |
2920 ValidateFormalParameterInitializer(&init_classifier, ok); | 2906 ValidateFormalParameterInitializer(&init_classifier, ok); |
2921 if (!*ok) return; | 2907 if (!*ok) return; |
2922 parameters->is_simple = false; | 2908 parameters->is_simple = false; |
2923 init_classifier.Discard(); | |
2924 classifier->RecordNonSimpleParameter(); | 2909 classifier->RecordNonSimpleParameter(); |
2925 | 2910 |
2926 if (allow_harmony_function_name()) { | 2911 if (allow_harmony_function_name()) { |
2927 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); | 2912 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); |
2928 } | 2913 } |
2929 } | 2914 } |
2930 | 2915 |
2931 Traits::AddFormalParameter(parameters, pattern, initializer, | 2916 Traits::AddFormalParameter(parameters, pattern, initializer, |
2932 scanner()->location().end_pos, is_rest); | 2917 scanner()->location().end_pos, is_rest); |
2933 } | 2918 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3081 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3066 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
3082 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3067 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
3083 materialized_literal_count = | 3068 materialized_literal_count = |
3084 function_state.materialized_literal_count(); | 3069 function_state.materialized_literal_count(); |
3085 expected_property_count = function_state.expected_property_count(); | 3070 expected_property_count = function_state.expected_property_count(); |
3086 } | 3071 } |
3087 } else { | 3072 } else { |
3088 // Single-expression body | 3073 // Single-expression body |
3089 int pos = position(); | 3074 int pos = position(); |
3090 parenthesized_function_ = false; | 3075 parenthesized_function_ = false; |
3091 ExpressionClassifier classifier(this); | 3076 ExpressionClassifier classifier; |
3092 ExpressionT expression = | 3077 ExpressionT expression = |
3093 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 3078 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
3094 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 3079 expression = Traits::RewriteNonPattern(expression, &classifier, CHECK_OK); |
3095 body = this->NewStatementList(1, zone()); | 3080 body = this->NewStatementList(1, zone()); |
3096 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3081 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); |
3097 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3082 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3098 materialized_literal_count = function_state.materialized_literal_count(); | 3083 materialized_literal_count = function_state.materialized_literal_count(); |
3099 expected_property_count = function_state.expected_property_count(); | 3084 expected_property_count = function_state.expected_property_count(); |
3100 } | 3085 } |
3101 super_loc = function_state.super_location(); | 3086 super_loc = function_state.super_location(); |
3102 | 3087 |
3103 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3088 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
3104 | 3089 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3190 } else if (next == Token::ILLEGAL) { | 3175 } else if (next == Token::ILLEGAL) { |
3191 Traits::ReportMessageAt( | 3176 Traits::ReportMessageAt( |
3192 Scanner::Location(position() + 1, peek_position()), | 3177 Scanner::Location(position() + 1, peek_position()), |
3193 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3178 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
3194 *ok = false; | 3179 *ok = false; |
3195 return Traits::EmptyExpression(); | 3180 return Traits::EmptyExpression(); |
3196 } | 3181 } |
3197 | 3182 |
3198 int expr_pos = peek_position(); | 3183 int expr_pos = peek_position(); |
3199 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); | 3184 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); |
3200 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3185 expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); |
3201 Traits::AddTemplateExpression(&ts, expression); | 3186 Traits::AddTemplateExpression(&ts, expression); |
3202 | 3187 |
3203 if (peek() != Token::RBRACE) { | 3188 if (peek() != Token::RBRACE) { |
3204 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3189 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
3205 MessageTemplate::kUnterminatedTemplateExpr); | 3190 MessageTemplate::kUnterminatedTemplateExpr); |
3206 *ok = false; | 3191 *ok = false; |
3207 return Traits::EmptyExpression(); | 3192 return Traits::EmptyExpression(); |
3208 } | 3193 } |
3209 | 3194 |
3210 // If we didn't die parsing that expression, our next token should be a | 3195 // If we didn't die parsing that expression, our next token should be a |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3244 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, | 3229 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, |
3245 message, kReferenceError, ok); | 3230 message, kReferenceError, ok); |
3246 } | 3231 } |
3247 | 3232 |
3248 | 3233 |
3249 template <typename Traits> | 3234 template <typename Traits> |
3250 typename ParserBase<Traits>::ExpressionT | 3235 typename ParserBase<Traits>::ExpressionT |
3251 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 3236 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
3252 ExpressionT expression, int beg_pos, int end_pos, | 3237 ExpressionT expression, int beg_pos, int end_pos, |
3253 MessageTemplate::Template message, ParseErrorType type, bool* ok) { | 3238 MessageTemplate::Template message, ParseErrorType type, bool* ok) { |
3254 ExpressionClassifier classifier(this); | 3239 ExpressionClassifier classifier; |
3255 ExpressionT result = ClassifyAndRewriteReferenceExpression( | 3240 ExpressionT result = ClassifyAndRewriteReferenceExpression( |
3256 &classifier, expression, beg_pos, end_pos, message, type); | 3241 &classifier, expression, beg_pos, end_pos, message, type); |
3257 ValidateExpression(&classifier, ok); | 3242 ValidateExpression(&classifier, ok); |
3258 if (!*ok) return this->EmptyExpression(); | 3243 if (!*ok) return this->EmptyExpression(); |
3259 return result; | 3244 return result; |
3260 } | 3245 } |
3261 | 3246 |
3262 | 3247 |
3263 template <typename Traits> | 3248 template <typename Traits> |
3264 typename ParserBase<Traits>::ExpressionT | 3249 typename ParserBase<Traits>::ExpressionT |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3298 template <typename Traits> | 3283 template <typename Traits> |
3299 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { | 3284 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { |
3300 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); | 3285 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); |
3301 } | 3286 } |
3302 | 3287 |
3303 | 3288 |
3304 template <typename Traits> | 3289 template <typename Traits> |
3305 void ParserBase<Traits>::CheckDestructuringElement( | 3290 void ParserBase<Traits>::CheckDestructuringElement( |
3306 ExpressionT expression, ExpressionClassifier* classifier, int begin, | 3291 ExpressionT expression, ExpressionClassifier* classifier, int begin, |
3307 int end) { | 3292 int end) { |
3308 if (!IsValidPattern(expression) && !expression->IsAssignment() && | 3293 if (!IsValidPattern(expression) && !IsAssignmentExpression(expression) && |
3309 !IsValidReferenceExpression(expression)) { | 3294 !IsValidReferenceExpression(expression)) { |
3310 classifier->RecordAssignmentPatternError( | 3295 classifier->RecordAssignmentPatternError( |
3311 Scanner::Location(begin, end), | 3296 Scanner::Location(begin, end), |
3312 MessageTemplate::kInvalidDestructuringTarget); | 3297 MessageTemplate::kInvalidDestructuringTarget); |
3313 } | 3298 } |
3314 } | 3299 } |
3315 | 3300 |
3316 | 3301 |
3317 #undef CHECK_OK | 3302 #undef CHECK_OK |
3318 #undef CHECK_OK_CUSTOM | 3303 #undef CHECK_OK_CUSTOM |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3364 } | 3349 } |
3365 if (has_seen_constructor_) { | 3350 if (has_seen_constructor_) { |
3366 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); | 3351 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); |
3367 *ok = false; | 3352 *ok = false; |
3368 return; | 3353 return; |
3369 } | 3354 } |
3370 has_seen_constructor_ = true; | 3355 has_seen_constructor_ = true; |
3371 return; | 3356 return; |
3372 } | 3357 } |
3373 } | 3358 } |
3374 | |
3375 | |
3376 } // namespace internal | 3359 } // namespace internal |
3377 } // namespace v8 | 3360 } // namespace v8 |
3378 | 3361 |
3379 #endif // V8_PARSING_PARSER_BASE_H | 3362 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |