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

Side by Side Diff: src/parsing/parser-base.h

Issue 1773653002: [strong] Remove all remainders of strong mode (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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
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_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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 stack_overflow_(false), 108 stack_overflow_(false),
109 allow_lazy_(false), 109 allow_lazy_(false),
110 allow_natives_(false), 110 allow_natives_(false),
111 allow_harmony_sloppy_(false), 111 allow_harmony_sloppy_(false),
112 allow_harmony_sloppy_function_(false), 112 allow_harmony_sloppy_function_(false),
113 allow_harmony_sloppy_let_(false), 113 allow_harmony_sloppy_let_(false),
114 allow_harmony_default_parameters_(false), 114 allow_harmony_default_parameters_(false),
115 allow_harmony_destructuring_bind_(false), 115 allow_harmony_destructuring_bind_(false),
116 allow_harmony_destructuring_assignment_(false), 116 allow_harmony_destructuring_assignment_(false),
117 allow_harmony_restrictive_declarations_(false), 117 allow_harmony_restrictive_declarations_(false),
118 allow_strong_mode_(false),
119 allow_legacy_const_(true), 118 allow_legacy_const_(true),
120 allow_harmony_do_expressions_(false), 119 allow_harmony_do_expressions_(false),
121 allow_harmony_function_name_(false), 120 allow_harmony_function_name_(false),
122 allow_harmony_function_sent_(false) {} 121 allow_harmony_function_sent_(false) {}
123 122
124 #define ALLOW_ACCESSORS(name) \ 123 #define ALLOW_ACCESSORS(name) \
125 bool allow_##name() const { return allow_##name##_; } \ 124 bool allow_##name() const { return allow_##name##_; } \
126 void set_allow_##name(bool allow) { allow_##name##_ = allow; } 125 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
127 126
128 ALLOW_ACCESSORS(lazy); 127 ALLOW_ACCESSORS(lazy);
129 ALLOW_ACCESSORS(natives); 128 ALLOW_ACCESSORS(natives);
130 ALLOW_ACCESSORS(harmony_sloppy); 129 ALLOW_ACCESSORS(harmony_sloppy);
131 ALLOW_ACCESSORS(harmony_sloppy_function); 130 ALLOW_ACCESSORS(harmony_sloppy_function);
132 ALLOW_ACCESSORS(harmony_sloppy_let); 131 ALLOW_ACCESSORS(harmony_sloppy_let);
133 ALLOW_ACCESSORS(harmony_default_parameters); 132 ALLOW_ACCESSORS(harmony_default_parameters);
134 ALLOW_ACCESSORS(harmony_destructuring_bind); 133 ALLOW_ACCESSORS(harmony_destructuring_bind);
135 ALLOW_ACCESSORS(harmony_destructuring_assignment); 134 ALLOW_ACCESSORS(harmony_destructuring_assignment);
136 ALLOW_ACCESSORS(harmony_restrictive_declarations); 135 ALLOW_ACCESSORS(harmony_restrictive_declarations);
137 ALLOW_ACCESSORS(strong_mode);
138 ALLOW_ACCESSORS(legacy_const); 136 ALLOW_ACCESSORS(legacy_const);
139 ALLOW_ACCESSORS(harmony_do_expressions); 137 ALLOW_ACCESSORS(harmony_do_expressions);
140 ALLOW_ACCESSORS(harmony_function_name); 138 ALLOW_ACCESSORS(harmony_function_name);
141 ALLOW_ACCESSORS(harmony_function_sent); 139 ALLOW_ACCESSORS(harmony_function_sent);
142 #undef ALLOW_ACCESSORS 140 #undef ALLOW_ACCESSORS
143 141
144 uintptr_t stack_limit() const { return stack_limit_; } 142 uintptr_t stack_limit() const { return stack_limit_; }
145 143
146 protected: 144 protected:
147 enum AllowRestrictedIdentifiers { 145 enum AllowRestrictedIdentifiers {
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 Expect(Token::IDENTIFIER, ok); 474 Expect(Token::IDENTIFIER, ok);
477 if (!*ok) return; 475 if (!*ok) return;
478 if (!scanner()->is_literal_contextual_keyword(keyword)) { 476 if (!scanner()->is_literal_contextual_keyword(keyword)) {
479 ReportUnexpectedToken(scanner()->current_token()); 477 ReportUnexpectedToken(scanner()->current_token());
480 *ok = false; 478 *ok = false;
481 } 479 }
482 } 480 }
483 481
484 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) { 482 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
485 if (Check(Token::IN)) { 483 if (Check(Token::IN)) {
486 if (is_strong(language_mode())) { 484 *visit_mode = ForEachStatement::ENUMERATE;
487 ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn);
488 *ok = false;
489 } else {
490 *visit_mode = ForEachStatement::ENUMERATE;
491 }
492 return true; 485 return true;
493 } else if (CheckContextualKeyword(CStrVector("of"))) { 486 } else if (CheckContextualKeyword(CStrVector("of"))) {
494 *visit_mode = ForEachStatement::ITERATE; 487 *visit_mode = ForEachStatement::ITERATE;
495 return true; 488 return true;
496 } 489 }
497 return false; 490 return false;
498 } 491 }
499 492
500 bool PeekInOrOf() { 493 bool PeekInOrOf() {
501 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); 494 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of"));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 MessageTemplate::kStrictEvalArguments); 535 MessageTemplate::kStrictEvalArguments);
543 *ok = false; 536 *ok = false;
544 return; 537 return;
545 } 538 }
546 if (function_name_validity == kFunctionNameIsStrictReserved) { 539 if (function_name_validity == kFunctionNameIsStrictReserved) {
547 Traits::ReportMessageAt(function_name_loc, 540 Traits::ReportMessageAt(function_name_loc,
548 MessageTemplate::kUnexpectedStrictReserved); 541 MessageTemplate::kUnexpectedStrictReserved);
549 *ok = false; 542 *ok = false;
550 return; 543 return;
551 } 544 }
552 if (is_strong(language_mode) && this->IsUndefined(function_name)) {
553 Traits::ReportMessageAt(function_name_loc,
554 MessageTemplate::kStrongUndefined);
555 *ok = false;
556 return;
557 }
558 } 545 }
559 546
560 // Determine precedence of given token. 547 // Determine precedence of given token.
561 static int Precedence(Token::Value token, bool accept_IN) { 548 static int Precedence(Token::Value token, bool accept_IN) {
562 if (token == Token::IN && !accept_IN) 549 if (token == Token::IN && !accept_IN)
563 return 0; // 0 precedence will terminate binary expression parsing 550 return 0; // 0 precedence will terminate binary expression parsing
564 return Token::Precedence(token); 551 return Token::Precedence(token);
565 } 552 }
566 553
567 typename Traits::Type::Factory* factory() { 554 typename Traits::Type::Factory* factory() {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 LanguageMode language_mode, 639 LanguageMode language_mode,
653 bool allow_duplicates, bool* ok) { 640 bool allow_duplicates, bool* ok) {
654 if (!allow_duplicates && 641 if (!allow_duplicates &&
655 !classifier->is_valid_formal_parameter_list_without_duplicates()) { 642 !classifier->is_valid_formal_parameter_list_without_duplicates()) {
656 ReportClassifierError(classifier->duplicate_formal_parameter_error()); 643 ReportClassifierError(classifier->duplicate_formal_parameter_error());
657 *ok = false; 644 *ok = false;
658 } else if (is_strict(language_mode) && 645 } else if (is_strict(language_mode) &&
659 !classifier->is_valid_strict_mode_formal_parameters()) { 646 !classifier->is_valid_strict_mode_formal_parameters()) {
660 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); 647 ReportClassifierError(classifier->strict_mode_formal_parameter_error());
661 *ok = false; 648 *ok = false;
662 } else if (is_strong(language_mode) &&
663 !classifier->is_valid_strong_mode_formal_parameters()) {
664 ReportClassifierError(classifier->strong_mode_formal_parameter_error());
665 *ok = false;
666 } 649 }
667 } 650 }
668 651
669 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, 652 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
670 ExpressionT expr, 653 ExpressionT expr,
671 bool parenthesized_formals, bool* ok) { 654 bool parenthesized_formals, bool* ok) {
672 if (classifier->is_valid_binding_pattern()) { 655 if (classifier->is_valid_binding_pattern()) {
673 // A simple arrow formal parameter: IDENTIFIER => BODY. 656 // A simple arrow formal parameter: IDENTIFIER => BODY.
674 if (!this->IsIdentifier(expr)) { 657 if (!this->IsIdentifier(expr)) {
675 Traits::ReportMessageAt(scanner()->location(), 658 Traits::ReportMessageAt(scanner()->location(),
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, 782 ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
800 const FormalParametersT& parameters, 783 const FormalParametersT& parameters,
801 const ExpressionClassifier& classifier, 784 const ExpressionClassifier& classifier,
802 bool* ok); 785 bool* ok);
803 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, 786 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
804 ExpressionClassifier* classifier, bool* ok); 787 ExpressionClassifier* classifier, bool* ok);
805 void AddTemplateExpression(ExpressionT); 788 void AddTemplateExpression(ExpressionT);
806 ExpressionT ParseSuperExpression(bool is_new, 789 ExpressionT ParseSuperExpression(bool is_new,
807 ExpressionClassifier* classifier, bool* ok); 790 ExpressionClassifier* classifier, bool* ok);
808 ExpressionT ParseNewTargetExpression(bool* ok); 791 ExpressionT ParseNewTargetExpression(bool* ok);
809 ExpressionT ParseStrongInitializationExpression(
810 ExpressionClassifier* classifier, bool* ok);
811 ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
812 bool* ok);
813 792
814 void ParseFormalParameter(FormalParametersT* parameters, 793 void ParseFormalParameter(FormalParametersT* parameters,
815 ExpressionClassifier* classifier, bool* ok); 794 ExpressionClassifier* classifier, bool* ok);
816 void ParseFormalParameterList(FormalParametersT* parameters, 795 void ParseFormalParameterList(FormalParametersT* parameters,
817 ExpressionClassifier* classifier, bool* ok); 796 ExpressionClassifier* classifier, bool* ok);
818 void CheckArityRestrictions(int param_count, FunctionKind function_type, 797 void CheckArityRestrictions(int param_count, FunctionKind function_type,
819 bool has_rest, int formals_start_pos, 798 bool has_rest, int formals_start_pos,
820 int formals_end_pos, bool* ok); 799 int formals_end_pos, bool* ok);
821 800
822 bool IsNextLetKeyword(); 801 bool IsNextLetKeyword();
(...skipping 13 matching lines...) Expand all
836 MessageTemplate::Template message, ParseErrorType type, bool* ok); 815 MessageTemplate::Template message, ParseErrorType type, bool* ok);
837 816
838 bool IsValidReferenceExpression(ExpressionT expression); 817 bool IsValidReferenceExpression(ExpressionT expression);
839 818
840 bool IsAssignableIdentifier(ExpressionT expression) { 819 bool IsAssignableIdentifier(ExpressionT expression) {
841 if (!Traits::IsIdentifier(expression)) return false; 820 if (!Traits::IsIdentifier(expression)) return false;
842 if (is_strict(language_mode()) && 821 if (is_strict(language_mode()) &&
843 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { 822 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
844 return false; 823 return false;
845 } 824 }
846 if (is_strong(language_mode()) &&
847 Traits::IsUndefined(Traits::AsIdentifier(expression))) {
848 return false;
849 }
850 return true; 825 return true;
851 } 826 }
852 827
853 bool IsValidPattern(ExpressionT expression) { 828 bool IsValidPattern(ExpressionT expression) {
854 return expression->IsObjectLiteral() || expression->IsArrayLiteral(); 829 return expression->IsObjectLiteral() || expression->IsArrayLiteral();
855 } 830 }
856 831
857 // Keep track of eval() calls since they disable all local variable 832 // Keep track of eval() calls since they disable all local variable
858 // optimizations. This checks if expression is an eval call, and if yes, 833 // optimizations. This checks if expression is an eval call, and if yes,
859 // forwards the information to scope. 834 // forwards the information to scope.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 922
948 bool allow_lazy_; 923 bool allow_lazy_;
949 bool allow_natives_; 924 bool allow_natives_;
950 bool allow_harmony_sloppy_; 925 bool allow_harmony_sloppy_;
951 bool allow_harmony_sloppy_function_; 926 bool allow_harmony_sloppy_function_;
952 bool allow_harmony_sloppy_let_; 927 bool allow_harmony_sloppy_let_;
953 bool allow_harmony_default_parameters_; 928 bool allow_harmony_default_parameters_;
954 bool allow_harmony_destructuring_bind_; 929 bool allow_harmony_destructuring_bind_;
955 bool allow_harmony_destructuring_assignment_; 930 bool allow_harmony_destructuring_assignment_;
956 bool allow_harmony_restrictive_declarations_; 931 bool allow_harmony_restrictive_declarations_;
957 bool allow_strong_mode_;
958 bool allow_legacy_const_; 932 bool allow_legacy_const_;
959 bool allow_harmony_do_expressions_; 933 bool allow_harmony_do_expressions_;
960 bool allow_harmony_function_name_; 934 bool allow_harmony_function_name_;
961 bool allow_harmony_function_sent_; 935 bool allow_harmony_function_sent_;
962 }; 936 };
963 937
964 template <class Traits> 938 template <class Traits>
965 ParserBase<Traits>::FunctionState::FunctionState( 939 ParserBase<Traits>::FunctionState::FunctionState(
966 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, 940 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
967 FunctionKind kind, typename Traits::Type::Factory* factory) 941 FunctionKind kind, typename Traits::Type::Factory* factory)
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 } 1071 }
1098 } 1072 }
1099 if (this->IsArguments(name)) { 1073 if (this->IsArguments(name)) {
1100 scope_->RecordArgumentsUsage(); 1074 scope_->RecordArgumentsUsage();
1101 classifier->RecordStrictModeFormalParameterError( 1075 classifier->RecordStrictModeFormalParameterError(
1102 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1076 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1103 if (is_strict(language_mode())) { 1077 if (is_strict(language_mode())) {
1104 classifier->RecordBindingPatternError( 1078 classifier->RecordBindingPatternError(
1105 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1079 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1106 } 1080 }
1107 if (is_strong(language_mode())) {
1108 classifier->RecordExpressionError(scanner()->location(),
1109 MessageTemplate::kStrongArguments);
1110 }
1111 }
1112 if (this->IsUndefined(name)) {
1113 classifier->RecordStrongModeFormalParameterError(
1114 scanner()->location(), MessageTemplate::kStrongUndefined);
1115 if (is_strong(language_mode())) {
1116 // TODO(dslomov): allow 'undefined' in nested patterns.
1117 classifier->RecordPatternError(scanner()->location(),
1118 MessageTemplate::kStrongUndefined);
1119 }
1120 } 1081 }
1121 1082
1122 if (classifier->duplicate_finder() != nullptr && 1083 if (classifier->duplicate_finder() != nullptr &&
1123 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 1084 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1124 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 1085 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1125 } 1086 }
1126 return name; 1087 return name;
1127 } else if (is_sloppy(language_mode()) && 1088 } else if (is_sloppy(language_mode()) &&
1128 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1089 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1129 next == Token::ESCAPED_STRICT_RESERVED_WORD || 1090 next == Token::ESCAPED_STRICT_RESERVED_WORD ||
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 // ClassLiteral 1214 // ClassLiteral
1254 // '(' Expression ')' 1215 // '(' Expression ')'
1255 // TemplateLiteral 1216 // TemplateLiteral
1256 // do Block 1217 // do Block
1257 1218
1258 int beg_pos = peek_position(); 1219 int beg_pos = peek_position();
1259 switch (peek()) { 1220 switch (peek()) {
1260 case Token::THIS: { 1221 case Token::THIS: {
1261 BindingPatternUnexpectedToken(classifier); 1222 BindingPatternUnexpectedToken(classifier);
1262 Consume(Token::THIS); 1223 Consume(Token::THIS);
1263 if (FLAG_strong_this && is_strong(language_mode())) {
1264 // Constructors' usages of 'this' in strong mode are parsed separately.
1265 // TODO(rossberg): this does not work with arrow functions yet.
1266 if (IsClassConstructor(function_state_->kind())) {
1267 ReportMessage(MessageTemplate::kStrongConstructorThis);
1268 *ok = false;
1269 return this->EmptyExpression();
1270 }
1271 }
1272 return this->ThisExpression(scope_, factory(), beg_pos); 1224 return this->ThisExpression(scope_, factory(), beg_pos);
1273 } 1225 }
1274 1226
1275 case Token::NULL_LITERAL: 1227 case Token::NULL_LITERAL:
1276 case Token::TRUE_LITERAL: 1228 case Token::TRUE_LITERAL:
1277 case Token::FALSE_LITERAL: 1229 case Token::FALSE_LITERAL:
1278 BindingPatternUnexpectedToken(classifier); 1230 BindingPatternUnexpectedToken(classifier);
1279 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1231 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1280 case Token::SMI: 1232 case Token::SMI:
1281 case Token::NUMBER: 1233 case Token::NUMBER:
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 // '[' Expression? (',' Expression?)* ']' 1453 // '[' Expression? (',' Expression?)* ']'
1502 1454
1503 int pos = peek_position(); 1455 int pos = peek_position();
1504 typename Traits::Type::ExpressionList values = 1456 typename Traits::Type::ExpressionList values =
1505 this->NewExpressionList(4, zone_); 1457 this->NewExpressionList(4, zone_);
1506 int first_spread_index = -1; 1458 int first_spread_index = -1;
1507 Expect(Token::LBRACK, CHECK_OK); 1459 Expect(Token::LBRACK, CHECK_OK);
1508 while (peek() != Token::RBRACK) { 1460 while (peek() != Token::RBRACK) {
1509 ExpressionT elem = this->EmptyExpression(); 1461 ExpressionT elem = this->EmptyExpression();
1510 if (peek() == Token::COMMA) { 1462 if (peek() == Token::COMMA) {
1511 if (is_strong(language_mode())) {
1512 ReportMessageAt(scanner()->peek_location(),
1513 MessageTemplate::kStrongEllision);
1514 *ok = false;
1515 return this->EmptyExpression();
1516 }
1517 elem = this->GetLiteralTheHole(peek_position(), factory()); 1463 elem = this->GetLiteralTheHole(peek_position(), factory());
1518 } else if (peek() == Token::ELLIPSIS) { 1464 } else if (peek() == Token::ELLIPSIS) {
1519 int start_pos = peek_position(); 1465 int start_pos = peek_position();
1520 Consume(Token::ELLIPSIS); 1466 Consume(Token::ELLIPSIS);
1521 int expr_pos = peek_position(); 1467 int expr_pos = peek_position();
1522 ExpressionT argument = 1468 ExpressionT argument =
1523 this->ParseAssignmentExpression(true, classifier, CHECK_OK); 1469 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
1524 elem = factory()->NewSpread(argument, start_pos, expr_pos); 1470 elem = factory()->NewSpread(argument, start_pos, expr_pos);
1525 1471
1526 if (first_spread_index < 0) { 1472 if (first_spread_index < 0) {
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 bool* ok) { 2151 bool* ok) {
2206 DCHECK(prec >= 4); 2152 DCHECK(prec >= 4);
2207 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); 2153 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2208 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 2154 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2209 // prec1 >= 4 2155 // prec1 >= 4
2210 while (Precedence(peek(), accept_IN) == prec1) { 2156 while (Precedence(peek(), accept_IN) == prec1) {
2211 Traits::RewriteNonPattern(classifier, CHECK_OK); 2157 Traits::RewriteNonPattern(classifier, CHECK_OK);
2212 BindingPatternUnexpectedToken(classifier); 2158 BindingPatternUnexpectedToken(classifier);
2213 ArrowFormalParametersUnexpectedToken(classifier); 2159 ArrowFormalParametersUnexpectedToken(classifier);
2214 Token::Value op = Next(); 2160 Token::Value op = Next();
2215 Scanner::Location op_location = scanner()->location();
2216 int pos = position(); 2161 int pos = position();
2217 ExpressionT y = 2162 ExpressionT y =
2218 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); 2163 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
2219 Traits::RewriteNonPattern(classifier, CHECK_OK); 2164 Traits::RewriteNonPattern(classifier, CHECK_OK);
2220 2165
2221 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, 2166 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2222 factory())) { 2167 factory())) {
2223 continue; 2168 continue;
2224 } 2169 }
2225 2170
2226 // For now we distinguish between comparisons and other binary 2171 // For now we distinguish between comparisons and other binary
2227 // operations. (We could combine the two and get rid of this 2172 // operations. (We could combine the two and get rid of this
2228 // code and AST node eventually.) 2173 // code and AST node eventually.)
2229 if (Token::IsCompareOp(op)) { 2174 if (Token::IsCompareOp(op)) {
2230 // We have a comparison. 2175 // We have a comparison.
2231 Token::Value cmp = op; 2176 Token::Value cmp = op;
2232 switch (op) { 2177 switch (op) {
2233 case Token::NE: cmp = Token::EQ; break; 2178 case Token::NE: cmp = Token::EQ; break;
2234 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 2179 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2235 default: break; 2180 default: break;
2236 } 2181 }
2237 if (cmp == Token::EQ && is_strong(language_mode())) { 2182 if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) {
2238 ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
2239 *ok = false;
2240 return this->EmptyExpression();
2241 } else if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) {
2242 x = Traits::RewriteInstanceof(x, y, pos); 2183 x = Traits::RewriteInstanceof(x, y, pos);
2243 } else { 2184 } else {
2244 x = factory()->NewCompareOperation(cmp, x, y, pos); 2185 x = factory()->NewCompareOperation(cmp, x, y, pos);
2245 if (cmp != op) { 2186 if (cmp != op) {
2246 // The comparison was negated - add a NOT. 2187 // The comparison was negated - add a NOT.
2247 x = factory()->NewUnaryOperation(Token::NOT, x, pos); 2188 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2248 } 2189 }
2249 } 2190 }
2250 } else { 2191 } else {
2251 // We have a "normal" binary operation. 2192 // We have a "normal" binary operation.
(...skipping 25 matching lines...) Expand all
2277 if (Token::IsUnaryOp(op)) { 2218 if (Token::IsUnaryOp(op)) {
2278 BindingPatternUnexpectedToken(classifier); 2219 BindingPatternUnexpectedToken(classifier);
2279 ArrowFormalParametersUnexpectedToken(classifier); 2220 ArrowFormalParametersUnexpectedToken(classifier);
2280 2221
2281 op = Next(); 2222 op = Next();
2282 int pos = position(); 2223 int pos = position();
2283 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); 2224 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
2284 Traits::RewriteNonPattern(classifier, CHECK_OK); 2225 Traits::RewriteNonPattern(classifier, CHECK_OK);
2285 2226
2286 if (op == Token::DELETE && is_strict(language_mode())) { 2227 if (op == Token::DELETE && is_strict(language_mode())) {
2287 if (is_strong(language_mode())) { 2228 if (this->IsIdentifier(expression)) {
2288 ReportMessage(MessageTemplate::kStrongDelete);
2289 *ok = false;
2290 return this->EmptyExpression();
2291 } else if (this->IsIdentifier(expression)) {
2292 // "delete identifier" is a syntax error in strict mode. 2229 // "delete identifier" is a syntax error in strict mode.
2293 ReportMessage(MessageTemplate::kStrictDelete); 2230 ReportMessage(MessageTemplate::kStrictDelete);
2294 *ok = false; 2231 *ok = false;
2295 return this->EmptyExpression(); 2232 return this->EmptyExpression();
2296 } 2233 }
2297 } 2234 }
2298 2235
2299 // Allow Traits do rewrite the expression. 2236 // Allow Traits do rewrite the expression.
2300 return this->BuildUnaryExpression(expression, op, pos, factory()); 2237 return this->BuildUnaryExpression(expression, op, pos, factory());
2301 } else if (Token::IsCountOp(op)) { 2238 } else if (Token::IsCountOp(op)) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 result = factory()->NewProperty(result, index, pos); 2313 result = factory()->NewProperty(result, index, pos);
2377 Expect(Token::RBRACK, CHECK_OK); 2314 Expect(Token::RBRACK, CHECK_OK);
2378 break; 2315 break;
2379 } 2316 }
2380 2317
2381 case Token::LPAREN: { 2318 case Token::LPAREN: {
2382 Traits::RewriteNonPattern(classifier, CHECK_OK); 2319 Traits::RewriteNonPattern(classifier, CHECK_OK);
2383 BindingPatternUnexpectedToken(classifier); 2320 BindingPatternUnexpectedToken(classifier);
2384 ArrowFormalParametersUnexpectedToken(classifier); 2321 ArrowFormalParametersUnexpectedToken(classifier);
2385 2322
2386 if (is_strong(language_mode()) && this->IsIdentifier(result) &&
2387 this->IsEval(this->AsIdentifier(result))) {
2388 ReportMessage(MessageTemplate::kStrongDirectEval);
2389 *ok = false;
2390 return this->EmptyExpression();
2391 }
2392 int pos; 2323 int pos;
2393 if (scanner()->current_token() == Token::IDENTIFIER || 2324 if (scanner()->current_token() == Token::IDENTIFIER ||
2394 scanner()->current_token() == Token::SUPER) { 2325 scanner()->current_token() == Token::SUPER) {
2395 // For call of an identifier we want to report position of 2326 // For call of an identifier we want to report position of
2396 // the identifier as position of the call in the stack trace. 2327 // the identifier as position of the call in the stack trace.
2397 pos = position(); 2328 pos = position();
2398 } else { 2329 } else {
2399 // For other kinds of calls we record position of the parenthesis as 2330 // For other kinds of calls we record position of the parenthesis as
2400 // position of the call. Note that this is extremely important for 2331 // position of the call. Note that this is extremely important for
2401 // expressions of the form function(){...}() for which call position 2332 // expressions of the form function(){...}() for which call position
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2599 result = ParsePrimaryExpression(classifier, CHECK_OK); 2530 result = ParsePrimaryExpression(classifier, CHECK_OK);
2600 } 2531 }
2601 2532
2602 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); 2533 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
2603 return result; 2534 return result;
2604 } 2535 }
2605 2536
2606 2537
2607 template <class Traits> 2538 template <class Traits>
2608 typename ParserBase<Traits>::ExpressionT 2539 typename ParserBase<Traits>::ExpressionT
2609 ParserBase<Traits>::ParseStrongInitializationExpression(
2610 ExpressionClassifier* classifier, bool* ok) {
2611 // InitializationExpression :: (strong mode)
2612 // 'this' '.' IdentifierName '=' AssignmentExpression
2613 // 'this' '[' Expression ']' '=' AssignmentExpression
2614
2615 FuncNameInferrer::State fni_state(fni_);
2616
2617 Consume(Token::THIS);
2618 int pos = position();
2619 function_state_->set_this_location(scanner()->location());
2620 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2621
2622 ExpressionT left = this->EmptyExpression();
2623 switch (peek()) {
2624 case Token::LBRACK: {
2625 Consume(Token::LBRACK);
2626 int pos = position();
2627 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
2628 Traits::RewriteNonPattern(classifier, CHECK_OK);
2629 left = factory()->NewProperty(this_expr, index, pos);
2630 if (fni_ != NULL) {
2631 this->PushPropertyName(fni_, index);
2632 }
2633 Expect(Token::RBRACK, CHECK_OK);
2634 break;
2635 }
2636 case Token::PERIOD: {
2637 Consume(Token::PERIOD);
2638 int pos = position();
2639 IdentifierT name = ParseIdentifierName(CHECK_OK);
2640 left = factory()->NewProperty(
2641 this_expr, factory()->NewStringLiteral(name, pos), pos);
2642 if (fni_ != NULL) {
2643 this->PushLiteralName(fni_, name);
2644 }
2645 break;
2646 }
2647 default:
2648 ReportMessage(MessageTemplate::kStrongConstructorThis);
2649 *ok = false;
2650 return this->EmptyExpression();
2651 }
2652
2653 if (peek() != Token::ASSIGN) {
2654 ReportMessageAt(function_state_->this_location(),
2655 MessageTemplate::kStrongConstructorThis);
2656 *ok = false;
2657 return this->EmptyExpression();
2658 }
2659 Consume(Token::ASSIGN);
2660 left = this->MarkExpressionAsAssigned(left);
2661
2662 ExpressionT right =
2663 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2664 Traits::RewriteNonPattern(classifier, CHECK_OK);
2665 this->CheckAssigningFunctionLiteralToProperty(left, right);
2666 function_state_->AddProperty();
2667 if (fni_ != NULL) {
2668 // Check if the right hand side is a call to avoid inferring a
2669 // name if we're dealing with "this.a = function(){...}();"-like
2670 // expression.
2671 if (!right->IsCall() && !right->IsCallNew()) {
2672 fni_->Infer();
2673 } else {
2674 fni_->RemoveLastFunction();
2675 }
2676 }
2677
2678 if (function_state_->return_location().IsValid()) {
2679 ReportMessageAt(function_state_->return_location(),
2680 MessageTemplate::kStrongConstructorReturnMisplaced);
2681 *ok = false;
2682 return this->EmptyExpression();
2683 }
2684
2685 return factory()->NewAssignment(Token::ASSIGN, left, right, pos);
2686 }
2687
2688
2689 template <class Traits>
2690 typename ParserBase<Traits>::ExpressionT
2691 ParserBase<Traits>::ParseStrongSuperCallExpression(
2692 ExpressionClassifier* classifier, bool* ok) {
2693 // SuperCallExpression :: (strong mode)
2694 // 'super' '(' ExpressionList ')'
2695 BindingPatternUnexpectedToken(classifier);
2696
2697 Consume(Token::SUPER);
2698 int pos = position();
2699 Scanner::Location super_loc = scanner()->location();
2700 ExpressionT expr = this->SuperCallReference(scope_, factory(), pos);
2701
2702 if (peek() != Token::LPAREN) {
2703 ReportMessage(MessageTemplate::kStrongConstructorSuper);
2704 *ok = false;
2705 return this->EmptyExpression();
2706 }
2707
2708 Scanner::Location spread_pos;
2709 typename Traits::Type::ExpressionList args =
2710 ParseArguments(&spread_pos, classifier, CHECK_OK);
2711
2712 // TODO(rossberg): This doesn't work with arrow functions yet.
2713 if (!IsSubclassConstructor(function_state_->kind())) {
2714 ReportMessage(MessageTemplate::kUnexpectedSuper);
2715 *ok = false;
2716 return this->EmptyExpression();
2717 } else if (function_state_->super_location().IsValid()) {
2718 ReportMessageAt(scanner()->location(),
2719 MessageTemplate::kStrongSuperCallDuplicate);
2720 *ok = false;
2721 return this->EmptyExpression();
2722 } else if (function_state_->this_location().IsValid()) {
2723 ReportMessageAt(scanner()->location(),
2724 MessageTemplate::kStrongSuperCallMisplaced);
2725 *ok = false;
2726 return this->EmptyExpression();
2727 } else if (function_state_->return_location().IsValid()) {
2728 ReportMessageAt(function_state_->return_location(),
2729 MessageTemplate::kStrongConstructorReturnMisplaced);
2730 *ok = false;
2731 return this->EmptyExpression();
2732 }
2733
2734 function_state_->set_super_location(super_loc);
2735 if (spread_pos.IsValid()) {
2736 args = Traits::PrepareSpreadArguments(args);
2737 expr = Traits::SpreadCall(expr, args, pos);
2738 } else {
2739 expr = factory()->NewCall(expr, args, pos);
2740 }
2741
2742 // Explicit calls to the super constructor using super() perform an implicit
2743 // binding assignment to the 'this' variable.
2744 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2745 return factory()->NewAssignment(Token::INIT, this_expr, expr, pos);
2746 }
2747
2748
2749 template <class Traits>
2750 typename ParserBase<Traits>::ExpressionT
2751 ParserBase<Traits>::ParseSuperExpression(bool is_new, 2540 ParserBase<Traits>::ParseSuperExpression(bool is_new,
2752 ExpressionClassifier* classifier, 2541 ExpressionClassifier* classifier,
2753 bool* ok) { 2542 bool* ok) {
2754 Expect(Token::SUPER, CHECK_OK); 2543 Expect(Token::SUPER, CHECK_OK);
2755 int pos = position(); 2544 int pos = position();
2756 2545
2757 Scope* scope = scope_->ReceiverScope(); 2546 Scope* scope = scope_->ReceiverScope();
2758 FunctionKind kind = scope->function_kind(); 2547 FunctionKind kind = scope->function_kind();
2759 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || 2548 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
2760 IsClassConstructor(kind)) { 2549 IsClassConstructor(kind)) {
2761 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { 2550 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
2762 scope->RecordSuperPropertyUsage(); 2551 scope->RecordSuperPropertyUsage();
2763 return this->SuperPropertyReference(scope_, factory(), pos); 2552 return this->SuperPropertyReference(scope_, factory(), pos);
2764 } 2553 }
2765 // new super() is never allowed. 2554 // new super() is never allowed.
2766 // super() is only allowed in derived constructor 2555 // super() is only allowed in derived constructor
2767 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { 2556 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
2768 if (is_strong(language_mode())) {
2769 // Super calls in strong mode are parsed separately.
2770 ReportMessageAt(scanner()->location(),
2771 MessageTemplate::kStrongConstructorSuper);
2772 *ok = false;
2773 return this->EmptyExpression();
2774 }
2775 // TODO(rossberg): This might not be the correct FunctionState for the 2557 // TODO(rossberg): This might not be the correct FunctionState for the
2776 // method here. 2558 // method here.
2777 function_state_->set_super_location(scanner()->location()); 2559 function_state_->set_super_location(scanner()->location());
2778 return this->SuperCallReference(scope_, factory(), pos); 2560 return this->SuperCallReference(scope_, factory(), pos);
2779 } 2561 }
2780 } 2562 }
2781 2563
2782 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); 2564 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
2783 *ok = false; 2565 *ok = false;
2784 return this->EmptyExpression(); 2566 return this->EmptyExpression();
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
3265 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, 3047 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos,
3266 int end_pos, MessageTemplate::Template message, ParseErrorType type) { 3048 int end_pos, MessageTemplate::Template message, ParseErrorType type) {
3267 Scanner::Location location(beg_pos, end_pos); 3049 Scanner::Location location(beg_pos, end_pos);
3268 if (this->IsIdentifier(expression)) { 3050 if (this->IsIdentifier(expression)) {
3269 if (is_strict(language_mode()) && 3051 if (is_strict(language_mode()) &&
3270 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 3052 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3271 classifier->RecordExpressionError( 3053 classifier->RecordExpressionError(
3272 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); 3054 location, MessageTemplate::kStrictEvalArguments, kSyntaxError);
3273 return expression; 3055 return expression;
3274 } 3056 }
3275 if (is_strong(language_mode()) &&
3276 this->IsUndefined(this->AsIdentifier(expression))) {
3277 classifier->RecordExpressionError(
3278 location, MessageTemplate::kStrongUndefined, kSyntaxError);
3279 return expression;
3280 }
3281 } 3057 }
3282 if (expression->IsValidReferenceExpression()) { 3058 if (expression->IsValidReferenceExpression()) {
3283 return expression; 3059 return expression;
3284 } else if (expression->IsCall()) { 3060 } else if (expression->IsCall()) {
3285 // If it is a call, make it a runtime error for legacy web compatibility. 3061 // If it is a call, make it a runtime error for legacy web compatibility.
3286 // Rewrite `expr' to `expr[throw ReferenceError]'. 3062 // Rewrite `expr' to `expr[throw ReferenceError]'.
3287 int pos = location.beg_pos; 3063 int pos = location.beg_pos;
3288 ExpressionT error = this->NewThrowReferenceError(message, pos); 3064 ExpressionT error = this->NewThrowReferenceError(message, pos);
3289 return factory()->NewProperty(expression, error, pos); 3065 return factory()->NewProperty(expression, error, pos);
3290 } else { 3066 } else {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3369 has_seen_constructor_ = true; 3145 has_seen_constructor_ = true;
3370 return; 3146 return;
3371 } 3147 }
3372 } 3148 }
3373 3149
3374 3150
3375 } // namespace internal 3151 } // namespace internal
3376 } // namespace v8 3152 } // namespace v8
3377 3153
3378 #endif // V8_PARSING_PARSER_BASE_H 3154 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« src/parsing/parser.cc ('K') | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698