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

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

Issue 23484020: Update handling of ambiguous name references (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months 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
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 "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 // Lookup class in the core lib which also contains various VM 1693 // Lookup class in the core lib which also contains various VM
1694 // helper methods and classes. Allow look up of private classes. 1694 // helper methods and classes. Allow look up of private classes.
1695 static RawClass* LookupCoreClass(const String& class_name) { 1695 static RawClass* LookupCoreClass(const String& class_name) {
1696 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 1696 const Library& core_lib = Library::Handle(Library::CoreLibrary());
1697 String& name = String::Handle(class_name.raw()); 1697 String& name = String::Handle(class_name.raw());
1698 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { 1698 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) {
1699 // Private identifiers are mangled on a per script basis. 1699 // Private identifiers are mangled on a per script basis.
1700 name = String::Concat(name, String::Handle(core_lib.private_key())); 1700 name = String::Concat(name, String::Handle(core_lib.private_key()));
1701 name = Symbols::New(name); 1701 name = Symbols::New(name);
1702 } 1702 }
1703 return core_lib.LookupClass(name, NULL); // No ambiguity error expected. 1703 return core_lib.LookupClass(name); // No ambiguity error expected.
regis 2013/09/09 21:29:07 Remove comment.
hausner 2013/09/09 21:52:08 Done.
1704 } 1704 }
1705 1705
1706 1706
1707 static const String& PrivateCoreLibName(const String& str) { 1707 static const String& PrivateCoreLibName(const String& str) {
1708 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 1708 const Library& core_lib = Library::Handle(Library::CoreLibrary());
1709 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); 1709 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str));
1710 return private_name; 1710 return private_name;
1711 } 1711 }
1712 1712
1713 1713
(...skipping 6731 matching lines...) Expand 10 before | Expand all | Expand 10 after
8445 return; 8445 return;
8446 } 8446 }
8447 *type = type_parameter.raw(); 8447 *type = type_parameter.raw();
8448 return; 8448 return;
8449 } 8449 }
8450 } 8450 }
8451 // The referenced class may not have been parsed yet. It would be wrong 8451 // The referenced class may not have been parsed yet. It would be wrong
8452 // to resolve it too early to an imported class of the same name. 8452 // to resolve it too early to an imported class of the same name.
8453 if (finalization > ClassFinalizer::kResolveTypeParameters) { 8453 if (finalization > ClassFinalizer::kResolveTypeParameters) {
8454 // Resolve classname in the scope of the current library. 8454 // Resolve classname in the scope of the current library.
8455 Error& error = Error::Handle();
8456 resolved_type_class = ResolveClassInCurrentLibraryScope( 8455 resolved_type_class = ResolveClassInCurrentLibraryScope(
8457 unresolved_class.token_pos(), 8456 unresolved_class_name);
8458 unresolved_class_name,
8459 &error);
8460 if (!error.IsNull()) {
8461 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) ||
8462 FLAG_error_on_bad_type) {
8463 *type = ClassFinalizer::NewFinalizedMalformedType(
8464 error,
8465 scope_class,
8466 unresolved_class.token_pos(),
8467 "cannot resolve class '%s'",
8468 unresolved_class_name.ToCString());
8469 } else {
8470 // Map the malformed type to dynamic and ignore type arguments.
8471 *type = Type::DynamicType();
8472 }
8473 return;
8474 }
8475 } 8457 }
8476 } else { 8458 } else {
8477 LibraryPrefix& lib_prefix = 8459 LibraryPrefix& lib_prefix =
8478 LibraryPrefix::Handle(unresolved_class.library_prefix()); 8460 LibraryPrefix::Handle(unresolved_class.library_prefix());
8479 // Resolve class name in the scope of the library prefix. 8461 // Resolve class name in the scope of the library prefix.
8480 Error& error = Error::Handle();
8481 resolved_type_class = ResolveClassInPrefixScope( 8462 resolved_type_class = ResolveClassInPrefixScope(
8482 unresolved_class.token_pos(),
8483 lib_prefix, 8463 lib_prefix,
8484 unresolved_class_name, 8464 unresolved_class_name);
regis 2013/09/09 21:29:07 same line?
hausner 2013/09/09 21:52:08 Done.
8485 &error);
8486 if (!error.IsNull()) {
8487 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) ||
8488 FLAG_error_on_bad_type) {
8489 *type = ClassFinalizer::NewFinalizedMalformedType(
8490 error,
8491 scope_class,
8492 unresolved_class.token_pos(),
8493 "cannot resolve class '%s'",
8494 unresolved_class_name.ToCString());
8495 } else {
8496 // Map the malformed type to dynamic and ignore type arguments.
8497 *type = Type::DynamicType();
8498 }
8499 return;
8500 }
8501 } 8465 }
8502 // At this point, we can only have a parameterized_type. 8466 // At this point, we can only have a parameterized_type.
8503 const Type& parameterized_type = Type::Cast(*type); 8467 const Type& parameterized_type = Type::Cast(*type);
8504 if (!resolved_type_class.IsNull()) { 8468 if (!resolved_type_class.IsNull()) {
8505 // Replace unresolved class with resolved type class. 8469 // Replace unresolved class with resolved type class.
8506 parameterized_type.set_type_class(resolved_type_class); 8470 parameterized_type.set_type_class(resolved_type_class);
8507 } else if (finalization >= ClassFinalizer::kCanonicalize) { 8471 } else if (finalization >= ClassFinalizer::kCanonicalize) {
8508 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || 8472 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) ||
8509 FLAG_error_on_bad_type) { 8473 FLAG_error_on_bad_type) {
8510 ClassFinalizer::FinalizeMalformedType( 8474 ClassFinalizer::FinalizeMalformedType(
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
8878 obj = lib.LookupLocalObject(accessor_name); 8842 obj = lib.LookupLocalObject(accessor_name);
8879 if (!obj.IsNull()) { 8843 if (!obj.IsNull()) {
8880 return obj.raw(); 8844 return obj.raw();
8881 } 8845 }
8882 accessor_name = Field::SetterName(name); 8846 accessor_name = Field::SetterName(name);
8883 obj = lib.LookupLocalObject(accessor_name); 8847 obj = lib.LookupLocalObject(accessor_name);
8884 return obj.raw(); 8848 return obj.raw();
8885 } 8849 }
8886 8850
8887 8851
8888 static RawObject* LookupNameInImport(Isolate* isolate,
8889 const Namespace& ns,
8890 const String& name) {
8891 // If the given name is filtered out by the import, don't look it up, nor its
8892 // getter and setter names.
8893 if (ns.HidesName(name)) {
8894 return Object::null();
8895 }
8896 Object& obj = Object::Handle(isolate);
8897 obj = ns.Lookup(name);
8898 if (!obj.IsNull()) {
8899 return obj.raw();
8900 }
8901 String& accessor_name = String::Handle(isolate, Field::GetterName(name));
8902 obj = ns.Lookup(accessor_name);
8903 if (!obj.IsNull()) {
8904 return obj.raw();
8905 }
8906 accessor_name = Field::SetterName(name);
8907 obj = ns.Lookup(accessor_name);
8908 return obj.raw();
8909 }
8910
8911
8912 // Resolve a name by checking the global scope of the current 8852 // Resolve a name by checking the global scope of the current
8913 // library. If not found in the current library, then look in the scopes 8853 // library. If not found in the current library, then look in the scopes
8914 // of all libraries that are imported without a library prefix. 8854 // of all libraries that are imported without a library prefix.
8915 // Issue an error if the name is not found in the global scope 8855 RawObject* Parser::ResolveNameInCurrentLibraryScope(const String& name) {
8916 // of the current library, but is defined in more than one imported
8917 // library, i.e. if the name cannot be resolved unambiguously.
8918 RawObject* Parser::ResolveNameInCurrentLibraryScope(intptr_t ident_pos,
8919 const String& name,
8920 Error* error) {
8921 TRACE_PARSER("ResolveNameInCurrentLibraryScope"); 8856 TRACE_PARSER("ResolveNameInCurrentLibraryScope");
8922 HANDLESCOPE(isolate()); 8857 HANDLESCOPE(isolate());
8923 Object& obj = Object::Handle(isolate(), 8858 Object& obj = Object::Handle(isolate(),
8924 LookupNameInLibrary(isolate(), library_, name)); 8859 LookupNameInLibrary(isolate(), library_, name));
8925 if (obj.IsNull()) { 8860 if (!obj.IsNull()) {
8926 // Name is not found in current library. Check scope of all 8861 return obj.raw();
8927 // imported libraries.
8928 String& first_lib_url = String::Handle(isolate());
8929 Namespace& import = Namespace::Handle(isolate());
8930 intptr_t num_imports = library_.num_imports();
8931 Object& imported_obj = Object::Handle(isolate());
8932 Library& lib = Library::Handle(isolate());
8933 for (int i = 0; i < num_imports; i++) {
8934 import = library_.ImportAt(i);
8935 imported_obj = LookupNameInImport(isolate(), import, name);
8936 if (!imported_obj.IsNull()) {
8937 lib ^= import.library();
8938 if (!first_lib_url.IsNull()) {
8939 // Found duplicate definition.
8940 Error& ambiguous_ref_error = Error::Handle();
8941 if (first_lib_url.raw() == lib.url()) {
8942 ambiguous_ref_error = FormatErrorMsg(
8943 script_, ident_pos, "Error",
8944 "ambiguous reference to '%s', "
8945 "as library '%s' is imported multiple times",
8946 name.ToCString(),
8947 first_lib_url.ToCString());
8948 } else {
8949 ambiguous_ref_error = FormatErrorMsg(
8950 script_, ident_pos, "Error",
8951 "ambiguous reference: "
8952 "'%s' is defined in library '%s' and also in '%s'",
8953 name.ToCString(),
8954 first_lib_url.ToCString(),
8955 String::Handle(lib.url()).ToCString());
8956 }
8957 if (error == NULL) {
8958 // Report a compile time error since the caller is not interested
8959 // in the error.
8960 ErrorMsg(ambiguous_ref_error);
8961 }
8962 *error = ambiguous_ref_error.raw();
8963 return Object::null();
8964 } else {
8965 first_lib_url = lib.url();
8966 obj = imported_obj.raw();
8967 }
8968 }
8969 }
8970 } 8862 }
8971 return obj.raw(); 8863 return library_.LookupImportedObject(name);
8972 } 8864 }
8973 8865
8974 8866
8975 RawClass* Parser::ResolveClassInCurrentLibraryScope(intptr_t ident_pos, 8867 RawClass* Parser::ResolveClassInCurrentLibraryScope(const String& name) {
8976 const String& name,
8977 Error* error) {
8978 const Object& obj = 8868 const Object& obj =
8979 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, name, error)); 8869 Object::Handle(ResolveNameInCurrentLibraryScope(name));
8980 if (obj.IsClass()) { 8870 if (obj.IsClass()) {
8981 return Class::Cast(obj).raw(); 8871 return Class::Cast(obj).raw();
8982 } 8872 }
8983 return Class::null(); 8873 return Class::null();
8984 } 8874 }
8985 8875
8986 8876
8987 // Resolve an identifier by checking the global scope of the current 8877 // Resolve an identifier by checking the global scope of the current
8988 // library. If not found in the current library, then look in the scopes 8878 // library. If not found in the current library, then look in the scopes
8989 // of all libraries that are imported without a library prefix. 8879 // of all libraries that are imported without a library prefix.
8990 // Issue an error if the identifier is not found in the global scope 8880 // Issue an error if the identifier is not found in the global scope
8991 // of the current library, but is defined in more than one imported 8881 // of the current library, but is defined in more than one imported
8992 // library, i.e. if the identifier cannot be resolved unambiguously. 8882 // library, i.e. if the identifier cannot be resolved unambiguously.
8993 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, 8883 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos,
8994 const String& ident) { 8884 const String& ident) {
8995 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); 8885 TRACE_PARSER("ResolveIdentInCurrentLibraryScope");
8996 const Object& obj = 8886 const Object& obj =
8997 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, ident, NULL)); 8887 Object::Handle(ResolveNameInCurrentLibraryScope(ident));
8998 if (obj.IsClass()) { 8888 if (obj.IsClass()) {
8999 const Class& cls = Class::Cast(obj); 8889 const Class& cls = Class::Cast(obj);
9000 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); 8890 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw()));
9001 } else if (obj.IsField()) { 8891 } else if (obj.IsField()) {
9002 const Field& field = Field::Cast(obj); 8892 const Field& field = Field::Cast(obj);
9003 ASSERT(field.is_static()); 8893 ASSERT(field.is_static());
9004 return GenerateStaticFieldLookup(field, ident_pos); 8894 return GenerateStaticFieldLookup(field, ident_pos);
9005 } else if (obj.IsFunction()) { 8895 } else if (obj.IsFunction()) {
9006 const Function& func = Function::Cast(obj); 8896 const Function& func = Function::Cast(obj);
9007 ASSERT(func.is_static()); 8897 ASSERT(func.is_static());
9008 if (func.IsGetterFunction() || func.IsSetterFunction()) { 8898 if (func.IsGetterFunction() || func.IsSetterFunction()) {
9009 return new StaticGetterNode(ident_pos, 8899 return new StaticGetterNode(ident_pos,
9010 /* receiver */ NULL, 8900 /* receiver */ NULL,
9011 /* is_super_getter */ false, 8901 /* is_super_getter */ false,
9012 Class::ZoneHandle(func.Owner()), 8902 Class::ZoneHandle(func.Owner()),
9013 ident); 8903 ident);
9014 8904
9015 } else { 8905 } else {
9016 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw())); 8906 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw()));
9017 } 8907 }
9018 } else { 8908 } else {
9019 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); 8909 ASSERT(obj.IsNull() || obj.IsLibraryPrefix());
9020 } 8910 }
9021 // Lexically unresolved primary identifiers are referenced by their name. 8911 // Lexically unresolved primary identifiers are referenced by their name.
9022 return new PrimaryNode(ident_pos, ident); 8912 return new PrimaryNode(ident_pos, ident);
9023 } 8913 }
9024 8914
9025 8915
9026 RawObject* Parser::ResolveNameInPrefixScope(intptr_t ident_pos, 8916 RawObject* Parser::ResolveNameInPrefixScope(const LibraryPrefix& prefix,
9027 const LibraryPrefix& prefix, 8917 const String& name) {
9028 const String& name,
9029 Error* error) {
9030 TRACE_PARSER("ResolveNameInPrefixScope");
9031 HANDLESCOPE(isolate()); 8918 HANDLESCOPE(isolate());
9032 Namespace& import = Namespace::Handle(isolate()); 8919 return prefix.LookupObject(name);
9033 String& first_lib_url = String::Handle(isolate());
9034 Object& obj = Object::Handle(isolate());
9035 Object& resolved_obj = Object::Handle(isolate());
9036 const Array& imports = Array::Handle(isolate(), prefix.imports());
9037 Library& lib = Library::Handle(isolate());
9038 for (intptr_t i = 0; i < prefix.num_imports(); i++) {
9039 import ^= imports.At(i);
9040 resolved_obj = LookupNameInImport(isolate(), import, name);
9041 if (!resolved_obj.IsNull()) {
9042 obj = resolved_obj.raw();
9043 lib = import.library();
9044 if (first_lib_url.IsNull()) {
9045 first_lib_url = lib.url();
9046 } else {
9047 // Found duplicate definition.
9048 Error& ambiguous_ref_error = Error::Handle();
9049 if (first_lib_url.raw() == lib.url()) {
9050 ambiguous_ref_error = FormatErrorMsg(
9051 script_, ident_pos, "Error",
9052 "ambiguous reference: '%s.%s' is imported multiple times",
9053 String::Handle(prefix.name()).ToCString(),
9054 name.ToCString());
9055 } else {
9056 ambiguous_ref_error = FormatErrorMsg(
9057 script_, ident_pos, "Error",
9058 "ambiguous reference: '%s.%s' is defined in '%s' and '%s'",
9059 String::Handle(prefix.name()).ToCString(),
9060 name.ToCString(),
9061 first_lib_url.ToCString(),
9062 String::Handle(lib.url()).ToCString());
9063 }
9064 if (error == NULL) {
9065 // Report a compile time error since the caller is not interested
9066 // in the error.
9067 ErrorMsg(ambiguous_ref_error);
9068 }
9069 *error = ambiguous_ref_error.raw();
9070 return Object::null();
9071 }
9072 }
9073 }
9074 return obj.raw();
9075 } 8920 }
9076 8921
9077 8922
9078 RawClass* Parser::ResolveClassInPrefixScope(intptr_t ident_pos, 8923 RawClass* Parser::ResolveClassInPrefixScope(const LibraryPrefix& prefix,
9079 const LibraryPrefix& prefix, 8924 const String& name) {
9080 const String& name,
9081 Error* error) {
9082 const Object& obj = 8925 const Object& obj =
9083 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, name, error)); 8926 Object::Handle(ResolveNameInPrefixScope(prefix, name));
9084 if (obj.IsClass()) { 8927 if (obj.IsClass()) {
9085 return Class::Cast(obj).raw(); 8928 return Class::Cast(obj).raw();
9086 } 8929 }
9087 return Class::null(); 8930 return Class::null();
9088 } 8931 }
9089 8932
9090 8933
9091 // Do a lookup for the identifier in the scope of the specified 8934 // Do a lookup for the identifier in the scope of the specified
9092 // library prefix. This means trying to resolve it locally in all of the 8935 // library prefix. This means trying to resolve it locally in all of the
9093 // libraries present in the library prefix. If there are multiple libraries 8936 // libraries present in the library prefix. If there are multiple libraries
9094 // with the name, issue an ambiguous reference error. 8937 // with the name, issue an ambiguous reference error.
9095 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, 8938 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos,
9096 const LibraryPrefix& prefix, 8939 const LibraryPrefix& prefix,
9097 const String& ident) { 8940 const String& ident) {
9098 TRACE_PARSER("ResolveIdentInPrefixScope"); 8941 TRACE_PARSER("ResolveIdentInPrefixScope");
9099 Object& obj = 8942 Object& obj = Object::Handle(ResolveNameInPrefixScope(prefix, ident));
9100 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, ident, NULL));
9101 if (obj.IsNull()) { 8943 if (obj.IsNull()) {
9102 // Unresolved prefixed primary identifier. 8944 // Unresolved prefixed primary identifier.
9103 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved", 8945 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved",
9104 String::Handle(prefix.name()).ToCString(), 8946 String::Handle(prefix.name()).ToCString(),
9105 ident.ToCString()); 8947 ident.ToCString());
9106 } 8948 }
9107 if (obj.IsClass()) { 8949 if (obj.IsClass()) {
9108 const Class& cls = Class::Cast(obj); 8950 const Class& cls = Class::Cast(obj);
9109 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); 8951 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw()));
9110 } else if (obj.IsField()) { 8952 } else if (obj.IsField()) {
(...skipping 1442 matching lines...) Expand 10 before | Expand all | Expand 10 after
10553 void Parser::SkipQualIdent() { 10395 void Parser::SkipQualIdent() {
10554 ASSERT(IsIdentifier()); 10396 ASSERT(IsIdentifier());
10555 ConsumeToken(); 10397 ConsumeToken();
10556 if (CurrentToken() == Token::kPERIOD) { 10398 if (CurrentToken() == Token::kPERIOD) {
10557 ConsumeToken(); // Consume the kPERIOD token. 10399 ConsumeToken(); // Consume the kPERIOD token.
10558 ExpectIdentifier("identifier expected after '.'"); 10400 ExpectIdentifier("identifier expected after '.'");
10559 } 10401 }
10560 } 10402 }
10561 10403
10562 } // namespace dart 10404 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698