Chromium Code Reviews| Index: runtime/vm/parser.cc |
| =================================================================== |
| --- runtime/vm/parser.cc (revision 13985) |
| +++ runtime/vm/parser.cc (working copy) |
| @@ -2515,8 +2515,10 @@ |
| if (type.IsTypeParameter() || type.IsDynamicType()) { |
| // Replace the type with a malformed type and compile a throw when called. |
| redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
| + Error::Handle(), // No previous error. |
| current_class(), |
| type_pos, |
| + ClassFinalizer::kTryResolve, // No compile-time error. |
| "factory '%s' may not redirect to %s'%s'", |
| method->name->ToCString(), |
| type.IsTypeParameter() ? "type parameter " : "", |
| @@ -6446,6 +6448,19 @@ |
| } |
| +RawError* Parser::FormatErrorMsg(const Script& script, |
| + intptr_t token_pos, |
| + const char* message_header, |
| + const char* format, ...) { |
| + va_list args; |
| + va_start(args, format); |
| + const Error& error = Error::Handle( |
| + FormatError(script, token_pos, message_header, format, args)); |
| + va_end(args); |
| + return error.raw(); |
| +} |
| + |
| + |
| RawString* Parser::FormatMessage(const Script& script, |
| intptr_t token_pos, |
| const char* message_header, |
| @@ -7637,37 +7652,67 @@ |
| if (ParsingStaticMember()) { |
| ASSERT(scope_class.raw() == current_class().raw()); |
| *type = ClassFinalizer::NewFinalizedMalformedType( |
| + Error::Handle(), // No previous error. |
| scope_class, |
| type->token_pos(), |
| + finalization, |
| "type parameter '%s' cannot be referenced " |
| "from static member", |
| String::Handle(type_parameter.name()).ToCString()); |
| return; |
| } |
| - // TODO(regis): Should this be a malformed type as well? |
| - // A type parameter cannot be parameterized, so report an error if |
| - // type arguments have previously been parsed. |
| + // A type parameter cannot be parameterized, so make the type |
| + // 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
|
| if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
| - ErrorMsg(type_parameter.token_pos(), |
| - "type parameter '%s' cannot be parameterized", |
| - String::Handle(type_parameter.name()).ToCString()); |
| + *type = ClassFinalizer::NewFinalizedMalformedType( |
| + Error::Handle(), // No previous error. |
| + scope_class, |
| + type_parameter.token_pos(), |
| + finalization, |
| + "type parameter '%s' cannot be parameterized", |
| + String::Handle(type_parameter.name()).ToCString()); |
| + return; |
| } |
| *type = type_parameter.raw(); |
| return; |
| } |
| } |
| // Resolve classname in the scope of the current library. |
| + Error& error = Error::Handle(); |
| resolved_type_class = |
| ResolveClassInCurrentLibraryScope(unresolved_class.token_pos(), |
| - unresolved_class_name); |
| + unresolved_class_name, |
| + &error); |
| + if (!error.IsNull()) { |
| + *type = ClassFinalizer::NewFinalizedMalformedType( |
| + error, |
| + scope_class, |
| + unresolved_class.token_pos(), |
| + finalization, |
| + "cannot resolve class '%s'", |
| + unresolved_class_name.ToCString()); |
| + return; |
| + } |
| } else { |
| LibraryPrefix& lib_prefix = |
| LibraryPrefix::Handle(unresolved_class.library_prefix()); |
| // Resolve class name in the scope of the library prefix. |
| + Error& error = Error::Handle(); |
| resolved_type_class = |
| ResolveClassInPrefixScope(unresolved_class.token_pos(), |
| - lib_prefix, |
| - unresolved_class_name); |
| + lib_prefix, |
| + unresolved_class_name, |
| + &error); |
| + if (!error.IsNull()) { |
| + *type = ClassFinalizer::NewFinalizedMalformedType( |
| + error, |
| + scope_class, |
| + unresolved_class.token_pos(), |
| + finalization, |
| + "cannot resolve class '%s'", |
| + unresolved_class_name.ToCString()); |
| + return; |
| + } |
| } |
| // At this point, we can only have a parameterized_type. |
| Type& parameterized_type = Type::Handle(); |
| @@ -8135,7 +8180,8 @@ |
| // of the current library, but is defined in more than one imported |
| // library, i.e. if the name cannot be resolved unambiguously. |
| RawObject* Parser::ResolveNameInCurrentLibraryScope(intptr_t ident_pos, |
| - const String& name) { |
| + const String& name, |
| + Error* error) { |
| TRACE_PARSER("ResolveNameInCurrentLibraryScope"); |
| Object& obj = Object::Handle(LookupNameInLibrary(library_, name)); |
| if (obj.IsNull()) { |
| @@ -8152,20 +8198,30 @@ |
| const Library& lib = Library::Handle(import.library()); |
| if (!first_lib_url.IsNull()) { |
| // Found duplicate definition. |
| + Error& ambiguous_ref_error = Error::Handle(); |
| if (first_lib_url.raw() == lib.url()) { |
| - ErrorMsg(ident_pos, |
| - "ambiguous reference: " |
| - "'%s' as library '%s' is imported multiple times", |
| - name.ToCString(), |
| - first_lib_url.ToCString()); |
| + ambiguous_ref_error = FormatErrorMsg( |
| + script_, ident_pos, "Error", |
| + "ambiguous reference: " |
| + "'%s' as library '%s' is imported multiple times", |
| + name.ToCString(), |
| + first_lib_url.ToCString()); |
| } else { |
| - ErrorMsg(ident_pos, |
| - "ambiguous reference: " |
| - "'%s' is defined in library '%s' and also in '%s'", |
| - name.ToCString(), |
| - first_lib_url.ToCString(), |
| - String::Handle(lib.url()).ToCString()); |
| + ambiguous_ref_error = FormatErrorMsg( |
| + script_, ident_pos, "Error", |
| + "ambiguous reference: " |
| + "'%s' is defined in library '%s' and also in '%s'", |
| + name.ToCString(), |
| + first_lib_url.ToCString(), |
| + String::Handle(lib.url()).ToCString()); |
| } |
| + if (error == NULL) { |
| + // Report a compile time error since the caller is not interested |
| + // in the error. |
| + ErrorMsg(ambiguous_ref_error); |
| + } |
| + *error = ambiguous_ref_error.raw(); |
| + return Object::null(); |
| } else { |
| first_lib_url = lib.url(); |
| obj = imported_obj.raw(); |
| @@ -8178,9 +8234,10 @@ |
| RawClass* Parser::ResolveClassInCurrentLibraryScope(intptr_t ident_pos, |
| - const String& name) { |
| + const String& name, |
| + Error* error) { |
| const Object& obj = |
| - Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, name)); |
| + Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, name, error)); |
| if (obj.IsClass()) { |
| return Class::Cast(obj).raw(); |
| } |
| @@ -8198,7 +8255,7 @@ |
| const String& ident) { |
| TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
| const Object& obj = |
| - Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, ident)); |
| + Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, ident, NULL)); |
| if (obj.IsClass()) { |
| const Class& cls = Class::Cast(obj); |
| return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
| @@ -8229,7 +8286,8 @@ |
| RawObject* Parser::ResolveNameInPrefixScope(intptr_t ident_pos, |
| const LibraryPrefix& prefix, |
| - const String& name) { |
| + const String& name, |
| + Error* error) { |
| TRACE_PARSER("ResolveNameInPrefixScope"); |
| Namespace& import = Namespace::Handle(); |
| String& first_lib_url = String::Handle(); |
| @@ -8246,19 +8304,29 @@ |
| first_lib_url = lib.url(); |
| } else { |
| // Found duplicate definition. |
| + Error& ambiguous_ref_error = Error::Handle(); |
| if (first_lib_url.raw() == lib.url()) { |
| - ErrorMsg(ident_pos, |
| - "ambiguous reference: '%s.%s' is imported multiple times", |
| - String::Handle(prefix.name()).ToCString(), |
| - name.ToCString()); |
| + ambiguous_ref_error = FormatErrorMsg( |
| + script_, ident_pos, "Error", |
| + "ambiguous reference: '%s.%s' is imported multiple times", |
| + String::Handle(prefix.name()).ToCString(), |
| + name.ToCString()); |
| } else { |
| - ErrorMsg(ident_pos, |
| - "ambiguous reference: '%s.%s' is defined in '%s' and '%s'", |
| - String::Handle(prefix.name()).ToCString(), |
| - name.ToCString(), |
| - first_lib_url.ToCString(), |
| - String::Handle(lib.url()).ToCString()); |
| + ambiguous_ref_error = FormatErrorMsg( |
| + script_, ident_pos, "Error", |
| + "ambiguous reference: '%s.%s' is defined in '%s' and '%s'", |
| + String::Handle(prefix.name()).ToCString(), |
| + name.ToCString(), |
| + first_lib_url.ToCString(), |
| + String::Handle(lib.url()).ToCString()); |
| } |
| + if (error == NULL) { |
| + // Report a compile time error since the caller is not interested |
| + // in the error. |
| + ErrorMsg(ambiguous_ref_error); |
| + } |
| + *error = ambiguous_ref_error.raw(); |
| + return Object::null(); |
| } |
| } |
| } |
| @@ -8268,9 +8336,10 @@ |
| RawClass* Parser::ResolveClassInPrefixScope(intptr_t ident_pos, |
| const LibraryPrefix& prefix, |
| - const String& name) { |
| + const String& name, |
| + Error* error) { |
| const Object& obj = |
| - Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, name)); |
| + Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, name, error)); |
| if (obj.IsClass()) { |
| return Class::Cast(obj).raw(); |
| } |
| @@ -8287,7 +8356,7 @@ |
| const String& ident) { |
| TRACE_PARSER("ResolveIdentInPrefixScope"); |
| Object& obj = |
| - Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, ident)); |
| + Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, ident, NULL)); |
| if (obj.IsNull()) { |
| // Unresolved prefixed primary identifier. |
| ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved", |
| @@ -8886,10 +8955,13 @@ |
| // In case the type is malformed, throw a dynamic type error after finishing |
| // parsing the instance creation expression. |
| if (type.IsTypeParameter() || type.IsDynamicType()) { |
| + ASSERT(!type.IsMalformed()); |
| // Replace the type with a malformed type. |
| type = ClassFinalizer::NewFinalizedMalformedType( |
| + Error::Handle(), // No previous error. |
| current_class(), |
| type_pos, |
| + ClassFinalizer::kTryResolve, // No compile-time error. |
| "%s'%s' cannot be instantiated", |
| type.IsTypeParameter() ? "type parameter " : "", |
| type.IsTypeParameter() ? |
| @@ -8953,8 +9025,10 @@ |
| // Replace the type with a malformed type and compile a throw or report |
| // a compile-time error if the constructor is const. |
| type = ClassFinalizer::NewFinalizedMalformedType( |
| + Error::Handle(), // No previous error. |
| current_class(), |
| call_pos, |
| + ClassFinalizer::kTryResolve, // No compile-time error. |
| "interface '%s' has no constructor named '%s'", |
| type_class_name.ToCString(), |
| external_constructor_name.ToCString()); |
| @@ -9021,8 +9095,10 @@ |
| // Replace the type with a malformed type and compile a throw or report a |
| // compile-time error if the constructor is const. |
| type = ClassFinalizer::NewFinalizedMalformedType( |
| + Error::Handle(), // No previous error. |
| current_class(), |
| call_pos, |
| + ClassFinalizer::kTryResolve, // No compile-time error. |
| "class '%s' has no constructor or factory named '%s'", |
| String::Handle(constructor_class.Name()).ToCString(), |
| external_constructor_name.ToCString()); |