Chromium Code Reviews| Index: vm/object.cc |
| =================================================================== |
| --- vm/object.cc (revision 4242) |
| +++ vm/object.cc (working copy) |
| @@ -4379,13 +4379,16 @@ |
| } |
| -RawString* Library::FindDuplicateDefinition(Library* conflicting_lib) const { |
| +RawString* Library::FindDuplicateDefinition() const { |
| DictionaryIterator it(*this); |
| Object& obj = Object::Handle(); |
| Class& cls = Class::Handle(); |
| Function& func = Function::Handle(); |
| Field& field = Field::Handle(); |
| String& entry_name = String::Handle(); |
| + String& error_message = String::Handle(); |
| + Library& conflicting_lib = Library::Handle(); |
| + LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); |
| while (it.HasNext()) { |
| obj = it.GetNext(); |
| ASSERT(!obj.IsNull()); |
| @@ -4401,15 +4404,25 @@ |
| } else if (obj.IsField()) { |
| field ^= obj.raw(); |
| entry_name = field.name(); |
| + } else if (obj.IsLibraryPrefix()) { |
| + // For library prefix objects we check to make sure there are no |
| + // duplicate definitions within the libraries imported using this |
| + // prefix. |
| + lib_prefix ^= obj.raw(); |
| + error_message = lib_prefix.CheckForDuplicateDefinition(); |
| + if (!error_message.IsNull()) { |
| + return error_message.raw(); |
| + } |
| + // We don't check library prefixes defined in this library for |
| + // conflicts because they are not visible in the importing scope and |
| + // hence cannot cause any duplicate definitions. |
| + continue; |
| } else { |
| - // We don't check for library prefixes defined in this library because |
| - // they are not visible in the importing scope and hence cannot |
| - // cause any duplicate definitions. |
| - continue; |
| + UNREACHABLE(); |
| } |
| - *conflicting_lib = LookupObjectInImporter(entry_name); |
| - if (!conflicting_lib->IsNull()) { |
| - return entry_name.raw(); |
| + conflicting_lib = LookupObjectInImporter(entry_name); |
| + if (!conflicting_lib.IsNull()) { |
| + return this->DuplicateDefineErrorString(entry_name, conflicting_lib); |
| } |
| } |
| return String::null(); |
| @@ -4434,6 +4447,15 @@ |
| } |
| +RawLibraryPrefix* Library::LookupLocalLibraryPrefix(const String& name) const { |
| + Object& obj = Object::Handle(LookupLocalObject(name)); |
| + if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
| + return LibraryPrefix::CheckedHandle(obj.raw()).raw(); |
| + } |
| + return LibraryPrefix::null(); |
| +} |
| + |
| + |
| void Library::AddAnonymousClass(const Class& cls) const { |
| intptr_t num_anonymous = this->raw_ptr()->num_anonymous_; |
| Array& anon_array = Array::Handle(this->raw_ptr()->anonymous_classes_); |
| @@ -4648,12 +4670,11 @@ |
| ObjectStore* object_store = isolate->object_store(); |
| ASSERT(object_store != NULL); |
| lib ^= object_store->registered_libraries(); |
| - String& entry_name = String::Handle(); |
| - Library& conflicting_lib = Library::Handle(); |
| + String& error_message = String::Handle(); |
| while (!lib.IsNull()) { |
| - entry_name = lib.FindDuplicateDefinition(&conflicting_lib); |
| - if (!entry_name.IsNull()) { |
| - return lib.DuplicateDefineErrorString(entry_name, conflicting_lib); |
| + error_message = lib.FindDuplicateDefinition(); |
| + if (!error_message.IsNull()) { |
| + return error_message.raw(); |
| } |
| lib ^= lib.next_registered(); |
| } |
| @@ -4723,6 +4744,67 @@ |
| } |
| +RawLibrary* LibraryPrefix::GetLibrary(int index) const { |
| + Library& lib = Library::Handle(); |
| + if ((index >= 0) || (index < num_libs())) { |
| + Array& libs = Array::Handle(libraries()); |
| + lib ^= libs.At(index); |
| + } |
| + return lib.raw(); |
| +} |
| + |
| + |
| +void LibraryPrefix::AddLibrary(const Library& library) const { |
| + Library& lib = Library::Handle(); |
| + intptr_t num_current_libs = num_libs(); |
| + |
| + // First check if the library is already in the list of libraries imported. |
| + if (num_current_libs > 0) { |
| + const String& url = String::Handle(library.url()); |
| + String& lib_url = String::Handle(); |
| + for (intptr_t i = 0; i < num_current_libs; i++) { |
| + lib = GetLibrary(i); |
| + ASSERT(!lib.IsNull()); |
| + lib_url = lib.url(); |
| + if (url.Equals(lib_url)) { |
| + return; // Library already imported with same prefix. |
| + } |
| + } |
| + } |
| + |
| + // The library needs to be added to the list. Grow the list if it is full. |
| + Array& libs = Array::Handle(libraries()); |
| + const intptr_t length = (libs.IsNull()) ? 0 : libs.Length(); |
| + if (num_current_libs < length) { |
| + libs.SetAt(num_current_libs, library); |
|
hausner
2012/02/15 18:04:27
If you handle the case of growing the array first,
siva
2012/02/15 20:52:47
Good point.
Restructured as suggested.
On 2012/0
|
| + } else { |
| + ASSERT(num_current_libs == length); |
| + const intptr_t new_length = length + kIncrementSize; |
| + const Array& new_libs = |
| + Array::Handle(Array::Grow(libs, new_length, Heap::kOld)); |
| + new_libs.SetAt(num_current_libs, library); |
| + set_libraries(new_libs); |
| + } |
| + set_num_libs(num_current_libs + 1); |
| +} |
| + |
| + |
| +RawClass* LibraryPrefix::LookupLocalClass(const String& class_name) const { |
| + Array& libs = Array::Handle(libraries()); |
| + Class& resolved_class = Class::Handle(); |
| + Library& lib = Library::Handle(); |
| + for (intptr_t i = 0; i < num_libs(); i++) { |
| + lib ^= libs.At(i); |
| + ASSERT(!lib.IsNull()); |
| + resolved_class = lib.LookupLocalClass(class_name); |
| + if (!resolved_class.IsNull()) { |
| + return resolved_class.raw(); |
| + } |
| + } |
| + return Class::null(); |
| +} |
| + |
| + |
| RawLibraryPrefix* LibraryPrefix::New() { |
| const Class& library_prefix_class = |
| Class::Handle(Object::library_prefix_class()); |
| @@ -4736,7 +4818,8 @@ |
| RawLibraryPrefix* LibraryPrefix::New(const String& name, const Library& lib) { |
| const LibraryPrefix& result = LibraryPrefix::Handle(LibraryPrefix::New()); |
| result.set_name(name); |
| - result.set_library(lib); |
| + result.set_num_libs(0); |
| + result.AddLibrary(lib); |
| return result.raw(); |
| } |
| @@ -4752,17 +4835,71 @@ |
| } |
| +RawString* LibraryPrefix::CheckForDuplicateDefinition() const { |
| + Library& lib = Library::Handle(); |
| + Library& conflicting_lib = Library::Handle(); |
| + Object& obj = Object::Handle(); |
| + Class& cls = Class::Handle(); |
| + Function& func = Function::Handle(); |
| + Field& field = Field::Handle(); |
| + String& entry_name = String::Handle(); |
| + |
| + for (intptr_t i = 0; i < num_libs(); i++) { |
| + lib = GetLibrary(i); |
| + ASSERT(!lib.IsNull()); |
| + DictionaryIterator it(lib); |
| + while (it.HasNext()) { |
| + obj = it.GetNext(); |
| + ASSERT(!obj.IsNull()); |
| + if (obj.IsClass()) { |
| + cls ^= obj.raw(); |
| + if (cls.IsCanonicalSignatureClass()) { |
| + continue; |
| + } |
| + entry_name = cls.Name(); |
| + } else if (obj.IsFunction()) { |
| + func ^= obj.raw(); |
| + entry_name = func.name(); |
| + } else if (obj.IsField()) { |
| + field ^= obj.raw(); |
| + entry_name = field.name(); |
| + } else { |
| + // We don't check library prefixes defined in this library for |
| + // conflicts because they are not visible in the importing scope and |
| + // hence cannot cause any duplicate definitions. |
| + continue; |
| + } |
| + for (intptr_t j = i + 1; j < num_libs(); j++) { |
| + conflicting_lib = GetLibrary(j); |
| + ASSERT(!conflicting_lib.IsNull()); |
| + // Check if name is found in the local scope of the library. |
| + obj = conflicting_lib.LookupLocalObject(entry_name); |
| + if (!obj.IsNull()) { |
| + return lib.DuplicateDefineErrorString(entry_name, conflicting_lib); |
| + } |
| + } |
| + } |
| + } |
| + return String::null(); |
| +} |
| + |
| + |
| void LibraryPrefix::set_name(const String& value) const { |
| ASSERT(value.IsSymbol()); |
| StorePointer(&raw_ptr()->name_, value.raw()); |
| } |
| -void LibraryPrefix::set_library(const Library& value) const { |
| - StorePointer(&raw_ptr()->library_, value.raw()); |
| +void LibraryPrefix::set_libraries(const Array& value) const { |
| + StorePointer(&raw_ptr()->libraries_, value.raw()); |
| } |
| +void LibraryPrefix::set_num_libs(intptr_t value) const { |
| + raw_ptr()->num_libs_ = value; |
| +} |
| + |
| + |
| RawError* Library::CompileAll() { |
| Error& error = Error::Handle(); |
| Library& lib = Library::Handle( |