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

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

Issue 2311903003: Move ParseHoistableDeclaration to ParserBase. (Closed)
Patch Set: rebased Created 4 years, 3 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 <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
(...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 // other functions are set up when entering the surrounding scope. 1445 // other functions are set up when entering the surrounding scope.
1446 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK); 1446 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1447 NativeFunctionLiteral* lit = 1447 NativeFunctionLiteral* lit =
1448 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); 1448 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1449 return factory()->NewExpressionStatement( 1449 return factory()->NewExpressionStatement(
1450 factory()->NewAssignment(Token::INIT, decl->proxy(), lit, 1450 factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1451 kNoSourcePosition), 1451 kNoSourcePosition),
1452 pos); 1452 pos);
1453 } 1453 }
1454 1454
1455 Statement* Parser::ParseHoistableDeclaration(
1456 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
1457 Expect(Token::FUNCTION, CHECK_OK);
1458 int pos = position();
1459 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
1460 if (Check(Token::MUL)) {
1461 flags |= ParseFunctionFlags::kIsGenerator;
1462 }
1463 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
1464 }
1465
1466 Statement* Parser::ParseAsyncFunctionDeclaration( 1455 Statement* Parser::ParseAsyncFunctionDeclaration(
1467 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { 1456 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
1468 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 1457 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
1469 int pos = position(); 1458 int pos = position();
1470 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 1459 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
1471 *ok = false; 1460 *ok = false;
1472 ReportUnexpectedToken(scanner()->current_token()); 1461 ReportUnexpectedToken(scanner()->current_token());
1473 return nullptr; 1462 return nullptr;
1474 } 1463 }
1475 Expect(Token::FUNCTION, CHECK_OK); 1464 Expect(Token::FUNCTION, CHECK_OK);
1476 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; 1465 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
1477 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); 1466 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
1478 } 1467 }
1479 1468
1480 Statement* Parser::ParseHoistableDeclaration(
1481 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
1482 bool default_export, bool* ok) {
1483 // FunctionDeclaration ::
1484 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
1485 // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
1486 // GeneratorDeclaration ::
1487 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
1488 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
1489 //
1490 // The anonymous forms are allowed iff [default_export] is true.
1491 //
1492 // 'function' and '*' (if present) have been consumed by the caller.
1493
1494 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
1495 const bool is_async = flags & ParseFunctionFlags::kIsAsync;
1496 DCHECK(!is_generator || !is_async);
1497
1498 const AstRawString* name;
1499 FunctionNameValidity name_validity;
1500 const AstRawString* variable_name;
1501 if (default_export && peek() == Token::LPAREN) {
1502 name = ast_value_factory()->default_string();
1503 name_validity = kSkipFunctionNameCheck;
1504 variable_name = ast_value_factory()->star_default_star_string();
1505 } else {
1506 bool is_strict_reserved;
1507 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1508 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
1509 : kFunctionNameValidityUnknown;
1510 variable_name = name;
1511 }
1512
1513 FuncNameInferrer::State fni_state(fni_);
1514 DCHECK_NOT_NULL(fni_);
1515 fni_->PushEnclosingName(name);
1516 FunctionLiteral* fun = ParseFunctionLiteral(
1517 name, scanner()->location(), name_validity,
1518 is_generator ? FunctionKind::kGeneratorFunction
1519 : is_async ? FunctionKind::kAsyncFunction
1520 : FunctionKind::kNormalFunction,
1521 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
1522
1523 // In ES6, a function behaves as a lexical binding, except in
1524 // a script scope, or the initial scope of eval or another function.
1525 VariableMode mode =
1526 (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET
1527 : VAR;
1528 VariableProxy* proxy = NewUnresolved(variable_name);
1529 Declaration* declaration =
1530 factory()->NewFunctionDeclaration(proxy, fun, scope(), pos);
1531 Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1532 CHECK_OK);
1533 if (names) names->Add(variable_name, zone());
1534 // Async functions don't undergo sloppy mode block scoped hoisting, and don't
1535 // allow duplicates in a block. Both are represented by the
1536 // sloppy_block_function_map. Don't add them to the map for async functions.
1537 // Generators are also supposed to be prohibited; currently doing this behind
1538 // a flag and UseCounting violations to assess web compatibility.
1539 if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() &&
1540 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
1541 SloppyBlockFunctionStatement* delegate =
1542 factory()->NewSloppyBlockFunctionStatement(scope());
1543 DeclarationScope* target_scope = GetDeclarationScope();
1544 target_scope->DeclareSloppyBlockFunction(variable_name, delegate);
1545 return delegate;
1546 }
1547 return factory()->NewEmptyStatement(kNoSourcePosition);
1548 }
1549
1550 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, 1469 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1551 bool default_export, bool* ok) { 1470 bool default_export, bool* ok) {
1552 // ClassDeclaration :: 1471 // ClassDeclaration ::
1553 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' 1472 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1554 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' 1473 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
1555 // 1474 //
1556 // The anonymous form is allowed iff [default_export] is true. 1475 // The anonymous form is allowed iff [default_export] is true.
1557 // 1476 //
1558 // 'class' is expected to be consumed by the caller. 1477 // 'class' is expected to be consumed by the caller.
1559 // 1478 //
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 1559
1641 void Parser::DeclareAndInitializeVariables( 1560 void Parser::DeclareAndInitializeVariables(
1642 Block* block, const DeclarationDescriptor* declaration_descriptor, 1561 Block* block, const DeclarationDescriptor* declaration_descriptor,
1643 const DeclarationParsingResult::Declaration* declaration, 1562 const DeclarationParsingResult::Declaration* declaration,
1644 ZoneList<const AstRawString*>* names, bool* ok) { 1563 ZoneList<const AstRawString*>* names, bool* ok) {
1645 DCHECK_NOT_NULL(block); 1564 DCHECK_NOT_NULL(block);
1646 PatternRewriter::DeclareAndInitializeVariables( 1565 PatternRewriter::DeclareAndInitializeVariables(
1647 this, block, declaration_descriptor, declaration, names, ok); 1566 this, block, declaration_descriptor, declaration, names, ok);
1648 } 1567 }
1649 1568
1569 Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1570 FunctionLiteral* function, int pos,
1571 bool is_generator, bool is_async,
1572 ZoneList<const AstRawString*>* names,
1573 bool* ok) {
1574 // In ES6, a function behaves as a lexical binding, except in
1575 // a script scope, or the initial scope of eval or another function.
1576 VariableMode mode =
1577 (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET
1578 : VAR;
1579 VariableProxy* proxy = NewUnresolved(variable_name);
1580 Declaration* declaration =
1581 factory()->NewFunctionDeclaration(proxy, function, scope(), pos);
1582 Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1583 CHECK_OK);
1584 if (names) names->Add(variable_name, zone());
1585 // Async functions don't undergo sloppy mode block scoped hoisting, and don't
1586 // allow duplicates in a block. Both are represented by the
1587 // sloppy_block_function_map. Don't add them to the map for async functions.
1588 // Generators are also supposed to be prohibited; currently doing this behind
1589 // a flag and UseCounting violations to assess web compatibility.
1590 if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() &&
1591 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
1592 SloppyBlockFunctionStatement* delegate =
1593 factory()->NewSloppyBlockFunctionStatement(scope());
1594 DeclarationScope* target_scope = GetDeclarationScope();
1595 target_scope->DeclareSloppyBlockFunction(variable_name, delegate);
1596 return delegate;
1597 }
1598 return factory()->NewEmptyStatement(kNoSourcePosition);
1599 }
1600
1650 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 1601 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1651 ZoneList<const AstRawString*>* names, 1602 ZoneList<const AstRawString*>* names,
1652 bool* ok) { 1603 bool* ok) {
1653 // VariableStatement :: 1604 // VariableStatement ::
1654 // VariableDeclarations ';' 1605 // VariableDeclarations ';'
1655 1606
1656 // The scope of a var declared variable anywhere inside a function 1607 // The scope of a var declared variable anywhere inside a function
1657 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1608 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1658 // transform a source-level var declaration into a (Function) Scope 1609 // transform a source-level var declaration into a (Function) Scope
1659 // declaration, and rewrite the source-level initialization into an assignment 1610 // declaration, and rewrite the source-level initialization into an assignment
(...skipping 4461 matching lines...) Expand 10 before | Expand all | Expand 10 after
6121 node->Print(Isolate::Current()); 6072 node->Print(Isolate::Current());
6122 } 6073 }
6123 #endif // DEBUG 6074 #endif // DEBUG
6124 6075
6125 #undef CHECK_OK 6076 #undef CHECK_OK
6126 #undef CHECK_OK_VOID 6077 #undef CHECK_OK_VOID
6127 #undef CHECK_FAILED 6078 #undef CHECK_FAILED
6128 6079
6129 } // namespace internal 6080 } // namespace internal
6130 } // namespace v8 6081 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698