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

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
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 // other functions are set up when entering the surrounding scope. 1497 // other functions are set up when entering the surrounding scope.
1498 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK); 1498 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1499 NativeFunctionLiteral* lit = 1499 NativeFunctionLiteral* lit =
1500 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); 1500 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1501 return factory()->NewExpressionStatement( 1501 return factory()->NewExpressionStatement(
1502 factory()->NewAssignment(Token::INIT, decl->proxy(), lit, 1502 factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1503 kNoSourcePosition), 1503 kNoSourcePosition),
1504 pos); 1504 pos);
1505 } 1505 }
1506 1506
1507 Statement* Parser::ParseHoistableDeclaration(
1508 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
1509 Expect(Token::FUNCTION, CHECK_OK);
1510 int pos = position();
1511 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
1512 if (Check(Token::MUL)) {
1513 flags |= ParseFunctionFlags::kIsGenerator;
1514 }
1515 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
1516 }
1517
1518 Statement* Parser::ParseAsyncFunctionDeclaration( 1507 Statement* Parser::ParseAsyncFunctionDeclaration(
1519 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { 1508 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
1520 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 1509 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
1521 int pos = position(); 1510 int pos = position();
1522 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 1511 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
1523 *ok = false; 1512 *ok = false;
1524 ReportUnexpectedToken(scanner()->current_token()); 1513 ReportUnexpectedToken(scanner()->current_token());
1525 return nullptr; 1514 return nullptr;
1526 } 1515 }
1527 Expect(Token::FUNCTION, CHECK_OK); 1516 Expect(Token::FUNCTION, CHECK_OK);
1528 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; 1517 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
1529 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); 1518 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
1530 } 1519 }
1531 1520
1532 Statement* Parser::ParseHoistableDeclaration(
1533 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
1534 bool default_export, bool* ok) {
1535 // FunctionDeclaration ::
1536 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
1537 // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
1538 // GeneratorDeclaration ::
1539 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
1540 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
1541 //
1542 // The anonymous forms are allowed iff [default_export] is true.
1543 //
1544 // 'function' and '*' (if present) have been consumed by the caller.
1545
1546 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
1547 const bool is_async = flags & ParseFunctionFlags::kIsAsync;
1548 DCHECK(!is_generator || !is_async);
1549
1550 const AstRawString* name;
1551 FunctionNameValidity name_validity;
1552 const AstRawString* variable_name;
1553 if (default_export && peek() == Token::LPAREN) {
1554 name = ast_value_factory()->default_string();
1555 name_validity = kSkipFunctionNameCheck;
1556 variable_name = ast_value_factory()->star_default_star_string();
1557 } else {
1558 bool is_strict_reserved;
1559 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1560 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
1561 : kFunctionNameValidityUnknown;
1562 variable_name = name;
1563 }
1564
1565 FuncNameInferrer::State fni_state(fni_);
1566 DCHECK_NOT_NULL(fni_);
1567 fni_->PushEnclosingName(name);
1568 FunctionLiteral* fun = ParseFunctionLiteral(
1569 name, scanner()->location(), name_validity,
1570 is_generator ? FunctionKind::kGeneratorFunction
1571 : is_async ? FunctionKind::kAsyncFunction
1572 : FunctionKind::kNormalFunction,
1573 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
1574
1575 // In ES6, a function behaves as a lexical binding, except in
1576 // a script scope, or the initial scope of eval or another function.
1577 VariableMode mode =
1578 (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET
1579 : VAR;
1580 VariableProxy* proxy = NewUnresolved(variable_name);
1581 Declaration* declaration =
1582 factory()->NewFunctionDeclaration(proxy, fun, scope(), pos);
1583 Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1584 CHECK_OK);
1585 if (names) names->Add(variable_name, zone());
1586 // Async functions don't undergo sloppy mode block scoped hoisting, and don't
1587 // allow duplicates in a block. Both are represented by the
1588 // sloppy_block_function_map. Don't add them to the map for async functions.
1589 // Generators are also supposed to be prohibited; currently doing this behind
1590 // a flag and UseCounting violations to assess web compatibility.
1591 if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() &&
1592 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
1593 SloppyBlockFunctionStatement* delegate =
1594 factory()->NewSloppyBlockFunctionStatement(scope());
1595 DeclarationScope* target_scope = GetDeclarationScope();
1596 target_scope->DeclareSloppyBlockFunction(variable_name, delegate);
1597 return delegate;
1598 }
1599 return factory()->NewEmptyStatement(kNoSourcePosition);
1600 }
1601
1602 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, 1521 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1603 bool default_export, bool* ok) { 1522 bool default_export, bool* ok) {
1604 // ClassDeclaration :: 1523 // ClassDeclaration ::
1605 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' 1524 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1606 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' 1525 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
1607 // 1526 //
1608 // The anonymous form is allowed iff [default_export] is true. 1527 // The anonymous form is allowed iff [default_export] is true.
1609 // 1528 //
1610 // 'class' is expected to be consumed by the caller. 1529 // 'class' is expected to be consumed by the caller.
1611 // 1530 //
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 1581
1663 void Parser::DeclareAndInitializeVariables( 1582 void Parser::DeclareAndInitializeVariables(
1664 Block* block, const DeclarationDescriptor* declaration_descriptor, 1583 Block* block, const DeclarationDescriptor* declaration_descriptor,
1665 const DeclarationParsingResult::Declaration* declaration, 1584 const DeclarationParsingResult::Declaration* declaration,
1666 ZoneList<const AstRawString*>* names, bool* ok) { 1585 ZoneList<const AstRawString*>* names, bool* ok) {
1667 DCHECK_NOT_NULL(block); 1586 DCHECK_NOT_NULL(block);
1668 PatternRewriter::DeclareAndInitializeVariables( 1587 PatternRewriter::DeclareAndInitializeVariables(
1669 this, block, declaration_descriptor, declaration, names, ok); 1588 this, block, declaration_descriptor, declaration, names, ok);
1670 } 1589 }
1671 1590
1591 Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1592 FunctionLiteral* function, int pos,
1593 bool is_generator, bool is_async,
1594 ZoneList<const AstRawString*>* names,
1595 bool* ok) {
1596 // In ES6, a function behaves as a lexical binding, except in
1597 // a script scope, or the initial scope of eval or another function.
1598 VariableMode mode =
1599 (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET
1600 : VAR;
1601 VariableProxy* proxy = NewUnresolved(variable_name);
1602 Declaration* declaration =
1603 factory()->NewFunctionDeclaration(proxy, function, scope(), pos);
1604 Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1605 CHECK_OK);
1606 if (names) names->Add(variable_name, zone());
1607 // Async functions don't undergo sloppy mode block scoped hoisting, and don't
1608 // allow duplicates in a block. Both are represented by the
1609 // sloppy_block_function_map. Don't add them to the map for async functions.
1610 // Generators are also supposed to be prohibited; currently doing this behind
1611 // a flag and UseCounting violations to assess web compatibility.
1612 if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() &&
1613 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
1614 SloppyBlockFunctionStatement* delegate =
1615 factory()->NewSloppyBlockFunctionStatement(scope());
1616 DeclarationScope* target_scope = GetDeclarationScope();
1617 target_scope->DeclareSloppyBlockFunction(variable_name, delegate);
1618 return delegate;
1619 }
1620 return factory()->NewEmptyStatement(kNoSourcePosition);
1621 }
1622
1672 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, 1623 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
1673 const AstRawString* label) { 1624 const AstRawString* label) {
1674 DCHECK(label != NULL); 1625 DCHECK(label != NULL);
1675 if (labels != NULL) { 1626 if (labels != NULL) {
1676 for (int i = labels->length(); i-- > 0; ) { 1627 for (int i = labels->length(); i-- > 0; ) {
1677 if (labels->at(i) == label) { 1628 if (labels->at(i) == label) {
1678 return true; 1629 return true;
1679 } 1630 }
1680 } 1631 }
1681 } 1632 }
(...skipping 4342 matching lines...) Expand 10 before | Expand all | Expand 10 after
6024 node->Print(Isolate::Current()); 5975 node->Print(Isolate::Current());
6025 } 5976 }
6026 #endif // DEBUG 5977 #endif // DEBUG
6027 5978
6028 #undef CHECK_OK 5979 #undef CHECK_OK
6029 #undef CHECK_OK_VOID 5980 #undef CHECK_OK_VOID
6030 #undef CHECK_FAILED 5981 #undef CHECK_FAILED
6031 5982
6032 } // namespace internal 5983 } // namespace internal
6033 } // namespace v8 5984 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698