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 |