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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
(...skipping 2497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2508 Type& redirection_type = Type::Handle(); | 2508 Type& redirection_type = Type::Handle(); |
2509 String& redirection_identifier = String::Handle(); | 2509 String& redirection_identifier = String::Handle(); |
2510 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { | 2510 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { |
2511 ConsumeToken(); | 2511 ConsumeToken(); |
2512 const intptr_t type_pos = TokenPos(); | 2512 const intptr_t type_pos = TokenPos(); |
2513 const AbstractType& type = AbstractType::Handle( | 2513 const AbstractType& type = AbstractType::Handle( |
2514 ParseType(ClassFinalizer::kTryResolve)); | 2514 ParseType(ClassFinalizer::kTryResolve)); |
2515 if (type.IsTypeParameter() || type.IsDynamicType()) { | 2515 if (type.IsTypeParameter() || type.IsDynamicType()) { |
2516 // Replace the type with a malformed type and compile a throw when called. | 2516 // Replace the type with a malformed type and compile a throw when called. |
2517 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 2517 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
2518 Error::Handle(), // No previous error. | |
2518 current_class(), | 2519 current_class(), |
2519 type_pos, | 2520 type_pos, |
2521 ClassFinalizer::kTryResolve, // No compile-time error. | |
2520 "factory '%s' may not redirect to %s'%s'", | 2522 "factory '%s' may not redirect to %s'%s'", |
2521 method->name->ToCString(), | 2523 method->name->ToCString(), |
2522 type.IsTypeParameter() ? "type parameter " : "", | 2524 type.IsTypeParameter() ? "type parameter " : "", |
2523 type.IsTypeParameter() ? | 2525 type.IsTypeParameter() ? |
2524 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); | 2526 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); |
2525 } else { | 2527 } else { |
2526 redirection_type ^= type.raw(); | 2528 redirection_type ^= type.raw(); |
2527 } | 2529 } |
2528 if (CurrentToken() == Token::kPERIOD) { | 2530 if (CurrentToken() == Token::kPERIOD) { |
2529 // Named constructor or factory. | 2531 // Named constructor or factory. |
(...skipping 3909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6439 intptr_t token_pos, | 6441 intptr_t token_pos, |
6440 const char* message_header, | 6442 const char* message_header, |
6441 const char* format, | 6443 const char* format, |
6442 va_list args) { | 6444 va_list args) { |
6443 const String& msg = String::Handle( | 6445 const String& msg = String::Handle( |
6444 FormatMessage(script, token_pos, message_header, format, args)); | 6446 FormatMessage(script, token_pos, message_header, format, args)); |
6445 return LanguageError::New(msg); | 6447 return LanguageError::New(msg); |
6446 } | 6448 } |
6447 | 6449 |
6448 | 6450 |
6451 RawError* Parser::FormatErrorMsg(const Script& script, | |
6452 intptr_t token_pos, | |
6453 const char* message_header, | |
6454 const char* format, ...) { | |
6455 va_list args; | |
6456 va_start(args, format); | |
6457 const Error& error = Error::Handle( | |
6458 FormatError(script, token_pos, message_header, format, args)); | |
6459 va_end(args); | |
6460 return error.raw(); | |
6461 } | |
6462 | |
6463 | |
6449 RawString* Parser::FormatMessage(const Script& script, | 6464 RawString* Parser::FormatMessage(const Script& script, |
6450 intptr_t token_pos, | 6465 intptr_t token_pos, |
6451 const char* message_header, | 6466 const char* message_header, |
6452 const char* format, va_list args) { | 6467 const char* format, va_list args) { |
6453 String& result = String::Handle(); | 6468 String& result = String::Handle(); |
6454 const String& msg = String::Handle(String::NewFormattedV(format, args)); | 6469 const String& msg = String::Handle(String::NewFormattedV(format, args)); |
6455 if (!script.IsNull()) { | 6470 if (!script.IsNull()) { |
6456 const String& script_url = String::CheckedHandle(script.url()); | 6471 const String& script_url = String::CheckedHandle(script.url()); |
6457 if (token_pos >= 0) { | 6472 if (token_pos >= 0) { |
6458 intptr_t line, column; | 6473 intptr_t line, column; |
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7630 // First check if the type is a type parameter of the given scope class. | 7645 // First check if the type is a type parameter of the given scope class. |
7631 const TypeParameter& type_parameter = TypeParameter::Handle( | 7646 const TypeParameter& type_parameter = TypeParameter::Handle( |
7632 scope_class.LookupTypeParameter(unresolved_class_name, | 7647 scope_class.LookupTypeParameter(unresolved_class_name, |
7633 type->token_pos())); | 7648 type->token_pos())); |
7634 if (!type_parameter.IsNull()) { | 7649 if (!type_parameter.IsNull()) { |
7635 // A type parameter is considered to be a malformed type when | 7650 // A type parameter is considered to be a malformed type when |
7636 // referenced by a static member. | 7651 // referenced by a static member. |
7637 if (ParsingStaticMember()) { | 7652 if (ParsingStaticMember()) { |
7638 ASSERT(scope_class.raw() == current_class().raw()); | 7653 ASSERT(scope_class.raw() == current_class().raw()); |
7639 *type = ClassFinalizer::NewFinalizedMalformedType( | 7654 *type = ClassFinalizer::NewFinalizedMalformedType( |
7655 Error::Handle(), // No previous error. | |
7640 scope_class, | 7656 scope_class, |
7641 type->token_pos(), | 7657 type->token_pos(), |
7658 finalization, | |
7642 "type parameter '%s' cannot be referenced " | 7659 "type parameter '%s' cannot be referenced " |
7643 "from static member", | 7660 "from static member", |
7644 String::Handle(type_parameter.name()).ToCString()); | 7661 String::Handle(type_parameter.name()).ToCString()); |
7645 return; | 7662 return; |
7646 } | 7663 } |
7647 // TODO(regis): Should this be a malformed type as well? | 7664 // A type parameter cannot be parameterized, so make the type |
7648 // A type parameter cannot be parameterized, so report an error if | 7665 // malformed if type arguments have previously been parsed. |
hausner
2012/10/23 22:02:24
indentation
regis
2012/10/23 22:30:25
Strange. I do not see this bad indentation in the
| |
7649 // type arguments have previously been parsed. | |
7650 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { | 7666 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
7651 ErrorMsg(type_parameter.token_pos(), | 7667 *type = ClassFinalizer::NewFinalizedMalformedType( |
7652 "type parameter '%s' cannot be parameterized", | 7668 Error::Handle(), // No previous error. |
7653 String::Handle(type_parameter.name()).ToCString()); | 7669 scope_class, |
7670 type_parameter.token_pos(), | |
7671 finalization, | |
7672 "type parameter '%s' cannot be parameterized", | |
7673 String::Handle(type_parameter.name()).ToCString()); | |
7674 return; | |
7654 } | 7675 } |
7655 *type = type_parameter.raw(); | 7676 *type = type_parameter.raw(); |
7656 return; | 7677 return; |
7657 } | 7678 } |
7658 } | 7679 } |
7659 // Resolve classname in the scope of the current library. | 7680 // Resolve classname in the scope of the current library. |
7681 Error& error = Error::Handle(); | |
7660 resolved_type_class = | 7682 resolved_type_class = |
7661 ResolveClassInCurrentLibraryScope(unresolved_class.token_pos(), | 7683 ResolveClassInCurrentLibraryScope(unresolved_class.token_pos(), |
7662 unresolved_class_name); | 7684 unresolved_class_name, |
7685 &error); | |
7686 if (!error.IsNull()) { | |
7687 *type = ClassFinalizer::NewFinalizedMalformedType( | |
7688 error, | |
7689 scope_class, | |
7690 unresolved_class.token_pos(), | |
7691 finalization, | |
7692 "cannot resolve class '%s'", | |
7693 unresolved_class_name.ToCString()); | |
7694 return; | |
7695 } | |
7663 } else { | 7696 } else { |
7664 LibraryPrefix& lib_prefix = | 7697 LibraryPrefix& lib_prefix = |
7665 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 7698 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
7666 // Resolve class name in the scope of the library prefix. | 7699 // Resolve class name in the scope of the library prefix. |
7700 Error& error = Error::Handle(); | |
7667 resolved_type_class = | 7701 resolved_type_class = |
7668 ResolveClassInPrefixScope(unresolved_class.token_pos(), | 7702 ResolveClassInPrefixScope(unresolved_class.token_pos(), |
7669 lib_prefix, | 7703 lib_prefix, |
7670 unresolved_class_name); | 7704 unresolved_class_name, |
7705 &error); | |
7706 if (!error.IsNull()) { | |
7707 *type = ClassFinalizer::NewFinalizedMalformedType( | |
7708 error, | |
7709 scope_class, | |
7710 unresolved_class.token_pos(), | |
7711 finalization, | |
7712 "cannot resolve class '%s'", | |
7713 unresolved_class_name.ToCString()); | |
7714 return; | |
7715 } | |
7671 } | 7716 } |
7672 // At this point, we can only have a parameterized_type. | 7717 // At this point, we can only have a parameterized_type. |
7673 Type& parameterized_type = Type::Handle(); | 7718 Type& parameterized_type = Type::Handle(); |
7674 parameterized_type ^= type->raw(); | 7719 parameterized_type ^= type->raw(); |
7675 if (!resolved_type_class.IsNull()) { | 7720 if (!resolved_type_class.IsNull()) { |
7676 // Replace unresolved class with resolved type class. | 7721 // Replace unresolved class with resolved type class. |
7677 parameterized_type.set_type_class(resolved_type_class); | 7722 parameterized_type.set_type_class(resolved_type_class); |
7678 } else if (finalization >= ClassFinalizer::kCanonicalize) { | 7723 } else if (finalization >= ClassFinalizer::kCanonicalize) { |
7679 // The type is malformed. | 7724 // The type is malformed. |
7680 ClassFinalizer::FinalizeMalformedType( | 7725 ClassFinalizer::FinalizeMalformedType( |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8128 } | 8173 } |
8129 | 8174 |
8130 | 8175 |
8131 // Resolve a name by checking the global scope of the current | 8176 // Resolve a name by checking the global scope of the current |
8132 // library. If not found in the current library, then look in the scopes | 8177 // library. If not found in the current library, then look in the scopes |
8133 // of all libraries that are imported without a library prefix. | 8178 // of all libraries that are imported without a library prefix. |
8134 // Issue an error if the name is not found in the global scope | 8179 // Issue an error if the name is not found in the global scope |
8135 // of the current library, but is defined in more than one imported | 8180 // of the current library, but is defined in more than one imported |
8136 // library, i.e. if the name cannot be resolved unambiguously. | 8181 // library, i.e. if the name cannot be resolved unambiguously. |
8137 RawObject* Parser::ResolveNameInCurrentLibraryScope(intptr_t ident_pos, | 8182 RawObject* Parser::ResolveNameInCurrentLibraryScope(intptr_t ident_pos, |
8138 const String& name) { | 8183 const String& name, |
8184 Error* error) { | |
8139 TRACE_PARSER("ResolveNameInCurrentLibraryScope"); | 8185 TRACE_PARSER("ResolveNameInCurrentLibraryScope"); |
8140 Object& obj = Object::Handle(LookupNameInLibrary(library_, name)); | 8186 Object& obj = Object::Handle(LookupNameInLibrary(library_, name)); |
8141 if (obj.IsNull()) { | 8187 if (obj.IsNull()) { |
8142 // Name is not found in current library. Check scope of all | 8188 // Name is not found in current library. Check scope of all |
8143 // imported libraries. | 8189 // imported libraries. |
8144 String& first_lib_url = String::Handle(); | 8190 String& first_lib_url = String::Handle(); |
8145 Namespace& import = Namespace::Handle(); | 8191 Namespace& import = Namespace::Handle(); |
8146 intptr_t num_imports = library_.num_imports(); | 8192 intptr_t num_imports = library_.num_imports(); |
8147 Object& imported_obj = Object::Handle(); | 8193 Object& imported_obj = Object::Handle(); |
8148 for (int i = 0; i < num_imports; i++) { | 8194 for (int i = 0; i < num_imports; i++) { |
8149 import ^= library_.ImportAt(i); | 8195 import ^= library_.ImportAt(i); |
8150 imported_obj = LookupNameInImport(import, name); | 8196 imported_obj = LookupNameInImport(import, name); |
8151 if (!imported_obj.IsNull()) { | 8197 if (!imported_obj.IsNull()) { |
8152 const Library& lib = Library::Handle(import.library()); | 8198 const Library& lib = Library::Handle(import.library()); |
8153 if (!first_lib_url.IsNull()) { | 8199 if (!first_lib_url.IsNull()) { |
8154 // Found duplicate definition. | 8200 // Found duplicate definition. |
8201 Error& ambiguous_ref_error = Error::Handle(); | |
8155 if (first_lib_url.raw() == lib.url()) { | 8202 if (first_lib_url.raw() == lib.url()) { |
8156 ErrorMsg(ident_pos, | 8203 ambiguous_ref_error = FormatErrorMsg( |
8157 "ambiguous reference: " | 8204 script_, ident_pos, "Error", |
8158 "'%s' as library '%s' is imported multiple times", | 8205 "ambiguous reference: " |
8159 name.ToCString(), | 8206 "'%s' as library '%s' is imported multiple times", |
8160 first_lib_url.ToCString()); | 8207 name.ToCString(), |
8208 first_lib_url.ToCString()); | |
8161 } else { | 8209 } else { |
8162 ErrorMsg(ident_pos, | 8210 ambiguous_ref_error = FormatErrorMsg( |
8163 "ambiguous reference: " | 8211 script_, ident_pos, "Error", |
8164 "'%s' is defined in library '%s' and also in '%s'", | 8212 "ambiguous reference: " |
8165 name.ToCString(), | 8213 "'%s' is defined in library '%s' and also in '%s'", |
8166 first_lib_url.ToCString(), | 8214 name.ToCString(), |
8167 String::Handle(lib.url()).ToCString()); | 8215 first_lib_url.ToCString(), |
8216 String::Handle(lib.url()).ToCString()); | |
8168 } | 8217 } |
8218 if (error == NULL) { | |
8219 // Report a compile time error since the caller is not interested | |
8220 // in the error. | |
8221 ErrorMsg(ambiguous_ref_error); | |
8222 } | |
8223 *error = ambiguous_ref_error.raw(); | |
8224 return Object::null(); | |
8169 } else { | 8225 } else { |
8170 first_lib_url = lib.url(); | 8226 first_lib_url = lib.url(); |
8171 obj = imported_obj.raw(); | 8227 obj = imported_obj.raw(); |
8172 } | 8228 } |
8173 } | 8229 } |
8174 } | 8230 } |
8175 } | 8231 } |
8176 return obj.raw(); | 8232 return obj.raw(); |
8177 } | 8233 } |
8178 | 8234 |
8179 | 8235 |
8180 RawClass* Parser::ResolveClassInCurrentLibraryScope(intptr_t ident_pos, | 8236 RawClass* Parser::ResolveClassInCurrentLibraryScope(intptr_t ident_pos, |
8181 const String& name) { | 8237 const String& name, |
8238 Error* error) { | |
8182 const Object& obj = | 8239 const Object& obj = |
8183 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, name)); | 8240 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, name, error)); |
8184 if (obj.IsClass()) { | 8241 if (obj.IsClass()) { |
8185 return Class::Cast(obj).raw(); | 8242 return Class::Cast(obj).raw(); |
8186 } | 8243 } |
8187 return Class::null(); | 8244 return Class::null(); |
8188 } | 8245 } |
8189 | 8246 |
8190 | 8247 |
8191 // Resolve an identifier by checking the global scope of the current | 8248 // Resolve an identifier by checking the global scope of the current |
8192 // library. If not found in the current library, then look in the scopes | 8249 // library. If not found in the current library, then look in the scopes |
8193 // of all libraries that are imported without a library prefix. | 8250 // of all libraries that are imported without a library prefix. |
8194 // Issue an error if the identifier is not found in the global scope | 8251 // Issue an error if the identifier is not found in the global scope |
8195 // of the current library, but is defined in more than one imported | 8252 // of the current library, but is defined in more than one imported |
8196 // library, i.e. if the identifier cannot be resolved unambiguously. | 8253 // library, i.e. if the identifier cannot be resolved unambiguously. |
8197 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, | 8254 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, |
8198 const String& ident) { | 8255 const String& ident) { |
8199 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 8256 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
8200 const Object& obj = | 8257 const Object& obj = |
8201 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, ident)); | 8258 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, ident, NULL)); |
8202 if (obj.IsClass()) { | 8259 if (obj.IsClass()) { |
8203 const Class& cls = Class::Cast(obj); | 8260 const Class& cls = Class::Cast(obj); |
8204 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); | 8261 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
8205 } else if (obj.IsField()) { | 8262 } else if (obj.IsField()) { |
8206 const Field& field = Field::Cast(obj); | 8263 const Field& field = Field::Cast(obj); |
8207 ASSERT(field.is_static()); | 8264 ASSERT(field.is_static()); |
8208 return GenerateStaticFieldLookup(field, ident_pos); | 8265 return GenerateStaticFieldLookup(field, ident_pos); |
8209 } else if (obj.IsFunction()) { | 8266 } else if (obj.IsFunction()) { |
8210 const Function& func = Function::Cast(obj); | 8267 const Function& func = Function::Cast(obj); |
8211 ASSERT(func.is_static()); | 8268 ASSERT(func.is_static()); |
(...skipping 10 matching lines...) Expand all Loading... | |
8222 } else { | 8279 } else { |
8223 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); | 8280 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); |
8224 } | 8281 } |
8225 // Lexically unresolved primary identifiers are referenced by their name. | 8282 // Lexically unresolved primary identifiers are referenced by their name. |
8226 return new PrimaryNode(ident_pos, ident); | 8283 return new PrimaryNode(ident_pos, ident); |
8227 } | 8284 } |
8228 | 8285 |
8229 | 8286 |
8230 RawObject* Parser::ResolveNameInPrefixScope(intptr_t ident_pos, | 8287 RawObject* Parser::ResolveNameInPrefixScope(intptr_t ident_pos, |
8231 const LibraryPrefix& prefix, | 8288 const LibraryPrefix& prefix, |
8232 const String& name) { | 8289 const String& name, |
8290 Error* error) { | |
8233 TRACE_PARSER("ResolveNameInPrefixScope"); | 8291 TRACE_PARSER("ResolveNameInPrefixScope"); |
8234 Namespace& import = Namespace::Handle(); | 8292 Namespace& import = Namespace::Handle(); |
8235 String& first_lib_url = String::Handle(); | 8293 String& first_lib_url = String::Handle(); |
8236 Object& obj = Object::Handle(); | 8294 Object& obj = Object::Handle(); |
8237 Object& resolved_obj = Object::Handle(); | 8295 Object& resolved_obj = Object::Handle(); |
8238 const Array& imports = Array::Handle(prefix.imports()); | 8296 const Array& imports = Array::Handle(prefix.imports()); |
8239 for (intptr_t i = 0; i < prefix.num_imports(); i++) { | 8297 for (intptr_t i = 0; i < prefix.num_imports(); i++) { |
8240 import ^= imports.At(i); | 8298 import ^= imports.At(i); |
8241 resolved_obj = LookupNameInImport(import, name); | 8299 resolved_obj = LookupNameInImport(import, name); |
8242 if (!resolved_obj.IsNull()) { | 8300 if (!resolved_obj.IsNull()) { |
8243 obj = resolved_obj.raw(); | 8301 obj = resolved_obj.raw(); |
8244 const Library& lib = Library::Handle(import.library()); | 8302 const Library& lib = Library::Handle(import.library()); |
8245 if (first_lib_url.IsNull()) { | 8303 if (first_lib_url.IsNull()) { |
8246 first_lib_url = lib.url(); | 8304 first_lib_url = lib.url(); |
8247 } else { | 8305 } else { |
8248 // Found duplicate definition. | 8306 // Found duplicate definition. |
8307 Error& ambiguous_ref_error = Error::Handle(); | |
8249 if (first_lib_url.raw() == lib.url()) { | 8308 if (first_lib_url.raw() == lib.url()) { |
8250 ErrorMsg(ident_pos, | 8309 ambiguous_ref_error = FormatErrorMsg( |
8251 "ambiguous reference: '%s.%s' is imported multiple times", | 8310 script_, ident_pos, "Error", |
8252 String::Handle(prefix.name()).ToCString(), | 8311 "ambiguous reference: '%s.%s' is imported multiple times", |
8253 name.ToCString()); | 8312 String::Handle(prefix.name()).ToCString(), |
8313 name.ToCString()); | |
8254 } else { | 8314 } else { |
8255 ErrorMsg(ident_pos, | 8315 ambiguous_ref_error = FormatErrorMsg( |
8256 "ambiguous reference: '%s.%s' is defined in '%s' and '%s'", | 8316 script_, ident_pos, "Error", |
8257 String::Handle(prefix.name()).ToCString(), | 8317 "ambiguous reference: '%s.%s' is defined in '%s' and '%s'", |
8258 name.ToCString(), | 8318 String::Handle(prefix.name()).ToCString(), |
8259 first_lib_url.ToCString(), | 8319 name.ToCString(), |
8260 String::Handle(lib.url()).ToCString()); | 8320 first_lib_url.ToCString(), |
8321 String::Handle(lib.url()).ToCString()); | |
8261 } | 8322 } |
8323 if (error == NULL) { | |
8324 // Report a compile time error since the caller is not interested | |
8325 // in the error. | |
8326 ErrorMsg(ambiguous_ref_error); | |
8327 } | |
8328 *error = ambiguous_ref_error.raw(); | |
8329 return Object::null(); | |
8262 } | 8330 } |
8263 } | 8331 } |
8264 } | 8332 } |
8265 return obj.raw(); | 8333 return obj.raw(); |
8266 } | 8334 } |
8267 | 8335 |
8268 | 8336 |
8269 RawClass* Parser::ResolveClassInPrefixScope(intptr_t ident_pos, | 8337 RawClass* Parser::ResolveClassInPrefixScope(intptr_t ident_pos, |
8270 const LibraryPrefix& prefix, | 8338 const LibraryPrefix& prefix, |
8271 const String& name) { | 8339 const String& name, |
8340 Error* error) { | |
8272 const Object& obj = | 8341 const Object& obj = |
8273 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, name)); | 8342 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, name, error)); |
8274 if (obj.IsClass()) { | 8343 if (obj.IsClass()) { |
8275 return Class::Cast(obj).raw(); | 8344 return Class::Cast(obj).raw(); |
8276 } | 8345 } |
8277 return Class::null(); | 8346 return Class::null(); |
8278 } | 8347 } |
8279 | 8348 |
8280 | 8349 |
8281 // Do a lookup for the identifier in the scope of the specified | 8350 // Do a lookup for the identifier in the scope of the specified |
8282 // library prefix. This means trying to resolve it locally in all of the | 8351 // library prefix. This means trying to resolve it locally in all of the |
8283 // libraries present in the library prefix. If there are multiple libraries | 8352 // libraries present in the library prefix. If there are multiple libraries |
8284 // with the name, issue an ambiguous reference error. | 8353 // with the name, issue an ambiguous reference error. |
8285 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 8354 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, |
8286 const LibraryPrefix& prefix, | 8355 const LibraryPrefix& prefix, |
8287 const String& ident) { | 8356 const String& ident) { |
8288 TRACE_PARSER("ResolveIdentInPrefixScope"); | 8357 TRACE_PARSER("ResolveIdentInPrefixScope"); |
8289 Object& obj = | 8358 Object& obj = |
8290 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, ident)); | 8359 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, ident, NULL)); |
8291 if (obj.IsNull()) { | 8360 if (obj.IsNull()) { |
8292 // Unresolved prefixed primary identifier. | 8361 // Unresolved prefixed primary identifier. |
8293 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved", | 8362 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved", |
8294 String::Handle(prefix.name()).ToCString(), | 8363 String::Handle(prefix.name()).ToCString(), |
8295 ident.ToCString()); | 8364 ident.ToCString()); |
8296 } | 8365 } |
8297 if (obj.IsClass()) { | 8366 if (obj.IsClass()) { |
8298 const Class& cls = Class::Cast(obj); | 8367 const Class& cls = Class::Cast(obj); |
8299 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); | 8368 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
8300 } else if (obj.IsField()) { | 8369 } else if (obj.IsField()) { |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8879 ConsumeToken(); | 8948 ConsumeToken(); |
8880 if (!IsIdentifier()) { | 8949 if (!IsIdentifier()) { |
8881 ErrorMsg("type name expected"); | 8950 ErrorMsg("type name expected"); |
8882 } | 8951 } |
8883 intptr_t type_pos = TokenPos(); | 8952 intptr_t type_pos = TokenPos(); |
8884 AbstractType& type = AbstractType::Handle( | 8953 AbstractType& type = AbstractType::Handle( |
8885 ParseType(ClassFinalizer::kCanonicalizeForCreation)); | 8954 ParseType(ClassFinalizer::kCanonicalizeForCreation)); |
8886 // In case the type is malformed, throw a dynamic type error after finishing | 8955 // In case the type is malformed, throw a dynamic type error after finishing |
8887 // parsing the instance creation expression. | 8956 // parsing the instance creation expression. |
8888 if (type.IsTypeParameter() || type.IsDynamicType()) { | 8957 if (type.IsTypeParameter() || type.IsDynamicType()) { |
8958 ASSERT(!type.IsMalformed()); | |
8889 // Replace the type with a malformed type. | 8959 // Replace the type with a malformed type. |
8890 type = ClassFinalizer::NewFinalizedMalformedType( | 8960 type = ClassFinalizer::NewFinalizedMalformedType( |
8961 Error::Handle(), // No previous error. | |
8891 current_class(), | 8962 current_class(), |
8892 type_pos, | 8963 type_pos, |
8964 ClassFinalizer::kTryResolve, // No compile-time error. | |
8893 "%s'%s' cannot be instantiated", | 8965 "%s'%s' cannot be instantiated", |
8894 type.IsTypeParameter() ? "type parameter " : "", | 8966 type.IsTypeParameter() ? "type parameter " : "", |
8895 type.IsTypeParameter() ? | 8967 type.IsTypeParameter() ? |
8896 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); | 8968 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); |
8897 } | 8969 } |
8898 | 8970 |
8899 // The grammar allows for an optional ('.' identifier)? after the type, which | 8971 // The grammar allows for an optional ('.' identifier)? after the type, which |
8900 // is a named constructor. Note that ParseType(kMustResolve) above will not | 8972 // is a named constructor. Note that ParseType(kMustResolve) above will not |
8901 // consume it as part of a misinterpreted qualified identifier, because only a | 8973 // consume it as part of a misinterpreted qualified identifier, because only a |
8902 // valid library prefix is accepted as qualifier. | 8974 // valid library prefix is accepted as qualifier. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8946 const String& constructor_name = | 9018 const String& constructor_name = |
8947 BuildConstructorName(type_class_name, named_constructor); | 9019 BuildConstructorName(type_class_name, named_constructor); |
8948 const String& external_constructor_name = | 9020 const String& external_constructor_name = |
8949 (named_constructor ? constructor_name : type_class_name); | 9021 (named_constructor ? constructor_name : type_class_name); |
8950 Function& constructor = Function::ZoneHandle( | 9022 Function& constructor = Function::ZoneHandle( |
8951 type_class.LookupConstructor(constructor_name)); | 9023 type_class.LookupConstructor(constructor_name)); |
8952 if (constructor.IsNull()) { | 9024 if (constructor.IsNull()) { |
8953 // Replace the type with a malformed type and compile a throw or report | 9025 // Replace the type with a malformed type and compile a throw or report |
8954 // a compile-time error if the constructor is const. | 9026 // a compile-time error if the constructor is const. |
8955 type = ClassFinalizer::NewFinalizedMalformedType( | 9027 type = ClassFinalizer::NewFinalizedMalformedType( |
9028 Error::Handle(), // No previous error. | |
8956 current_class(), | 9029 current_class(), |
8957 call_pos, | 9030 call_pos, |
9031 ClassFinalizer::kTryResolve, // No compile-time error. | |
8958 "interface '%s' has no constructor named '%s'", | 9032 "interface '%s' has no constructor named '%s'", |
8959 type_class_name.ToCString(), | 9033 type_class_name.ToCString(), |
8960 external_constructor_name.ToCString()); | 9034 external_constructor_name.ToCString()); |
8961 if (is_const) { | 9035 if (is_const) { |
8962 const Error& error = Error::Handle(type.malformed_error()); | 9036 const Error& error = Error::Handle(type.malformed_error()); |
8963 ErrorMsg(error); | 9037 ErrorMsg(error); |
8964 } | 9038 } |
8965 return ThrowNoSuchMethodError(call_pos, external_constructor_name); | 9039 return ThrowNoSuchMethodError(call_pos, external_constructor_name); |
8966 } | 9040 } |
8967 String& error_message = String::Handle(); | 9041 String& error_message = String::Handle(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9014 Function& constructor = Function::ZoneHandle( | 9088 Function& constructor = Function::ZoneHandle( |
9015 constructor_class.LookupConstructor(constructor_name)); | 9089 constructor_class.LookupConstructor(constructor_name)); |
9016 if (constructor.IsNull()) { | 9090 if (constructor.IsNull()) { |
9017 constructor = constructor_class.LookupFactory(constructor_name); | 9091 constructor = constructor_class.LookupFactory(constructor_name); |
9018 if (constructor.IsNull()) { | 9092 if (constructor.IsNull()) { |
9019 const String& external_constructor_name = | 9093 const String& external_constructor_name = |
9020 (named_constructor ? constructor_name : constructor_class_name); | 9094 (named_constructor ? constructor_name : constructor_class_name); |
9021 // Replace the type with a malformed type and compile a throw or report a | 9095 // Replace the type with a malformed type and compile a throw or report a |
9022 // compile-time error if the constructor is const. | 9096 // compile-time error if the constructor is const. |
9023 type = ClassFinalizer::NewFinalizedMalformedType( | 9097 type = ClassFinalizer::NewFinalizedMalformedType( |
9098 Error::Handle(), // No previous error. | |
9024 current_class(), | 9099 current_class(), |
9025 call_pos, | 9100 call_pos, |
9101 ClassFinalizer::kTryResolve, // No compile-time error. | |
9026 "class '%s' has no constructor or factory named '%s'", | 9102 "class '%s' has no constructor or factory named '%s'", |
9027 String::Handle(constructor_class.Name()).ToCString(), | 9103 String::Handle(constructor_class.Name()).ToCString(), |
9028 external_constructor_name.ToCString()); | 9104 external_constructor_name.ToCString()); |
9029 if (is_const) { | 9105 if (is_const) { |
9030 const Error& error = Error::Handle(type.malformed_error()); | 9106 const Error& error = Error::Handle(type.malformed_error()); |
9031 ErrorMsg(error); | 9107 ErrorMsg(error); |
9032 } | 9108 } |
9033 return ThrowNoSuchMethodError(call_pos, external_constructor_name); | 9109 return ThrowNoSuchMethodError(call_pos, external_constructor_name); |
9034 } else if (constructor.IsRedirectingFactory()) { | 9110 } else if (constructor.IsRedirectingFactory()) { |
9035 type = constructor.RedirectionType(); | 9111 type = constructor.RedirectionType(); |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9764 void Parser::SkipQualIdent() { | 9840 void Parser::SkipQualIdent() { |
9765 ASSERT(IsIdentifier()); | 9841 ASSERT(IsIdentifier()); |
9766 ConsumeToken(); | 9842 ConsumeToken(); |
9767 if (CurrentToken() == Token::kPERIOD) { | 9843 if (CurrentToken() == Token::kPERIOD) { |
9768 ConsumeToken(); // Consume the kPERIOD token. | 9844 ConsumeToken(); // Consume the kPERIOD token. |
9769 ExpectIdentifier("identifier expected after '.'"); | 9845 ExpectIdentifier("identifier expected after '.'"); |
9770 } | 9846 } |
9771 } | 9847 } |
9772 | 9848 |
9773 } // namespace dart | 9849 } // namespace dart |
OLD | NEW |