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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 442 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
443 tok == Token::RBRACE || | 443 tok == Token::RBRACE || |
444 tok == Token::EOS) { | 444 tok == Token::EOS) { |
445 return; | 445 return; |
446 } | 446 } |
447 Expect(Token::SEMICOLON, ok); | 447 Expect(Token::SEMICOLON, ok); |
448 } | 448 } |
449 | 449 |
450 bool peek_any_identifier() { | 450 bool peek_any_identifier() { |
451 Token::Value next = peek(); | 451 Token::Value next = peek(); |
452 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || | 452 return next == Token::IDENTIFIER || next == Token::AWAIT || |
453 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 453 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD || |
454 next == Token::STATIC || next == Token::YIELD; | 454 next == Token::LET || next == Token::STATIC || next == Token::YIELD; |
455 } | 455 } |
456 | 456 |
457 bool CheckContextualKeyword(Vector<const char> keyword) { | 457 bool CheckContextualKeyword(Vector<const char> keyword) { |
458 if (PeekContextualKeyword(keyword)) { | 458 if (PeekContextualKeyword(keyword)) { |
459 Consume(Token::IDENTIFIER); | 459 Consume(Token::IDENTIFIER); |
460 return true; | 460 return true; |
461 } | 461 } |
462 return false; | 462 return false; |
463 } | 463 } |
464 | 464 |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 *arg = nullptr; | 1003 *arg = nullptr; |
1004 break; | 1004 break; |
1005 case Token::STRING: | 1005 case Token::STRING: |
1006 *message = MessageTemplate::kUnexpectedTokenString; | 1006 *message = MessageTemplate::kUnexpectedTokenString; |
1007 *arg = nullptr; | 1007 *arg = nullptr; |
1008 break; | 1008 break; |
1009 case Token::IDENTIFIER: | 1009 case Token::IDENTIFIER: |
1010 *message = MessageTemplate::kUnexpectedTokenIdentifier; | 1010 *message = MessageTemplate::kUnexpectedTokenIdentifier; |
1011 *arg = nullptr; | 1011 *arg = nullptr; |
1012 break; | 1012 break; |
1013 case Token::FUTURE_RESERVED_WORD: | 1013 case Token::AWAIT: |
| 1014 case Token::ENUM: |
1014 *message = MessageTemplate::kUnexpectedReserved; | 1015 *message = MessageTemplate::kUnexpectedReserved; |
1015 *arg = nullptr; | 1016 *arg = nullptr; |
1016 break; | 1017 break; |
1017 case Token::LET: | 1018 case Token::LET: |
1018 case Token::STATIC: | 1019 case Token::STATIC: |
1019 case Token::YIELD: | 1020 case Token::YIELD: |
1020 case Token::FUTURE_STRICT_RESERVED_WORD: | 1021 case Token::FUTURE_STRICT_RESERVED_WORD: |
1021 *message = is_strict(language_mode()) | 1022 *message = is_strict(language_mode()) |
1022 ? MessageTemplate::kUnexpectedStrictReserved | 1023 ? MessageTemplate::kUnexpectedStrictReserved |
1023 : MessageTemplate::kUnexpectedTokenIdentifier; | 1024 : MessageTemplate::kUnexpectedTokenIdentifier; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 | 1075 |
1075 return result; | 1076 return result; |
1076 } | 1077 } |
1077 | 1078 |
1078 | 1079 |
1079 template <class Traits> | 1080 template <class Traits> |
1080 typename ParserBase<Traits>::IdentifierT | 1081 typename ParserBase<Traits>::IdentifierT |
1081 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1082 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
1082 bool* ok) { | 1083 bool* ok) { |
1083 Token::Value next = Next(); | 1084 Token::Value next = Next(); |
1084 if (next == Token::IDENTIFIER) { | 1085 if (next == Token::IDENTIFIER || |
| 1086 (next == Token::AWAIT && !scope_->inside_module())) { |
1085 IdentifierT name = this->GetSymbol(scanner()); | 1087 IdentifierT name = this->GetSymbol(scanner()); |
1086 // When this function is used to read a formal parameter, we don't always | 1088 // When this function is used to read a formal parameter, we don't always |
1087 // know whether the function is going to be strict or sloppy. Indeed for | 1089 // know whether the function is going to be strict or sloppy. Indeed for |
1088 // arrow functions we don't always know that the identifier we are reading | 1090 // arrow functions we don't always know that the identifier we are reading |
1089 // is actually a formal parameter. Therefore besides the errors that we | 1091 // is actually a formal parameter. Therefore besides the errors that we |
1090 // must detect because we know we're in strict mode, we also record any | 1092 // must detect because we know we're in strict mode, we also record any |
1091 // error that we might make in the future once we know the language mode. | 1093 // error that we might make in the future once we know the language mode. |
1092 if (this->IsEval(name)) { | 1094 if (this->IsEval(name)) { |
1093 classifier->RecordStrictModeFormalParameterError( | 1095 classifier->RecordStrictModeFormalParameterError( |
1094 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1096 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 return Traits::EmptyIdentifier(); | 1153 return Traits::EmptyIdentifier(); |
1152 } | 1154 } |
1153 } | 1155 } |
1154 | 1156 |
1155 | 1157 |
1156 template <class Traits> | 1158 template <class Traits> |
1157 typename ParserBase<Traits>::IdentifierT | 1159 typename ParserBase<Traits>::IdentifierT |
1158 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( | 1160 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( |
1159 bool is_generator, bool* is_strict_reserved, bool* ok) { | 1161 bool is_generator, bool* is_strict_reserved, bool* ok) { |
1160 Token::Value next = Next(); | 1162 Token::Value next = Next(); |
1161 if (next == Token::IDENTIFIER) { | 1163 if (next == Token::IDENTIFIER || |
| 1164 (next == Token::AWAIT && !scope_->inside_module())) { |
1162 *is_strict_reserved = false; | 1165 *is_strict_reserved = false; |
1163 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1166 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
1164 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { | 1167 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { |
1165 *is_strict_reserved = true; | 1168 *is_strict_reserved = true; |
1166 } else { | 1169 } else { |
1167 ReportUnexpectedToken(next); | 1170 ReportUnexpectedToken(next); |
1168 *ok = false; | 1171 *ok = false; |
1169 return Traits::EmptyIdentifier(); | 1172 return Traits::EmptyIdentifier(); |
1170 } | 1173 } |
1171 | 1174 |
1172 IdentifierT name = this->GetSymbol(scanner()); | 1175 IdentifierT name = this->GetSymbol(scanner()); |
1173 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1176 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1174 return name; | 1177 return name; |
1175 } | 1178 } |
1176 | 1179 |
1177 | |
1178 template <class Traits> | 1180 template <class Traits> |
1179 typename ParserBase<Traits>::IdentifierT | 1181 typename ParserBase<Traits>::IdentifierT |
1180 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1182 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
1181 Token::Value next = Next(); | 1183 Token::Value next = Next(); |
1182 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 1184 if (next != Token::IDENTIFIER && next != Token::ENUM && |
1183 next != Token::LET && next != Token::STATIC && next != Token::YIELD && | 1185 next != Token::AWAIT && next != Token::LET && next != Token::STATIC && |
1184 next != Token::FUTURE_STRICT_RESERVED_WORD && | 1186 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD && |
1185 next != Token::ESCAPED_KEYWORD && | 1187 next != Token::ESCAPED_KEYWORD && |
1186 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1188 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
1187 this->ReportUnexpectedToken(next); | 1189 this->ReportUnexpectedToken(next); |
1188 *ok = false; | 1190 *ok = false; |
1189 return Traits::EmptyIdentifier(); | 1191 return Traits::EmptyIdentifier(); |
1190 } | 1192 } |
1191 | 1193 |
1192 IdentifierT name = this->GetSymbol(scanner()); | 1194 IdentifierT name = this->GetSymbol(scanner()); |
1193 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1195 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1194 return name; | 1196 return name; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1283 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1282 case Token::SMI: | 1284 case Token::SMI: |
1283 case Token::NUMBER: | 1285 case Token::NUMBER: |
1284 BindingPatternUnexpectedToken(classifier); | 1286 BindingPatternUnexpectedToken(classifier); |
1285 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1287 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1286 | 1288 |
1287 case Token::IDENTIFIER: | 1289 case Token::IDENTIFIER: |
1288 case Token::LET: | 1290 case Token::LET: |
1289 case Token::STATIC: | 1291 case Token::STATIC: |
1290 case Token::YIELD: | 1292 case Token::YIELD: |
| 1293 case Token::AWAIT: |
1291 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1294 case Token::ESCAPED_STRICT_RESERVED_WORD: |
1292 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1295 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1293 // Using eval or arguments in this context is OK even in strict mode. | 1296 // Using eval or arguments in this context is OK even in strict mode. |
1294 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1297 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
1295 return this->ExpressionFromIdentifier( | 1298 return this->ExpressionFromIdentifier( |
1296 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 1299 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
1297 } | 1300 } |
1298 | 1301 |
1299 case Token::STRING: { | 1302 case Token::STRING: { |
1300 BindingPatternUnexpectedToken(classifier); | 1303 BindingPatternUnexpectedToken(classifier); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 int beg_pos = peek_position(); | 1668 int beg_pos = peek_position(); |
1666 value = this->ParseAssignmentExpression( | 1669 value = this->ParseAssignmentExpression( |
1667 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1670 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1668 CheckDestructuringElement(value, classifier, beg_pos, | 1671 CheckDestructuringElement(value, classifier, beg_pos, |
1669 scanner()->location().end_pos); | 1672 scanner()->location().end_pos); |
1670 | 1673 |
1671 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 1674 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
1672 *is_computed_name); | 1675 *is_computed_name); |
1673 } | 1676 } |
1674 | 1677 |
1675 if (Token::IsIdentifier(name_token, language_mode(), | 1678 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), |
1676 this->is_generator()) && | 1679 scope_->inside_module()) && |
1677 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1680 (peek() == Token::COMMA || peek() == Token::RBRACE || |
1678 peek() == Token::ASSIGN)) { | 1681 peek() == Token::ASSIGN)) { |
1679 // PropertyDefinition | 1682 // PropertyDefinition |
1680 // IdentifierReference | 1683 // IdentifierReference |
1681 // CoverInitializedName | 1684 // CoverInitializedName |
1682 // | 1685 // |
1683 // CoverInitializedName | 1686 // CoverInitializedName |
1684 // IdentifierReference Initializer? | 1687 // IdentifierReference Initializer? |
1685 if (classifier->duplicate_finder() != nullptr && | 1688 if (classifier->duplicate_finder() != nullptr && |
1686 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1689 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
(...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3018 return false; | 3021 return false; |
3019 } | 3022 } |
3020 Token::Value next_next = PeekAhead(); | 3023 Token::Value next_next = PeekAhead(); |
3021 switch (next_next) { | 3024 switch (next_next) { |
3022 case Token::LBRACE: | 3025 case Token::LBRACE: |
3023 case Token::LBRACK: | 3026 case Token::LBRACK: |
3024 case Token::IDENTIFIER: | 3027 case Token::IDENTIFIER: |
3025 case Token::STATIC: | 3028 case Token::STATIC: |
3026 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 3029 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
3027 case Token::YIELD: | 3030 case Token::YIELD: |
| 3031 case Token::AWAIT: |
3028 return true; | 3032 return true; |
3029 default: | 3033 default: |
3030 return false; | 3034 return false; |
3031 } | 3035 } |
3032 } | 3036 } |
3033 | 3037 |
3034 | 3038 |
3035 template <class Traits> | 3039 template <class Traits> |
3036 typename ParserBase<Traits>::ExpressionT | 3040 typename ParserBase<Traits>::ExpressionT |
3037 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3041 ParserBase<Traits>::ParseArrowFunctionLiteral( |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3372 has_seen_constructor_ = true; | 3376 has_seen_constructor_ = true; |
3373 return; | 3377 return; |
3374 } | 3378 } |
3375 } | 3379 } |
3376 | 3380 |
3377 | 3381 |
3378 } // namespace internal | 3382 } // namespace internal |
3379 } // namespace v8 | 3383 } // namespace v8 |
3380 | 3384 |
3381 #endif // V8_PARSING_PARSER_BASE_H | 3385 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |