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

Side by Side Diff: runtime/vm/parser.cc

Issue 11312095: Fix various inheritance bugs (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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, &params); 4011 ParseFormalParameterList(allow_explicit_default_values, &params);
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698