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

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

Issue 2368083002: [parser] Refactor of ParseClass* and ParseNativeDeclaration (Closed)
Patch Set: The real patch Created 4 years, 2 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 1504 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 ReportMessage(MessageTemplate::kParamDupe); 1515 ReportMessage(MessageTemplate::kParamDupe);
1516 } 1516 }
1517 return nullptr; 1517 return nullptr;
1518 } 1518 }
1519 if (sloppy_mode_block_scope_function_redefinition) { 1519 if (sloppy_mode_block_scope_function_redefinition) {
1520 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; 1520 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1521 } 1521 }
1522 return variable; 1522 return variable;
1523 } 1523 }
1524 1524
1525 // Language extension which is only enabled for source files loaded
1526 // through the API's extension mechanism. A native function
1527 // declaration is resolved by looking up the function through a
1528 // callback provided by the extension.
1529 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1530 int pos = peek_position();
1531 Expect(Token::FUNCTION, CHECK_OK);
1532 // Allow "eval" or "arguments" for backward compatibility.
1533 const AstRawString* name =
1534 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1535 Expect(Token::LPAREN, CHECK_OK);
1536 bool done = (peek() == Token::RPAREN);
1537 while (!done) {
1538 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1539 done = (peek() == Token::RPAREN);
1540 if (!done) {
1541 Expect(Token::COMMA, CHECK_OK);
1542 }
1543 }
1544 Expect(Token::RPAREN, CHECK_OK);
1545 Expect(Token::SEMICOLON, CHECK_OK);
1546
1547 // Make sure that the function containing the native declaration
1548 // isn't lazily compiled. The extension structures are only
1549 // accessible while parsing the first time not when reparsing
1550 // because of lazy compilation.
1551 GetClosureScope()->ForceEagerCompilation();
1552
1553 // TODO(1240846): It's weird that native function declarations are
1554 // introduced dynamically when we meet their declarations, whereas
1555 // other functions are set up when entering the surrounding scope.
1556 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1557 NativeFunctionLiteral* lit =
1558 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1559 return factory()->NewExpressionStatement(
1560 factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1561 kNoSourcePosition),
1562 pos);
1563 }
1564
1565 Statement* Parser::ParseAsyncFunctionDeclaration( 1525 Statement* Parser::ParseAsyncFunctionDeclaration(
1566 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { 1526 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
1567 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 1527 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
1568 int pos = position(); 1528 int pos = position();
1569 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 1529 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
1570 *ok = false; 1530 *ok = false;
1571 ReportUnexpectedToken(scanner()->current_token()); 1531 ReportUnexpectedToken(scanner()->current_token());
1572 return nullptr; 1532 return nullptr;
1573 } 1533 }
1574 Expect(Token::FUNCTION, CHECK_OK); 1534 Expect(Token::FUNCTION, CHECK_OK);
1575 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; 1535 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
1576 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); 1536 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
1577 } 1537 }
1578 1538
1579 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1580 bool default_export, bool* ok) {
1581 // ClassDeclaration ::
1582 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1583 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
1584 //
1585 // The anonymous form is allowed iff [default_export] is true.
1586 //
1587 // 'class' is expected to be consumed by the caller.
1588 //
1589 // A ClassDeclaration
1590 //
1591 // class C { ... }
1592 //
1593 // has the same semantics as:
1594 //
1595 // let C = class C { ... };
1596 //
1597 // so rewrite it as such.
1598
1599 int pos = position();
1600
1601 const AstRawString* name;
1602 bool is_strict_reserved;
1603 const AstRawString* variable_name;
1604 if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
1605 name = ast_value_factory()->default_string();
1606 is_strict_reserved = false;
1607 variable_name = ast_value_factory()->star_default_star_string();
1608 } else {
1609 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1610 variable_name = name;
1611 }
1612
1613 ExpressionClassifier no_classifier(this);
1614 Expression* value = ParseClassLiteral(name, scanner()->location(),
1615 is_strict_reserved, pos, CHECK_OK);
1616
1617 Declaration* decl = DeclareVariable(variable_name, LET, pos, CHECK_OK);
1618 decl->proxy()->var()->set_initializer_position(position());
1619 Assignment* assignment =
1620 factory()->NewAssignment(Token::INIT, decl->proxy(), value, pos);
1621 Statement* assignment_statement =
1622 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1623 if (names) names->Add(variable_name, zone());
1624 return assignment_statement;
1625 }
1626
1627 Block* Parser::BuildInitializationBlock( 1539 Block* Parser::BuildInitializationBlock(
1628 DeclarationParsingResult* parsing_result, 1540 DeclarationParsingResult* parsing_result,
1629 ZoneList<const AstRawString*>* names, bool* ok) { 1541 ZoneList<const AstRawString*>* names, bool* ok) {
1630 Block* result = factory()->NewBlock( 1542 Block* result = factory()->NewBlock(
1631 NULL, 1, true, parsing_result->descriptor.declaration_pos); 1543 NULL, 1, true, parsing_result->descriptor.declaration_pos);
1632 for (auto declaration : parsing_result->declarations) { 1544 for (auto declaration : parsing_result->declarations) {
1633 PatternRewriter::DeclareAndInitializeVariables( 1545 PatternRewriter::DeclareAndInitializeVariables(
1634 this, result, &(parsing_result->descriptor), &declaration, names, 1546 this, result, &(parsing_result->descriptor), &declaration, names,
1635 CHECK_OK); 1547 CHECK_OK);
1636 } 1548 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { 1584 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
1673 SloppyBlockFunctionStatement* delegate = 1585 SloppyBlockFunctionStatement* delegate =
1674 factory()->NewSloppyBlockFunctionStatement(scope()); 1586 factory()->NewSloppyBlockFunctionStatement(scope());
1675 DeclarationScope* target_scope = GetDeclarationScope(); 1587 DeclarationScope* target_scope = GetDeclarationScope();
1676 target_scope->DeclareSloppyBlockFunction(variable_name, delegate); 1588 target_scope->DeclareSloppyBlockFunction(variable_name, delegate);
1677 return delegate; 1589 return delegate;
1678 } 1590 }
1679 return factory()->NewEmptyStatement(kNoSourcePosition); 1591 return factory()->NewEmptyStatement(kNoSourcePosition);
1680 } 1592 }
1681 1593
1594 Statement* Parser::DeclareClass(const AstRawString* variable_name,
1595 Expression* value,
1596 ZoneList<const AstRawString*>* names, int pos,
1597 bool* ok) {
1598 Declaration* decl = DeclareVariable(variable_name, LET, pos, CHECK_OK);
1599 decl->proxy()->var()->set_initializer_position(position());
marja 2016/09/26 09:35:27 It's pretty... involved? fragile? that we pass "in
nickie 2016/09/26 12:19:59 Again, 'pos' is the position of the class token, w
1600 Assignment* assignment =
1601 factory()->NewAssignment(Token::INIT, decl->proxy(), value, pos);
1602 Statement* assignment_statement =
1603 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1604 if (names) names->Add(variable_name, zone());
1605 return assignment_statement;
1606 }
1607
1608 Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
1609 // Make sure that the function containing the native declaration
1610 // isn't lazily compiled. The extension structures are only
1611 // accessible while parsing the first time not when reparsing
1612 // because of lazy compilation.
1613 GetClosureScope()->ForceEagerCompilation();
1614
1615 // TODO(1240846): It's weird that native function declarations are
1616 // introduced dynamically when we meet their declarations, whereas
1617 // other functions are set up when entering the surrounding scope.
1618 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1619 NativeFunctionLiteral* lit =
1620 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1621 return factory()->NewExpressionStatement(
1622 factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1623 kNoSourcePosition),
1624 pos);
1625 }
1626
1682 ZoneList<const AstRawString*>* Parser::DeclareLabel( 1627 ZoneList<const AstRawString*>* Parser::DeclareLabel(
1683 ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) { 1628 ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
1684 const AstRawString* label = var->raw_name(); 1629 const AstRawString* label = var->raw_name();
1685 // TODO(1240780): We don't check for redeclaration of labels 1630 // TODO(1240780): We don't check for redeclaration of labels
1686 // during preparsing since keeping track of the set of active 1631 // during preparsing since keeping track of the set of active
1687 // labels requires nontrivial changes to the way scopes are 1632 // labels requires nontrivial changes to the way scopes are
1688 // structured. However, these are probably changes we want to 1633 // structured. However, these are probably changes we want to
1689 // make later anyway so we should go back and fix this then. 1634 // make later anyway so we should go back and fix this then.
1690 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 1635 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
1691 ReportMessage(MessageTemplate::kLabelRedeclaration, label); 1636 ReportMessage(MessageTemplate::kLabelRedeclaration, label);
(...skipping 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after
3612 CallClassFieldInitializer( 3557 CallClassFieldInitializer(
3613 constructor->scope(), 3558 constructor->scope(),
3614 constructor->scope()->NewUnresolved( 3559 constructor->scope()->NewUnresolved(
3615 factory(), ast_value_factory()->this_string(), kNoSourcePosition, 3560 factory(), ast_value_factory()->this_string(), kNoSourcePosition,
3616 kNoSourcePosition + 4, THIS_VARIABLE)), 3561 kNoSourcePosition + 4, THIS_VARIABLE)),
3617 kNoSourcePosition); 3562 kNoSourcePosition);
3618 constructor->body()->InsertAt(0, call_initializer, zone()); 3563 constructor->body()->InsertAt(0, call_initializer, zone());
3619 return constructor; 3564 return constructor;
3620 } 3565 }
3621 3566
3622 Expression* Parser::ParseClassLiteral(const AstRawString* name, 3567 void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope,
3623 Scanner::Location class_name_location, 3568 ClassInfo* class_info, int pos, bool* ok) {
3624 bool name_is_strict_reserved, int pos,
3625 bool* ok) {
3626 // All parts of a ClassDeclaration and ClassExpression are strict code.
3627 if (name_is_strict_reserved) {
3628 ReportMessageAt(class_name_location,
3629 MessageTemplate::kUnexpectedStrictReserved);
3630 *ok = false;
3631 return nullptr;
3632 }
3633 if (IsEvalOrArguments(name)) {
3634 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
3635 *ok = false;
3636 return nullptr;
3637 }
3638
3639 BlockState block_state(&scope_state_);
3640 RaiseLanguageMode(STRICT);
3641 #ifdef DEBUG 3569 #ifdef DEBUG
3642 scope()->SetScopeName(name); 3570 scope()->SetScopeName(name);
3643 #endif 3571 #endif
3644 3572
3645 VariableProxy* proxy = nullptr;
3646 if (name != nullptr) { 3573 if (name != nullptr) {
3647 proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE); 3574 class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3648 // TODO(verwaest): declare via block_state. 3575 // TODO(verwaest): declare via block_state.
adamk 2016/09/26 20:36:32 Not sure this TODO is still relevant.
nickie 2016/09/27 08:52:17 Yes, I suppose not. I'm removing it. As a more g
3649 Declaration* declaration = 3576 Declaration* declaration =
3650 factory()->NewVariableDeclaration(proxy, block_state.scope(), pos); 3577 factory()->NewVariableDeclaration(class_info->proxy, block_scope, pos);
3651 Declare(declaration, DeclarationDescriptor::NORMAL, CONST, 3578 Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3652 Variable::DefaultInitializationFlag(CONST), CHECK_OK); 3579 Variable::DefaultInitializationFlag(CONST), ok);
3653 } 3580 }
3581 }
3654 3582
3655 Expression* extends = nullptr; 3583 void Parser::DeclareClassProperty(const AstRawString* class_name,
3656 if (Check(Token::EXTENDS)) { 3584 ClassLiteralProperty* property,
3657 block_state.set_start_position(scanner()->location().end_pos); 3585 ClassInfo* class_info, bool* ok) {
3658 ExpressionClassifier extends_classifier(this); 3586 if (class_info->has_seen_constructor && class_info->constructor == nullptr) {
3659 extends = ParseLeftHandSideExpression(CHECK_OK); 3587 class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
3660 CheckNoTailCallExpressions(CHECK_OK); 3588 DCHECK_NOT_NULL(class_info->constructor);
3661 RewriteNonPattern(CHECK_OK); 3589 class_info->constructor->set_raw_name(
3662 impl()->AccumulateFormalParameterContainmentErrors(); 3590 class_name != nullptr ? class_name
3591 : ast_value_factory()->empty_string());
marja 2016/09/26 09:35:27 Could we return here to reduce the indentation of
nickie 2016/09/26 12:19:59 Done.
3663 } else { 3592 } else {
3664 block_state.set_start_position(scanner()->location().end_pos); 3593 if (property->kind() == ClassLiteralProperty::FIELD) {
3594 DCHECK(allow_harmony_class_fields());
3595 if (property->is_static()) {
3596 if (class_info->static_initializer_var == nullptr) {
3597 class_info->static_initializer_var =
3598 NewTemporary(ast_value_factory()->empty_string());
3599 }
3600 // TODO(bakkot) only do this conditionally
3601 Expression* function = InstallHomeObject(
3602 property->value(),
3603 factory()->NewVariableProxy(class_info->static_initializer_var));
3604 ZoneList<Expression*>* args =
3605 new (zone()) ZoneList<Expression*>(2, zone());
3606 args->Add(function, zone());
3607 args->Add(
3608 factory()->NewVariableProxy(class_info->static_initializer_var),
3609 zone());
3610 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args,
3611 kNoSourcePosition);
3612 property->set_value(call);
3613 } else {
3614 // if (is_computed_name) { // TODO(bakkot) figure out why this is
3615 // necessary for non-computed names in full-codegen
3616 ZoneList<Expression*>* to_name_args =
3617 new (zone()) ZoneList<Expression*>(1, zone());
3618 to_name_args->Add(property->key(), zone());
3619 property->set_key(factory()->NewCallRuntime(
3620 Runtime::kToName, to_name_args, kNoSourcePosition));
3621 //}
3622 const AstRawString* name = ClassFieldVariableName(
3623 true, ast_value_factory(),
3624 class_info->instance_field_initializers->length());
3625 VariableProxy* name_proxy =
3626 factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3627 Declaration* name_declaration = factory()->NewVariableDeclaration(
3628 name_proxy, scope(), kNoSourcePosition);
3629 Variable* name_var =
3630 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
3631 kNeedsInitialization, ok, scope());
3632 if (!*ok) return;
marja 2016/09/26 09:35:27 Here you removed a DCHECK (which was incorrect, wa
nickie 2016/09/26 12:19:59 I was not sure if this was meant to be DCHECK(*ok)
3633 class_info->instance_field_initializers->Add(property->value(), zone());
3634 property->set_value(factory()->NewVariableProxy(name_var));
3635 }
3636 }
3637 class_info->properties->Add(property, zone());
3665 } 3638 }
3639 }
3666 3640
3667 3641 Expression* Parser::RewriteClassLiteral(const AstRawString* name,
3668 ClassLiteralChecker checker(this); 3642 ClassInfo* class_info, int pos,
3669 ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4); 3643 bool* ok) {
3670 ZoneList<Expression*>* instance_field_initializers = 3644 int end_pos = scanner()->location().end_pos;
3671 new (zone()) ZoneList<Expression*>(0, zone());
3672 FunctionLiteral* constructor = nullptr;
3673 bool has_seen_constructor = false;
3674 Variable* static_initializer_var = nullptr;
3675
3676 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); 3645 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
3677 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); 3646 Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
3678 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); 3647 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
3679 3648
3680 Expect(Token::LBRACE, CHECK_OK); 3649 bool has_extends = class_info->extends != nullptr;
3681 3650 bool has_instance_fields =
3682 const bool has_extends = extends != nullptr; 3651 class_info->instance_field_initializers->length() > 0;
3683 while (peek() != Token::RBRACE) { 3652 DCHECK(!has_instance_fields || allow_harmony_class_fields());
3684 if (Check(Token::SEMICOLON)) continue; 3653 bool has_default_constructor = class_info->constructor == nullptr;
3685 FuncNameInferrer::State fni_state(fni_); 3654 if (has_default_constructor) {
3686 bool is_computed_name = false; // Classes do not care about computed 3655 class_info->constructor =
3687 // property names here. 3656 DefaultConstructor(name, has_extends, has_instance_fields, pos, end_pos,
3688 ExpressionClassifier property_classifier(this); 3657 scope()->language_mode());
3689 ClassLiteral::Property* property =
3690 ParseClassPropertyDefinition(&checker, has_extends, &is_computed_name,
3691 &has_seen_constructor, CHECK_OK);
3692 RewriteNonPattern(CHECK_OK);
3693 impl()->AccumulateFormalParameterContainmentErrors();
3694
3695 if (has_seen_constructor && constructor == nullptr) {
3696 constructor = GetPropertyValue(property)->AsFunctionLiteral();
3697 DCHECK_NOT_NULL(constructor);
3698 constructor->set_raw_name(
3699 name != nullptr ? name : ast_value_factory()->empty_string());
3700 } else {
3701 if (property->kind() == ClassLiteralProperty::FIELD) {
3702 DCHECK(allow_harmony_class_fields());
3703 if (property->is_static()) {
3704 if (static_initializer_var == nullptr) {
3705 static_initializer_var =
3706 NewTemporary(ast_value_factory()->empty_string());
3707 }
3708 // TODO(bakkot) only do this conditionally
3709 Expression* function = InstallHomeObject(
3710 property->value(),
3711 factory()->NewVariableProxy(static_initializer_var));
3712 ZoneList<Expression*>* args =
3713 new (zone()) ZoneList<Expression*>(2, zone());
3714 args->Add(function, zone());
3715 args->Add(factory()->NewVariableProxy(static_initializer_var),
3716 zone());
3717 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall,
3718 args, kNoSourcePosition);
3719 property->set_value(call);
3720 } else {
3721 // if (is_computed_name) { // TODO(bakkot) figure out why this is
3722 // necessary for non-computed names in full-codegen
3723 ZoneList<Expression*>* to_name_args =
3724 new (zone()) ZoneList<Expression*>(1, zone());
3725 to_name_args->Add(property->key(), zone());
3726 property->set_key(factory()->NewCallRuntime(
3727 Runtime::kToName, to_name_args, kNoSourcePosition));
3728 //}
3729 const AstRawString* name = ClassFieldVariableName(
3730 true, ast_value_factory(), instance_field_initializers->length());
3731 VariableProxy* name_proxy =
3732 factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3733 Declaration* name_declaration = factory()->NewVariableDeclaration(
3734 name_proxy, scope(), kNoSourcePosition);
3735 Variable* name_var =
3736 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
3737 kNeedsInitialization, ok, scope());
3738 DCHECK(ok);
3739 if (!ok) return nullptr;
3740 instance_field_initializers->Add(property->value(), zone());
3741 property->set_value(factory()->NewVariableProxy(name_var));
3742 }
3743 }
3744 properties->Add(property, zone());
3745 }
3746
3747 DCHECK_NOT_NULL(fni_);
3748 fni_->Infer();
3749 } 3658 }
3750 3659
3751 Expect(Token::RBRACE, CHECK_OK); 3660 if (has_instance_fields && !has_extends) {
3752 int end_pos = scanner()->location().end_pos; 3661 class_info->constructor =
3753 3662 InsertClassFieldInitializer(class_info->constructor);
3754 bool has_instance_fields = instance_field_initializers->length() > 0; 3663 class_info->constructor->set_requires_class_field_init(true);
3755 DCHECK(!has_instance_fields || allow_harmony_class_fields());
3756 bool has_default_constructor = constructor == nullptr;
3757 if (has_default_constructor) {
3758 constructor = DefaultConstructor(name, has_extends, has_instance_fields,
3759 pos, end_pos, block_state.language_mode());
3760 }
3761
3762 if (has_instance_fields && extends == nullptr) {
3763 constructor = InsertClassFieldInitializer(constructor);
3764 constructor->set_requires_class_field_init(true);
3765 } // The derived case is handled by rewriting super calls. 3664 } // The derived case is handled by rewriting super calls.
3766 3665
3767 block_state.set_end_position(end_pos); 3666 scope()->set_end_position(end_pos);
3768 3667
3769 if (name != nullptr) { 3668 if (name != nullptr) {
3770 DCHECK_NOT_NULL(proxy); 3669 DCHECK_NOT_NULL(class_info->proxy);
3771 proxy->var()->set_initializer_position(end_pos); 3670 class_info->proxy->var()->set_initializer_position(end_pos);
marja 2016/09/26 09:35:27 This code is now somehow... far away (logically) f
nickie 2016/09/26 17:28:12 I covered this in my previous comment. The field
3772 } 3671 }
3773 3672
3774 ClassLiteral* class_literal = factory()->NewClassLiteral( 3673 ClassLiteral* class_literal = factory()->NewClassLiteral(
3775 proxy, extends, constructor, properties, pos, end_pos); 3674 class_info->proxy, class_info->extends, class_info->constructor,
3675 class_info->properties, pos, end_pos);
3776 3676
3777 if (static_initializer_var != nullptr) { 3677 if (class_info->static_initializer_var != nullptr) {
3778 class_literal->set_static_initializer_proxy( 3678 class_literal->set_static_initializer_proxy(
3779 factory()->NewVariableProxy(static_initializer_var)); 3679 factory()->NewVariableProxy(class_info->static_initializer_var));
3780 } 3680 }
3781 3681
3782 do_block->statements()->Add( 3682 do_block->statements()->Add(
marja 2016/09/26 09:35:27 This function is (still) hard to follow without kn
nickie 2016/09/26 17:28:12 OK, here's what I can do. I'm adding comments in
3783 factory()->NewExpressionStatement( 3683 factory()->NewExpressionStatement(
3784 factory()->NewAssignment(Token::ASSIGN, 3684 factory()->NewAssignment(Token::ASSIGN,
3785 factory()->NewVariableProxy(result_var), 3685 factory()->NewVariableProxy(result_var),
3786 class_literal, kNoSourcePosition), 3686 class_literal, kNoSourcePosition),
3787 pos), 3687 pos),
3788 zone()); 3688 zone());
3789 if (allow_harmony_class_fields() && 3689 if (allow_harmony_class_fields() &&
3790 (has_instance_fields || 3690 (has_instance_fields || (has_extends && !has_default_constructor))) {
3791 (extends != nullptr && !has_default_constructor))) {
3792 // Default constructors for derived classes without fields will not try to 3691 // Default constructors for derived classes without fields will not try to
3793 // read this variable, so there's no need to create it. 3692 // read this variable, so there's no need to create it.
3794 const AstRawString* init_fn_name = 3693 const AstRawString* init_fn_name =
3795 ast_value_factory()->dot_class_field_init_string(); 3694 ast_value_factory()->dot_class_field_init_string();
3796 Variable* init_fn_var = scope()->DeclareLocal( 3695 Variable* init_fn_var = scope()->DeclareLocal(
3797 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE); 3696 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE);
3798 Expression* initializer = 3697 Expression* initializer =
3799 has_instance_fields 3698 has_instance_fields
3800 ? static_cast<Expression*>(SynthesizeClassFieldInitializer( 3699 ? static_cast<Expression*>(SynthesizeClassFieldInitializer(
3801 instance_field_initializers->length())) 3700 class_info->instance_field_initializers->length()))
3802 : factory()->NewBooleanLiteral(false, kNoSourcePosition); 3701 : factory()->NewBooleanLiteral(false, kNoSourcePosition);
3803 Assignment* assignment = factory()->NewAssignment( 3702 Assignment* assignment = factory()->NewAssignment(
3804 Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer, 3703 Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer,
3805 kNoSourcePosition); 3704 kNoSourcePosition);
3806 do_block->statements()->Add( 3705 do_block->statements()->Add(
3807 factory()->NewExpressionStatement(assignment, kNoSourcePosition), 3706 factory()->NewExpressionStatement(assignment, kNoSourcePosition),
3808 zone()); 3707 zone());
3809 } 3708 }
3810 for (int i = 0; i < instance_field_initializers->length(); ++i) { 3709 for (int i = 0; i < class_info->instance_field_initializers->length(); ++i) {
3811 const AstRawString* function_name = 3710 const AstRawString* function_name =
3812 ClassFieldVariableName(false, ast_value_factory(), i); 3711 ClassFieldVariableName(false, ast_value_factory(), i);
3813 VariableProxy* function_proxy = 3712 VariableProxy* function_proxy =
3814 factory()->NewVariableProxy(function_name, NORMAL_VARIABLE); 3713 factory()->NewVariableProxy(function_name, NORMAL_VARIABLE);
3815 Declaration* function_declaration = factory()->NewVariableDeclaration( 3714 Declaration* function_declaration = factory()->NewVariableDeclaration(
3816 function_proxy, scope(), kNoSourcePosition); 3715 function_proxy, scope(), kNoSourcePosition);
3817 Variable* function_var = 3716 Variable* function_var =
3818 Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST, 3717 Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST,
3819 kNeedsInitialization, ok, scope()); 3718 kNeedsInitialization, ok, scope());
3820 DCHECK(ok); 3719 if (!*ok) return nullptr;
3821 if (!ok) return nullptr;
3822 Property* prototype_property = factory()->NewProperty( 3720 Property* prototype_property = factory()->NewProperty(
3823 factory()->NewVariableProxy(result_var), 3721 factory()->NewVariableProxy(result_var),
3824 factory()->NewStringLiteral(ast_value_factory()->prototype_string(), 3722 factory()->NewStringLiteral(ast_value_factory()->prototype_string(),
3825 kNoSourcePosition), 3723 kNoSourcePosition),
3826 kNoSourcePosition); 3724 kNoSourcePosition);
3827 Expression* function_value = InstallHomeObject( 3725 Expression* function_value = InstallHomeObject(
3828 instance_field_initializers->at(i), 3726 class_info->instance_field_initializers->at(i),
3829 prototype_property); // TODO(bakkot) ideally this would be conditional, 3727 prototype_property); // TODO(bakkot) ideally this would be conditional,
3830 // especially in trivial cases 3728 // especially in trivial cases
3831 Assignment* function_assignment = factory()->NewAssignment( 3729 Assignment* function_assignment = factory()->NewAssignment(
3832 Token::INIT, factory()->NewVariableProxy(function_var), function_value, 3730 Token::INIT, factory()->NewVariableProxy(function_var), function_value,
3833 kNoSourcePosition); 3731 kNoSourcePosition);
3834 do_block->statements()->Add(factory()->NewExpressionStatement( 3732 do_block->statements()->Add(factory()->NewExpressionStatement(
3835 function_assignment, kNoSourcePosition), 3733 function_assignment, kNoSourcePosition),
3836 zone()); 3734 zone());
3837 } 3735 }
3838 do_block->set_scope(block_state.FinalizedBlockScope()); 3736 do_block->set_scope(scope()->FinalizeBlockScope());
3839 do_expr->set_represented_function(constructor); 3737 do_expr->set_represented_function(class_info->constructor);
3840 3738
3841 return do_expr; 3739 return do_expr;
3842 } 3740 }
3843 3741
3844
3845 Literal* Parser::GetLiteralUndefined(int position) { 3742 Literal* Parser::GetLiteralUndefined(int position) {
3846 return factory()->NewUndefinedLiteral(position); 3743 return factory()->NewUndefinedLiteral(position);
3847 } 3744 }
3848 3745
3849 3746
3850 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 3747 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3851 Declaration* decl = scope->CheckConflictingVarDeclarations(); 3748 Declaration* decl = scope->CheckConflictingVarDeclarations();
3852 if (decl != NULL) { 3749 if (decl != NULL) {
3853 // In ES6, conflicting variable bindings are early errors. 3750 // In ES6, conflicting variable bindings are early errors.
3854 const AstRawString* name = decl->proxy()->raw_name(); 3751 const AstRawString* name = decl->proxy()->raw_name();
(...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after
5606 5503
5607 return final_loop; 5504 return final_loop;
5608 } 5505 }
5609 5506
5610 #undef CHECK_OK 5507 #undef CHECK_OK
5611 #undef CHECK_OK_VOID 5508 #undef CHECK_OK_VOID
5612 #undef CHECK_FAILED 5509 #undef CHECK_FAILED
5613 5510
5614 } // namespace internal 5511 } // namespace internal
5615 } // namespace v8 5512 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | src/parsing/parser-base.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698