| 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 |