Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: src/parsing/parser.cc

Issue 2108193003: [modules] AST and parser rework. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@anonymous-declarations
Patch Set: . Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 AstNodeFactory function_factory(ast_value_factory()); 942 AstNodeFactory function_factory(ast_value_factory());
943 FunctionState function_state(&function_state_, &scope_, scope, 943 FunctionState function_state(&function_state_, &scope_, scope,
944 kNormalFunction, &function_factory); 944 kNormalFunction, &function_factory);
945 945
946 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 946 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
947 bool ok = true; 947 bool ok = true;
948 int beg_pos = scanner()->location().beg_pos; 948 int beg_pos = scanner()->location().beg_pos;
949 parsing_module_ = info->is_module(); 949 parsing_module_ = info->is_module();
950 if (parsing_module_) { 950 if (parsing_module_) {
951 ParseModuleItemList(body, &ok); 951 ParseModuleItemList(body, &ok);
952 ok = ok &&
953 scope_->module()->Validate(scope_, &pending_error_handler_, zone());
952 } else { 954 } else {
953 // Don't count the mode in the use counters--give the program a chance 955 // Don't count the mode in the use counters--give the program a chance
954 // to enable script-wide strict mode below. 956 // to enable script-wide strict mode below.
955 scope_->SetLanguageMode(info->language_mode()); 957 scope_->SetLanguageMode(info->language_mode());
956 ParseStatementList(body, Token::EOS, &ok); 958 ParseStatementList(body, Token::EOS, &ok);
957 } 959 }
958 960
959 // The parser will peek but not consume EOS. Our scope logically goes all 961 // The parser will peek but not consume EOS. Our scope logically goes all
960 // the way to the EOS, though. 962 // the way to the EOS, though.
961 scope->set_end_position(scanner()->peek_location().beg_pos); 963 scope->set_end_position(scanner()->peek_location().beg_pos);
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 } 1314 }
1313 /* falls through */ 1315 /* falls through */
1314 default: 1316 default:
1315 break; 1317 break;
1316 } 1318 }
1317 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); 1319 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok);
1318 } 1320 }
1319 1321
1320 1322
1321 Statement* Parser::ParseModuleItem(bool* ok) { 1323 Statement* Parser::ParseModuleItem(bool* ok) {
1322 // (Ecma 262 6th Edition, 15.2): 1324 // ecma262/#prod-ModuleItem
1323 // ModuleItem : 1325 // ModuleItem :
1324 // ImportDeclaration 1326 // ImportDeclaration
1325 // ExportDeclaration 1327 // ExportDeclaration
1326 // StatementListItem 1328 // StatementListItem
1327 1329
1328 switch (peek()) { 1330 switch (peek()) {
1329 case Token::IMPORT: 1331 case Token::IMPORT:
1330 return ParseImportDeclaration(ok); 1332 ParseImportDeclaration(CHECK_OK);
1333 return factory()->NewEmptyStatement(kNoSourcePosition);
1331 case Token::EXPORT: 1334 case Token::EXPORT:
1332 return ParseExportDeclaration(ok); 1335 return ParseExportDeclaration(ok);
1333 default: 1336 default:
1334 return ParseStatementListItem(ok); 1337 return ParseStatementListItem(ok);
1335 } 1338 }
1336 } 1339 }
1337 1340
1338 1341
1339 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) { 1342 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
adamk 2016/07/13 18:38:21 This doesn't seem to need a return value at all (c
neis 2016/07/14 10:28:24 void* is needed because of the beautiful CHECK_OK
adamk 2016/07/14 18:26:33 Except no one calls this with CHECK_OK. But I gues
1340 // (Ecma 262 6th Edition, 15.2): 1343 // ecma262/#prod-Module
1341 // Module : 1344 // Module :
1342 // ModuleBody? 1345 // ModuleBody?
1343 // 1346 //
1347 // ecma262/#prod-ModuleItemList
1344 // ModuleBody : 1348 // ModuleBody :
1345 // ModuleItem* 1349 // ModuleItem*
1346 1350
1347 DCHECK(scope_->is_module_scope()); 1351 DCHECK(scope_->is_module_scope());
1348
1349 while (peek() != Token::EOS) { 1352 while (peek() != Token::EOS) {
1350 Statement* stat = ParseModuleItem(CHECK_OK); 1353 Statement* stat = ParseModuleItem(CHECK_OK);
1351 if (stat && !stat->IsEmpty()) { 1354 if (stat && !stat->IsEmpty()) {
1352 body->Add(stat, zone()); 1355 body->Add(stat, zone());
1353 } 1356 }
1354 } 1357 }
1355
1356 // Check that all exports are bound.
1357 ModuleDescriptor* descriptor = scope_->module();
1358 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
1359 it.Advance()) {
1360 if (scope_->LookupLocal(it.local_name()) == NULL) {
1361 // TODO(adamk): Pass both local_name and export_name once ParserTraits
1362 // supports multiple arg error messages.
1363 // Also try to report this at a better location.
1364 ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined,
1365 it.local_name());
1366 *ok = false;
1367 return NULL;
1368 }
1369 }
1370
1371 return NULL; 1358 return NULL;
1372 } 1359 }
1373 1360
1374 1361
1375 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { 1362 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1376 // ModuleSpecifier : 1363 // ModuleSpecifier :
1377 // StringLiteral 1364 // StringLiteral
1378 1365
1379 Expect(Token::STRING, CHECK_OK); 1366 Expect(Token::STRING, CHECK_OK);
1380 return GetSymbol(scanner()); 1367 return GetSymbol(scanner());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1418 } 1405 }
1419 export_names->Add(export_name, zone()); 1406 export_names->Add(export_name, zone());
1420 local_names->Add(local_name, zone()); 1407 local_names->Add(local_name, zone());
1421 export_locations->Add(scanner()->location(), zone()); 1408 export_locations->Add(scanner()->location(), zone());
1422 if (peek() == Token::RBRACE) break; 1409 if (peek() == Token::RBRACE) break;
1423 Expect(Token::COMMA, CHECK_OK); 1410 Expect(Token::COMMA, CHECK_OK);
1424 } 1411 }
1425 1412
1426 Expect(Token::RBRACE, CHECK_OK); 1413 Expect(Token::RBRACE, CHECK_OK);
1427 1414
1428 return 0; 1415 return nullptr;
1429 } 1416 }
1430 1417
1431 1418
1432 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) { 1419 ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports(
1420 int pos, bool* ok) {
1433 // NamedImports : 1421 // NamedImports :
1434 // '{' '}' 1422 // '{' '}'
1435 // '{' ImportsList '}' 1423 // '{' ImportsList '}'
1436 // '{' ImportsList ',' '}' 1424 // '{' ImportsList ',' '}'
1437 // 1425 //
1438 // ImportsList : 1426 // ImportsList :
1439 // ImportSpecifier 1427 // ImportSpecifier
1440 // ImportsList ',' ImportSpecifier 1428 // ImportsList ',' ImportSpecifier
1441 // 1429 //
1442 // ImportSpecifier : 1430 // ImportSpecifier :
1443 // BindingIdentifier 1431 // BindingIdentifier
1444 // IdentifierName 'as' BindingIdentifier 1432 // IdentifierName 'as' BindingIdentifier
1445 1433
1446 Expect(Token::LBRACE, CHECK_OK); 1434 Expect(Token::LBRACE, CHECK_OK);
1447 1435
1448 ZoneList<ImportDeclaration*>* result = 1436 auto result = new (zone()) ZoneList<const NamedImport*>(1, zone());
1449 new (zone()) ZoneList<ImportDeclaration*>(1, zone());
1450 while (peek() != Token::RBRACE) { 1437 while (peek() != Token::RBRACE) {
1451 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); 1438 const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1452 const AstRawString* local_name = import_name; 1439 const AstRawString* local_name = import_name;
1453 // In the presence of 'as', the left-side of the 'as' can 1440 // In the presence of 'as', the left-side of the 'as' can
1454 // be any IdentifierName. But without 'as', it must be a valid 1441 // be any IdentifierName. But without 'as', it must be a valid
1455 // BindingIdentifier. 1442 // BindingIdentifier.
1456 if (CheckContextualKeyword(CStrVector("as"))) { 1443 if (CheckContextualKeyword(CStrVector("as"))) {
1457 local_name = ParseIdentifierName(CHECK_OK); 1444 local_name = ParseIdentifierName(CHECK_OK);
1458 } 1445 }
1459 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false, 1446 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false,
1460 parsing_module_)) { 1447 parsing_module_)) {
1461 *ok = false; 1448 *ok = false;
1462 ReportMessage(MessageTemplate::kUnexpectedReserved); 1449 ReportMessage(MessageTemplate::kUnexpectedReserved);
1463 return NULL; 1450 return nullptr;
1464 } else if (IsEvalOrArguments(local_name)) { 1451 } else if (IsEvalOrArguments(local_name)) {
1465 *ok = false; 1452 *ok = false;
1466 ReportMessage(MessageTemplate::kStrictEvalArguments); 1453 ReportMessage(MessageTemplate::kStrictEvalArguments);
1467 return NULL; 1454 return nullptr;
1468 } 1455 }
1469 VariableProxy* proxy = NewUnresolved(local_name, CONST); 1456
1470 ImportDeclaration* declaration = 1457 DeclareImport(local_name, position(), CHECK_OK); // XXX
adamk 2016/07/13 18:38:22 What's this XXX about? Should it be replaced with
neis 2016/07/14 10:28:24 Just an indicator for you (see below). Removed now
1471 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos); 1458
1472 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 1459 NamedImport* import = new (zone()->New(sizeof(NamedImport)))
adamk 2016/07/13 18:38:22 Same as elsewhere, if you make NamedImport a ZoneO
neis 2016/07/14 10:28:24 Done.
1473 result->Add(declaration, zone()); 1460 NamedImport(import_name, local_name, scanner()->location());
1461 result->Add(import, zone());
1462
1474 if (peek() == Token::RBRACE) break; 1463 if (peek() == Token::RBRACE) break;
1475 Expect(Token::COMMA, CHECK_OK); 1464 Expect(Token::COMMA, CHECK_OK);
1476 } 1465 }
1477 1466
1478 Expect(Token::RBRACE, CHECK_OK); 1467 Expect(Token::RBRACE, CHECK_OK);
1479
1480 return result; 1468 return result;
1481 } 1469 }
1482 1470
1483 1471
1484 Statement* Parser::ParseImportDeclaration(bool* ok) { 1472 void* Parser::ParseImportDeclaration(bool* ok) {
1485 // ImportDeclaration : 1473 // ImportDeclaration :
1486 // 'import' ImportClause 'from' ModuleSpecifier ';' 1474 // 'import' ImportClause 'from' ModuleSpecifier ';'
1487 // 'import' ModuleSpecifier ';' 1475 // 'import' ModuleSpecifier ';'
1488 // 1476 //
1489 // ImportClause : 1477 // ImportClause :
1478 // ImportedDefaultBinding
1490 // NameSpaceImport 1479 // NameSpaceImport
1491 // NamedImports 1480 // NamedImports
1492 // ImportedDefaultBinding
1493 // ImportedDefaultBinding ',' NameSpaceImport 1481 // ImportedDefaultBinding ',' NameSpaceImport
1494 // ImportedDefaultBinding ',' NamedImports 1482 // ImportedDefaultBinding ',' NamedImports
1495 // 1483 //
1496 // NameSpaceImport : 1484 // NameSpaceImport :
1497 // '*' 'as' ImportedBinding 1485 // '*' 'as' ImportedBinding
1498 1486
1499 int pos = peek_position(); 1487 int pos = peek_position();
1500 Expect(Token::IMPORT, CHECK_OK); 1488 Expect(Token::IMPORT, CHECK_OK);
1501 1489
1502 Token::Value tok = peek(); 1490 Token::Value tok = peek();
1503 1491
1504 // 'import' ModuleSpecifier ';' 1492 // 'import' ModuleSpecifier ';'
1505 if (tok == Token::STRING) { 1493 if (tok == Token::STRING) {
1506 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); 1494 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1507 scope_->module()->AddModuleRequest(module_specifier, zone());
1508 ExpectSemicolon(CHECK_OK); 1495 ExpectSemicolon(CHECK_OK);
1509 return factory()->NewEmptyStatement(pos); 1496 scope_->module()->AddEmptyImport(
1497 module_specifier, scanner()->location(), zone());
1498 return nullptr;
1510 } 1499 }
1511 1500
1512 // Parse ImportedDefaultBinding if present. 1501 // Parse ImportedDefaultBinding if present.
1513 ImportDeclaration* import_default_declaration = NULL; 1502 const AstRawString* import_default_binding = nullptr;
1503 Scanner::Location import_default_binding_loc;
1514 if (tok != Token::MUL && tok != Token::LBRACE) { 1504 if (tok != Token::MUL && tok != Token::LBRACE) {
1515 const AstRawString* local_name = 1505 import_default_binding =
1516 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); 1506 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1517 VariableProxy* proxy = NewUnresolved(local_name, CONST); 1507 import_default_binding_loc = scanner()->location();
1518 import_default_declaration = factory()->NewImportDeclaration( 1508 DeclareImport(import_default_binding, pos, CHECK_OK); // XXX
adamk 2016/07/13 18:38:22 ???
neis 2016/07/14 10:28:24 Done.
1519 proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
1520 Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true,
1521 CHECK_OK);
1522 } 1509 }
1523 1510
1524 const AstRawString* module_instance_binding = NULL; 1511 // Parse NameSpaceImport or NamedImports if present.
1525 ZoneList<ImportDeclaration*>* named_declarations = NULL; 1512 const AstRawString* module_namespace_binding = nullptr;
1526 if (import_default_declaration == NULL || Check(Token::COMMA)) { 1513 Scanner::Location module_namespace_binding_loc;
1514 const ZoneList<const NamedImport*>* named_imports = nullptr;
1515 if (import_default_binding == nullptr || Check(Token::COMMA)) {
1527 switch (peek()) { 1516 switch (peek()) {
1528 case Token::MUL: { 1517 case Token::MUL: {
1529 Consume(Token::MUL); 1518 Consume(Token::MUL);
1530 ExpectContextualKeyword(CStrVector("as"), CHECK_OK); 1519 ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1531 module_instance_binding = 1520 module_namespace_binding =
1532 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); 1521 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1533 // TODO(ES6): Add an appropriate declaration. 1522 module_namespace_binding_loc = scanner()->location();
1534 break; 1523 break;
1535 } 1524 }
1536 1525
1537 case Token::LBRACE: 1526 case Token::LBRACE:
1538 named_declarations = ParseNamedImports(pos, CHECK_OK); 1527 named_imports = ParseNamedImports(pos, CHECK_OK);
1539 break; 1528 break;
1540 1529
1541 default: 1530 default:
1542 *ok = false; 1531 *ok = false;
1543 ReportUnexpectedToken(scanner()->current_token()); 1532 ReportUnexpectedToken(scanner()->current_token());
1544 return NULL; 1533 return nullptr;
1545 } 1534 }
1546 } 1535 }
1547 1536
1548 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1537 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1549 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); 1538 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1550 scope_->module()->AddModuleRequest(module_specifier, zone()); 1539 ExpectSemicolon(CHECK_OK);
1551 1540
1552 if (module_instance_binding != NULL) { 1541 // Now that we have all the information, we can make the appropriate
1553 // TODO(ES6): Set the module specifier for the module namespace binding. 1542 // declarations.
1543
1544 if (module_namespace_binding != nullptr) {
1545 scope_->module()->AddStarImport(
1546 module_namespace_binding, module_specifier,
1547 module_namespace_binding_loc, zone());
1548 // TODO(neis): Create special immutable binding for the namespace object.
1554 } 1549 }
1555 1550
1556 if (import_default_declaration != NULL) { 1551 // TODO(neis): Would prefer to call DeclareImport below rather than above and
1557 import_default_declaration->set_module_specifier(module_specifier); 1552 // in ParseNamedImports, but then a possible error message would point to the
1553 // wrong location. Maybe have a DeclareAt version of Declare that takes a
1554 // location?
1555
1556 if (import_default_binding != nullptr) {
1557 scope_->module()->AddNonStarImport(
1558 ast_value_factory()->default_string(), import_default_binding,
1559 module_specifier, import_default_binding_loc, zone());
1560 // DeclareImport(import_default_binding, pos, CHECK_OK);
adamk 2016/07/13 18:38:22 Are these what the XXXs are about?
neis 2016/07/14 10:28:24 Exactly.
1558 } 1561 }
1559 1562
1560 if (named_declarations != NULL) { 1563 if (named_imports != nullptr) {
1561 for (int i = 0; i < named_declarations->length(); ++i) { 1564 if (named_imports->length() == 0) {
1562 named_declarations->at(i)->set_module_specifier(module_specifier); 1565 scope_->module()->AddEmptyImport(
1566 module_specifier, scanner()->location(), zone());
1567 } else {
1568 for (int i = 0; i < named_imports->length(); ++i) {
1569 const NamedImport* import = named_imports->at(i);
1570 scope_->module()->AddNonStarImport(
1571 import->import_name, import->local_name,
1572 module_specifier, import->location, zone());
1573 // DeclareImport(import->local_name, pos, CHECK_OK);
1574 }
1563 } 1575 }
1564 } 1576 }
1565 1577
1566 ExpectSemicolon(CHECK_OK); 1578 return nullptr;
1567 return factory()->NewEmptyStatement(pos);
1568 } 1579 }
1569 1580
1570 1581
1571 Statement* Parser::ParseExportDefault(bool* ok) { 1582 Statement* Parser::ParseExportDefault(bool* ok) {
1572 // Supports the following productions, starting after the 'default' token: 1583 // Supports the following productions, starting after the 'default' token:
1573 // 'export' 'default' FunctionDeclaration 1584 // 'export' 'default' HoistableDeclaration
1574 // 'export' 'default' ClassDeclaration 1585 // 'export' 'default' ClassDeclaration
1575 // 'export' 'default' AssignmentExpression[In] ';' 1586 // 'export' 'default' AssignmentExpression[In] ';'
1576 1587
1577 Expect(Token::DEFAULT, CHECK_OK); 1588 Expect(Token::DEFAULT, CHECK_OK);
1578 Scanner::Location default_loc = scanner()->location(); 1589 Scanner::Location default_loc = scanner()->location();
1579 1590
1580 const AstRawString* default_string = ast_value_factory()->default_string(); 1591 ZoneList<const AstRawString*> local_names(1, zone());
1581 ZoneList<const AstRawString*> names(1, zone());
1582 Statement* result = nullptr; 1592 Statement* result = nullptr;
1583 Expression* default_export = nullptr;
1584 switch (peek()) { 1593 switch (peek()) {
1585 case Token::FUNCTION: 1594 case Token::FUNCTION:
1586 result = ParseHoistableDeclaration(&names, true, CHECK_OK); 1595 result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
1587 break; 1596 break;
1588 1597
1589 case Token::CLASS: 1598 case Token::CLASS:
1590 Consume(Token::CLASS); 1599 Consume(Token::CLASS);
1591 result = ParseClassDeclaration(&names, true, CHECK_OK); 1600 result = ParseClassDeclaration(&local_names, true, CHECK_OK);
1592 break; 1601 break;
1593 1602
1594 case Token::ASYNC: 1603 case Token::ASYNC:
1595 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && 1604 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
1596 !scanner()->HasAnyLineTerminatorAfterNext()) { 1605 !scanner()->HasAnyLineTerminatorAfterNext()) {
1597 Consume(Token::ASYNC); 1606 Consume(Token::ASYNC);
1598 result = ParseAsyncFunctionDeclaration(&names, true, CHECK_OK); 1607 result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
1599 break; 1608 break;
1600 } 1609 }
1601 /* falls through */ 1610 /* falls through */
1602 1611
1603 default: { 1612 default: {
1604 int pos = peek_position(); 1613 int pos = position();
1605 ExpressionClassifier classifier(this); 1614 ExpressionClassifier classifier(this);
1606 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); 1615 Expression* value =
1616 ParseAssignmentExpression(true, &classifier, CHECK_OK);
1607 RewriteNonPattern(&classifier, CHECK_OK); 1617 RewriteNonPattern(&classifier, CHECK_OK);
1608 1618
1619 if (value->IsAnonymousFunctionDefinition()) {
1620 // Ensure that the function's "name" property gets set to "default", by
1621 // rewriting e.g.
1622 // function () {}
1623 // to
1624 // %SetFunctionName(function () {}, "default")
1625 // Note that %SetFunctionName returns the function.
1626 //
1627 // TODO(neis): Make sure this only happens when the function value does
1628 // not already have an own "name" property, as can happen with class
1629 // literals:
1630 // class { static name() {} }
1631 //
1632 ZoneList<Expression*>* args =
1633 new (zone()) ZoneList<Expression*>(1, zone());
1634 args->Add(value, zone());
1635 args->Add(factory()->NewStringLiteral(
1636 ast_value_factory()->default_string(), kNoSourcePosition), zone());
1637 value = factory()->NewCallRuntime(
1638 Runtime::kFunctionSetName, args, kNoSourcePosition);
adamk 2016/07/13 18:38:22 Oh, I didn't understand your question this morning
neis 2016/07/14 10:28:23 Ah, I see. Done (with some refactoring of the exi
1639 }
1640
1641 const AstRawString* local_name =
1642 ast_value_factory()->star_default_star_string();
1643 local_names.Add(local_name, zone());
1644
1645 // It's fine to declare this as CONST because the user has no way of
1646 // writing to it.
1647 VariableProxy* proxy = NewUnresolved(local_name, CONST);
1648 Declaration* declaration =
1649 factory()->NewVariableDeclaration(proxy, CONST, scope_, pos);
1650 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
1651 proxy->var()->set_initializer_position(position());
1652
1653 Assignment* assignment = factory()->NewAssignment(
1654 Token::INIT, proxy, value, kNoSourcePosition);
1655 result = factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1656
1609 ExpectSemicolon(CHECK_OK); 1657 ExpectSemicolon(CHECK_OK);
1610 result = factory()->NewExpressionStatement(expr, pos);
1611 break; 1658 break;
1612 } 1659 }
1613 } 1660 }
1614 1661
1615 DCHECK_LE(names.length(), 1); 1662 DCHECK_EQ(local_names.length(), 1);
1616 if (names.length() == 1) { 1663 scope_->module()->AddNonStarExport(
1617 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok); 1664 local_names.first(), ast_value_factory()->default_string(), default_loc,
1618 if (!*ok) { 1665 zone());
1619 ParserTraits::ReportMessageAt(
1620 default_loc, MessageTemplate::kDuplicateExport, default_string);
1621 return nullptr;
1622 }
1623 } else {
1624 // TODO(ES6): Assign result to a const binding with the name "*default*"
1625 // and add an export entry with "*default*" as the local name.
1626 USE(default_export);
1627 }
1628 1666
1667 DCHECK_NOT_NULL(result);
1629 return result; 1668 return result;
1630 } 1669 }
1631 1670
1632
1633 Statement* Parser::ParseExportDeclaration(bool* ok) { 1671 Statement* Parser::ParseExportDeclaration(bool* ok) {
1634 // ExportDeclaration: 1672 // ExportDeclaration:
1635 // 'export' '*' 'from' ModuleSpecifier ';' 1673 // 'export' '*' 'from' ModuleSpecifier ';'
1636 // 'export' ExportClause ('from' ModuleSpecifier)? ';' 1674 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1637 // 'export' VariableStatement 1675 // 'export' VariableStatement
1638 // 'export' Declaration 1676 // 'export' Declaration
1639 // 'export' 'default' ... (handled in ParseExportDefault) 1677 // 'export' 'default' ... (handled in ParseExportDefault)
1640 1678
1641 int pos = peek_position(); 1679 int pos = peek_position();
1642 Expect(Token::EXPORT, CHECK_OK); 1680 Expect(Token::EXPORT, CHECK_OK);
1643 1681
1644 Statement* result = NULL; 1682 Statement* result = nullptr;
1645 ZoneList<const AstRawString*> names(1, zone()); 1683 ZoneList<const AstRawString*> names(1, zone());
1646 switch (peek()) { 1684 switch (peek()) {
1647 case Token::DEFAULT: 1685 case Token::DEFAULT:
1648 return ParseExportDefault(ok); 1686 return ParseExportDefault(ok);
1649 1687
1650 case Token::MUL: { 1688 case Token::MUL: {
1651 Consume(Token::MUL); 1689 Consume(Token::MUL);
1652 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1690 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1653 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); 1691 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1654 scope_->module()->AddModuleRequest(module_specifier, zone());
1655 // TODO(ES6): scope_->module()->AddStarExport(...)
1656 ExpectSemicolon(CHECK_OK); 1692 ExpectSemicolon(CHECK_OK);
1693 scope_->module()->AddStarExport(
1694 module_specifier, scanner()->location(), zone());
1657 return factory()->NewEmptyStatement(pos); 1695 return factory()->NewEmptyStatement(pos);
1658 } 1696 }
1659 1697
1660 case Token::LBRACE: { 1698 case Token::LBRACE: {
1661 // There are two cases here: 1699 // There are two cases here:
1662 // 1700 //
1663 // 'export' ExportClause ';' 1701 // 'export' ExportClause ';'
1664 // and 1702 // and
1665 // 'export' ExportClause FromClause ';' 1703 // 'export' ExportClause FromClause ';'
1666 // 1704 //
1667 // In the first case, the exported identifiers in ExportClause must 1705 // In the first case, the exported identifiers in ExportClause must
1668 // not be reserved words, while in the latter they may be. We 1706 // not be reserved words, while in the latter they may be. We
1669 // pass in a location that gets filled with the first reserved word 1707 // pass in a location that gets filled with the first reserved word
1670 // encountered, and then throw a SyntaxError if we are in the 1708 // encountered, and then throw a SyntaxError if we are in the
1671 // non-FromClause case. 1709 // non-FromClause case.
1672 Scanner::Location reserved_loc = Scanner::Location::invalid(); 1710 Scanner::Location reserved_loc = Scanner::Location::invalid();
1673 ZoneList<const AstRawString*> export_names(1, zone()); 1711 ZoneList<const AstRawString*> export_names(1, zone());
1674 ZoneList<Scanner::Location> export_locations(1, zone()); 1712 ZoneList<Scanner::Location> export_locations(1, zone());
1675 ZoneList<const AstRawString*> local_names(1, zone()); 1713 ZoneList<const AstRawString*> local_names(1, zone());
1676 ParseExportClause(&export_names, &export_locations, &local_names, 1714 ParseExportClause(&export_names, &export_locations, &local_names,
1677 &reserved_loc, CHECK_OK); 1715 &reserved_loc, CHECK_OK);
1678 const AstRawString* indirect_export_module_specifier = NULL; 1716 const AstRawString* module_specifier = nullptr;
1679 if (CheckContextualKeyword(CStrVector("from"))) { 1717 if (CheckContextualKeyword(CStrVector("from"))) {
1680 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK); 1718 module_specifier = ParseModuleSpecifier(CHECK_OK);
1681 } else if (reserved_loc.IsValid()) { 1719 } else if (reserved_loc.IsValid()) {
1682 // No FromClause, so reserved words are invalid in ExportClause. 1720 // No FromClause, so reserved words are invalid in ExportClause.
1683 *ok = false; 1721 *ok = false;
1684 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved); 1722 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1685 return NULL; 1723 return nullptr;
1686 } 1724 }
1687 ExpectSemicolon(CHECK_OK); 1725 ExpectSemicolon(CHECK_OK);
1688 const int length = export_names.length(); 1726 const int length = export_names.length();
1689 DCHECK_EQ(length, local_names.length()); 1727 DCHECK_EQ(length, local_names.length());
1690 DCHECK_EQ(length, export_locations.length()); 1728 DCHECK_EQ(length, export_locations.length());
1691 if (indirect_export_module_specifier == NULL) { 1729 if (module_specifier == nullptr) {
1692 for (int i = 0; i < length; ++i) { 1730 for (int i = 0; i < length; ++i) {
1693 scope_->module()->AddLocalExport(export_names[i], local_names[i], 1731 scope_->module()->AddNonStarExport(local_names[i], export_names[i],
1694 zone(), ok); 1732 export_locations[i], zone());
1695 if (!*ok) {
1696 ParserTraits::ReportMessageAt(export_locations[i],
1697 MessageTemplate::kDuplicateExport,
1698 export_names[i]);
1699 return NULL;
1700 }
1701 } 1733 }
1702 } else { 1734 } else {
1703 scope_->module()->AddModuleRequest(indirect_export_module_specifier, 1735 if (length == 0) {
adamk 2016/07/13 18:38:22 You can collapse this up into the outer if stateme
neis 2016/07/14 10:28:23 Done. Also removed the TODO since the exact locati
1704 zone()); 1736 // TODO(neis): Provide better location.
1705 for (int i = 0; i < length; ++i) { 1737 scope_->module()->AddEmptyImport(
1706 // TODO(ES6): scope_->module()->AddIndirectExport(...);( 1738 module_specifier, scanner()->location(), zone());
1739 } else {
1740 auto& import_names = local_names;
adamk 2016/07/13 18:38:22 Is this just for clarity? I'd leave it out.
neis 2016/07/14 10:28:23 Yes. Done. Instead, I renamed local_names to origi
1741 for (int i = 0; i < length; ++i) {
1742 scope_->module()->AddNonStarExport(
1743 import_names[i], export_names[i], module_specifier,
1744 export_locations[i], zone());
1745 }
1707 } 1746 }
1708 } 1747 }
1709 return factory()->NewEmptyStatement(pos); 1748 return factory()->NewEmptyStatement(pos);
1710 } 1749 }
1711 1750
1712 case Token::FUNCTION: 1751 case Token::FUNCTION:
1713 result = ParseHoistableDeclaration(&names, false, CHECK_OK); 1752 result = ParseHoistableDeclaration(&names, false, CHECK_OK);
1714 break; 1753 break;
1715 1754
1716 case Token::CLASS: 1755 case Token::CLASS:
1717 Consume(Token::CLASS); 1756 Consume(Token::CLASS);
1718 result = ParseClassDeclaration(&names, false, CHECK_OK); 1757 result = ParseClassDeclaration(&names, false, CHECK_OK);
1719 break; 1758 break;
1720 1759
1721 case Token::VAR: 1760 case Token::VAR:
1722 case Token::LET: 1761 case Token::LET:
1723 case Token::CONST: 1762 case Token::CONST:
1724 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); 1763 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1725 break; 1764 break;
1726 1765
1727 case Token::ASYNC: 1766 case Token::ASYNC:
1728 if (allow_harmony_async_await()) { 1767 if (allow_harmony_async_await()) {
1768 // TODO(neis): Why don't we have the same check here as in
1769 // ParseStatementListItem?
1729 Consume(Token::ASYNC); 1770 Consume(Token::ASYNC);
1730 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); 1771 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
1731 break; 1772 break;
1732 } 1773 }
1733 /* falls through */ 1774 /* falls through */
1734 1775
1735 default: 1776 default:
1736 *ok = false; 1777 *ok = false;
1737 ReportUnexpectedToken(scanner()->current_token()); 1778 ReportUnexpectedToken(scanner()->current_token());
1738 return NULL; 1779 return nullptr;
1739 } 1780 }
1740 1781
1741 // Extract declared names into export declarations.
1742 ModuleDescriptor* descriptor = scope_->module(); 1782 ModuleDescriptor* descriptor = scope_->module();
1743 for (int i = 0; i < names.length(); ++i) { 1783 for (int i = 0; i < names.length(); ++i) {
1744 descriptor->AddLocalExport(names[i], names[i], zone(), ok); 1784 // TODO(neis): Provide better location.
1745 if (!*ok) { 1785 descriptor->AddNonStarExport(
1746 // TODO(adamk): Possibly report this error at the right place. 1786 names[i], names[i], scanner()->location(), zone());
1747 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]);
1748 return NULL;
1749 }
1750 } 1787 }
1751 1788
1752 DCHECK_NOT_NULL(result); 1789 DCHECK_NOT_NULL(result);
1753 return result; 1790 return result;
1754 } 1791 }
1755 1792
1756 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, 1793 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1757 AllowLabelledFunctionStatement allow_function, 1794 AllowLabelledFunctionStatement allow_function,
1758 bool* ok) { 1795 bool* ok) {
1759 // Statement :: 1796 // Statement ::
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 // Let/const variables in harmony mode are always added to the immediately 1932 // Let/const variables in harmony mode are always added to the immediately
1896 // enclosing scope. 1933 // enclosing scope.
1897 Scope* scope = 1934 Scope* scope =
1898 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); 1935 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope();
1899 return scope->NewUnresolved(factory(), name, Variable::NORMAL, 1936 return scope->NewUnresolved(factory(), name, Variable::NORMAL,
1900 scanner()->location().beg_pos, 1937 scanner()->location().beg_pos,
1901 scanner()->location().end_pos); 1938 scanner()->location().end_pos);
1902 } 1939 }
1903 1940
1904 1941
1942 void* Parser::DeclareImport(const AstRawString* local_name, int pos, bool* ok) {
1943 DCHECK_NOT_NULL(local_name);
1944 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1945 Declaration* declaration =
1946 factory()->NewVariableDeclaration(proxy, IMPORT, scope_, pos);
1947 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
1948 return nullptr;
1949 }
1950
1951
1905 Variable* Parser::Declare(Declaration* declaration, 1952 Variable* Parser::Declare(Declaration* declaration,
1906 DeclarationDescriptor::Kind declaration_kind, 1953 DeclarationDescriptor::Kind declaration_kind,
1907 bool resolve, bool* ok, Scope* scope) { 1954 bool resolve, bool* ok, Scope* scope) {
1908 VariableProxy* proxy = declaration->proxy(); 1955 VariableProxy* proxy = declaration->proxy();
1909 DCHECK(proxy->raw_name() != NULL); 1956 DCHECK(proxy->raw_name() != NULL);
1910 const AstRawString* name = proxy->raw_name(); 1957 const AstRawString* name = proxy->raw_name();
1911 VariableMode mode = declaration->mode(); 1958 VariableMode mode = declaration->mode();
1912 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY); 1959 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY);
1913 bool is_function_declaration = declaration->IsFunctionDeclaration(); 1960 bool is_function_declaration = declaration->IsFunctionDeclaration();
1914 if (scope == nullptr) scope = scope_; 1961 if (scope == nullptr) scope = scope_;
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2166 2213
2167 FuncNameInferrer::State fni_state(fni_); 2214 FuncNameInferrer::State fni_state(fni_);
2168 if (fni_ != NULL) fni_->PushEnclosingName(name); 2215 if (fni_ != NULL) fni_->PushEnclosingName(name);
2169 FunctionLiteral* fun = ParseFunctionLiteral( 2216 FunctionLiteral* fun = ParseFunctionLiteral(
2170 name, scanner()->location(), name_validity, 2217 name, scanner()->location(), name_validity,
2171 is_generator ? FunctionKind::kGeneratorFunction 2218 is_generator ? FunctionKind::kGeneratorFunction
2172 : is_async ? FunctionKind::kAsyncFunction 2219 : is_async ? FunctionKind::kAsyncFunction
2173 : FunctionKind::kNormalFunction, 2220 : FunctionKind::kNormalFunction,
2174 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); 2221 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
2175 2222
2176 // Even if we're not at the top-level of the global or a function
2177 // scope, we treat it as such and introduce the function with its
2178 // initial value upon entering the corresponding scope.
2179 // In ES6, a function behaves as a lexical binding, except in 2223 // In ES6, a function behaves as a lexical binding, except in
2180 // a script scope, or the initial scope of eval or another function. 2224 // a script scope, or the initial scope of eval or another function.
2181 VariableMode mode = 2225 VariableMode mode =
2182 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET 2226 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET
2183 : VAR; 2227 : VAR;
2184 VariableProxy* proxy = NewUnresolved(variable_name, mode); 2228 VariableProxy* proxy = NewUnresolved(variable_name, mode);
2185 Declaration* declaration = 2229 Declaration* declaration =
2186 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); 2230 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2187 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 2231 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2188 if (names) names->Add(variable_name, zone()); 2232 if (names) names->Add(variable_name, zone());
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
2488 if (labels != NULL) { 2532 if (labels != NULL) {
2489 for (int i = labels->length(); i-- > 0; ) { 2533 for (int i = labels->length(); i-- > 0; ) {
2490 if (labels->at(i) == label) { 2534 if (labels->at(i) == label) {
2491 return true; 2535 return true;
2492 } 2536 }
2493 } 2537 }
2494 } 2538 }
2495 return false; 2539 return false;
2496 } 2540 }
2497 2541
2542 // TODO(neis): Better name.
adamk 2016/07/13 18:38:22 Please expand on this TODO (why does it need a bet
neis 2016/07/14 10:28:23 This doesn't belong into this CL, removed.
2498 Statement* Parser::ParseFunctionDeclaration(bool* ok) { 2543 Statement* Parser::ParseFunctionDeclaration(bool* ok) {
2499 Consume(Token::FUNCTION); 2544 Consume(Token::FUNCTION);
2500 int pos = position(); 2545 int pos = position();
2501 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; 2546 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
2502 if (Check(Token::MUL)) { 2547 if (Check(Token::MUL)) {
2503 flags |= ParseFunctionFlags::kIsGenerator; 2548 flags |= ParseFunctionFlags::kIsGenerator;
2504 if (allow_harmony_restrictive_declarations()) { 2549 if (allow_harmony_restrictive_declarations()) {
2505 ParserTraits::ReportMessageAt(scanner()->location(), 2550 ParserTraits::ReportMessageAt(scanner()->location(),
2506 MessageTemplate::kGeneratorInLegacyContext); 2551 MessageTemplate::kGeneratorInLegacyContext);
2507 *ok = false; 2552 *ok = false;
(...skipping 4493 matching lines...) Expand 10 before | Expand all | Expand 10 after
7001 7046
7002 #ifdef DEBUG 7047 #ifdef DEBUG
7003 void Parser::Print(AstNode* node) { 7048 void Parser::Print(AstNode* node) {
7004 ast_value_factory()->Internalize(Isolate::Current()); 7049 ast_value_factory()->Internalize(Isolate::Current());
7005 node->Print(Isolate::Current()); 7050 node->Print(Isolate::Current());
7006 } 7051 }
7007 #endif // DEBUG 7052 #endif // DEBUG
7008 7053
7009 } // namespace internal 7054 } // namespace internal
7010 } // namespace v8 7055 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698