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