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 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |