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 "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 AstNodeFactory function_factory(ast_value_factory()); | 941 AstNodeFactory function_factory(ast_value_factory()); |
942 FunctionState function_state(&function_state_, &scope_, scope, | 942 FunctionState function_state(&function_state_, &scope_, scope, |
943 kNormalFunction, &function_factory); | 943 kNormalFunction, &function_factory); |
944 | 944 |
945 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 945 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
946 bool ok = true; | 946 bool ok = true; |
947 int beg_pos = scanner()->location().beg_pos; | 947 int beg_pos = scanner()->location().beg_pos; |
948 parsing_module_ = info->is_module(); | 948 parsing_module_ = info->is_module(); |
949 if (parsing_module_) { | 949 if (parsing_module_) { |
950 ParseModuleItemList(body, &ok); | 950 ParseModuleItemList(body, &ok); |
| 951 ok = ok && |
| 952 scope_->module()->Validate(scope_, &pending_error_handler_, zone()); |
951 } else { | 953 } else { |
952 // Don't count the mode in the use counters--give the program a chance | 954 // Don't count the mode in the use counters--give the program a chance |
953 // to enable script-wide strict mode below. | 955 // to enable script-wide strict mode below. |
954 scope_->SetLanguageMode(info->language_mode()); | 956 scope_->SetLanguageMode(info->language_mode()); |
955 ParseStatementList(body, Token::EOS, &ok); | 957 ParseStatementList(body, Token::EOS, &ok); |
956 } | 958 } |
957 | 959 |
958 // The parser will peek but not consume EOS. Our scope logically goes all | 960 // The parser will peek but not consume EOS. Our scope logically goes all |
959 // the way to the EOS, though. | 961 // the way to the EOS, though. |
960 scope->set_end_position(scanner()->peek_location().beg_pos); | 962 scope->set_end_position(scanner()->peek_location().beg_pos); |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1311 } | 1313 } |
1312 /* falls through */ | 1314 /* falls through */ |
1313 default: | 1315 default: |
1314 break; | 1316 break; |
1315 } | 1317 } |
1316 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); | 1318 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); |
1317 } | 1319 } |
1318 | 1320 |
1319 | 1321 |
1320 Statement* Parser::ParseModuleItem(bool* ok) { | 1322 Statement* Parser::ParseModuleItem(bool* ok) { |
1321 // (Ecma 262 6th Edition, 15.2): | 1323 // ecma262/#prod-ModuleItem |
1322 // ModuleItem : | 1324 // ModuleItem : |
1323 // ImportDeclaration | 1325 // ImportDeclaration |
1324 // ExportDeclaration | 1326 // ExportDeclaration |
1325 // StatementListItem | 1327 // StatementListItem |
1326 | 1328 |
1327 switch (peek()) { | 1329 switch (peek()) { |
1328 case Token::IMPORT: | 1330 case Token::IMPORT: |
1329 return ParseImportDeclaration(ok); | 1331 ParseImportDeclaration(CHECK_OK); |
| 1332 return factory()->NewEmptyStatement(kNoSourcePosition); |
1330 case Token::EXPORT: | 1333 case Token::EXPORT: |
1331 return ParseExportDeclaration(ok); | 1334 return ParseExportDeclaration(ok); |
1332 default: | 1335 default: |
1333 return ParseStatementListItem(ok); | 1336 return ParseStatementListItem(ok); |
1334 } | 1337 } |
1335 } | 1338 } |
1336 | 1339 |
1337 | 1340 |
1338 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) { | 1341 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) { |
1339 // (Ecma 262 6th Edition, 15.2): | 1342 // ecma262/#prod-Module |
1340 // Module : | 1343 // Module : |
1341 // ModuleBody? | 1344 // ModuleBody? |
1342 // | 1345 // |
| 1346 // ecma262/#prod-ModuleItemList |
1343 // ModuleBody : | 1347 // ModuleBody : |
1344 // ModuleItem* | 1348 // ModuleItem* |
1345 | 1349 |
1346 DCHECK(scope_->is_module_scope()); | 1350 DCHECK(scope_->is_module_scope()); |
1347 | |
1348 while (peek() != Token::EOS) { | 1351 while (peek() != Token::EOS) { |
1349 Statement* stat = ParseModuleItem(CHECK_OK); | 1352 Statement* stat = ParseModuleItem(CHECK_OK); |
1350 if (stat && !stat->IsEmpty()) { | 1353 if (stat && !stat->IsEmpty()) { |
1351 body->Add(stat, zone()); | 1354 body->Add(stat, zone()); |
1352 } | 1355 } |
1353 } | 1356 } |
1354 | 1357 return nullptr; |
1355 // Check that all exports are bound. | |
1356 ModuleDescriptor* descriptor = scope_->module(); | |
1357 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done(); | |
1358 it.Advance()) { | |
1359 if (scope_->LookupLocal(it.local_name()) == NULL) { | |
1360 // TODO(adamk): Pass both local_name and export_name once ParserTraits | |
1361 // supports multiple arg error messages. | |
1362 // Also try to report this at a better location. | |
1363 ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined, | |
1364 it.local_name()); | |
1365 *ok = false; | |
1366 return NULL; | |
1367 } | |
1368 } | |
1369 | |
1370 return NULL; | |
1371 } | 1358 } |
1372 | 1359 |
1373 | 1360 |
1374 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { | 1361 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { |
1375 // ModuleSpecifier : | 1362 // ModuleSpecifier : |
1376 // StringLiteral | 1363 // StringLiteral |
1377 | 1364 |
1378 Expect(Token::STRING, CHECK_OK); | 1365 Expect(Token::STRING, CHECK_OK); |
1379 return GetSymbol(scanner()); | 1366 return GetSymbol(scanner()); |
1380 } | 1367 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 } | 1404 } |
1418 export_names->Add(export_name, zone()); | 1405 export_names->Add(export_name, zone()); |
1419 local_names->Add(local_name, zone()); | 1406 local_names->Add(local_name, zone()); |
1420 export_locations->Add(scanner()->location(), zone()); | 1407 export_locations->Add(scanner()->location(), zone()); |
1421 if (peek() == Token::RBRACE) break; | 1408 if (peek() == Token::RBRACE) break; |
1422 Expect(Token::COMMA, CHECK_OK); | 1409 Expect(Token::COMMA, CHECK_OK); |
1423 } | 1410 } |
1424 | 1411 |
1425 Expect(Token::RBRACE, CHECK_OK); | 1412 Expect(Token::RBRACE, CHECK_OK); |
1426 | 1413 |
1427 return 0; | 1414 return nullptr; |
1428 } | 1415 } |
1429 | 1416 |
1430 | 1417 |
1431 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) { | 1418 ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports( |
| 1419 int pos, bool* ok) { |
1432 // NamedImports : | 1420 // NamedImports : |
1433 // '{' '}' | 1421 // '{' '}' |
1434 // '{' ImportsList '}' | 1422 // '{' ImportsList '}' |
1435 // '{' ImportsList ',' '}' | 1423 // '{' ImportsList ',' '}' |
1436 // | 1424 // |
1437 // ImportsList : | 1425 // ImportsList : |
1438 // ImportSpecifier | 1426 // ImportSpecifier |
1439 // ImportsList ',' ImportSpecifier | 1427 // ImportsList ',' ImportSpecifier |
1440 // | 1428 // |
1441 // ImportSpecifier : | 1429 // ImportSpecifier : |
1442 // BindingIdentifier | 1430 // BindingIdentifier |
1443 // IdentifierName 'as' BindingIdentifier | 1431 // IdentifierName 'as' BindingIdentifier |
1444 | 1432 |
1445 Expect(Token::LBRACE, CHECK_OK); | 1433 Expect(Token::LBRACE, CHECK_OK); |
1446 | 1434 |
1447 ZoneList<ImportDeclaration*>* result = | 1435 auto result = new (zone()) ZoneList<const NamedImport*>(1, zone()); |
1448 new (zone()) ZoneList<ImportDeclaration*>(1, zone()); | |
1449 while (peek() != Token::RBRACE) { | 1436 while (peek() != Token::RBRACE) { |
1450 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); | 1437 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); |
1451 const AstRawString* local_name = import_name; | 1438 const AstRawString* local_name = import_name; |
1452 // In the presence of 'as', the left-side of the 'as' can | 1439 // In the presence of 'as', the left-side of the 'as' can |
1453 // be any IdentifierName. But without 'as', it must be a valid | 1440 // be any IdentifierName. But without 'as', it must be a valid |
1454 // BindingIdentifier. | 1441 // BindingIdentifier. |
1455 if (CheckContextualKeyword(CStrVector("as"))) { | 1442 if (CheckContextualKeyword(CStrVector("as"))) { |
1456 local_name = ParseIdentifierName(CHECK_OK); | 1443 local_name = ParseIdentifierName(CHECK_OK); |
1457 } | 1444 } |
1458 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false, | 1445 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false, |
1459 parsing_module_)) { | 1446 parsing_module_)) { |
1460 *ok = false; | 1447 *ok = false; |
1461 ReportMessage(MessageTemplate::kUnexpectedReserved); | 1448 ReportMessage(MessageTemplate::kUnexpectedReserved); |
1462 return NULL; | 1449 return nullptr; |
1463 } else if (IsEvalOrArguments(local_name)) { | 1450 } else if (IsEvalOrArguments(local_name)) { |
1464 *ok = false; | 1451 *ok = false; |
1465 ReportMessage(MessageTemplate::kStrictEvalArguments); | 1452 ReportMessage(MessageTemplate::kStrictEvalArguments); |
1466 return NULL; | 1453 return nullptr; |
1467 } | 1454 } |
1468 VariableProxy* proxy = NewUnresolved(local_name, CONST); | 1455 |
1469 ImportDeclaration* declaration = | 1456 DeclareImport(local_name, position(), CHECK_OK); |
1470 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos); | 1457 |
1471 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 1458 NamedImport* import = new (zone()) NamedImport( |
1472 result->Add(declaration, zone()); | 1459 import_name, local_name, scanner()->location()); |
| 1460 result->Add(import, zone()); |
| 1461 |
1473 if (peek() == Token::RBRACE) break; | 1462 if (peek() == Token::RBRACE) break; |
1474 Expect(Token::COMMA, CHECK_OK); | 1463 Expect(Token::COMMA, CHECK_OK); |
1475 } | 1464 } |
1476 | 1465 |
1477 Expect(Token::RBRACE, CHECK_OK); | 1466 Expect(Token::RBRACE, CHECK_OK); |
1478 | |
1479 return result; | 1467 return result; |
1480 } | 1468 } |
1481 | 1469 |
1482 | 1470 |
1483 Statement* Parser::ParseImportDeclaration(bool* ok) { | 1471 void* Parser::ParseImportDeclaration(bool* ok) { |
1484 // ImportDeclaration : | 1472 // ImportDeclaration : |
1485 // 'import' ImportClause 'from' ModuleSpecifier ';' | 1473 // 'import' ImportClause 'from' ModuleSpecifier ';' |
1486 // 'import' ModuleSpecifier ';' | 1474 // 'import' ModuleSpecifier ';' |
1487 // | 1475 // |
1488 // ImportClause : | 1476 // ImportClause : |
| 1477 // ImportedDefaultBinding |
1489 // NameSpaceImport | 1478 // NameSpaceImport |
1490 // NamedImports | 1479 // NamedImports |
1491 // ImportedDefaultBinding | |
1492 // ImportedDefaultBinding ',' NameSpaceImport | 1480 // ImportedDefaultBinding ',' NameSpaceImport |
1493 // ImportedDefaultBinding ',' NamedImports | 1481 // ImportedDefaultBinding ',' NamedImports |
1494 // | 1482 // |
1495 // NameSpaceImport : | 1483 // NameSpaceImport : |
1496 // '*' 'as' ImportedBinding | 1484 // '*' 'as' ImportedBinding |
1497 | 1485 |
1498 int pos = peek_position(); | 1486 int pos = peek_position(); |
1499 Expect(Token::IMPORT, CHECK_OK); | 1487 Expect(Token::IMPORT, CHECK_OK); |
1500 | 1488 |
1501 Token::Value tok = peek(); | 1489 Token::Value tok = peek(); |
1502 | 1490 |
1503 // 'import' ModuleSpecifier ';' | 1491 // 'import' ModuleSpecifier ';' |
1504 if (tok == Token::STRING) { | 1492 if (tok == Token::STRING) { |
1505 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); | 1493 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); |
1506 scope_->module()->AddModuleRequest(module_specifier, zone()); | |
1507 ExpectSemicolon(CHECK_OK); | 1494 ExpectSemicolon(CHECK_OK); |
1508 return factory()->NewEmptyStatement(pos); | 1495 scope_->module()->AddEmptyImport( |
| 1496 module_specifier, scanner()->location(), zone()); |
| 1497 return nullptr; |
1509 } | 1498 } |
1510 | 1499 |
1511 // Parse ImportedDefaultBinding if present. | 1500 // Parse ImportedDefaultBinding if present. |
1512 ImportDeclaration* import_default_declaration = NULL; | 1501 const AstRawString* import_default_binding = nullptr; |
| 1502 Scanner::Location import_default_binding_loc; |
1513 if (tok != Token::MUL && tok != Token::LBRACE) { | 1503 if (tok != Token::MUL && tok != Token::LBRACE) { |
1514 const AstRawString* local_name = | 1504 import_default_binding = |
1515 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); | 1505 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
1516 VariableProxy* proxy = NewUnresolved(local_name, CONST); | 1506 import_default_binding_loc = scanner()->location(); |
1517 import_default_declaration = factory()->NewImportDeclaration( | 1507 DeclareImport(import_default_binding, pos, CHECK_OK); |
1518 proxy, ast_value_factory()->default_string(), NULL, scope_, pos); | |
1519 Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true, | |
1520 CHECK_OK); | |
1521 } | 1508 } |
1522 | 1509 |
1523 const AstRawString* module_instance_binding = NULL; | 1510 // Parse NameSpaceImport or NamedImports if present. |
1524 ZoneList<ImportDeclaration*>* named_declarations = NULL; | 1511 const AstRawString* module_namespace_binding = nullptr; |
1525 if (import_default_declaration == NULL || Check(Token::COMMA)) { | 1512 Scanner::Location module_namespace_binding_loc; |
| 1513 const ZoneList<const NamedImport*>* named_imports = nullptr; |
| 1514 if (import_default_binding == nullptr || Check(Token::COMMA)) { |
1526 switch (peek()) { | 1515 switch (peek()) { |
1527 case Token::MUL: { | 1516 case Token::MUL: { |
1528 Consume(Token::MUL); | 1517 Consume(Token::MUL); |
1529 ExpectContextualKeyword(CStrVector("as"), CHECK_OK); | 1518 ExpectContextualKeyword(CStrVector("as"), CHECK_OK); |
1530 module_instance_binding = | 1519 module_namespace_binding = |
1531 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); | 1520 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
1532 // TODO(ES6): Add an appropriate declaration. | 1521 module_namespace_binding_loc = scanner()->location(); |
1533 break; | 1522 break; |
1534 } | 1523 } |
1535 | 1524 |
1536 case Token::LBRACE: | 1525 case Token::LBRACE: |
1537 named_declarations = ParseNamedImports(pos, CHECK_OK); | 1526 named_imports = ParseNamedImports(pos, CHECK_OK); |
1538 break; | 1527 break; |
1539 | 1528 |
1540 default: | 1529 default: |
1541 *ok = false; | 1530 *ok = false; |
1542 ReportUnexpectedToken(scanner()->current_token()); | 1531 ReportUnexpectedToken(scanner()->current_token()); |
1543 return NULL; | 1532 return nullptr; |
1544 } | 1533 } |
1545 } | 1534 } |
1546 | 1535 |
1547 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1536 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1548 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); | 1537 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); |
1549 scope_->module()->AddModuleRequest(module_specifier, zone()); | 1538 ExpectSemicolon(CHECK_OK); |
1550 | 1539 |
1551 if (module_instance_binding != NULL) { | 1540 // Now that we have all the information, we can make the appropriate |
1552 // TODO(ES6): Set the module specifier for the module namespace binding. | 1541 // declarations. |
| 1542 |
| 1543 if (module_namespace_binding != nullptr) { |
| 1544 scope_->module()->AddStarImport( |
| 1545 module_namespace_binding, module_specifier, |
| 1546 module_namespace_binding_loc, zone()); |
| 1547 // TODO(neis): Create special immutable binding for the namespace object. |
1553 } | 1548 } |
1554 | 1549 |
1555 if (import_default_declaration != NULL) { | 1550 // TODO(neis): Would prefer to call DeclareImport below rather than above and |
1556 import_default_declaration->set_module_specifier(module_specifier); | 1551 // in ParseNamedImports, but then a possible error message would point to the |
| 1552 // wrong location. Maybe have a DeclareAt version of Declare that takes a |
| 1553 // location? |
| 1554 |
| 1555 if (import_default_binding != nullptr) { |
| 1556 scope_->module()->AddImport( |
| 1557 ast_value_factory()->default_string(), import_default_binding, |
| 1558 module_specifier, import_default_binding_loc, zone()); |
| 1559 // DeclareImport(import_default_binding, pos, CHECK_OK); |
1557 } | 1560 } |
1558 | 1561 |
1559 if (named_declarations != NULL) { | 1562 if (named_imports != nullptr) { |
1560 for (int i = 0; i < named_declarations->length(); ++i) { | 1563 if (named_imports->length() == 0) { |
1561 named_declarations->at(i)->set_module_specifier(module_specifier); | 1564 scope_->module()->AddEmptyImport( |
| 1565 module_specifier, scanner()->location(), zone()); |
| 1566 } else { |
| 1567 for (int i = 0; i < named_imports->length(); ++i) { |
| 1568 const NamedImport* import = named_imports->at(i); |
| 1569 scope_->module()->AddImport( |
| 1570 import->import_name, import->local_name, |
| 1571 module_specifier, import->location, zone()); |
| 1572 // DeclareImport(import->local_name, pos, CHECK_OK); |
| 1573 } |
1562 } | 1574 } |
1563 } | 1575 } |
1564 | 1576 |
1565 ExpectSemicolon(CHECK_OK); | 1577 return nullptr; |
1566 return factory()->NewEmptyStatement(pos); | |
1567 } | 1578 } |
1568 | 1579 |
1569 | 1580 |
1570 Statement* Parser::ParseExportDefault(bool* ok) { | 1581 Statement* Parser::ParseExportDefault(bool* ok) { |
1571 // Supports the following productions, starting after the 'default' token: | 1582 // Supports the following productions, starting after the 'default' token: |
1572 // 'export' 'default' FunctionDeclaration | 1583 // 'export' 'default' HoistableDeclaration |
1573 // 'export' 'default' ClassDeclaration | 1584 // 'export' 'default' ClassDeclaration |
1574 // 'export' 'default' AssignmentExpression[In] ';' | 1585 // 'export' 'default' AssignmentExpression[In] ';' |
1575 | 1586 |
1576 Expect(Token::DEFAULT, CHECK_OK); | 1587 Expect(Token::DEFAULT, CHECK_OK); |
1577 Scanner::Location default_loc = scanner()->location(); | 1588 Scanner::Location default_loc = scanner()->location(); |
1578 | 1589 |
1579 const AstRawString* default_string = ast_value_factory()->default_string(); | 1590 ZoneList<const AstRawString*> local_names(1, zone()); |
1580 ZoneList<const AstRawString*> names(1, zone()); | |
1581 Statement* result = nullptr; | 1591 Statement* result = nullptr; |
1582 Expression* default_export = nullptr; | |
1583 switch (peek()) { | 1592 switch (peek()) { |
1584 case Token::FUNCTION: | 1593 case Token::FUNCTION: |
1585 result = ParseHoistableDeclaration(&names, true, CHECK_OK); | 1594 result = ParseHoistableDeclaration(&local_names, true, CHECK_OK); |
1586 break; | 1595 break; |
1587 | 1596 |
1588 case Token::CLASS: | 1597 case Token::CLASS: |
1589 Consume(Token::CLASS); | 1598 Consume(Token::CLASS); |
1590 result = ParseClassDeclaration(&names, true, CHECK_OK); | 1599 result = ParseClassDeclaration(&local_names, true, CHECK_OK); |
1591 break; | 1600 break; |
1592 | 1601 |
1593 case Token::ASYNC: | 1602 case Token::ASYNC: |
1594 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && | 1603 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && |
1595 !scanner()->HasAnyLineTerminatorAfterNext()) { | 1604 !scanner()->HasAnyLineTerminatorAfterNext()) { |
1596 Consume(Token::ASYNC); | 1605 Consume(Token::ASYNC); |
1597 result = ParseAsyncFunctionDeclaration(&names, true, CHECK_OK); | 1606 result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK); |
1598 break; | 1607 break; |
1599 } | 1608 } |
1600 /* falls through */ | 1609 /* falls through */ |
1601 | 1610 |
1602 default: { | 1611 default: { |
1603 int pos = peek_position(); | 1612 int pos = position(); |
1604 ExpressionClassifier classifier(this); | 1613 ExpressionClassifier classifier(this); |
1605 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); | 1614 Expression* value = |
| 1615 ParseAssignmentExpression(true, &classifier, CHECK_OK); |
1606 RewriteNonPattern(&classifier, CHECK_OK); | 1616 RewriteNonPattern(&classifier, CHECK_OK); |
| 1617 SetFunctionName(value, ast_value_factory()->default_string()); |
| 1618 |
| 1619 const AstRawString* local_name = |
| 1620 ast_value_factory()->star_default_star_string(); |
| 1621 local_names.Add(local_name, zone()); |
| 1622 |
| 1623 // It's fine to declare this as CONST because the user has no way of |
| 1624 // writing to it. |
| 1625 VariableProxy* proxy = NewUnresolved(local_name, CONST); |
| 1626 Declaration* declaration = |
| 1627 factory()->NewVariableDeclaration(proxy, CONST, scope_, pos); |
| 1628 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 1629 proxy->var()->set_initializer_position(position()); |
| 1630 |
| 1631 Assignment* assignment = factory()->NewAssignment( |
| 1632 Token::INIT, proxy, value, kNoSourcePosition); |
| 1633 result = factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
1607 | 1634 |
1608 ExpectSemicolon(CHECK_OK); | 1635 ExpectSemicolon(CHECK_OK); |
1609 result = factory()->NewExpressionStatement(expr, pos); | |
1610 break; | 1636 break; |
1611 } | 1637 } |
1612 } | 1638 } |
1613 | 1639 |
1614 DCHECK_LE(names.length(), 1); | 1640 DCHECK_EQ(local_names.length(), 1); |
1615 if (names.length() == 1) { | 1641 scope_->module()->AddExport( |
1616 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok); | 1642 local_names.first(), ast_value_factory()->default_string(), default_loc, |
1617 if (!*ok) { | 1643 zone()); |
1618 ParserTraits::ReportMessageAt( | |
1619 default_loc, MessageTemplate::kDuplicateExport, default_string); | |
1620 return nullptr; | |
1621 } | |
1622 } else { | |
1623 // TODO(ES6): Assign result to a const binding with the name "*default*" | |
1624 // and add an export entry with "*default*" as the local name. | |
1625 USE(default_export); | |
1626 } | |
1627 | 1644 |
| 1645 DCHECK_NOT_NULL(result); |
1628 return result; | 1646 return result; |
1629 } | 1647 } |
1630 | 1648 |
1631 | |
1632 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1649 Statement* Parser::ParseExportDeclaration(bool* ok) { |
1633 // ExportDeclaration: | 1650 // ExportDeclaration: |
1634 // 'export' '*' 'from' ModuleSpecifier ';' | 1651 // 'export' '*' 'from' ModuleSpecifier ';' |
1635 // 'export' ExportClause ('from' ModuleSpecifier)? ';' | 1652 // 'export' ExportClause ('from' ModuleSpecifier)? ';' |
1636 // 'export' VariableStatement | 1653 // 'export' VariableStatement |
1637 // 'export' Declaration | 1654 // 'export' Declaration |
1638 // 'export' 'default' ... (handled in ParseExportDefault) | 1655 // 'export' 'default' ... (handled in ParseExportDefault) |
1639 | 1656 |
1640 int pos = peek_position(); | 1657 int pos = peek_position(); |
1641 Expect(Token::EXPORT, CHECK_OK); | 1658 Expect(Token::EXPORT, CHECK_OK); |
1642 | 1659 |
1643 Statement* result = NULL; | 1660 Statement* result = nullptr; |
1644 ZoneList<const AstRawString*> names(1, zone()); | 1661 ZoneList<const AstRawString*> names(1, zone()); |
1645 switch (peek()) { | 1662 switch (peek()) { |
1646 case Token::DEFAULT: | 1663 case Token::DEFAULT: |
1647 return ParseExportDefault(ok); | 1664 return ParseExportDefault(ok); |
1648 | 1665 |
1649 case Token::MUL: { | 1666 case Token::MUL: { |
1650 Consume(Token::MUL); | 1667 Consume(Token::MUL); |
1651 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1668 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1652 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); | 1669 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); |
1653 scope_->module()->AddModuleRequest(module_specifier, zone()); | |
1654 // TODO(ES6): scope_->module()->AddStarExport(...) | |
1655 ExpectSemicolon(CHECK_OK); | 1670 ExpectSemicolon(CHECK_OK); |
| 1671 scope_->module()->AddStarExport( |
| 1672 module_specifier, scanner()->location(), zone()); |
1656 return factory()->NewEmptyStatement(pos); | 1673 return factory()->NewEmptyStatement(pos); |
1657 } | 1674 } |
1658 | 1675 |
1659 case Token::LBRACE: { | 1676 case Token::LBRACE: { |
1660 // There are two cases here: | 1677 // There are two cases here: |
1661 // | 1678 // |
1662 // 'export' ExportClause ';' | 1679 // 'export' ExportClause ';' |
1663 // and | 1680 // and |
1664 // 'export' ExportClause FromClause ';' | 1681 // 'export' ExportClause FromClause ';' |
1665 // | 1682 // |
1666 // In the first case, the exported identifiers in ExportClause must | 1683 // In the first case, the exported identifiers in ExportClause must |
1667 // not be reserved words, while in the latter they may be. We | 1684 // not be reserved words, while in the latter they may be. We |
1668 // pass in a location that gets filled with the first reserved word | 1685 // pass in a location that gets filled with the first reserved word |
1669 // encountered, and then throw a SyntaxError if we are in the | 1686 // encountered, and then throw a SyntaxError if we are in the |
1670 // non-FromClause case. | 1687 // non-FromClause case. |
1671 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 1688 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
1672 ZoneList<const AstRawString*> export_names(1, zone()); | 1689 ZoneList<const AstRawString*> export_names(1, zone()); |
1673 ZoneList<Scanner::Location> export_locations(1, zone()); | 1690 ZoneList<Scanner::Location> export_locations(1, zone()); |
1674 ZoneList<const AstRawString*> local_names(1, zone()); | 1691 ZoneList<const AstRawString*> original_names(1, zone()); |
1675 ParseExportClause(&export_names, &export_locations, &local_names, | 1692 ParseExportClause(&export_names, &export_locations, &original_names, |
1676 &reserved_loc, CHECK_OK); | 1693 &reserved_loc, CHECK_OK); |
1677 const AstRawString* indirect_export_module_specifier = NULL; | 1694 const AstRawString* module_specifier = nullptr; |
1678 if (CheckContextualKeyword(CStrVector("from"))) { | 1695 if (CheckContextualKeyword(CStrVector("from"))) { |
1679 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK); | 1696 module_specifier = ParseModuleSpecifier(CHECK_OK); |
1680 } else if (reserved_loc.IsValid()) { | 1697 } else if (reserved_loc.IsValid()) { |
1681 // No FromClause, so reserved words are invalid in ExportClause. | 1698 // No FromClause, so reserved words are invalid in ExportClause. |
1682 *ok = false; | 1699 *ok = false; |
1683 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved); | 1700 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved); |
1684 return NULL; | 1701 return nullptr; |
1685 } | 1702 } |
1686 ExpectSemicolon(CHECK_OK); | 1703 ExpectSemicolon(CHECK_OK); |
1687 const int length = export_names.length(); | 1704 const int length = export_names.length(); |
1688 DCHECK_EQ(length, local_names.length()); | 1705 DCHECK_EQ(length, original_names.length()); |
1689 DCHECK_EQ(length, export_locations.length()); | 1706 DCHECK_EQ(length, export_locations.length()); |
1690 if (indirect_export_module_specifier == NULL) { | 1707 if (module_specifier == nullptr) { |
1691 for (int i = 0; i < length; ++i) { | 1708 for (int i = 0; i < length; ++i) { |
1692 scope_->module()->AddLocalExport(export_names[i], local_names[i], | 1709 scope_->module()->AddExport(original_names[i], export_names[i], |
1693 zone(), ok); | 1710 export_locations[i], zone()); |
1694 if (!*ok) { | |
1695 ParserTraits::ReportMessageAt(export_locations[i], | |
1696 MessageTemplate::kDuplicateExport, | |
1697 export_names[i]); | |
1698 return NULL; | |
1699 } | |
1700 } | 1711 } |
| 1712 } else if (length == 0) { |
| 1713 scope_->module()->AddEmptyImport( |
| 1714 module_specifier, scanner()->location(), zone()); |
1701 } else { | 1715 } else { |
1702 scope_->module()->AddModuleRequest(indirect_export_module_specifier, | |
1703 zone()); | |
1704 for (int i = 0; i < length; ++i) { | 1716 for (int i = 0; i < length; ++i) { |
1705 // TODO(ES6): scope_->module()->AddIndirectExport(...);( | 1717 scope_->module()->AddExport( |
| 1718 original_names[i], export_names[i], module_specifier, |
| 1719 export_locations[i], zone()); |
1706 } | 1720 } |
1707 } | 1721 } |
1708 return factory()->NewEmptyStatement(pos); | 1722 return factory()->NewEmptyStatement(pos); |
1709 } | 1723 } |
1710 | 1724 |
1711 case Token::FUNCTION: | 1725 case Token::FUNCTION: |
1712 result = ParseHoistableDeclaration(&names, false, CHECK_OK); | 1726 result = ParseHoistableDeclaration(&names, false, CHECK_OK); |
1713 break; | 1727 break; |
1714 | 1728 |
1715 case Token::CLASS: | 1729 case Token::CLASS: |
1716 Consume(Token::CLASS); | 1730 Consume(Token::CLASS); |
1717 result = ParseClassDeclaration(&names, false, CHECK_OK); | 1731 result = ParseClassDeclaration(&names, false, CHECK_OK); |
1718 break; | 1732 break; |
1719 | 1733 |
1720 case Token::VAR: | 1734 case Token::VAR: |
1721 case Token::LET: | 1735 case Token::LET: |
1722 case Token::CONST: | 1736 case Token::CONST: |
1723 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); | 1737 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); |
1724 break; | 1738 break; |
1725 | 1739 |
1726 case Token::ASYNC: | 1740 case Token::ASYNC: |
1727 if (allow_harmony_async_await()) { | 1741 if (allow_harmony_async_await()) { |
| 1742 // TODO(neis): Why don't we have the same check here as in |
| 1743 // ParseStatementListItem? |
1728 Consume(Token::ASYNC); | 1744 Consume(Token::ASYNC); |
1729 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); | 1745 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); |
1730 break; | 1746 break; |
1731 } | 1747 } |
1732 /* falls through */ | 1748 /* falls through */ |
1733 | 1749 |
1734 default: | 1750 default: |
1735 *ok = false; | 1751 *ok = false; |
1736 ReportUnexpectedToken(scanner()->current_token()); | 1752 ReportUnexpectedToken(scanner()->current_token()); |
1737 return NULL; | 1753 return nullptr; |
1738 } | 1754 } |
1739 | 1755 |
1740 // Extract declared names into export declarations. | |
1741 ModuleDescriptor* descriptor = scope_->module(); | 1756 ModuleDescriptor* descriptor = scope_->module(); |
1742 for (int i = 0; i < names.length(); ++i) { | 1757 for (int i = 0; i < names.length(); ++i) { |
1743 descriptor->AddLocalExport(names[i], names[i], zone(), ok); | 1758 // TODO(neis): Provide better location. |
1744 if (!*ok) { | 1759 descriptor->AddExport(names[i], names[i], scanner()->location(), zone()); |
1745 // TODO(adamk): Possibly report this error at the right place. | |
1746 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]); | |
1747 return NULL; | |
1748 } | |
1749 } | 1760 } |
1750 | 1761 |
1751 DCHECK_NOT_NULL(result); | 1762 DCHECK_NOT_NULL(result); |
1752 return result; | 1763 return result; |
1753 } | 1764 } |
1754 | 1765 |
1755 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, | 1766 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, |
1756 AllowLabelledFunctionStatement allow_function, | 1767 AllowLabelledFunctionStatement allow_function, |
1757 bool* ok) { | 1768 bool* ok) { |
1758 // Statement :: | 1769 // Statement :: |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 // scope. | 1904 // scope. |
1894 // Let/const variables are always added to the immediately enclosing scope. | 1905 // Let/const variables are always added to the immediately enclosing scope. |
1895 Scope* scope = | 1906 Scope* scope = |
1896 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); | 1907 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); |
1897 return scope->NewUnresolved(factory(), name, Variable::NORMAL, | 1908 return scope->NewUnresolved(factory(), name, Variable::NORMAL, |
1898 scanner()->location().beg_pos, | 1909 scanner()->location().beg_pos, |
1899 scanner()->location().end_pos); | 1910 scanner()->location().end_pos); |
1900 } | 1911 } |
1901 | 1912 |
1902 | 1913 |
| 1914 void* Parser::DeclareImport(const AstRawString* local_name, int pos, bool* ok) { |
| 1915 DCHECK_NOT_NULL(local_name); |
| 1916 VariableProxy* proxy = NewUnresolved(local_name, IMPORT); |
| 1917 Declaration* declaration = |
| 1918 factory()->NewVariableDeclaration(proxy, IMPORT, scope_, pos); |
| 1919 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 1920 return nullptr; |
| 1921 } |
| 1922 |
| 1923 |
1903 Variable* Parser::Declare(Declaration* declaration, | 1924 Variable* Parser::Declare(Declaration* declaration, |
1904 DeclarationDescriptor::Kind declaration_kind, | 1925 DeclarationDescriptor::Kind declaration_kind, |
1905 bool resolve, bool* ok, Scope* scope) { | 1926 bool resolve, bool* ok, Scope* scope) { |
1906 VariableProxy* proxy = declaration->proxy(); | 1927 VariableProxy* proxy = declaration->proxy(); |
1907 DCHECK(proxy->raw_name() != NULL); | 1928 DCHECK(proxy->raw_name() != NULL); |
1908 const AstRawString* name = proxy->raw_name(); | 1929 const AstRawString* name = proxy->raw_name(); |
1909 VariableMode mode = declaration->mode(); | 1930 VariableMode mode = declaration->mode(); |
1910 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY); | 1931 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY); |
1911 bool is_function_declaration = declaration->IsFunctionDeclaration(); | 1932 bool is_function_declaration = declaration->IsFunctionDeclaration(); |
1912 if (scope == nullptr) scope = scope_; | 1933 if (scope == nullptr) scope = scope_; |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2164 | 2185 |
2165 FuncNameInferrer::State fni_state(fni_); | 2186 FuncNameInferrer::State fni_state(fni_); |
2166 if (fni_ != NULL) fni_->PushEnclosingName(name); | 2187 if (fni_ != NULL) fni_->PushEnclosingName(name); |
2167 FunctionLiteral* fun = ParseFunctionLiteral( | 2188 FunctionLiteral* fun = ParseFunctionLiteral( |
2168 name, scanner()->location(), name_validity, | 2189 name, scanner()->location(), name_validity, |
2169 is_generator ? FunctionKind::kGeneratorFunction | 2190 is_generator ? FunctionKind::kGeneratorFunction |
2170 : is_async ? FunctionKind::kAsyncFunction | 2191 : is_async ? FunctionKind::kAsyncFunction |
2171 : FunctionKind::kNormalFunction, | 2192 : FunctionKind::kNormalFunction, |
2172 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 2193 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
2173 | 2194 |
2174 // Even if we're not at the top-level of the global or a function | |
2175 // scope, we treat it as such and introduce the function with its | |
2176 // initial value upon entering the corresponding scope. | |
2177 // In ES6, a function behaves as a lexical binding, except in | 2195 // In ES6, a function behaves as a lexical binding, except in |
2178 // a script scope, or the initial scope of eval or another function. | 2196 // a script scope, or the initial scope of eval or another function. |
2179 VariableMode mode = | 2197 VariableMode mode = |
2180 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET | 2198 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET |
2181 : VAR; | 2199 : VAR; |
2182 VariableProxy* proxy = NewUnresolved(variable_name, mode); | 2200 VariableProxy* proxy = NewUnresolved(variable_name, mode); |
2183 Declaration* declaration = | 2201 Declaration* declaration = |
2184 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 2202 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
2185 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2203 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
2186 if (names) names->Add(variable_name, zone()); | 2204 if (names) names->Add(variable_name, zone()); |
(...skipping 3854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6041 DCHECK_NOT_NULL(name); | 6059 DCHECK_NOT_NULL(name); |
6042 const AstRawString* prefix = | 6060 const AstRawString* prefix = |
6043 is_getter ? parser_->ast_value_factory()->get_space_string() | 6061 is_getter ? parser_->ast_value_factory()->get_space_string() |
6044 : parser_->ast_value_factory()->set_space_string(); | 6062 : parser_->ast_value_factory()->set_space_string(); |
6045 function->set_raw_name( | 6063 function->set_raw_name( |
6046 parser_->ast_value_factory()->NewConsString(prefix, name)); | 6064 parser_->ast_value_factory()->NewConsString(prefix, name)); |
6047 return; | 6065 return; |
6048 } | 6066 } |
6049 } | 6067 } |
6050 | 6068 |
6051 if (!value->IsAnonymousFunctionDefinition()) return; | |
6052 DCHECK_NOT_NULL(name); | |
6053 | |
6054 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]] | 6069 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]] |
6055 // of an object literal. | 6070 // of an object literal. |
6056 if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return; | 6071 if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return; |
6057 | 6072 |
6058 if (function != nullptr) { | 6073 DCHECK(!value->IsAnonymousFunctionDefinition() || |
6059 function->set_raw_name(name); | 6074 property->kind() == ObjectLiteralProperty::COMPUTED); |
6060 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind()); | 6075 SetFunctionName(value, name); |
6061 } else { | |
6062 DCHECK(value->IsClassLiteral()); | |
6063 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind()); | |
6064 value->AsClassLiteral()->constructor()->set_raw_name(name); | |
6065 } | |
6066 } | 6076 } |
6067 | 6077 |
6068 | 6078 |
6069 void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value, | 6079 void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value, |
6070 Expression* identifier) { | 6080 Expression* identifier) { |
| 6081 if (!identifier->IsVariableProxy()) return; |
| 6082 SetFunctionName(value, identifier->AsVariableProxy()->raw_name()); |
| 6083 } |
| 6084 |
| 6085 |
| 6086 void ParserTraits::SetFunctionName(Expression* value, |
| 6087 const AstRawString* name) { |
| 6088 DCHECK_NOT_NULL(name); |
6071 if (!value->IsAnonymousFunctionDefinition()) return; | 6089 if (!value->IsAnonymousFunctionDefinition()) return; |
6072 if (!identifier->IsVariableProxy()) return; | |
6073 | |
6074 auto name = identifier->AsVariableProxy()->raw_name(); | |
6075 DCHECK_NOT_NULL(name); | |
6076 | |
6077 auto function = value->AsFunctionLiteral(); | 6090 auto function = value->AsFunctionLiteral(); |
6078 if (function != nullptr) { | 6091 if (function != nullptr) { |
6079 function->set_raw_name(name); | 6092 function->set_raw_name(name); |
6080 } else { | 6093 } else { |
6081 DCHECK(value->IsClassLiteral()); | 6094 DCHECK(value->IsClassLiteral()); |
6082 value->AsClassLiteral()->constructor()->set_raw_name(name); | 6095 value->AsClassLiteral()->constructor()->set_raw_name(name); |
6083 } | 6096 } |
6084 } | 6097 } |
6085 | 6098 |
6086 | 6099 |
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7049 | 7062 |
7050 #ifdef DEBUG | 7063 #ifdef DEBUG |
7051 void Parser::Print(AstNode* node) { | 7064 void Parser::Print(AstNode* node) { |
7052 ast_value_factory()->Internalize(Isolate::Current()); | 7065 ast_value_factory()->Internalize(Isolate::Current()); |
7053 node->Print(Isolate::Current()); | 7066 node->Print(Isolate::Current()); |
7054 } | 7067 } |
7055 #endif // DEBUG | 7068 #endif // DEBUG |
7056 | 7069 |
7057 } // namespace internal | 7070 } // namespace internal |
7058 } // namespace v8 | 7071 } // namespace v8 |
OLD | NEW |