Chromium Code Reviews| 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 |