| 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 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 bool is_interface, | 575 bool is_interface, |
| 576 intptr_t token_pos) | 576 intptr_t token_pos) |
| 577 : clazz_(cls), | 577 : clazz_(cls), |
| 578 class_name_(cls_name), | 578 class_name_(cls_name), |
| 579 is_interface_(is_interface), | 579 is_interface_(is_interface), |
| 580 token_pos_(token_pos), | 580 token_pos_(token_pos), |
| 581 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 581 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 582 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { | 582 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { |
| 583 } | 583 } |
| 584 | 584 |
| 585 // Parameter 'name' is the unmangled name, i.e. without the setter |
| 586 // name mangling. |
| 585 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { | 587 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { |
| 586 // First check if a function or field of same name exists. | 588 // First check if a function or field of same name exists. |
| 587 if (NameExists<Function>(functions_, name) || | 589 if ((kind != RawFunction::kSetterFunction) && FunctionExists(name)) { |
| 588 NameExists<Field>(fields_, name)) { | |
| 589 return true; | 590 return true; |
| 590 } | 591 } |
| 591 String& accessor_name = String::Handle(); | 592 // Now check whether there is a field and whether its implicit getter |
| 592 if (kind != RawFunction::kSetterFunction) { | 593 // or setter collides with the name. |
| 593 // Check if a getter function of same name exists. | 594 Field* field = LookupField(name); |
| 594 accessor_name = Field::GetterName(name); | 595 if (field != NULL) { |
| 595 if (NameExists<Function>(functions_, accessor_name)) { | 596 if (kind == RawFunction::kSetterFunction) { |
| 597 // It's ok to have an implicit getter, it does not collide with |
| 598 // this setter function. |
| 599 if (!field->is_final()) { |
| 600 return true; |
| 601 } |
| 602 } else { |
| 603 // The implicit getter of the field collides with the name. |
| 596 return true; | 604 return true; |
| 597 } | 605 } |
| 598 } | 606 } |
| 599 if (kind != RawFunction::kGetterFunction) { | 607 |
| 608 String& accessor_name = String::Handle(); |
| 609 if (kind == RawFunction::kSetterFunction) { |
| 600 // Check if a setter function of same name exists. | 610 // Check if a setter function of same name exists. |
| 601 accessor_name = Field::SetterName(name); | 611 accessor_name = Field::SetterName(name); |
| 602 if (NameExists<Function>(functions_, accessor_name)) { | 612 if (FunctionExists(accessor_name)) { |
| 613 return true; |
| 614 } |
| 615 } else { |
| 616 // Check if a getter function of same name exists. |
| 617 accessor_name = Field::GetterName(name); |
| 618 if (FunctionExists(accessor_name)) { |
| 603 return true; | 619 return true; |
| 604 } | 620 } |
| 605 } | 621 } |
| 606 return false; | 622 return false; |
| 607 } | 623 } |
| 608 | 624 |
| 609 bool FieldNameExists(const String& name) const { | 625 bool FieldNameExists(const String& name, bool check_setter) const { |
| 610 // First check if a function or field of same name exists. | 626 // First check if a function or field of same name exists. |
| 611 if (NameExists<Function>(functions_, name) || | 627 if (FunctionExists(name) || FieldExists(name)) { |
| 612 NameExists<Field>(fields_, name)) { | |
| 613 return true; | 628 return true; |
| 614 } | 629 } |
| 615 // Now check if a getter/setter function of same name exists. | 630 // Now check if a getter/setter function of same name exists. |
| 616 String& getter_name = String::Handle(Field::GetterName(name)); | 631 String& getter_name = String::Handle(Field::GetterName(name)); |
| 617 String& setter_name = String::Handle(Field::SetterName(name)); | 632 if (FunctionExists(getter_name)) { |
| 618 if (NameExists<Function>(functions_, getter_name) || | |
| 619 NameExists<Function>(functions_, setter_name)) { | |
| 620 return true; | 633 return true; |
| 621 } | 634 } |
| 635 if (check_setter) { |
| 636 String& setter_name = String::Handle(Field::SetterName(name)); |
| 637 if (FunctionExists(setter_name)) { |
| 638 return true; |
| 639 } |
| 640 } |
| 622 return false; | 641 return false; |
| 623 } | 642 } |
| 624 | 643 |
| 625 void AddFunction(const Function& function) { | 644 void AddFunction(const Function& function) { |
| 626 ASSERT(!NameExists<Function>(functions_, String::Handle(function.name()))); | 645 ASSERT(!FunctionExists(String::Handle(function.name()))); |
| 627 functions_.Add(function); | 646 functions_.Add(function); |
| 628 } | 647 } |
| 629 | 648 |
| 630 const GrowableObjectArray& functions() const { | 649 const GrowableObjectArray& functions() const { |
| 631 return functions_; | 650 return functions_; |
| 632 } | 651 } |
| 633 | 652 |
| 634 void AddField(const Field& field) { | 653 void AddField(const Field& field) { |
| 635 ASSERT(!NameExists<Field>(fields_, String::Handle(field.name()))); | 654 ASSERT(!FieldExists(String::Handle(field.name()))); |
| 636 fields_.Add(field); | 655 fields_.Add(field); |
| 637 } | 656 } |
| 638 | 657 |
| 639 const GrowableObjectArray& fields() const { | 658 const GrowableObjectArray& fields() const { |
| 640 return fields_; | 659 return fields_; |
| 641 } | 660 } |
| 642 | 661 |
| 643 RawClass* clazz() const { | 662 RawClass* clazz() const { |
| 644 return clazz_.raw(); | 663 return clazz_.raw(); |
| 645 } | 664 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 MemberDesc* LookupMember(const String& name) const { | 697 MemberDesc* LookupMember(const String& name) const { |
| 679 for (int i = 0; i < members_.length(); i++) { | 698 for (int i = 0; i < members_.length(); i++) { |
| 680 if (name.Equals(*members_[i].name)) { | 699 if (name.Equals(*members_[i].name)) { |
| 681 return &members_[i]; | 700 return &members_[i]; |
| 682 } | 701 } |
| 683 } | 702 } |
| 684 return NULL; | 703 return NULL; |
| 685 } | 704 } |
| 686 | 705 |
| 687 private: | 706 private: |
| 688 template<typename T> | 707 Field* LookupField(const String& name) const { |
| 689 bool NameExists(const GrowableObjectArray& list, const String& name) const { | |
| 690 String& test_name = String::Handle(); | 708 String& test_name = String::Handle(); |
| 691 T& obj = T::Handle(); | 709 Field& field = Field::Handle(); |
| 692 for (int i = 0; i < list.Length(); i++) { | 710 for (int i = 0; i < fields_.Length(); i++) { |
| 693 obj ^= list.At(i); | 711 field ^= fields_.At(i); |
| 694 test_name = obj.name(); | 712 test_name = field.name(); |
| 695 if (name.Equals(test_name)) { | 713 if (name.Equals(test_name)) { |
| 696 return true; | 714 return &field; |
| 697 } | 715 } |
| 698 } | 716 } |
| 699 return false; | 717 return NULL; |
| 718 } |
| 719 |
| 720 bool FieldExists(const String& name) const { |
| 721 return LookupField(name) != NULL; |
| 722 } |
| 723 |
| 724 Function* LookupFunction(const String& name) const { |
| 725 String& test_name = String::Handle(); |
| 726 Function& func = Function::Handle(); |
| 727 for (int i = 0; i < functions_.Length(); i++) { |
| 728 func ^= functions_.At(i); |
| 729 test_name = func.name(); |
| 730 if (name.Equals(test_name)) { |
| 731 return &func; |
| 732 } |
| 733 } |
| 734 return NULL; |
| 735 } |
| 736 |
| 737 bool FunctionExists(const String& name) const { |
| 738 return LookupFunction(name) != NULL; |
| 700 } | 739 } |
| 701 | 740 |
| 702 const Class& clazz_; | 741 const Class& clazz_; |
| 703 const String& class_name_; | 742 const String& class_name_; |
| 704 const bool is_interface_; | 743 const bool is_interface_; |
| 705 intptr_t token_pos_; // Token index of "class" keyword. | 744 intptr_t token_pos_; // Token index of "class" keyword. |
| 706 GrowableObjectArray& functions_; | 745 GrowableObjectArray& functions_; |
| 707 GrowableObjectArray& fields_; | 746 GrowableObjectArray& fields_; |
| 708 GrowableArray<MemberDesc> members_; | 747 GrowableArray<MemberDesc> members_; |
| 709 }; | 748 }; |
| (...skipping 2021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2731 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 2770 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
| 2732 TRACE_PARSER("ParseFieldDefinition"); | 2771 TRACE_PARSER("ParseFieldDefinition"); |
| 2733 // The parser has read the first field name and is now at the token | 2772 // The parser has read the first field name and is now at the token |
| 2734 // after the field name. | 2773 // after the field name. |
| 2735 ASSERT(CurrentToken() == Token::kSEMICOLON || | 2774 ASSERT(CurrentToken() == Token::kSEMICOLON || |
| 2736 CurrentToken() == Token::kCOMMA || | 2775 CurrentToken() == Token::kCOMMA || |
| 2737 CurrentToken() == Token::kASSIGN); | 2776 CurrentToken() == Token::kASSIGN); |
| 2738 ASSERT(field->type != NULL); | 2777 ASSERT(field->type != NULL); |
| 2739 ASSERT(field->name_pos > 0); | 2778 ASSERT(field->name_pos > 0); |
| 2740 ASSERT(current_member_ == field); | 2779 ASSERT(current_member_ == field); |
| 2780 // All const fields are also final. |
| 2741 ASSERT(!field->has_const || field->has_final); | 2781 ASSERT(!field->has_const || field->has_final); |
| 2742 | 2782 |
| 2743 if (field->has_abstract) { | 2783 if (field->has_abstract) { |
| 2744 ErrorMsg("keyword 'abstract' not allowed in field declaration"); | 2784 ErrorMsg("keyword 'abstract' not allowed in field declaration"); |
| 2745 } | 2785 } |
| 2746 if (field->has_external) { | 2786 if (field->has_external) { |
| 2747 ErrorMsg("keyword 'external' not allowed in field declaration"); | 2787 ErrorMsg("keyword 'external' not allowed in field declaration"); |
| 2748 } | 2788 } |
| 2749 if (field->has_factory) { | 2789 if (field->has_factory) { |
| 2750 ErrorMsg("keyword 'factory' not allowed in field declaration"); | 2790 ErrorMsg("keyword 'factory' not allowed in field declaration"); |
| 2751 } | 2791 } |
| 2752 if (members->FieldNameExists(*field->name)) { | 2792 if (members->FieldNameExists(*field->name, !field->has_final)) { |
| 2753 ErrorMsg(field->name_pos, | 2793 ErrorMsg(field->name_pos, |
| 2754 "'%s' field/method already defined\n", field->name->ToCString()); | 2794 "'%s' field/method already defined\n", field->name->ToCString()); |
| 2755 } | 2795 } |
| 2756 Function& getter = Function::Handle(); | 2796 Function& getter = Function::Handle(); |
| 2757 Function& setter = Function::Handle(); | 2797 Function& setter = Function::Handle(); |
| 2758 Field& class_field = Field::Handle(); | 2798 Field& class_field = Field::Handle(); |
| 2759 Instance& init_value = Instance::Handle(); | 2799 Instance& init_value = Instance::Handle(); |
| 2760 while (true) { | 2800 while (true) { |
| 2761 bool has_initializer = CurrentToken() == Token::kASSIGN; | 2801 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 2762 bool has_simple_literal = false; | 2802 bool has_simple_literal = false; |
| (...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3859 String& var_name = *ExpectIdentifier("variable name expected"); | 3899 String& var_name = *ExpectIdentifier("variable name expected"); |
| 3860 | 3900 |
| 3861 if (library_.LookupLocalObject(var_name) != Object::null()) { | 3901 if (library_.LookupLocalObject(var_name) != Object::null()) { |
| 3862 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 3902 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 3863 } | 3903 } |
| 3864 String& accessor_name = String::Handle(Field::GetterName(var_name)); | 3904 String& accessor_name = String::Handle(Field::GetterName(var_name)); |
| 3865 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 3905 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 3866 ErrorMsg(name_pos, "getter for '%s' is already defined", | 3906 ErrorMsg(name_pos, "getter for '%s' is already defined", |
| 3867 var_name.ToCString()); | 3907 var_name.ToCString()); |
| 3868 } | 3908 } |
| 3869 accessor_name = Field::SetterName(var_name); | 3909 // A const or final variable does not define an implicit setter, |
| 3870 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 3910 // so we only check setters for non-final variables. |
| 3871 ErrorMsg(name_pos, "setter for '%s' is already defined", | 3911 if (!is_final) { |
| 3872 var_name.ToCString()); | 3912 accessor_name = Field::SetterName(var_name); |
| 3913 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 3914 ErrorMsg(name_pos, "setter for '%s' is already defined", |
| 3915 var_name.ToCString()); |
| 3916 } |
| 3873 } | 3917 } |
| 3874 | 3918 |
| 3875 field = Field::New(var_name, is_static, is_final, is_const, | 3919 field = Field::New(var_name, is_static, is_final, is_const, |
| 3876 current_class(), name_pos); | 3920 current_class(), name_pos); |
| 3877 field.set_type(type); | 3921 field.set_type(type); |
| 3878 field.set_value(Instance::Handle(Instance::null())); | 3922 field.set_value(Instance::Handle(Instance::null())); |
| 3879 top_level->fields.Add(field); | 3923 top_level->fields.Add(field); |
| 3880 library_.AddObject(field, var_name); | 3924 library_.AddObject(field, var_name); |
| 3881 if (CurrentToken() == Token::kASSIGN) { | 3925 if (CurrentToken() == Token::kASSIGN) { |
| 3882 ConsumeToken(); | 3926 ConsumeToken(); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3950 if (found && !is_patch) { | 3994 if (found && !is_patch) { |
| 3951 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); | 3995 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); |
| 3952 } else if (!found && is_patch) { | 3996 } else if (!found && is_patch) { |
| 3953 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); | 3997 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); |
| 3954 } | 3998 } |
| 3955 String& accessor_name = String::Handle(Field::GetterName(func_name)); | 3999 String& accessor_name = String::Handle(Field::GetterName(func_name)); |
| 3956 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4000 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 3957 ErrorMsg(name_pos, "'%s' is already defined as getter", | 4001 ErrorMsg(name_pos, "'%s' is already defined as getter", |
| 3958 func_name.ToCString()); | 4002 func_name.ToCString()); |
| 3959 } | 4003 } |
| 3960 accessor_name = Field::SetterName(func_name); | 4004 // A setter named x= may co-exist with a function named x, thus we do |
| 3961 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4005 // not need to check setters. |
| 3962 ErrorMsg(name_pos, "'%s' is already defined as setter", | |
| 3963 func_name.ToCString()); | |
| 3964 } | |
| 3965 | 4006 |
| 3966 if (CurrentToken() != Token::kLPAREN) { | 4007 if (CurrentToken() != Token::kLPAREN) { |
| 3967 ErrorMsg("'(' expected"); | 4008 ErrorMsg("'(' expected"); |
| 3968 } | 4009 } |
| 3969 const intptr_t function_pos = TokenPos(); | 4010 const intptr_t function_pos = TokenPos(); |
| 3970 ParamList params; | 4011 ParamList params; |
| 3971 const bool allow_explicit_default_values = true; | 4012 const bool allow_explicit_default_values = true; |
| 3972 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 4013 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 3973 | 4014 |
| 3974 intptr_t function_end_pos = function_pos; | 4015 intptr_t function_end_pos = function_pos; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4064 } else { | 4105 } else { |
| 4065 expected_num_parameters = 1; | 4106 expected_num_parameters = 1; |
| 4066 accessor_name = Field::SetterSymbol(*field_name); | 4107 accessor_name = Field::SetterSymbol(*field_name); |
| 4067 } | 4108 } |
| 4068 if ((params.num_fixed_parameters != expected_num_parameters) || | 4109 if ((params.num_fixed_parameters != expected_num_parameters) || |
| 4069 (params.num_optional_parameters != 0)) { | 4110 (params.num_optional_parameters != 0)) { |
| 4070 ErrorMsg(name_pos, "illegal %s parameters", | 4111 ErrorMsg(name_pos, "illegal %s parameters", |
| 4071 is_getter ? "getter" : "setter"); | 4112 is_getter ? "getter" : "setter"); |
| 4072 } | 4113 } |
| 4073 | 4114 |
| 4074 if (library_.LookupLocalObject(*field_name) != Object::null()) { | 4115 if (is_getter && library_.LookupLocalObject(*field_name) != Object::null()) { |
| 4075 ErrorMsg(name_pos, "'%s' is already defined in this library", | 4116 ErrorMsg(name_pos, "'%s' is already defined in this library", |
| 4076 field_name->ToCString()); | 4117 field_name->ToCString()); |
| 4077 } | 4118 } |
| 4119 if (!is_getter) { |
| 4120 // Check whether there is a field with the same name that has an implicit |
| 4121 // setter. |
| 4122 const Field& field = Field::Handle(library_.LookupLocalField(*field_name)); |
| 4123 if (!field.IsNull() && !field.is_final()) { |
| 4124 ErrorMsg(name_pos, "Variable '%s' is already defined in this library", |
| 4125 field_name->ToCString()); |
| 4126 } |
| 4127 } |
| 4078 bool found = library_.LookupLocalObject(accessor_name) != Object::null(); | 4128 bool found = library_.LookupLocalObject(accessor_name) != Object::null(); |
| 4079 if (found && !is_patch) { | 4129 if (found && !is_patch) { |
| 4080 ErrorMsg(name_pos, "%s for '%s' is already defined", | 4130 ErrorMsg(name_pos, "%s for '%s' is already defined", |
| 4081 is_getter ? "getter" : "setter", | 4131 is_getter ? "getter" : "setter", |
| 4082 field_name->ToCString()); | 4132 field_name->ToCString()); |
| 4083 } else if (!found && is_patch) { | 4133 } else if (!found && is_patch) { |
| 4084 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", | 4134 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", |
| 4085 is_getter ? "getter" : "setter", | 4135 is_getter ? "getter" : "setter", |
| 4086 field_name->ToCString()); | 4136 field_name->ToCString()); |
| 4087 } | 4137 } |
| (...skipping 5813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9901 void Parser::SkipQualIdent() { | 9951 void Parser::SkipQualIdent() { |
| 9902 ASSERT(IsIdentifier()); | 9952 ASSERT(IsIdentifier()); |
| 9903 ConsumeToken(); | 9953 ConsumeToken(); |
| 9904 if (CurrentToken() == Token::kPERIOD) { | 9954 if (CurrentToken() == Token::kPERIOD) { |
| 9905 ConsumeToken(); // Consume the kPERIOD token. | 9955 ConsumeToken(); // Consume the kPERIOD token. |
| 9906 ExpectIdentifier("identifier expected after '.'"); | 9956 ExpectIdentifier("identifier expected after '.'"); |
| 9907 } | 9957 } |
| 9908 } | 9958 } |
| 9909 | 9959 |
| 9910 } // namespace dart | 9960 } // namespace dart |
| OLD | NEW |