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