Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index 6cc8e5421676438b17b07fdde16c095f27fbaeca..58459e093fa6274058d5afb8eaef66fd1c99ede3 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -3573,7 +3573,7 @@ void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
(LookaheadToken(3) == Token::kPERIOD); |
const AbstractType& type = AbstractType::Handle(Z, |
ParseType(ClassFinalizer::kResolveTypeParameters, |
- false, // Deferred types not allowed. |
+ true, |
consume_unresolved_prefix)); |
if (!type.IsMalformed() && type.IsTypeParameter()) { |
// Replace the type with a malformed type and compile a throw when called. |
@@ -12019,13 +12019,16 @@ RawAbstractType* Parser::ParseType( |
// If deferred prefixes are allowed but it is not yet loaded, |
// remember that this function depends on the prefix. |
if (allow_deferred_type && !prefix.is_loaded()) { |
- ASSERT(parsed_function() != NULL); |
- parsed_function()->AddDeferredPrefix(prefix); |
+ if (parsed_function() != NULL) { |
+ parsed_function()->AddDeferredPrefix(prefix); |
+ } |
} |
- // If the deferred prefixes are not allowed, or if the prefix |
- // is not yet loaded, return a malformed type. Otherwise, handle |
- // resolution below, as needed. |
- if (!prefix.is_loaded() || !allow_deferred_type) { |
+ // If the deferred prefixes are not allowed, or if the prefix is not yet |
+ // loaded when finalization is requested, return a malformed type. |
+ // Otherwise, handle resolution below, as needed. |
+ if (!allow_deferred_type || |
+ (!prefix.is_loaded() |
+ && (finalization > ClassFinalizer::kResolveTypeParameters))) { |
ParseTypeArguments(ClassFinalizer::kIgnore); |
return ClassFinalizer::NewFinalizedMalformedType( |
Error::Handle(Z), // No previous error. |
@@ -12702,6 +12705,28 @@ AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
} |
} |
+ if (!redirect_type.HasResolvedTypeClass()) { |
+ // If the redirection type is unresolved, we convert the allocation |
+ // into throwing a type error. |
+ const UnresolvedClass& cls = |
+ UnresolvedClass::Handle(Z, redirect_type.unresolved_class()); |
+ const LibraryPrefix& prefix = |
+ LibraryPrefix::Handle(Z, cls.library_prefix()); |
+ if (!prefix.IsNull() && !prefix.is_loaded()) { |
+ // If the redirection type is unresolved because it refers to |
+ // an unloaded deferred prefix, mark this function as depending |
+ // on the library prefix. It will then get invalidated when the |
+ // prefix is loaded. |
+ parsed_function()->AddDeferredPrefix(prefix); |
+ } |
+ redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
+ Error::Handle(Z), |
+ script_, |
+ call_pos, |
+ "redirection type '%s' is not loaded", |
+ String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
+ } |
+ |
if (redirect_type.IsMalformedOrMalbounded()) { |
if (is_const) { |
ReportError(Error::Handle(Z, redirect_type.error())); |