Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| index 69e3b45b9d02d08514b558f3b894906b061ee331..04c589517109f5262ee33740b6b428f58ccdfeb5 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| @@ -1666,34 +1666,50 @@ class TypeResolver { |
| TypeResolver(this.compiler); |
| - Element resolveTypeName(Scope scope, |
| - Identifier prefixName, |
| - Identifier typeName) { |
| + /// Tries to resolve the type name as an element. |
| + Element resolveTypeName(Identifier prefixName, |
| + Identifier typeName, |
| + Scope scope, |
| + {bool deferredIsMalformed: true}) { |
| + Element element; |
| + bool deferredTypeAnnotation = false; |
| if (prefixName != null) { |
| - Element element = |
| + Element prefixElement = |
| lookupInScope(compiler, prefixName, scope, prefixName.source); |
| - if (element != null && element.isPrefix()) { |
| + if (prefixElement != null && prefixElement.isPrefix()) { |
| // The receiver is a prefix. Lookup in the imported members. |
| - PrefixElement prefix = element; |
| - return prefix.lookupLocalMember(typeName.source); |
| + PrefixElement prefix = prefixElement; |
| + element = prefix.lookupLocalMember(typeName.source); |
| + if (element != null && |
| + prefix.isDeferred && |
| + deferredIsMalformed && |
| + compiler.deferredLoadTask.splitProgram) { |
|
floitsch
2014/03/03 14:18:06
why the check for compiler.deferredLoadTast.splitP
sigurdm
2014/03/04 12:36:19
Added a comment explaining why.
|
| + element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION, |
| + {'node': typeName}, |
| + element.name, |
| + element); |
| + } |
| + } else { |
| + // The caller of this method will create the ErroneousElement for |
| + // the MalformedType. |
| + element = null; |
| } |
| - // The caller of this method will create the ErroneousElement for |
| - // the MalformedType. |
| - return null; |
| } else { |
| String stringValue = typeName.source; |
| if (identical(stringValue, 'void')) { |
| - return compiler.types.voidType.element; |
| + element = compiler.types.voidType.element; |
| } else if (identical(stringValue, 'dynamic')) { |
| - return compiler.dynamicClass; |
| + element = compiler.dynamicClass; |
| } else { |
| - return lookupInScope(compiler, typeName, scope, typeName.source); |
| + element = lookupInScope(compiler, typeName, scope, typeName.source); |
| } |
| } |
| + return element; |
|
floitsch
2014/03/03 14:18:06
nit: I preferred the individual returns. But keep
sigurdm
2014/03/04 12:36:19
Done.
|
| } |
| DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, |
| - {bool malformedIsError: false}) { |
| + {bool malformedIsError: false, |
| + bool deferredIsMalformed: true}) { |
| Identifier typeName; |
| Identifier prefixName; |
| Send send = node.typeName.asSend(); |
| @@ -1705,20 +1721,24 @@ class TypeResolver { |
| typeName = node.typeName.asIdentifier(); |
| } |
| - Element element = resolveTypeName(visitor.scope, prefixName, typeName); |
| + Element element = resolveTypeName(prefixName, typeName, visitor.scope, |
| + deferredIsMalformed: deferredIsMalformed); |
| DartType reportFailureAndCreateType(MessageKind messageKind, |
| Map messageArguments, |
| - {DartType userProvidedBadType}) { |
| + {DartType userProvidedBadType, |
| + Element erroneousElement}) { |
| if (malformedIsError) { |
| visitor.error(node, messageKind, messageArguments); |
| } else { |
| compiler.backend.registerThrowRuntimeError(visitor.mapping); |
| visitor.warning(node, messageKind, messageArguments); |
| } |
| - Element erroneousElement = new ErroneousElementX( |
| - messageKind, messageArguments, typeName.source, |
| - visitor.enclosingElement); |
| + if (erroneousElement == null) { |
| + erroneousElement = new ErroneousElementX( |
| + messageKind, messageArguments, typeName.source, |
| + visitor.enclosingElement); |
| + } |
| LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); |
| resolveTypeArguments(visitor, node, null, arguments); |
| return new MalformedType(erroneousElement, |
| @@ -1738,6 +1758,7 @@ class TypeResolver { |
| return type; |
| } |
| + // Now try to construct the type from the element. |
|
floitsch
2014/03/03 14:18:06
-Now-
sigurdm
2014/03/04 12:36:19
Done.
|
| DartType type; |
| if (element == null) { |
| type = reportFailureAndCreateType( |
| @@ -1750,6 +1771,11 @@ class TypeResolver { |
| } else if (!element.impliesType()) { |
| type = reportFailureAndCreateType( |
| MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| + } else if (element.isErroneous()) { |
| + ErroneousElement erroneousElement = element; |
| + type = reportFailureAndCreateType( |
| + erroneousElement.messageKind, erroneousElement.messageArguments, |
| + erroneousElement: erroneousElement); |
| } else { |
| bool addTypeVariableBoundsCheck = false; |
| if (identical(element, compiler.types.voidType.element) || |
| @@ -3160,9 +3186,11 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| } |
| DartType resolveTypeAnnotation(TypeAnnotation node, |
| - {bool malformedIsError: false}) { |
| + {bool malformedIsError: false, |
| + bool deferredIsMalformed: true}) { |
| DartType type = typeResolver.resolveTypeAnnotation( |
| - this, node, malformedIsError: malformedIsError); |
| + this, node, malformedIsError: malformedIsError, |
| + deferredIsMalformed: deferredIsMalformed); |
| if (type == null) return null; |
| if (inCheckContext) { |
| compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| @@ -4457,8 +4485,11 @@ class ConstructorResolver extends CommonResolverVisitor<Element> { |
| Element visitTypeAnnotation(TypeAnnotation node) { |
| assert(invariant(node, type == null)); |
| + // This is not really resolving a type-annotation, but the name of the |
| + // constructor. Therefore we allow deferred types. |
| type = resolver.resolveTypeAnnotation(node, |
| - malformedIsError: inConstContext); |
| + malformedIsError: inConstContext, |
| + deferredIsMalformed: false); |
| compiler.backend.registerRequiredType(type, resolver.enclosingElement); |
| return type.element; |
| } |