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

Unified Diff: runtime/vm/class_finalizer.cc

Issue 21049012: Update VM to handle malformed types according to revised spec (issues 9055, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/class_finalizer.cc
===================================================================
--- runtime/vm/class_finalizer.cc (revision 25651)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -347,7 +347,6 @@
Error::Handle(), // No previous error.
cls,
factory.token_pos(),
- kResolveTypeParameters, // No compile-time error.
"factory may not redirect to 'dynamic'");
factory.SetRedirectionType(type);
ASSERT(factory.RedirectionTarget() == Function::null());
@@ -375,7 +374,6 @@
Error::Handle(), // No previous error.
cls,
factory.token_pos(),
- kResolveTypeParameters, // No compile-time error.
"class '%s' has no constructor or factory named '%s'",
target_class_name.ToCString(),
user_visible_target_name.ToCString());
@@ -390,7 +388,6 @@
Error::Handle(), // No previous error.
cls,
factory.token_pos(),
- kResolveTypeParameters, // No compile-time error.
"constructor '%s' has incompatible parameters with "
"redirecting factory '%s'",
String::Handle(target.name()).ToCString(),
@@ -437,8 +434,7 @@
if (malformed_error.IsNull()) {
target_type ^= FinalizeType(cls, target_type, kCanonicalize);
} else {
- FinalizeMalformedType(malformed_error,
- cls, target_type, kFinalize,
+ FinalizeMalformedType(malformed_error, cls, target_type,
"cannot resolve redirecting factory");
target_target = Function::null();
}
@@ -453,9 +449,6 @@
const AbstractType& type,
FinalizationKind finalization) {
if (type.IsResolved() || type.IsFinalized()) {
- if ((finalization == kCanonicalizeWellFormed) && type.IsMalformed()) {
- ReportError(Error::Handle(type.malformed_error()));
- }
return;
}
if (FLAG_trace_type_finalization) {
@@ -479,17 +472,27 @@
// Replace unresolved class with resolved type class.
const Type& parameterized_type = Type::Cast(type);
- if (!type_class.IsNull()) {
- parameterized_type.set_type_class(type_class);
- } else {
- // The type class could not be resolved. The type is malformed.
- FinalizeMalformedType(ambiguous_error, // May be null.
- cls, parameterized_type, finalization,
- "cannot resolve class name '%s' from '%s'",
- String::Handle(unresolved_class.Name()).ToCString(),
- String::Handle(cls.Name()).ToCString());
+ if (type_class.IsNull()) {
+ if ((finalization == kCanonicalizeWellFormed) ||
+ FLAG_error_on_malformed_type) {
+ // The type class could not be resolved. The type is malformed.
+ FinalizeMalformedType(
+ ambiguous_error, // May be null.
+ cls,
+ parameterized_type,
+ "cannot resolve class '%s' from '%s'",
+ String::Handle(unresolved_class.Name()).ToCString(),
+ String::Handle(cls.Name()).ToCString());
+ } else {
+ // Map the malformed type to dynamic and ignore type arguments.
+ parameterized_type.set_type_class(Class::Handle(
+ Object::dynamic_class()));
+ parameterized_type.set_arguments(
+ Object::null_abstract_type_arguments());
+ }
return;
}
+ parameterized_type.set_type_class(type_class);
}
// Resolve type arguments, if any.
@@ -708,14 +711,8 @@
if (type.IsFinalized()) {
// Ensure type is canonical if canonicalization is requested, unless type is
// malformed.
- if (finalization >= kCanonicalize) {
- if (type.IsMalformed()) {
- if (finalization == kCanonicalizeWellFormed) {
- ReportError(Error::Handle(type.malformed_error()));
- }
- } else {
- return type.Canonicalize();
- }
+ if ((finalization >= kCanonicalize) && !type.IsMalformed()) {
+ return type.Canonicalize();
}
return type.raw();
}
@@ -749,15 +746,8 @@
// At this point, we can only have a parameterized_type.
const Type& parameterized_type = Type::Cast(type);
- if (parameterized_type.IsBeingFinalized()) {
- // Self reference detected. The type is malformed.
- FinalizeMalformedType(
- Error::Handle(), // No previous error.
- cls, parameterized_type, finalization,
- "type '%s' illegally refers to itself",
- String::Handle(parameterized_type.UserVisibleName()).ToCString());
- return parameterized_type.raw();
- }
+ // Types illegally referring to themselves should have been detected earlier.
+ ASSERT(!parameterized_type.IsBeingFinalized());
// Mark type as being finalized in order to detect illegal self reference.
parameterized_type.set_is_being_finalized();
@@ -784,19 +774,8 @@
type_argument = arguments.TypeAt(i);
type_argument = FinalizeType(cls, type_argument, finalization);
if (type_argument.IsMalformed()) {
- // In production mode, malformed type arguments are mapped to dynamic.
- // In checked mode, a type with malformed type arguments is malformed.
- if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) {
- const Error& error = Error::Handle(type_argument.malformed_error());
- const String& type_name =
- String::Handle(parameterized_type.UserVisibleName());
- FinalizeMalformedType(error, cls, parameterized_type, finalization,
- "type '%s' has malformed type argument",
- type_name.ToCString());
- return parameterized_type.raw();
- } else {
- type_argument = Type::DynamicType();
- }
+ // Malformed type arguments are mapped to dynamic.
+ type_argument = Type::DynamicType();
}
arguments.SetTypeAt(i, type_argument);
}
@@ -813,20 +792,17 @@
// 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.
- if (finalization >= kCanonicalizeExpression) {
+ if (FLAG_error_on_malformed_type) {
const Script& script = Script::Handle(cls.script());
- const String& type_name =
- String::Handle(parameterized_type.UserVisibleName());
+ const String& type_class_name = String::Handle(type_class.Name());
ReportError(script, parameterized_type.token_pos(),
- "wrong number of type arguments in type '%s'",
- type_name.ToCString());
+ "wrong number of type arguments for class '%s'",
+ type_class_name.ToCString());
}
- FinalizeMalformedType(
- Error::Handle(), // No previous error.
- cls, parameterized_type, finalization,
- "wrong number of type arguments in type '%s'",
- String::Handle(parameterized_type.UserVisibleName()).ToCString());
- return parameterized_type.raw();
+ // Make the type raw and continue without reporting any error.
+ // A static warning should have been reported.
+ arguments = AbstractTypeArguments::null();
+ parameterized_type.set_arguments(arguments);
}
// The full type argument vector consists of the type arguments of the
// super types of type_class, which may be initialized from the parsed
@@ -908,17 +884,12 @@
// The malformed bound will be ignored in production mode.
if (!bound_error.IsNull()) {
// No compile-time error during finalization.
- FinalizationKind bound_finalization = kResolveTypeParameters;
- if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) {
- bound_finalization = finalization;
- }
const String& parameterized_type_name = String::Handle(
parameterized_type.UserVisibleName());
const Type& malformed_bound = Type::Handle(
NewFinalizedMalformedType(bound_error,
cls,
parameterized_type.token_pos(),
- bound_finalization,
"type '%s' has an out of bound type argument",
parameterized_type_name.ToCString()));
return BoundedType::New(parameterized_type,
@@ -942,10 +913,8 @@
// interface.
ResolveType(cls, type, kCanonicalize);
type = FinalizeType(cls, type, kCanonicalize);
- // In production mode, a malformed result type is mapped to dynamic.
- if (!FLAG_enable_type_checks && type.IsMalformed()) {
- type = Type::DynamicType();
- }
+ // A malformed result type is mapped to dynamic.
+ ASSERT(!type.IsMalformed());
function.set_result_type(type);
// Resolve formal parameter types.
const intptr_t num_parameters = function.NumParameters();
@@ -953,10 +922,8 @@
type = function.ParameterTypeAt(i);
ResolveType(cls, type, kCanonicalize);
type = FinalizeType(cls, type, kCanonicalize);
- // In production mode, a malformed parameter type is mapped to dynamic.
- if (!FLAG_enable_type_checks && type.IsMalformed()) {
- type = Type::DynamicType();
- }
+ // A malformed parameter type is mapped to dynamic.
+ ASSERT(!type.IsMalformed());
function.SetParameterTypeAt(i, type);
}
}
@@ -1875,6 +1842,9 @@
// 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.IsDynamicType()) {
const Script& script = Script::Handle(cls.script());
ReportError(script, cls.token_pos(),
@@ -1940,6 +1910,9 @@
interface ^= super_interfaces.At(i);
ResolveType(cls, interface, kCanonicalizeWellFormed);
ASSERT(!interface.IsTypeParameter()); // Should be detected by parser.
+ if (interface.IsMalformed()) {
+ ReportError(Error::Handle(interface.malformed_error()));
+ }
if (interface.IsDynamicType()) {
const Script& script = Script::Handle(cls.script());
ReportError(script, cls.token_pos(),
@@ -2051,35 +2024,24 @@
void ClassFinalizer::ReportMalformedType(const Error& prev_error,
const Class& cls,
const Type& type,
- FinalizationKind finalization,
const char* format,
va_list args) {
LanguageError& error = LanguageError::Handle();
- if (FLAG_enable_type_checks ||
- !type.HasResolvedTypeClass() ||
- (finalization == kCanonicalizeWellFormed) ||
- FLAG_error_on_malformed_type) {
- const Script& script = Script::Handle(cls.script());
- if (prev_error.IsNull()) {
- error ^= Parser::FormatError(
- script, type.token_pos(), "Error", format, args);
- } else {
- error ^= Parser::FormatErrorWithAppend(
- prev_error, script, type.token_pos(), "Error", format, args);
- }
- if ((finalization == kCanonicalizeWellFormed) ||
- FLAG_error_on_malformed_type) {
- ReportError(error);
- }
+ const Script& script = Script::Handle(cls.script());
+ if (prev_error.IsNull()) {
+ error ^= Parser::FormatError(
+ script, type.token_pos(), "Error", format, args);
+ } else {
+ error ^= Parser::FormatErrorWithAppend(
+ prev_error, script, type.token_pos(), "Error", format, args);
}
- // In checked mode, always mark the type as malformed.
- // In production mode, mark the type as malformed only if its type class is
- // not resolved.
- // In both mode, make the type raw, since it may not be possible to
- // properly finalize its type arguments.
- if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) {
- type.set_malformed_error(error);
+ if (FLAG_error_on_malformed_type) {
+ ReportError(error);
}
+ type.set_malformed_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()));
type.set_arguments(Object::null_abstract_type_arguments());
if (!type.IsFinalized()) {
type.SetIsFinalized();
@@ -2092,12 +2054,10 @@
}
-RawType* ClassFinalizer::NewFinalizedMalformedType(
- const Error& prev_error,
- const Class& cls,
- intptr_t type_pos,
- FinalizationKind finalization,
- const char* format, ...) {
+RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error,
+ const Class& cls,
+ intptr_t type_pos,
+ const char* format, ...) {
va_list args;
va_start(args, format);
const UnresolvedClass& unresolved_class = UnresolvedClass::Handle(
@@ -2106,7 +2066,7 @@
type_pos));
const Type& type = Type::Handle(
Type::New(unresolved_class, TypeArguments::Handle(), type_pos));
- ReportMalformedType(prev_error, cls, type, finalization, format, args);
+ ReportMalformedType(prev_error, cls, type, format, args);
va_end(args);
ASSERT(type.IsMalformed());
ASSERT(type.IsFinalized());
@@ -2117,11 +2077,10 @@
void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
const Class& cls,
const Type& type,
- FinalizationKind finalization,
const char* format, ...) {
va_list args;
va_start(args, format);
- ReportMalformedType(prev_error, cls, type, finalization, format, args);
+ ReportMalformedType(prev_error, cls, type, format, args);
va_end(args);
}
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698