| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 3602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3613 } | 3613 } |
| 3614 } | 3614 } |
| 3615 } | 3615 } |
| 3616 | 3616 |
| 3617 | 3617 |
| 3618 void Parser::ParseTopLevelFunction(TopLevel* top_level) { | 3618 void Parser::ParseTopLevelFunction(TopLevel* top_level) { |
| 3619 TRACE_PARSER("ParseTopLevelFunction"); | 3619 TRACE_PARSER("ParseTopLevelFunction"); |
| 3620 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3620 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 3621 const bool is_static = true; | 3621 const bool is_static = true; |
| 3622 bool is_external = false; | 3622 bool is_external = false; |
| 3623 if (CurrentToken() == Token::kEXTERNAL) { | 3623 bool is_patch = false; |
| 3624 if (is_patch_source() && |
| 3625 (CurrentToken() == Token::kIDENT) && |
| 3626 CurrentLiteral()->Equals("patch") && |
| 3627 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3628 ConsumeToken(); |
| 3629 is_patch = true; |
| 3630 } else if (CurrentToken() == Token::kEXTERNAL) { |
| 3624 ConsumeToken(); | 3631 ConsumeToken(); |
| 3625 is_external = true; | 3632 is_external = true; |
| 3626 } | 3633 } |
| 3627 if (CurrentToken() == Token::kVOID) { | 3634 if (CurrentToken() == Token::kVOID) { |
| 3628 ConsumeToken(); | 3635 ConsumeToken(); |
| 3629 result_type = Type::VoidType(); | 3636 result_type = Type::VoidType(); |
| 3630 } else { | 3637 } else { |
| 3631 // Parse optional type. | 3638 // Parse optional type. |
| 3632 if ((CurrentToken() == Token::kIDENT) && | 3639 if ((CurrentToken() == Token::kIDENT) && |
| 3633 (LookaheadToken(1) != Token::kLPAREN)) { | 3640 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3634 result_type = ParseType(ClassFinalizer::kTryResolve); | 3641 result_type = ParseType(ClassFinalizer::kTryResolve); |
| 3635 } | 3642 } |
| 3636 } | 3643 } |
| 3637 const intptr_t name_pos = TokenPos(); | 3644 const intptr_t name_pos = TokenPos(); |
| 3638 const String& func_name = *ExpectIdentifier("function name expected"); | 3645 const String& func_name = *ExpectIdentifier("function name expected"); |
| 3639 | 3646 |
| 3640 if (library_.LookupObject(func_name) != Object::null()) { | 3647 bool found = library_.LookupObject(func_name) != Object::null(); |
| 3648 if (found && !is_patch) { |
| 3641 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); | 3649 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); |
| 3650 } else if (!found && is_patch) { |
| 3651 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); |
| 3642 } | 3652 } |
| 3643 String& accessor_name = String::Handle(Field::GetterName(func_name)); | 3653 String& accessor_name = String::Handle(Field::GetterName(func_name)); |
| 3644 if (library_.LookupObject(accessor_name) != Object::null()) { | 3654 if (library_.LookupObject(accessor_name) != Object::null()) { |
| 3645 ErrorMsg(name_pos, "'%s' is already defined as getter", | 3655 ErrorMsg(name_pos, "'%s' is already defined as getter", |
| 3646 func_name.ToCString()); | 3656 func_name.ToCString()); |
| 3647 } | 3657 } |
| 3648 accessor_name = Field::SetterName(func_name); | 3658 accessor_name = Field::SetterName(func_name); |
| 3649 if (library_.LookupObject(accessor_name) != Object::null()) { | 3659 if (library_.LookupObject(accessor_name) != Object::null()) { |
| 3650 ErrorMsg(name_pos, "'%s' is already defined as setter", | 3660 ErrorMsg(name_pos, "'%s' is already defined as setter", |
| 3651 func_name.ToCString()); | 3661 func_name.ToCString()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3681 is_static, | 3691 is_static, |
| 3682 /* is_const = */ false, | 3692 /* is_const = */ false, |
| 3683 /* is_abstract = */ false, | 3693 /* is_abstract = */ false, |
| 3684 is_external, | 3694 is_external, |
| 3685 current_class(), | 3695 current_class(), |
| 3686 function_pos)); | 3696 function_pos)); |
| 3687 func.set_result_type(result_type); | 3697 func.set_result_type(result_type); |
| 3688 func.set_end_token_pos(function_end_pos); | 3698 func.set_end_token_pos(function_end_pos); |
| 3689 AddFormalParamsToFunction(¶ms, func); | 3699 AddFormalParamsToFunction(¶ms, func); |
| 3690 top_level->functions.Add(func); | 3700 top_level->functions.Add(func); |
| 3691 library_.AddObject(func, func_name); | 3701 if (!is_patch) { |
| 3702 library_.AddObject(func, func_name); |
| 3703 } else { |
| 3704 library_.ReplaceObject(func, func_name); |
| 3705 } |
| 3692 } | 3706 } |
| 3693 | 3707 |
| 3694 | 3708 |
| 3695 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { | 3709 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { |
| 3696 TRACE_PARSER("ParseTopLevelAccessor"); | 3710 TRACE_PARSER("ParseTopLevelAccessor"); |
| 3697 const bool is_static = true; | 3711 const bool is_static = true; |
| 3712 bool is_external = false; |
| 3713 bool is_patch = false; |
| 3698 AbstractType& result_type = AbstractType::Handle(); | 3714 AbstractType& result_type = AbstractType::Handle(); |
| 3715 if (is_patch_source() && |
| 3716 (CurrentToken() == Token::kIDENT) && |
| 3717 (CurrentLiteral()->Equals("patch"))) { |
| 3718 ConsumeToken(); |
| 3719 is_patch = true; |
| 3720 } else if (CurrentToken() == Token::kEXTERNAL) { |
| 3721 ConsumeToken(); |
| 3722 is_external = true; |
| 3723 } |
| 3699 bool is_getter = (CurrentToken() == Token::kGET); | 3724 bool is_getter = (CurrentToken() == Token::kGET); |
| 3700 if (CurrentToken() == Token::kGET || | 3725 if (CurrentToken() == Token::kGET || |
| 3701 CurrentToken() == Token::kSET) { | 3726 CurrentToken() == Token::kSET) { |
| 3702 ConsumeToken(); | 3727 ConsumeToken(); |
| 3703 result_type = Type::DynamicType(); | 3728 result_type = Type::DynamicType(); |
| 3704 } else { | 3729 } else { |
| 3705 if (CurrentToken() == Token::kVOID) { | 3730 if (CurrentToken() == Token::kVOID) { |
| 3706 ConsumeToken(); | 3731 ConsumeToken(); |
| 3707 result_type = Type::VoidType(); | 3732 result_type = Type::VoidType(); |
| 3708 } else { | 3733 } else { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3737 if ((params.num_fixed_parameters != expected_num_parameters) || | 3762 if ((params.num_fixed_parameters != expected_num_parameters) || |
| 3738 (params.num_optional_parameters != 0)) { | 3763 (params.num_optional_parameters != 0)) { |
| 3739 ErrorMsg(name_pos, "illegal %s parameters", | 3764 ErrorMsg(name_pos, "illegal %s parameters", |
| 3740 is_getter ? "getter" : "setter"); | 3765 is_getter ? "getter" : "setter"); |
| 3741 } | 3766 } |
| 3742 | 3767 |
| 3743 if (library_.LookupObject(*field_name) != Object::null()) { | 3768 if (library_.LookupObject(*field_name) != Object::null()) { |
| 3744 ErrorMsg(name_pos, "'%s' is already defined in this library", | 3769 ErrorMsg(name_pos, "'%s' is already defined in this library", |
| 3745 field_name->ToCString()); | 3770 field_name->ToCString()); |
| 3746 } | 3771 } |
| 3747 if (library_.LookupObject(accessor_name) != Object::null()) { | 3772 bool found = library_.LookupObject(accessor_name) != Object::null(); |
| 3773 if (found && !is_patch) { |
| 3748 ErrorMsg(name_pos, "%s for '%s' is already defined", | 3774 ErrorMsg(name_pos, "%s for '%s' is already defined", |
| 3749 is_getter ? "getter" : "setter", | 3775 is_getter ? "getter" : "setter", |
| 3750 field_name->ToCString()); | 3776 field_name->ToCString()); |
| 3777 } else if (!found && is_patch) { |
| 3778 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", |
| 3779 is_getter ? "getter" : "setter", |
| 3780 field_name->ToCString()); |
| 3751 } | 3781 } |
| 3752 | 3782 |
| 3753 if (CurrentToken() == Token::kLBRACE) { | 3783 if (is_external) { |
| 3784 ExpectSemicolon(); |
| 3785 } else if (CurrentToken() == Token::kLBRACE) { |
| 3754 SkipBlock(); | 3786 SkipBlock(); |
| 3755 } else if (CurrentToken() == Token::kARROW) { | 3787 } else if (CurrentToken() == Token::kARROW) { |
| 3756 ConsumeToken(); | 3788 ConsumeToken(); |
| 3757 SkipExpr(); | 3789 SkipExpr(); |
| 3758 ExpectSemicolon(); | 3790 ExpectSemicolon(); |
| 3759 } else if (IsLiteral("native")) { | 3791 } else if (IsLiteral("native")) { |
| 3760 ParseNativeDeclaration(); | 3792 ParseNativeDeclaration(); |
| 3761 } else { | 3793 } else { |
| 3762 ErrorMsg("function block expected"); | 3794 ErrorMsg("function block expected"); |
| 3763 } | 3795 } |
| 3764 Function& func = Function::Handle( | 3796 Function& func = Function::Handle( |
| 3765 Function::New(accessor_name, | 3797 Function::New(accessor_name, |
| 3766 is_getter? RawFunction::kGetterFunction : | 3798 is_getter? RawFunction::kGetterFunction : |
| 3767 RawFunction::kSetterFunction, | 3799 RawFunction::kSetterFunction, |
| 3768 is_static, | 3800 is_static, |
| 3769 /* is_const = */ false, | 3801 /* is_const = */ false, |
| 3770 /* is_abstract = */ false, | 3802 /* is_abstract = */ false, |
| 3771 /* is_external = */ false, | 3803 is_external, |
| 3772 current_class(), | 3804 current_class(), |
| 3773 accessor_pos)); | 3805 accessor_pos)); |
| 3774 func.set_result_type(result_type); | 3806 func.set_result_type(result_type); |
| 3775 AddFormalParamsToFunction(¶ms, func); | 3807 AddFormalParamsToFunction(¶ms, func); |
| 3776 top_level->functions.Add(func); | 3808 top_level->functions.Add(func); |
| 3777 library_.AddObject(func, accessor_name); | 3809 if (!is_patch) { |
| 3810 library_.AddObject(func, accessor_name); |
| 3811 } else { |
| 3812 library_.ReplaceObject(func, accessor_name); |
| 3813 } |
| 3778 } | 3814 } |
| 3779 | 3815 |
| 3780 | 3816 |
| 3781 void Parser::ParseLibraryName() { | 3817 void Parser::ParseLibraryName() { |
| 3782 TRACE_PARSER("ParseLibraryName"); | 3818 TRACE_PARSER("ParseLibraryName"); |
| 3783 if ((script_.kind() == RawScript::kLibraryTag) && | 3819 if ((script_.kind() == RawScript::kLibraryTag) && |
| 3784 (CurrentToken() != Token::kLIBRARY)) { | 3820 (CurrentToken() != Token::kLIBRARY)) { |
| 3785 // Handle error case early to get consistent error message. | 3821 // Handle error case early to get consistent error message. |
| 3786 ExpectToken(Token::kLIBRARY); | 3822 ExpectToken(Token::kLIBRARY); |
| 3787 } | 3823 } |
| (...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4685 SetPosition(saved_pos); | 4721 SetPosition(saved_pos); |
| 4686 return is_var_decl; | 4722 return is_var_decl; |
| 4687 } | 4723 } |
| 4688 | 4724 |
| 4689 | 4725 |
| 4690 // Look ahead to detect whether the next tokens should be parsed as | 4726 // Look ahead to detect whether the next tokens should be parsed as |
| 4691 // a function declaration. Token position remains unchanged. | 4727 // a function declaration. Token position remains unchanged. |
| 4692 bool Parser::IsFunctionDeclaration() { | 4728 bool Parser::IsFunctionDeclaration() { |
| 4693 const intptr_t saved_pos = TokenPos(); | 4729 const intptr_t saved_pos = TokenPos(); |
| 4694 bool is_external = false; | 4730 bool is_external = false; |
| 4695 if (is_top_level_ && (CurrentToken() == Token::kEXTERNAL)) { | 4731 if (is_top_level_) { |
| 4696 // Skip over 'external' for top-level function declarations. | 4732 if (is_patch_source() && |
| 4697 is_external = true; | 4733 (CurrentToken() == Token::kIDENT) && |
| 4698 ConsumeToken(); | 4734 CurrentLiteral()->Equals("patch") && |
| 4735 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4736 // Skip over 'patch' for top-level function declarations in patch sources. |
| 4737 ConsumeToken(); |
| 4738 } else if (CurrentToken() == Token::kEXTERNAL) { |
| 4739 // Skip over 'external' for top-level function declarations. |
| 4740 is_external = true; |
| 4741 ConsumeToken(); |
| 4742 } |
| 4699 } | 4743 } |
| 4700 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4744 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 4701 // Possibly a function without explicit return type. | 4745 // Possibly a function without explicit return type. |
| 4702 ConsumeToken(); // Consume function identifier. | 4746 ConsumeToken(); // Consume function identifier. |
| 4703 } else if (TryParseReturnType()) { | 4747 } else if (TryParseReturnType()) { |
| 4704 if (!IsIdentifier()) { | 4748 if (!IsIdentifier()) { |
| 4705 SetPosition(saved_pos); | 4749 SetPosition(saved_pos); |
| 4706 return false; | 4750 return false; |
| 4707 } | 4751 } |
| 4708 ConsumeToken(); // Consume function identifier. | 4752 ConsumeToken(); // Consume function identifier. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4720 SetPosition(saved_pos); | 4764 SetPosition(saved_pos); |
| 4721 return true; | 4765 return true; |
| 4722 } | 4766 } |
| 4723 } | 4767 } |
| 4724 SetPosition(saved_pos); | 4768 SetPosition(saved_pos); |
| 4725 return false; | 4769 return false; |
| 4726 } | 4770 } |
| 4727 | 4771 |
| 4728 | 4772 |
| 4729 bool Parser::IsTopLevelAccessor() { | 4773 bool Parser::IsTopLevelAccessor() { |
| 4774 const intptr_t saved_pos = TokenPos(); |
| 4775 if (is_patch_source() && |
| 4776 (CurrentToken() == Token::kIDENT) && |
| 4777 (CurrentLiteral()->Equals("patch"))) { |
| 4778 ConsumeToken(); |
| 4779 } else if (CurrentToken() == Token::kEXTERNAL) { |
| 4780 ConsumeToken(); |
| 4781 } |
| 4730 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4782 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4783 SetPosition(saved_pos); |
| 4731 return true; | 4784 return true; |
| 4732 } | 4785 } |
| 4733 const intptr_t saved_pos = TokenPos(); | |
| 4734 if (TryParseReturnType()) { | 4786 if (TryParseReturnType()) { |
| 4735 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4787 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4736 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 4788 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
| 4737 SetPosition(saved_pos); | 4789 SetPosition(saved_pos); |
| 4738 return true; | 4790 return true; |
| 4739 } | 4791 } |
| 4740 } | 4792 } |
| 4741 } | 4793 } |
| 4742 SetPosition(saved_pos); | 4794 SetPosition(saved_pos); |
| 4743 return false; | 4795 return false; |
| (...skipping 4200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8944 void Parser::SkipQualIdent() { | 8996 void Parser::SkipQualIdent() { |
| 8945 ASSERT(IsIdentifier()); | 8997 ASSERT(IsIdentifier()); |
| 8946 ConsumeToken(); | 8998 ConsumeToken(); |
| 8947 if (CurrentToken() == Token::kPERIOD) { | 8999 if (CurrentToken() == Token::kPERIOD) { |
| 8948 ConsumeToken(); // Consume the kPERIOD token. | 9000 ConsumeToken(); // Consume the kPERIOD token. |
| 8949 ExpectIdentifier("identifier expected after '.'"); | 9001 ExpectIdentifier("identifier expected after '.'"); |
| 8950 } | 9002 } |
| 8951 } | 9003 } |
| 8952 | 9004 |
| 8953 } // namespace dart | 9005 } // namespace dart |
| OLD | NEW |