Chromium Code Reviews| Index: runtime/vm/class_finalizer.cc |
| =================================================================== |
| --- runtime/vm/class_finalizer.cc (revision 30364) |
| +++ runtime/vm/class_finalizer.cc (working copy) |
| @@ -286,13 +286,9 @@ |
| } |
| if (factory.is_const()) { |
| type = factory.RedirectionType(); |
| - if (type.IsMalformed()) { |
| - ReportError(Error::Handle(type.malformed_error())); |
| + if (type.IsMalformed() || type.IsMalbounded()) { |
|
hausner
2013/11/18 22:19:44
Could you use IsMalformedOrMalbounded() here?
Or
regis
2013/11/18 23:24:39
Good point. I used the combined call, because it s
|
| + ReportError(Error::Handle(type.error())); |
| } |
| - Error& error = Error::Handle(); |
| - if (type.IsMalboundedWithError(&error)) { |
| - ReportError(error); |
| - } |
| } |
| } |
| } |
| @@ -814,7 +810,7 @@ |
| // Specifying no type arguments indicates a raw type, which is not an error. |
| // However, type parameter bounds are checked below, even for a raw type. |
| if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| - // Wrong number of type arguments. The type is malformed. |
| + // Wrong number of type arguments. The type is mapped to the raw type. |
| if (FLAG_error_on_bad_type) { |
| const Script& script = Script::Handle(cls.script()); |
| const String& type_class_name = String::Handle(type_class.Name()); |
| @@ -919,18 +915,17 @@ |
| FinalizeTypesInClass(type_class); |
| } |
| - // If a bound error occurred, return a BoundedType with a malformed bound. |
| - // The malformed bound will be ignored in production mode. |
| + // If a bound error occurred, mark the type as malbounded. |
| + // The bound error will be ignored in production mode. |
| if (!bound_error.IsNull()) { |
| // No compile-time error during finalization. |
| const String& parameterized_type_name = String::Handle( |
| parameterized_type.UserVisibleName()); |
| - const Type& malformed_bound = Type::Handle( |
| - NewFinalizedMalformedType(bound_error, |
| - Script::Handle(cls.script()), |
| - parameterized_type.token_pos(), |
| - "type '%s' has an out of bound type argument", |
| - parameterized_type_name.ToCString())); |
| + FinalizeMalboundedType(bound_error, |
| + Script::Handle(cls.script()), |
| + parameterized_type, |
| + "type '%s' has an out of bound type argument", |
| + parameterized_type_name.ToCString()); |
| if (FLAG_trace_type_finalization) { |
| OS::Print("Done finalizing malbounded type '%s' with bound error: %s\n", |
| @@ -938,9 +933,7 @@ |
| bound_error.ToCString()); |
| } |
| - return BoundedType::New(parameterized_type, |
| - malformed_bound, |
| - TypeParameter::Handle()); |
| + return parameterized_type.raw();; |
| } |
| if (FLAG_trace_type_finalization) { |
| @@ -1163,18 +1156,18 @@ |
| (field.value() != Object::sentinel().raw())) { |
| // The parser does not preset the value if the type is a type parameter or |
| // is parameterized unless the value is null. |
| - Error& malformed_error = Error::Handle(); |
| - if (type.IsMalformed()) { |
| - malformed_error = type.malformed_error(); |
| + Error& error = Error::Handle(); |
| + if (type.IsMalformedOrMalbounded()) { |
| + error = type.error(); |
| } else { |
| ASSERT(type.IsInstantiated()); |
| } |
| const Instance& const_value = Instance::Handle(field.value()); |
| - if (!malformed_error.IsNull() || |
| + if (!error.IsNull() || |
| (!type.IsDynamicType() && |
| !const_value.IsInstanceOf(type, |
| AbstractTypeArguments::Handle(), |
| - &malformed_error))) { |
| + &error))) { |
| if (FLAG_error_on_bad_type) { |
| const AbstractType& const_value_type = AbstractType::Handle( |
| const_value.GetType()); |
| @@ -1182,7 +1175,7 @@ |
| const_value_type.UserVisibleName()); |
| const String& type_name = String::Handle(type.UserVisibleName()); |
| const Script& script = Script::Handle(cls.script()); |
| - ReportError(malformed_error, script, field.token_pos(), |
| + ReportError(error, script, field.token_pos(), |
| "error initializing static %s field '%s': " |
| "type '%s' is not a subtype of type '%s'", |
| field.is_const() ? "const" : "final", |
| @@ -2410,8 +2403,8 @@ |
| // Resolve super type. Failures lead to a longjmp. |
| ResolveType(cls, super_type, kCanonicalizeWellFormed); |
| - if (super_type.IsMalformed()) { |
| - ReportError(Error::Handle(super_type.malformed_error())); |
| + if (super_type.IsMalformedOrMalbounded()) { |
| + ReportError(Error::Handle(super_type.error())); |
| } |
| if (super_type.IsDynamicType()) { |
| const Script& script = Script::Handle(cls.script()); |
| @@ -2488,8 +2481,9 @@ |
| interface ^= super_interfaces.At(i); |
| ResolveType(cls, interface, kCanonicalizeWellFormed); |
| ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
| + // A malbounded interface is only reported when involved in a type test. |
| if (interface.IsMalformed()) { |
| - ReportError(Error::Handle(interface.malformed_error())); |
| + ReportError(Error::Handle(interface.error())); |
| } |
| if (interface.IsDynamicType()) { |
| const Script& script = Script::Handle(cls.script()); |
| @@ -2622,7 +2616,7 @@ |
| if (FLAG_error_on_bad_type) { |
| ReportError(error); |
| } |
| - type.set_malformed_error(error); |
| + type.set_error(error); |
| // Make the type raw, since it may not be possible to |
| // properly finalize its type arguments. |
| type.set_type_class(Class::Handle(Object::dynamic_class())); |
| @@ -2669,6 +2663,29 @@ |
| } |
| +void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, |
| + const Script& script, |
| + const Type& type, |
| + const char* format, ...) { |
| + va_list args; |
| + va_start(args, format); |
| + LanguageError& error = LanguageError::Handle( |
| + LanguageError::NewFormattedV( |
| + prev_error, script, type.token_pos(), |
| + LanguageError::kMalboundedType, Heap::kOld, |
| + format, args)); |
| + va_end(args); |
| + if (FLAG_error_on_bad_type) { |
| + ReportError(error); |
| + } |
| + type.set_error(error); |
| + if (!type.IsFinalized()) { |
| + type.SetIsFinalized(); |
| + // Do not canonicalize malbounded types. |
| + } |
| +} |
| + |
| + |
| void ClassFinalizer::ReportError(const Error& error) { |
| Isolate::Current()->long_jump_base()->Jump(1, error); |
| UNREACHABLE(); |