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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 v8::Extension* extension, AstValueFactory* ast_value_factory, | 98 v8::Extension* extension, AstValueFactory* ast_value_factory, |
99 ParserRecorder* log, typename Traits::Type::Parser this_object) | 99 ParserRecorder* log, typename Traits::Type::Parser this_object) |
100 : Traits(this_object), | 100 : Traits(this_object), |
101 scope_(NULL), | 101 scope_(NULL), |
102 function_state_(NULL), | 102 function_state_(NULL), |
103 extension_(extension), | 103 extension_(extension), |
104 fni_(NULL), | 104 fni_(NULL), |
105 ast_value_factory_(ast_value_factory), | 105 ast_value_factory_(ast_value_factory), |
106 log_(log), | 106 log_(log), |
107 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 107 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
| 108 parsing_module_(false), |
108 stack_limit_(stack_limit), | 109 stack_limit_(stack_limit), |
109 zone_(zone), | 110 zone_(zone), |
110 scanner_(scanner), | 111 scanner_(scanner), |
111 stack_overflow_(false), | 112 stack_overflow_(false), |
112 allow_lazy_(false), | 113 allow_lazy_(false), |
113 allow_natives_(false), | 114 allow_natives_(false), |
114 allow_tailcalls_(false), | 115 allow_tailcalls_(false), |
115 allow_harmony_restrictive_declarations_(false), | 116 allow_harmony_restrictive_declarations_(false), |
116 allow_harmony_do_expressions_(false), | 117 allow_harmony_do_expressions_(false), |
117 allow_harmony_for_in_(false), | 118 allow_harmony_for_in_(false), |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 513 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
513 tok == Token::RBRACE || | 514 tok == Token::RBRACE || |
514 tok == Token::EOS) { | 515 tok == Token::EOS) { |
515 return; | 516 return; |
516 } | 517 } |
517 Expect(Token::SEMICOLON, ok); | 518 Expect(Token::SEMICOLON, ok); |
518 } | 519 } |
519 | 520 |
520 bool peek_any_identifier() { | 521 bool peek_any_identifier() { |
521 Token::Value next = peek(); | 522 Token::Value next = peek(); |
522 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || | 523 return next == Token::IDENTIFIER || next == Token::AWAIT || |
523 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 524 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD || |
524 next == Token::STATIC || next == Token::YIELD; | 525 next == Token::LET || next == Token::STATIC || next == Token::YIELD; |
525 } | 526 } |
526 | 527 |
527 bool CheckContextualKeyword(Vector<const char> keyword) { | 528 bool CheckContextualKeyword(Vector<const char> keyword) { |
528 if (PeekContextualKeyword(keyword)) { | 529 if (PeekContextualKeyword(keyword)) { |
529 Consume(Token::IDENTIFIER); | 530 Consume(Token::IDENTIFIER); |
530 return true; | 531 return true; |
531 } | 532 } |
532 return false; | 533 return false; |
533 } | 534 } |
534 | 535 |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 bool has_seen_constructor_; | 977 bool has_seen_constructor_; |
977 }; | 978 }; |
978 | 979 |
979 Scope* scope_; // Scope stack. | 980 Scope* scope_; // Scope stack. |
980 FunctionState* function_state_; // Function state stack. | 981 FunctionState* function_state_; // Function state stack. |
981 v8::Extension* extension_; | 982 v8::Extension* extension_; |
982 FuncNameInferrer* fni_; | 983 FuncNameInferrer* fni_; |
983 AstValueFactory* ast_value_factory_; // Not owned. | 984 AstValueFactory* ast_value_factory_; // Not owned. |
984 ParserRecorder* log_; | 985 ParserRecorder* log_; |
985 Mode mode_; | 986 Mode mode_; |
| 987 bool parsing_module_; |
986 uintptr_t stack_limit_; | 988 uintptr_t stack_limit_; |
987 | 989 |
988 private: | 990 private: |
989 Zone* zone_; | 991 Zone* zone_; |
990 | 992 |
991 Scanner* scanner_; | 993 Scanner* scanner_; |
992 bool stack_overflow_; | 994 bool stack_overflow_; |
993 | 995 |
994 bool allow_lazy_; | 996 bool allow_lazy_; |
995 bool allow_natives_; | 997 bool allow_natives_; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 case Token::SMI: | 1052 case Token::SMI: |
1051 case Token::NUMBER: | 1053 case Token::NUMBER: |
1052 *message = MessageTemplate::kUnexpectedTokenNumber; | 1054 *message = MessageTemplate::kUnexpectedTokenNumber; |
1053 break; | 1055 break; |
1054 case Token::STRING: | 1056 case Token::STRING: |
1055 *message = MessageTemplate::kUnexpectedTokenString; | 1057 *message = MessageTemplate::kUnexpectedTokenString; |
1056 break; | 1058 break; |
1057 case Token::IDENTIFIER: | 1059 case Token::IDENTIFIER: |
1058 *message = MessageTemplate::kUnexpectedTokenIdentifier; | 1060 *message = MessageTemplate::kUnexpectedTokenIdentifier; |
1059 break; | 1061 break; |
1060 case Token::FUTURE_RESERVED_WORD: | 1062 case Token::AWAIT: |
| 1063 case Token::ENUM: |
1061 *message = MessageTemplate::kUnexpectedReserved; | 1064 *message = MessageTemplate::kUnexpectedReserved; |
1062 break; | 1065 break; |
1063 case Token::LET: | 1066 case Token::LET: |
1064 case Token::STATIC: | 1067 case Token::STATIC: |
1065 case Token::YIELD: | 1068 case Token::YIELD: |
1066 case Token::FUTURE_STRICT_RESERVED_WORD: | 1069 case Token::FUTURE_STRICT_RESERVED_WORD: |
1067 *message = is_strict(language_mode()) | 1070 *message = is_strict(language_mode()) |
1068 ? MessageTemplate::kUnexpectedStrictReserved | 1071 ? MessageTemplate::kUnexpectedStrictReserved |
1069 : MessageTemplate::kUnexpectedTokenIdentifier; | 1072 : MessageTemplate::kUnexpectedTokenIdentifier; |
1070 break; | 1073 break; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 | 1128 |
1126 return result; | 1129 return result; |
1127 } | 1130 } |
1128 | 1131 |
1129 | 1132 |
1130 template <class Traits> | 1133 template <class Traits> |
1131 typename ParserBase<Traits>::IdentifierT | 1134 typename ParserBase<Traits>::IdentifierT |
1132 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1135 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
1133 bool* ok) { | 1136 bool* ok) { |
1134 Token::Value next = Next(); | 1137 Token::Value next = Next(); |
1135 if (next == Token::IDENTIFIER) { | 1138 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { |
1136 IdentifierT name = this->GetSymbol(scanner()); | 1139 IdentifierT name = this->GetSymbol(scanner()); |
1137 // When this function is used to read a formal parameter, we don't always | 1140 // When this function is used to read a formal parameter, we don't always |
1138 // know whether the function is going to be strict or sloppy. Indeed for | 1141 // know whether the function is going to be strict or sloppy. Indeed for |
1139 // arrow functions we don't always know that the identifier we are reading | 1142 // arrow functions we don't always know that the identifier we are reading |
1140 // is actually a formal parameter. Therefore besides the errors that we | 1143 // is actually a formal parameter. Therefore besides the errors that we |
1141 // must detect because we know we're in strict mode, we also record any | 1144 // must detect because we know we're in strict mode, we also record any |
1142 // error that we might make in the future once we know the language mode. | 1145 // error that we might make in the future once we know the language mode. |
1143 if (this->IsEval(name)) { | 1146 if (this->IsEval(name)) { |
1144 classifier->RecordStrictModeFormalParameterError( | 1147 classifier->RecordStrictModeFormalParameterError( |
1145 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1148 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 return Traits::EmptyIdentifier(); | 1192 return Traits::EmptyIdentifier(); |
1190 } | 1193 } |
1191 } | 1194 } |
1192 | 1195 |
1193 | 1196 |
1194 template <class Traits> | 1197 template <class Traits> |
1195 typename ParserBase<Traits>::IdentifierT | 1198 typename ParserBase<Traits>::IdentifierT |
1196 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( | 1199 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( |
1197 bool is_generator, bool* is_strict_reserved, bool* ok) { | 1200 bool is_generator, bool* is_strict_reserved, bool* ok) { |
1198 Token::Value next = Next(); | 1201 Token::Value next = Next(); |
1199 if (next == Token::IDENTIFIER) { | 1202 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { |
1200 *is_strict_reserved = false; | 1203 *is_strict_reserved = false; |
1201 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1204 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
1202 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { | 1205 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { |
1203 *is_strict_reserved = true; | 1206 *is_strict_reserved = true; |
1204 } else { | 1207 } else { |
1205 ReportUnexpectedToken(next); | 1208 ReportUnexpectedToken(next); |
1206 *ok = false; | 1209 *ok = false; |
1207 return Traits::EmptyIdentifier(); | 1210 return Traits::EmptyIdentifier(); |
1208 } | 1211 } |
1209 | 1212 |
1210 IdentifierT name = this->GetSymbol(scanner()); | 1213 IdentifierT name = this->GetSymbol(scanner()); |
1211 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1214 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1212 return name; | 1215 return name; |
1213 } | 1216 } |
1214 | 1217 |
1215 | |
1216 template <class Traits> | 1218 template <class Traits> |
1217 typename ParserBase<Traits>::IdentifierT | 1219 typename ParserBase<Traits>::IdentifierT |
1218 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1220 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
1219 Token::Value next = Next(); | 1221 Token::Value next = Next(); |
1220 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 1222 if (next != Token::IDENTIFIER && next != Token::ENUM && |
1221 next != Token::LET && next != Token::STATIC && next != Token::YIELD && | 1223 next != Token::AWAIT && next != Token::LET && next != Token::STATIC && |
1222 next != Token::FUTURE_STRICT_RESERVED_WORD && | 1224 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD && |
1223 next != Token::ESCAPED_KEYWORD && | 1225 next != Token::ESCAPED_KEYWORD && |
1224 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1226 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
1225 this->ReportUnexpectedToken(next); | 1227 this->ReportUnexpectedToken(next); |
1226 *ok = false; | 1228 *ok = false; |
1227 return Traits::EmptyIdentifier(); | 1229 return Traits::EmptyIdentifier(); |
1228 } | 1230 } |
1229 | 1231 |
1230 IdentifierT name = this->GetSymbol(scanner()); | 1232 IdentifierT name = this->GetSymbol(scanner()); |
1231 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1233 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1232 return name; | 1234 return name; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1311 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1310 case Token::SMI: | 1312 case Token::SMI: |
1311 case Token::NUMBER: | 1313 case Token::NUMBER: |
1312 BindingPatternUnexpectedToken(classifier); | 1314 BindingPatternUnexpectedToken(classifier); |
1313 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1315 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1314 | 1316 |
1315 case Token::IDENTIFIER: | 1317 case Token::IDENTIFIER: |
1316 case Token::LET: | 1318 case Token::LET: |
1317 case Token::STATIC: | 1319 case Token::STATIC: |
1318 case Token::YIELD: | 1320 case Token::YIELD: |
| 1321 case Token::AWAIT: |
1319 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1322 case Token::ESCAPED_STRICT_RESERVED_WORD: |
1320 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1323 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1321 // Using eval or arguments in this context is OK even in strict mode. | 1324 // Using eval or arguments in this context is OK even in strict mode. |
1322 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1325 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
1323 return this->ExpressionFromIdentifier( | 1326 return this->ExpressionFromIdentifier( |
1324 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 1327 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
1325 } | 1328 } |
1326 | 1329 |
1327 case Token::STRING: { | 1330 case Token::STRING: { |
1328 BindingPatternUnexpectedToken(classifier); | 1331 BindingPatternUnexpectedToken(classifier); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 int beg_pos = peek_position(); | 1679 int beg_pos = peek_position(); |
1677 value = this->ParseAssignmentExpression( | 1680 value = this->ParseAssignmentExpression( |
1678 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1681 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1679 CheckDestructuringElement(value, classifier, beg_pos, | 1682 CheckDestructuringElement(value, classifier, beg_pos, |
1680 scanner()->location().end_pos); | 1683 scanner()->location().end_pos); |
1681 | 1684 |
1682 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 1685 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
1683 *is_computed_name); | 1686 *is_computed_name); |
1684 } | 1687 } |
1685 | 1688 |
1686 if (Token::IsIdentifier(name_token, language_mode(), | 1689 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), |
1687 this->is_generator()) && | 1690 parsing_module_) && |
1688 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1691 (peek() == Token::COMMA || peek() == Token::RBRACE || |
1689 peek() == Token::ASSIGN)) { | 1692 peek() == Token::ASSIGN)) { |
1690 // PropertyDefinition | 1693 // PropertyDefinition |
1691 // IdentifierReference | 1694 // IdentifierReference |
1692 // CoverInitializedName | 1695 // CoverInitializedName |
1693 // | 1696 // |
1694 // CoverInitializedName | 1697 // CoverInitializedName |
1695 // IdentifierReference Initializer? | 1698 // IdentifierReference Initializer? |
1696 if (classifier->duplicate_finder() != nullptr && | 1699 if (classifier->duplicate_finder() != nullptr && |
1697 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1700 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2859 bool ParserBase<Traits>::IsNextLetKeyword() { | 2862 bool ParserBase<Traits>::IsNextLetKeyword() { |
2860 DCHECK(peek() == Token::LET); | 2863 DCHECK(peek() == Token::LET); |
2861 Token::Value next_next = PeekAhead(); | 2864 Token::Value next_next = PeekAhead(); |
2862 switch (next_next) { | 2865 switch (next_next) { |
2863 case Token::LBRACE: | 2866 case Token::LBRACE: |
2864 case Token::LBRACK: | 2867 case Token::LBRACK: |
2865 case Token::IDENTIFIER: | 2868 case Token::IDENTIFIER: |
2866 case Token::STATIC: | 2869 case Token::STATIC: |
2867 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 2870 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
2868 case Token::YIELD: | 2871 case Token::YIELD: |
| 2872 case Token::AWAIT: |
2869 return true; | 2873 return true; |
2870 default: | 2874 default: |
2871 return false; | 2875 return false; |
2872 } | 2876 } |
2873 } | 2877 } |
2874 | 2878 |
2875 | 2879 |
2876 template <class Traits> | 2880 template <class Traits> |
2877 typename ParserBase<Traits>::ExpressionT | 2881 typename ParserBase<Traits>::ExpressionT |
2878 ParserBase<Traits>::ParseArrowFunctionLiteral( | 2882 ParserBase<Traits>::ParseArrowFunctionLiteral( |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3207 has_seen_constructor_ = true; | 3211 has_seen_constructor_ = true; |
3208 return; | 3212 return; |
3209 } | 3213 } |
3210 } | 3214 } |
3211 | 3215 |
3212 | 3216 |
3213 } // namespace internal | 3217 } // namespace internal |
3214 } // namespace v8 | 3218 } // namespace v8 |
3215 | 3219 |
3216 #endif // V8_PARSING_PARSER_BASE_H | 3220 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |