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 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 Token::Value name_tok; | 1087 Token::Value name_tok; |
1088 while ((name_tok = peek()) != Token::RBRACE) { | 1088 while ((name_tok = peek()) != Token::RBRACE) { |
1089 // Keep track of the first reserved word encountered in case our | 1089 // Keep track of the first reserved word encountered in case our |
1090 // caller needs to report an error. | 1090 // caller needs to report an error. |
1091 if (!reserved_loc->IsValid() && | 1091 if (!reserved_loc->IsValid() && |
1092 !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) { | 1092 !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) { |
1093 *reserved_loc = scanner()->location(); | 1093 *reserved_loc = scanner()->location(); |
1094 } | 1094 } |
1095 const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID); | 1095 const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID); |
1096 const AstRawString* export_name = NULL; | 1096 const AstRawString* export_name = NULL; |
| 1097 Scanner::Location location = scanner()->location(); |
1097 if (CheckContextualKeyword(CStrVector("as"))) { | 1098 if (CheckContextualKeyword(CStrVector("as"))) { |
1098 export_name = ParseIdentifierName(CHECK_OK_VOID); | 1099 export_name = ParseIdentifierName(CHECK_OK_VOID); |
| 1100 // Set the location to the whole "a as b" string, so that it makes sense |
| 1101 // both for errors due to "a" and for errors due to "b". |
| 1102 location.end_pos = scanner()->location().end_pos; |
1099 } | 1103 } |
1100 if (export_name == NULL) { | 1104 if (export_name == NULL) { |
1101 export_name = local_name; | 1105 export_name = local_name; |
1102 } | 1106 } |
1103 export_names->Add(export_name, zone()); | 1107 export_names->Add(export_name, zone()); |
1104 local_names->Add(local_name, zone()); | 1108 local_names->Add(local_name, zone()); |
1105 export_locations->Add(scanner()->location(), zone()); | 1109 export_locations->Add(location, zone()); |
1106 if (peek() == Token::RBRACE) break; | 1110 if (peek() == Token::RBRACE) break; |
1107 Expect(Token::COMMA, CHECK_OK_VOID); | 1111 Expect(Token::COMMA, CHECK_OK_VOID); |
1108 } | 1112 } |
1109 | 1113 |
1110 Expect(Token::RBRACE, CHECK_OK_VOID); | 1114 Expect(Token::RBRACE, CHECK_OK_VOID); |
1111 } | 1115 } |
1112 | 1116 |
1113 | 1117 |
1114 ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports( | 1118 ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports( |
1115 int pos, bool* ok) { | 1119 int pos, bool* ok) { |
1116 // NamedImports : | 1120 // NamedImports : |
1117 // '{' '}' | 1121 // '{' '}' |
1118 // '{' ImportsList '}' | 1122 // '{' ImportsList '}' |
1119 // '{' ImportsList ',' '}' | 1123 // '{' ImportsList ',' '}' |
1120 // | 1124 // |
1121 // ImportsList : | 1125 // ImportsList : |
1122 // ImportSpecifier | 1126 // ImportSpecifier |
1123 // ImportsList ',' ImportSpecifier | 1127 // ImportsList ',' ImportSpecifier |
1124 // | 1128 // |
1125 // ImportSpecifier : | 1129 // ImportSpecifier : |
1126 // BindingIdentifier | 1130 // BindingIdentifier |
1127 // IdentifierName 'as' BindingIdentifier | 1131 // IdentifierName 'as' BindingIdentifier |
1128 | 1132 |
1129 Expect(Token::LBRACE, CHECK_OK); | 1133 Expect(Token::LBRACE, CHECK_OK); |
1130 | 1134 |
1131 auto result = new (zone()) ZoneList<const NamedImport*>(1, zone()); | 1135 auto result = new (zone()) ZoneList<const NamedImport*>(1, zone()); |
1132 while (peek() != Token::RBRACE) { | 1136 while (peek() != Token::RBRACE) { |
1133 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); | 1137 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); |
1134 const AstRawString* local_name = import_name; | 1138 const AstRawString* local_name = import_name; |
| 1139 Scanner::Location location = scanner()->location(); |
1135 // In the presence of 'as', the left-side of the 'as' can | 1140 // In the presence of 'as', the left-side of the 'as' can |
1136 // be any IdentifierName. But without 'as', it must be a valid | 1141 // be any IdentifierName. But without 'as', it must be a valid |
1137 // BindingIdentifier. | 1142 // BindingIdentifier. |
1138 if (CheckContextualKeyword(CStrVector("as"))) { | 1143 if (CheckContextualKeyword(CStrVector("as"))) { |
1139 local_name = ParseIdentifierName(CHECK_OK); | 1144 local_name = ParseIdentifierName(CHECK_OK); |
1140 } | 1145 } |
1141 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false, | 1146 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false, |
1142 parsing_module_)) { | 1147 parsing_module_)) { |
1143 *ok = false; | 1148 *ok = false; |
1144 ReportMessage(MessageTemplate::kUnexpectedReserved); | 1149 ReportMessage(MessageTemplate::kUnexpectedReserved); |
1145 return nullptr; | 1150 return nullptr; |
1146 } else if (IsEvalOrArguments(local_name)) { | 1151 } else if (IsEvalOrArguments(local_name)) { |
1147 *ok = false; | 1152 *ok = false; |
1148 ReportMessage(MessageTemplate::kStrictEvalArguments); | 1153 ReportMessage(MessageTemplate::kStrictEvalArguments); |
1149 return nullptr; | 1154 return nullptr; |
1150 } | 1155 } |
1151 | 1156 |
1152 DeclareModuleImport(local_name, position(), CHECK_OK); | 1157 DeclareModuleImport(local_name, position(), CHECK_OK); |
1153 | 1158 |
1154 NamedImport* import = new (zone()) NamedImport( | 1159 NamedImport* import = |
1155 import_name, local_name, scanner()->location()); | 1160 new (zone()) NamedImport(import_name, local_name, location); |
1156 result->Add(import, zone()); | 1161 result->Add(import, zone()); |
1157 | 1162 |
1158 if (peek() == Token::RBRACE) break; | 1163 if (peek() == Token::RBRACE) break; |
1159 Expect(Token::COMMA, CHECK_OK); | 1164 Expect(Token::COMMA, CHECK_OK); |
1160 } | 1165 } |
1161 | 1166 |
1162 Expect(Token::RBRACE, CHECK_OK); | 1167 Expect(Token::RBRACE, CHECK_OK); |
1163 return result; | 1168 return result; |
1164 } | 1169 } |
1165 | 1170 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 } | 1337 } |
1333 | 1338 |
1334 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1339 Statement* Parser::ParseExportDeclaration(bool* ok) { |
1335 // ExportDeclaration: | 1340 // ExportDeclaration: |
1336 // 'export' '*' 'from' ModuleSpecifier ';' | 1341 // 'export' '*' 'from' ModuleSpecifier ';' |
1337 // 'export' ExportClause ('from' ModuleSpecifier)? ';' | 1342 // 'export' ExportClause ('from' ModuleSpecifier)? ';' |
1338 // 'export' VariableStatement | 1343 // 'export' VariableStatement |
1339 // 'export' Declaration | 1344 // 'export' Declaration |
1340 // 'export' 'default' ... (handled in ParseExportDefault) | 1345 // 'export' 'default' ... (handled in ParseExportDefault) |
1341 | 1346 |
1342 int pos = peek_position(); | |
1343 Expect(Token::EXPORT, CHECK_OK); | 1347 Expect(Token::EXPORT, CHECK_OK); |
| 1348 int pos = position(); |
1344 | 1349 |
1345 Statement* result = nullptr; | 1350 Statement* result = nullptr; |
1346 ZoneList<const AstRawString*> names(1, zone()); | 1351 ZoneList<const AstRawString*> names(1, zone()); |
| 1352 Scanner::Location loc = scanner()->peek_location(); |
1347 switch (peek()) { | 1353 switch (peek()) { |
1348 case Token::DEFAULT: | 1354 case Token::DEFAULT: |
1349 return ParseExportDefault(ok); | 1355 return ParseExportDefault(ok); |
1350 | 1356 |
1351 case Token::MUL: { | 1357 case Token::MUL: { |
1352 Consume(Token::MUL); | 1358 Consume(Token::MUL); |
| 1359 loc = scanner()->location(); |
1353 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1360 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1354 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); | 1361 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); |
1355 ExpectSemicolon(CHECK_OK); | 1362 ExpectSemicolon(CHECK_OK); |
1356 module()->AddStarExport(module_specifier, scanner()->location(), zone()); | 1363 module()->AddStarExport(module_specifier, loc, zone()); |
1357 return factory()->NewEmptyStatement(pos); | 1364 return factory()->NewEmptyStatement(pos); |
1358 } | 1365 } |
1359 | 1366 |
1360 case Token::LBRACE: { | 1367 case Token::LBRACE: { |
1361 // There are two cases here: | 1368 // There are two cases here: |
1362 // | 1369 // |
1363 // 'export' ExportClause ';' | 1370 // 'export' ExportClause ';' |
1364 // and | 1371 // and |
1365 // 'export' ExportClause FromClause ';' | 1372 // 'export' ExportClause FromClause ';' |
1366 // | 1373 // |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); | 1434 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); |
1428 break; | 1435 break; |
1429 } | 1436 } |
1430 /* falls through */ | 1437 /* falls through */ |
1431 | 1438 |
1432 default: | 1439 default: |
1433 *ok = false; | 1440 *ok = false; |
1434 ReportUnexpectedToken(scanner()->current_token()); | 1441 ReportUnexpectedToken(scanner()->current_token()); |
1435 return nullptr; | 1442 return nullptr; |
1436 } | 1443 } |
| 1444 loc.end_pos = scanner()->location().end_pos; |
1437 | 1445 |
1438 ModuleDescriptor* descriptor = module(); | 1446 ModuleDescriptor* descriptor = module(); |
1439 for (int i = 0; i < names.length(); ++i) { | 1447 for (int i = 0; i < names.length(); ++i) { |
1440 // TODO(neis): Provide better location. | 1448 descriptor->AddExport(names[i], names[i], loc, zone()); |
1441 descriptor->AddExport(names[i], names[i], scanner()->location(), zone()); | |
1442 } | 1449 } |
1443 | 1450 |
1444 DCHECK_NOT_NULL(result); | 1451 DCHECK_NOT_NULL(result); |
1445 return result; | 1452 return result; |
1446 } | 1453 } |
1447 | 1454 |
1448 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos, | 1455 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos, |
1449 VariableKind kind) { | 1456 VariableKind kind) { |
1450 return scope()->NewUnresolved(factory(), name, begin_pos, kind); | 1457 return scope()->NewUnresolved(factory(), name, begin_pos, kind); |
1451 } | 1458 } |
(...skipping 3951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5403 | 5410 |
5404 return final_loop; | 5411 return final_loop; |
5405 } | 5412 } |
5406 | 5413 |
5407 #undef CHECK_OK | 5414 #undef CHECK_OK |
5408 #undef CHECK_OK_VOID | 5415 #undef CHECK_OK_VOID |
5409 #undef CHECK_FAILED | 5416 #undef CHECK_FAILED |
5410 | 5417 |
5411 } // namespace internal | 5418 } // namespace internal |
5412 } // namespace v8 | 5419 } // namespace v8 |
OLD | NEW |