Index: runtime/vm/object.cc |
=================================================================== |
--- runtime/vm/object.cc (revision 27310) |
+++ runtime/vm/object.cc (working copy) |
@@ -169,8 +169,7 @@ |
const char* function_name) { |
ASSERT(!lib.IsNull()); |
const Class& cls = Class::Handle( |
- lib.LookupClassAllowPrivate(String::Handle(String::New(class_name)), |
- NULL)); // No ambiguity error expected. |
+ lib.LookupClassAllowPrivate(String::Handle(String::New(class_name)))); |
ASSERT(!cls.IsNull()); |
const Function& function = |
Function::Handle( |
@@ -2223,12 +2222,8 @@ |
RawClass* Class::NewNativeWrapper(const Library& library, |
const String& name, |
int field_count) { |
- String& ambiguity_error_msg = String::Handle(); |
- Class& cls = Class::Handle(library.LookupClass(name, &ambiguity_error_msg)); |
+ Class& cls = Class::Handle(library.LookupClass(name)); |
if (cls.IsNull()) { |
- if (!ambiguity_error_msg.IsNull()) { |
- return Class::null(); |
- } |
cls = New(name, Script::Handle(), Scanner::kDummyTokenIndex); |
cls.SetFields(Object::empty_array()); |
cls.SetFunctions(Object::empty_array()); |
@@ -6735,8 +6730,9 @@ |
} |
-// Lookup a name in the library's export namespace. |
-RawObject* Library::LookupExport(const String& name) const { |
+// Lookup a name in the library's re-export namespace. The name is |
+// unmangled, i.e. no getter or setter names should be looked up. |
+RawObject* Library::LookupReExport(const String& name) const { |
if (HasExports()) { |
const Array& exports = Array::Handle(this->exports()); |
// Break potential export cycle while looking up name. |
@@ -6914,10 +6910,8 @@ |
} |
-RawField* Library::LookupFieldAllowPrivate(const String& name, |
- String* ambiguity_error_msg) const { |
- Object& obj = Object::Handle( |
- LookupObjectAllowPrivate(name, ambiguity_error_msg)); |
+RawField* Library::LookupFieldAllowPrivate(const String& name) const { |
+ Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); |
if (obj.IsField()) { |
return Field::Cast(obj).raw(); |
} |
@@ -6934,11 +6928,8 @@ |
} |
-RawFunction* Library::LookupFunctionAllowPrivate( |
- const String& name, |
- String* ambiguity_error_msg) const { |
- Object& obj = Object::Handle( |
- LookupObjectAllowPrivate(name, ambiguity_error_msg)); |
+RawFunction* Library::LookupFunctionAllowPrivate(const String& name) const { |
+ Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); |
if (obj.IsFunction()) { |
return Function::Cast(obj).raw(); |
} |
@@ -6967,9 +6958,7 @@ |
} |
-RawObject* Library::LookupObjectAllowPrivate( |
- const String& name, |
- String* ambiguity_error_msg) const { |
+RawObject* Library::LookupObjectAllowPrivate(const String& name) const { |
// First check if name is found in the local scope of the library. |
Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); |
if (!obj.IsNull()) { |
@@ -6981,30 +6970,27 @@ |
return Object::null(); |
} |
- // Now check if name is found in any imported libs. It is a compile-time error |
- // if the name is found in more than one import and actually used. |
- return LookupImportedObject(name, ambiguity_error_msg); |
+ // Now check if name is found in any imported libs. |
+ return LookupImportedObject(name); |
} |
-RawObject* Library::LookupObject(const String& name, |
- String* ambiguity_error_msg) const { |
+RawObject* Library::LookupObject(const String& name) const { |
// First check if name is found in the local scope of the library. |
Object& obj = Object::Handle(LookupLocalObject(name)); |
if (!obj.IsNull()) { |
return obj.raw(); |
} |
- // Now check if name is found in any imported libs. It is a compile-time error |
- // if the name is found in more than one import and actually used. |
- return LookupImportedObject(name, ambiguity_error_msg); |
+ // Now check if name is found in any imported libs. |
+ return LookupImportedObject(name); |
} |
-RawObject* Library::LookupImportedObject(const String& name, |
- String* ambiguity_error_msg) const { |
+RawObject* Library::LookupImportedObject(const String& name) const { |
Object& obj = Object::Handle(); |
Namespace& import = Namespace::Handle(); |
Library& import_lib = Library::Handle(); |
+ String& import_lib_url = String::Handle(); |
String& first_import_lib_url = String::Handle(); |
Object& found_obj = Object::Handle(); |
for (intptr_t i = 0; i < num_imports(); i++) { |
@@ -7012,46 +6998,33 @@ |
obj = import.Lookup(name); |
if (!obj.IsNull()) { |
import_lib = import.library(); |
- if (!first_import_lib_url.IsNull()) { |
- // Found duplicate definition. |
- const intptr_t kMessageBufferSize = 512; |
- char message_buffer[kMessageBufferSize]; |
- if (first_import_lib_url.raw() == url()) { |
- OS::SNPrint(message_buffer, |
- kMessageBufferSize, |
- "ambiguous reference to '%s', " |
- "as library '%s' is imported multiple times", |
- name.ToCString(), |
- first_import_lib_url.ToCString()); |
+ import_lib_url = import_lib.url(); |
+ if (found_obj.raw() != obj.raw()) { |
+ if (first_import_lib_url.IsNull() || |
+ first_import_lib_url.StartsWith(Symbols::DartScheme())) { |
+ // This is the first object we found, or the |
+ // previously found object is exported from a Dart |
+ // system library. The newly found object hides the one |
+ // from the Dart library. |
+ first_import_lib_url = import_lib.url(); |
+ found_obj = obj.raw(); |
+ } else if (import_lib_url.StartsWith(Symbols::DartScheme())) { |
+ // The newly found object is exported from a Dart system |
+ // library. It is hidden by the previously found object. |
+ // We continue to search. |
} else { |
- OS::SNPrint(message_buffer, |
- kMessageBufferSize, |
- "ambiguous reference: " |
- "'%s' is defined in library '%s' and also in '%s'", |
- name.ToCString(), |
- first_import_lib_url.ToCString(), |
- String::Handle(url()).ToCString()); |
+ // We found two different objects with the same name. |
+ return Object::null(); |
} |
- // If the caller does not expect an ambiguity error, it may pass NULL as |
- // ambiguity_error_msg in order to avoid the allocation of a handle. |
- // It typically does so when looking up an object in the core library, |
- // which is guaranteed not to contain ambiguities, unless the core lib |
- // is under development, in which case the assert below may fail. |
- ASSERT(ambiguity_error_msg != NULL); // No ambiguity error expected. |
- *ambiguity_error_msg = String::New(message_buffer); |
- return Object::null(); |
} |
- first_import_lib_url = url(); |
- found_obj = obj.raw(); |
} |
} |
return found_obj.raw(); |
} |
-RawClass* Library::LookupClass(const String& name, |
- String* ambiguity_error_msg) const { |
- Object& obj = Object::Handle(LookupObject(name, ambiguity_error_msg)); |
+RawClass* Library::LookupClass(const String& name) const { |
+ Object& obj = Object::Handle(LookupObject(name)); |
if (obj.IsClass()) { |
return Class::Cast(obj).raw(); |
} |
@@ -7068,13 +7041,11 @@ |
} |
-RawClass* Library::LookupClassAllowPrivate(const String& name, |
- String* ambiguity_error_msg) const { |
+RawClass* Library::LookupClassAllowPrivate(const String& name) const { |
// See if the class is available in this library or in the top level |
// scope of any imported library. |
Isolate* isolate = Isolate::Current(); |
- const Class& cls = Class::Handle(isolate, LookupClass(name, |
- ambiguity_error_msg)); |
+ const Class& cls = Class::Handle(isolate, LookupClass(name)); |
if (!cls.IsNull()) { |
return cls.raw(); |
} |
@@ -7556,58 +7527,48 @@ |
} |
-RawClass* LibraryPrefix::LookupClass(const String& class_name, |
- String* ambiguity_error_msg) const { |
+RawObject* LibraryPrefix::LookupObject(const String& name) const { |
Array& imports = Array::Handle(this->imports()); |
Object& obj = Object::Handle(); |
Namespace& import = Namespace::Handle(); |
Library& import_lib = Library::Handle(); |
+ String& import_lib_url = String::Handle(); |
String& first_import_lib_url = String::Handle(); |
Object& found_obj = Object::Handle(); |
for (intptr_t i = 0; i < num_imports(); i++) { |
import ^= imports.At(i); |
- obj = import.Lookup(class_name); |
+ obj = import.Lookup(name); |
if (!obj.IsNull()) { |
import_lib = import.library(); |
- if (!first_import_lib_url.IsNull()) { |
- // Found duplicate definition. |
- const intptr_t kMessageBufferSize = 512; |
- char message_buffer[kMessageBufferSize]; |
- if (first_import_lib_url.raw() == import_lib.url()) { |
- OS::SNPrint(message_buffer, |
- kMessageBufferSize, |
- "ambiguous reference to '%s', " |
- "as library '%s' is imported multiple times via " |
- "prefix '%s'", |
- class_name.ToCString(), |
- first_import_lib_url.ToCString(), |
- String::Handle(name()).ToCString()); |
+ import_lib_url = import_lib.url(); |
+ if (found_obj.raw() != obj.raw()) { |
+ if (first_import_lib_url.IsNull() || |
+ first_import_lib_url.StartsWith(Symbols::DartScheme())) { |
+ // This is the first object we found, or the |
+ // previously found object is exported from a Dart |
+ // system library. The newly found object hides the one |
+ // from the Dart library. |
+ first_import_lib_url = import_lib.url(); |
+ found_obj = obj.raw(); |
+ } else if (import_lib_url.StartsWith(Symbols::DartScheme())) { |
+ // The newly found object is exported from a Dart system |
+ // library. It is hidden by the previously found object. |
+ // We continue to search. |
} else { |
- OS::SNPrint(message_buffer, |
- kMessageBufferSize, |
- "ambiguous reference: " |
- "'%s' is defined in library '%s' and also in '%s', " |
- "both imported via prefix '%s'", |
- class_name.ToCString(), |
- first_import_lib_url.ToCString(), |
- String::Handle(import_lib.url()).ToCString(), |
- String::Handle(name()).ToCString()); |
+ // We found two different objects with the same name. |
+ return Object::null(); |
} |
- // If the caller does not expect an ambiguity error, it may pass NULL as |
- // ambiguity_error_msg in order to avoid the allocation of a handle. |
- // It typically does so when looking up a class in the core library, |
- // which is guaranteed not to contain ambiguities, unless the core lib |
- // is under development, in which case the assert below may fail. |
- ASSERT(ambiguity_error_msg != NULL); // No ambiguity error expected. |
- *ambiguity_error_msg = String::New(message_buffer); |
- return Class::null(); |
} |
- first_import_lib_url = import_lib.url(); |
- found_obj = obj.raw(); |
} |
} |
- if (found_obj.IsClass()) { |
- return Class::Cast(found_obj).raw(); |
+ return found_obj.raw(); |
+} |
+ |
+ |
+RawClass* LibraryPrefix::LookupClass(const String& class_name) const { |
+ const Object& obj = Object::Handle(LookupObject(class_name)); |
+ if (obj.IsClass()) { |
+ return Class::Cast(obj).raw(); |
} |
return Class::null(); |
} |
@@ -7726,18 +7687,35 @@ |
} |
+// Look up object with given name in library and filter out hidden |
+// names. Also look up getters and setters. |
RawObject* Namespace::Lookup(const String& name) const { |
Isolate* isolate = Isolate::Current(); |
const Library& lib = Library::Handle(isolate, library()); |
intptr_t ignore = 0; |
+ |
// Lookup the name in the library's symbols. |
+ const String* filter_name = &name; |
Object& obj = Object::Handle(isolate, lib.LookupEntry(name, &ignore)); |
+ if (Field::IsGetterName(name)) { |
+ filter_name = &String::Handle(Field::NameFromGetter(name)); |
+ } else if (Field::IsSetterName(name)) { |
+ filter_name = &String::Handle(Field::NameFromGetter(name)); |
+ } else { |
+ if (obj.IsNull() || obj.IsLibraryPrefix()) { |
+ obj = lib.LookupEntry(String::Handle(Field::GetterName(name)), &ignore); |
+ if (obj.IsNull()) { |
+ obj = lib.LookupEntry(String::Handle(Field::SetterName(name)), &ignore); |
+ } |
+ } |
+ } |
+ |
// Library prefixes are not exported. |
if (obj.IsNull() || obj.IsLibraryPrefix()) { |
// Lookup in the re-exported symbols. |
- obj = lib.LookupExport(name); |
+ obj = lib.LookupReExport(name); |
} |
- if (obj.IsNull() || HidesName(name) || obj.IsLibraryPrefix()) { |
+ if (obj.IsNull() || HidesName(*filter_name) || obj.IsLibraryPrefix()) { |
return Object::null(); |
} |
return obj.raw(); |
@@ -7811,10 +7789,10 @@ |
const Library& lib = *libs[l]; |
if (strcmp(class_name, "::") == 0) { |
func_str = Symbols::New(function_name); |
- func = lib.LookupFunctionAllowPrivate(func_str, NULL); |
+ func = lib.LookupFunctionAllowPrivate(func_str); |
} else { |
class_str = String::New(class_name); |
- cls = lib.LookupClassAllowPrivate(class_str, NULL); |
+ cls = lib.LookupClassAllowPrivate(class_str); |
if (!cls.IsNull()) { |
func_str = String::New(function_name); |
if (function_name[0] == '.') { |