Index: runtime/vm/class_finalizer.cc |
=================================================================== |
--- runtime/vm/class_finalizer.cc (revision 14582) |
+++ runtime/vm/class_finalizer.cc (working copy) |
@@ -955,6 +955,8 @@ |
} |
+// Check if an instance field or method of same name exists |
+// in any super class. |
static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, |
const String& name) { |
Class& super_class = Class::Handle(); |
@@ -962,7 +964,6 @@ |
Field& field = Field::Handle(); |
super_class = cls.SuperClass(); |
while (!super_class.IsNull()) { |
- // Check if an instance member of same name exists in any super class. |
function = super_class.LookupFunction(name); |
if (!function.IsNull() && !function.is_static()) { |
return super_class.raw(); |
@@ -977,13 +978,13 @@ |
} |
+// Check if an instance method of same name exists in any super class. |
static RawClass* FindSuperOwnerOfFunction(const Class& cls, |
const String& name) { |
Class& super_class = Class::Handle(); |
Function& function = Function::Handle(); |
super_class = cls.SuperClass(); |
while (!super_class.IsNull()) { |
- // Check if a function of same name exists in any super class. |
function = super_class.LookupFunction(name); |
if (!function.IsNull() && !function.is_static()) { |
return super_class.raw(); |
@@ -1023,8 +1024,6 @@ |
// The only compile errors we report are therefore: |
// - a getter having the same name as a method (but not a getter) in a super |
// class or in a subclass. |
- // - a setter having the same name as a method (but not a setter) in a super |
- // class or in a subclass. |
// - a static field, instance field, or static method (but not an instance |
// method) having the same name as an instance member in a super class. |
@@ -1042,18 +1041,36 @@ |
type = FinalizeType(cls, type, kCanonicalize); |
field.set_type(type); |
name = field.name(); |
- super_class = FindSuperOwnerOfInstanceMember(cls, name); |
- if (!super_class.IsNull()) { |
- const String& class_name = String::Handle(cls.Name()); |
- const String& super_class_name = String::Handle(super_class.Name()); |
- const Script& script = Script::Handle(cls.script()); |
- ReportError(script, field.token_pos(), |
- "field '%s' of class '%s' conflicts with instance " |
- "member '%s' of super class '%s'", |
- name.ToCString(), |
- class_name.ToCString(), |
- name.ToCString(), |
- super_class_name.ToCString()); |
+ if (field.is_static()) { |
+ super_class = FindSuperOwnerOfInstanceMember(cls, name); |
+ if (!super_class.IsNull()) { |
+ const String& class_name = String::Handle(cls.Name()); |
+ const String& super_class_name = String::Handle(super_class.Name()); |
+ const Script& script = Script::Handle(cls.script()); |
+ ReportError(script, field.token_pos(), |
+ "static field '%s' of class '%s' conflicts with " |
+ "instance member '%s' of super class '%s'", |
+ name.ToCString(), |
+ class_name.ToCString(), |
+ name.ToCString(), |
+ super_class_name.ToCString()); |
+ } |
+ } else { |
+ // Instance field. Check whether the field overrides a method |
+ // (but not getter). |
+ super_class = FindSuperOwnerOfFunction(cls, name); |
+ if (!super_class.IsNull()) { |
+ const String& class_name = String::Handle(cls.Name()); |
+ const String& super_class_name = String::Handle(super_class.Name()); |
+ const Script& script = Script::Handle(cls.script()); |
+ ReportError(script, field.token_pos(), |
+ "field '%s' of class '%s' conflicts with method '%s' " |
+ "of super class '%s'", |
+ name.ToCString(), |
+ class_name.ToCString(), |
+ name.ToCString(), |
+ super_class_name.ToCString()); |
+ } |
} |
} |
// Collect interfaces, super interfaces, and super classes of this class. |
@@ -1131,22 +1148,9 @@ |
name.ToCString(), |
super_class_name.ToCString()); |
} |
- } else if (function.IsSetterFunction()) { |
- name = Field::NameFromSetter(function_name); |
- super_class = FindSuperOwnerOfFunction(cls, name); |
- if (!super_class.IsNull()) { |
- const String& class_name = String::Handle(cls.Name()); |
- const String& super_class_name = String::Handle(super_class.Name()); |
- const Script& script = Script::Handle(cls.script()); |
- ReportError(script, function.token_pos(), |
- "setter '%s' of class '%s' conflicts with " |
- "function '%s' of super class '%s'", |
- name.ToCString(), |
- class_name.ToCString(), |
- name.ToCString(), |
- super_class_name.ToCString()); |
- } |
- } else { |
+ } else if (!function.IsSetterFunction()) { |
+ // A function cannot conflict with a setter, since they cannot |
+ // have the same name. Thus, we do not need to check setters. |
name = Field::GetterName(function_name); |
super_class = FindSuperOwnerOfFunction(cls, name); |
if (!super_class.IsNull()) { |
@@ -1161,20 +1165,6 @@ |
function_name.ToCString(), |
super_class_name.ToCString()); |
} |
- name = Field::SetterName(function_name); |
- super_class = FindSuperOwnerOfFunction(cls, name); |
- if (!super_class.IsNull()) { |
- const String& class_name = String::Handle(cls.Name()); |
- const String& super_class_name = String::Handle(super_class.Name()); |
- const Script& script = Script::Handle(cls.script()); |
- ReportError(script, function.token_pos(), |
- "function '%s' of class '%s' conflicts with " |
- "setter '%s' of super class '%s'", |
- function_name.ToCString(), |
- class_name.ToCString(), |
- function_name.ToCString(), |
- super_class_name.ToCString()); |
- } |
} |
} |
} |