OLD | NEW |
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 Loading... |
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); |
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 Loading... |
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(); | 8462 resolved_type_class = |
8481 resolved_type_class = ResolveClassInPrefixScope( | 8463 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); |
8482 unresolved_class.token_pos(), | |
8483 lib_prefix, | |
8484 unresolved_class_name, | |
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 } | 8464 } |
8502 // At this point, we can only have a parameterized_type. | 8465 // At this point, we can only have a parameterized_type. |
8503 const Type& parameterized_type = Type::Cast(*type); | 8466 const Type& parameterized_type = Type::Cast(*type); |
8504 if (!resolved_type_class.IsNull()) { | 8467 if (!resolved_type_class.IsNull()) { |
8505 // Replace unresolved class with resolved type class. | 8468 // Replace unresolved class with resolved type class. |
8506 parameterized_type.set_type_class(resolved_type_class); | 8469 parameterized_type.set_type_class(resolved_type_class); |
8507 } else if (finalization >= ClassFinalizer::kCanonicalize) { | 8470 } else if (finalization >= ClassFinalizer::kCanonicalize) { |
8508 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || | 8471 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || |
8509 FLAG_error_on_bad_type) { | 8472 FLAG_error_on_bad_type) { |
8510 ClassFinalizer::FinalizeMalformedType( | 8473 ClassFinalizer::FinalizeMalformedType( |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8878 obj = lib.LookupLocalObject(accessor_name); | 8841 obj = lib.LookupLocalObject(accessor_name); |
8879 if (!obj.IsNull()) { | 8842 if (!obj.IsNull()) { |
8880 return obj.raw(); | 8843 return obj.raw(); |
8881 } | 8844 } |
8882 accessor_name = Field::SetterName(name); | 8845 accessor_name = Field::SetterName(name); |
8883 obj = lib.LookupLocalObject(accessor_name); | 8846 obj = lib.LookupLocalObject(accessor_name); |
8884 return obj.raw(); | 8847 return obj.raw(); |
8885 } | 8848 } |
8886 | 8849 |
8887 | 8850 |
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 | 8851 // 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 | 8852 // library. If not found in the current library, then look in the scopes |
8914 // of all libraries that are imported without a library prefix. | 8853 // of all libraries that are imported without a library prefix. |
8915 // Issue an error if the name is not found in the global scope | 8854 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"); | 8855 TRACE_PARSER("ResolveNameInCurrentLibraryScope"); |
8922 HANDLESCOPE(isolate()); | 8856 HANDLESCOPE(isolate()); |
8923 Object& obj = Object::Handle(isolate(), | 8857 Object& obj = Object::Handle(isolate(), |
8924 LookupNameInLibrary(isolate(), library_, name)); | 8858 LookupNameInLibrary(isolate(), library_, name)); |
8925 if (obj.IsNull()) { | 8859 if (!obj.IsNull()) { |
8926 // Name is not found in current library. Check scope of all | 8860 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 } | 8861 } |
8971 return obj.raw(); | 8862 return library_.LookupImportedObject(name); |
8972 } | 8863 } |
8973 | 8864 |
8974 | 8865 |
8975 RawClass* Parser::ResolveClassInCurrentLibraryScope(intptr_t ident_pos, | 8866 RawClass* Parser::ResolveClassInCurrentLibraryScope(const String& name) { |
8976 const String& name, | |
8977 Error* error) { | |
8978 const Object& obj = | 8867 const Object& obj = |
8979 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, name, error)); | 8868 Object::Handle(ResolveNameInCurrentLibraryScope(name)); |
8980 if (obj.IsClass()) { | 8869 if (obj.IsClass()) { |
8981 return Class::Cast(obj).raw(); | 8870 return Class::Cast(obj).raw(); |
8982 } | 8871 } |
8983 return Class::null(); | 8872 return Class::null(); |
8984 } | 8873 } |
8985 | 8874 |
8986 | 8875 |
8987 // Resolve an identifier by checking the global scope of the current | 8876 // 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 | 8877 // library. If not found in the current library, then look in the scopes |
8989 // of all libraries that are imported without a library prefix. | 8878 // of all libraries that are imported without a library prefix. |
8990 // Issue an error if the identifier is not found in the global scope | 8879 // 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 | 8880 // of the current library, but is defined in more than one imported |
8992 // library, i.e. if the identifier cannot be resolved unambiguously. | 8881 // library, i.e. if the identifier cannot be resolved unambiguously. |
8993 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, | 8882 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, |
8994 const String& ident) { | 8883 const String& ident) { |
8995 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 8884 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
8996 const Object& obj = | 8885 const Object& obj = |
8997 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, ident, NULL)); | 8886 Object::Handle(ResolveNameInCurrentLibraryScope(ident)); |
8998 if (obj.IsClass()) { | 8887 if (obj.IsClass()) { |
8999 const Class& cls = Class::Cast(obj); | 8888 const Class& cls = Class::Cast(obj); |
9000 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); | 8889 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
9001 } else if (obj.IsField()) { | 8890 } else if (obj.IsField()) { |
9002 const Field& field = Field::Cast(obj); | 8891 const Field& field = Field::Cast(obj); |
9003 ASSERT(field.is_static()); | 8892 ASSERT(field.is_static()); |
9004 return GenerateStaticFieldLookup(field, ident_pos); | 8893 return GenerateStaticFieldLookup(field, ident_pos); |
9005 } else if (obj.IsFunction()) { | 8894 } else if (obj.IsFunction()) { |
9006 const Function& func = Function::Cast(obj); | 8895 const Function& func = Function::Cast(obj); |
9007 ASSERT(func.is_static()); | 8896 ASSERT(func.is_static()); |
9008 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 8897 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
9009 return new StaticGetterNode(ident_pos, | 8898 return new StaticGetterNode(ident_pos, |
9010 /* receiver */ NULL, | 8899 /* receiver */ NULL, |
9011 /* is_super_getter */ false, | 8900 /* is_super_getter */ false, |
9012 Class::ZoneHandle(func.Owner()), | 8901 Class::ZoneHandle(func.Owner()), |
9013 ident); | 8902 ident); |
9014 | 8903 |
9015 } else { | 8904 } else { |
9016 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw())); | 8905 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw())); |
9017 } | 8906 } |
9018 } else { | 8907 } else { |
9019 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); | 8908 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); |
9020 } | 8909 } |
9021 // Lexically unresolved primary identifiers are referenced by their name. | 8910 // Lexically unresolved primary identifiers are referenced by their name. |
9022 return new PrimaryNode(ident_pos, ident); | 8911 return new PrimaryNode(ident_pos, ident); |
9023 } | 8912 } |
9024 | 8913 |
9025 | 8914 |
9026 RawObject* Parser::ResolveNameInPrefixScope(intptr_t ident_pos, | 8915 RawObject* Parser::ResolveNameInPrefixScope(const LibraryPrefix& prefix, |
9027 const LibraryPrefix& prefix, | 8916 const String& name) { |
9028 const String& name, | |
9029 Error* error) { | |
9030 TRACE_PARSER("ResolveNameInPrefixScope"); | |
9031 HANDLESCOPE(isolate()); | 8917 HANDLESCOPE(isolate()); |
9032 Namespace& import = Namespace::Handle(isolate()); | 8918 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 } | 8919 } |
9076 | 8920 |
9077 | 8921 |
9078 RawClass* Parser::ResolveClassInPrefixScope(intptr_t ident_pos, | 8922 RawClass* Parser::ResolveClassInPrefixScope(const LibraryPrefix& prefix, |
9079 const LibraryPrefix& prefix, | 8923 const String& name) { |
9080 const String& name, | |
9081 Error* error) { | |
9082 const Object& obj = | 8924 const Object& obj = |
9083 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, name, error)); | 8925 Object::Handle(ResolveNameInPrefixScope(prefix, name)); |
9084 if (obj.IsClass()) { | 8926 if (obj.IsClass()) { |
9085 return Class::Cast(obj).raw(); | 8927 return Class::Cast(obj).raw(); |
9086 } | 8928 } |
9087 return Class::null(); | 8929 return Class::null(); |
9088 } | 8930 } |
9089 | 8931 |
9090 | 8932 |
9091 // Do a lookup for the identifier in the scope of the specified | 8933 // 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 | 8934 // 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 | 8935 // libraries present in the library prefix. If there are multiple libraries |
9094 // with the name, issue an ambiguous reference error. | 8936 // with the name, issue an ambiguous reference error. |
9095 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 8937 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, |
9096 const LibraryPrefix& prefix, | 8938 const LibraryPrefix& prefix, |
9097 const String& ident) { | 8939 const String& ident) { |
9098 TRACE_PARSER("ResolveIdentInPrefixScope"); | 8940 TRACE_PARSER("ResolveIdentInPrefixScope"); |
9099 Object& obj = | 8941 Object& obj = Object::Handle(ResolveNameInPrefixScope(prefix, ident)); |
9100 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, ident, NULL)); | |
9101 if (obj.IsNull()) { | 8942 if (obj.IsNull()) { |
9102 // Unresolved prefixed primary identifier. | 8943 // Unresolved prefixed primary identifier. |
9103 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved", | 8944 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved", |
9104 String::Handle(prefix.name()).ToCString(), | 8945 String::Handle(prefix.name()).ToCString(), |
9105 ident.ToCString()); | 8946 ident.ToCString()); |
9106 } | 8947 } |
9107 if (obj.IsClass()) { | 8948 if (obj.IsClass()) { |
9108 const Class& cls = Class::Cast(obj); | 8949 const Class& cls = Class::Cast(obj); |
9109 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); | 8950 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
9110 } else if (obj.IsField()) { | 8951 } else if (obj.IsField()) { |
(...skipping 1442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10553 void Parser::SkipQualIdent() { | 10394 void Parser::SkipQualIdent() { |
10554 ASSERT(IsIdentifier()); | 10395 ASSERT(IsIdentifier()); |
10555 ConsumeToken(); | 10396 ConsumeToken(); |
10556 if (CurrentToken() == Token::kPERIOD) { | 10397 if (CurrentToken() == Token::kPERIOD) { |
10557 ConsumeToken(); // Consume the kPERIOD token. | 10398 ConsumeToken(); // Consume the kPERIOD token. |
10558 ExpectIdentifier("identifier expected after '.'"); | 10399 ExpectIdentifier("identifier expected after '.'"); |
10559 } | 10400 } |
10560 } | 10401 } |
10561 | 10402 |
10562 } // namespace dart | 10403 } // namespace dart |
OLD | NEW |