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

Unified Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 19097003: Support new malformed types semantics. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix unittests. 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
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 8660177a3db7d47096d23591c33435a573c18673..cea260dac883e35ab42b2a75dc43a0386350761a 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -1427,22 +1427,9 @@ class TypeResolver {
}
}
- // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean
- // flags instead of closures.
- DartType resolveTypeAnnotation(
- MappingVisitor visitor,
- TypeAnnotation node,
- {onFailure(Node node, DualKind kind, [Map arguments])}) {
- if (onFailure == null) {
- onFailure = (n, k, [arguments]) {};
- }
- return resolveTypeAnnotationInContext(visitor, node, onFailure);
- }
-
- DartType resolveTypeAnnotationInContext(
- MappingVisitor visitor,
- TypeAnnotation node,
- onFailure(Node node, DualKind kind, [Map arguments])) {
+ DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
+ {bool malformedIsError: false,
+ bool ambiguousIsError: false}) {
Identifier typeName;
SourceString prefixName;
Send send = node.typeName.asSend();
@@ -1458,24 +1445,31 @@ class TypeResolver {
DartType type;
DartType reportFailureAndCreateType(DualKind messageKind,
- Map messageArguments) {
- onFailure(node, messageKind, messageArguments);
+ Map messageArguments,
+ {DartType userProvidedBadType,
+ bool isError: false,
+ bool isAmbiguous: false}) {
+ if (isError) {
+ visitor.error(node, messageKind.error, messageArguments);
+ } else {
+ visitor.warning(node, messageKind.warning, messageArguments);
+ }
var erroneousElement = new ErroneousElementX(
messageKind.error, messageArguments, typeName.source,
visitor.enclosingElement);
var arguments = new LinkBuilder<DartType>();
- resolveTypeArguments(
- visitor, node, null,
- onFailure, arguments);
- return new MalformedType(erroneousElement, null, arguments.toLink());
+ resolveTypeArguments(visitor, node, null, arguments);
+ return isAmbiguous
+ ? new AmbiguousType(erroneousElement, arguments.toLink())
+ : new MalformedType(erroneousElement,
+ userProvidedBadType, arguments.toLink());
}
DartType checkNoTypeArguments(DartType type) {
var arguments = new LinkBuilder<DartType>();
- bool hashTypeArgumentMismatch = resolveTypeArguments(
- visitor, node, const Link<DartType>(),
- onFailure, arguments);
- if (hashTypeArgumentMismatch) {
+ bool hasTypeArgumentMismatch = resolveTypeArguments(
+ visitor, node, const Link<DartType>(), arguments);
+ if (hasTypeArgumentMismatch) {
type = new MalformedType(
new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
{'type': node}, typeName.source, visitor.enclosingElement),
@@ -1486,33 +1480,33 @@ class TypeResolver {
if (element == null) {
type = reportFailureAndCreateType(
- MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
+ MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName},
+ isError: malformedIsError);
} else if (element.isAmbiguous()) {
AmbiguousElement ambiguous = element;
type = reportFailureAndCreateType(
- ambiguous.messageKind, ambiguous.messageArguments);
+ ambiguous.messageKind, ambiguous.messageArguments,
+ isError: ambiguousIsError, isAmbiguous: true);
ambiguous.diagnose(visitor.mapping.currentElement, compiler);
} else if (!element.impliesType()) {
type = reportFailureAndCreateType(
- MessageKind.NOT_A_TYPE, {'node': node.typeName});
+ MessageKind.NOT_A_TYPE, {'node': node.typeName},
+ isError: malformedIsError);
} else {
if (identical(element, compiler.types.voidType.element) ||
- identical(element, compiler.types.dynamicType.element)) {
+ identical(element, compiler.dynamicClass)) {
type = checkNoTypeArguments(element.computeType(compiler));
} else if (element.isClass()) {
ClassElement cls = element;
compiler.resolver._ensureClassWillBeResolved(cls);
element.computeType(compiler);
var arguments = new LinkBuilder<DartType>();
- bool hashTypeArgumentMismatch = resolveTypeArguments(
- visitor, node, cls.typeVariables,
- onFailure, arguments);
- if (hashTypeArgumentMismatch) {
- type = new MalformedType(
- new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
- {'type': node}, typeName.source, visitor.enclosingElement),
- new InterfaceType.userProvidedBadType(cls.declaration,
- arguments.toLink()));
+ bool hasTypeArgumentMismatch = resolveTypeArguments(
+ visitor, node, cls.typeVariables, arguments);
+ if (hasTypeArgumentMismatch) {
+ type = new BadInterfaceType(cls.declaration,
+ new InterfaceType.forUserProvidedBadType(cls.declaration,
+ arguments.toLink()));
} else {
if (arguments.isEmpty) {
type = cls.rawType;
@@ -1525,14 +1519,12 @@ class TypeResolver {
// TODO(ahe): Should be [ensureResolved].
compiler.resolveTypedef(typdef);
var arguments = new LinkBuilder<DartType>();
- bool hashTypeArgumentMismatch = resolveTypeArguments(
- visitor, node, typdef.typeVariables,
- onFailure, arguments);
- if (hashTypeArgumentMismatch) {
- type = new MalformedType(
- new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
- {'type': node}, typeName.source, visitor.enclosingElement),
- new TypedefType.userProvidedBadType(typdef, arguments.toLink()));
+ bool hasTypeArgumentMismatch = resolveTypeArguments(
+ visitor, node, typdef.typeVariables, arguments);
+ if (hasTypeArgumentMismatch) {
+ type = new BadTypedefType(typdef,
+ new TypedefType.forUserProvidedBadType(typdef,
+ arguments.toLink()));
} else {
if (arguments.isEmpty) {
type = typdef.rawType;
@@ -1550,16 +1542,11 @@ class TypeResolver {
!isInFactoryConstructor &&
Elements.isInStaticContext(visitor.enclosingElement)) {
compiler.backend.registerThrowRuntimeError(visitor.mapping);
- compiler.reportWarningCode(
- node,
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.warning,
- {'typeVariableName': node});
- type = new MalformedType(
- new ErroneousElementX(
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.error,
- {'typeVariableName': node},
- typeName.source, visitor.enclosingElement),
- element.computeType(compiler));
+ type = reportFailureAndCreateType(
+ MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
+ {'typeVariableName': node},
+ userProvidedBadType: element.computeType(compiler),
+ isError: malformedIsError);
} else {
type = element.computeType(compiler);
}
@@ -1583,8 +1570,8 @@ class TypeResolver {
MappingVisitor visitor,
TypeAnnotation node,
Link<DartType> typeVariables,
- onFailure(Node node, DualKind kind, [Map arguments]),
- LinkBuilder<DartType> arguments) {
+ LinkBuilder<DartType> arguments,
+ {bool ambiguousIsError: false}) {
if (node.typeArguments == null) {
return false;
}
@@ -1593,19 +1580,20 @@ class TypeResolver {
!typeArguments.isEmpty;
typeArguments = typeArguments.tail) {
if (typeVariables != null && typeVariables.isEmpty) {
- onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
+ visitor.warning(
+ typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
typeArgumentCountMismatch = true;
}
- DartType argType = resolveTypeAnnotationInContext(visitor,
- typeArguments.head,
- onFailure);
+ DartType argType = resolveTypeAnnotation(visitor, typeArguments.head,
+ ambiguousIsError: ambiguousIsError);
arguments.addLast(argType);
if (typeVariables != null && !typeVariables.isEmpty) {
typeVariables = typeVariables.tail;
}
}
if (typeVariables != null && !typeVariables.isEmpty) {
- onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
+ visitor.warning(node.typeArguments,
+ MessageKind.MISSING_TYPE_ARGUMENT.warning);
typeArgumentCountMismatch = true;
}
return typeArgumentCountMismatch;
@@ -1661,7 +1649,6 @@ class ResolverVisitor extends MappingVisitor<Element> {
Scope scope;
ClassElement currentClass;
ExpressionStatement currentExpressionStatement;
- bool typeRequired = false;
bool sendIsMemberAccess = false;
StatementScope statementScope;
int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
@@ -2280,13 +2267,13 @@ class ResolverVisitor extends MappingVisitor<Element> {
String operatorString = node.selector.asOperator().source.stringValue;
if (operatorString == 'is') {
DartType type =
- resolveTypeRequired(node.typeAnnotationFromIsCheckOrCast);
+ resolveTypeExpression(node.typeAnnotationFromIsCheckOrCast);
if (type != null) {
compiler.enqueuer.resolution.registerIsCheck(type, mapping);
}
resolvedArguments = true;
} else if (operatorString == 'as') {
- DartType type = resolveTypeRequired(node.arguments.head);
+ DartType type = resolveTypeExpression(node.arguments.head);
if (type != null) {
compiler.enqueuer.resolution.registerAsCheck(type, mapping);
}
@@ -2698,23 +2685,17 @@ class ResolverVisitor extends MappingVisitor<Element> {
return node.accept(new ConstructorResolver(compiler, this));
}
- DartType resolveTypeRequired(TypeAnnotation node) {
- bool old = typeRequired;
- typeRequired = true;
- DartType result = resolveTypeAnnotation(node);
- typeRequired = old;
- return result;
+ DartType resolveTypeExpression(TypeAnnotation node) {
+ return resolveTypeAnnotation(node, isTypeExpression: true);
}
- DartType resolveTypeAnnotation(TypeAnnotation node) {
- Function report = typeRequired ? dualError : dualWarning;
+ DartType resolveTypeAnnotation(TypeAnnotation node,
+ {bool isTypeExpression: false}) {
DartType type = typeResolver.resolveTypeAnnotation(
- this, node, onFailure: report);
+ this, node, ambiguousIsError: isTypeExpression);
if (type == null) return null;
if (inCheckContext) {
compiler.enqueuer.resolution.registerIsCheck(type, mapping);
- }
- if (typeRequired || inCheckContext) {
compiler.backend.registerRequiredType(type, enclosingElement);
}
return type;
@@ -2731,12 +2712,13 @@ class ResolverVisitor extends MappingVisitor<Element> {
if (arguments != null) {
Link<Node> nodes = arguments.nodes;
if (nodes.isEmpty) {
+ // The syntax [: <>[] :] is not allowed.
error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error);
} else {
- typeArgument = resolveTypeRequired(nodes.head);
+ typeArgument = resolveTypeExpression(nodes.head);
for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
- error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.error);
- resolveTypeRequired(nodes.head);
+ warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
+ resolveTypeAnnotation(nodes.head);
}
}
}
@@ -2754,6 +2736,7 @@ class ResolverVisitor extends MappingVisitor<Element> {
}
mapping.setType(node, listType);
world.registerInstantiatedType(listType, mapping);
+ compiler.backend.registerRequiredType(listType, enclosingElement);
visit(node.elements);
}
@@ -2935,17 +2918,18 @@ class ResolverVisitor extends MappingVisitor<Element> {
if (arguments != null) {
Link<Node> nodes = arguments.nodes;
if (nodes.isEmpty) {
+ // The syntax [: <>{} :] is not allowed.
error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error);
} else {
- keyTypeArgument = resolveTypeRequired(nodes.head);
+ keyTypeArgument = resolveTypeExpression(nodes.head);
nodes = nodes.tail;
if (nodes.isEmpty) {
- error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error);
+ warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT.warning);
} else {
- valueTypeArgument = resolveTypeRequired(nodes.head);
+ valueTypeArgument = resolveTypeExpression(nodes.head);
for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
- error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.error);
- resolveTypeRequired(nodes.head);
+ warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
+ resolveTypeAnnotation(nodes.head);
}
}
}
@@ -2967,6 +2951,7 @@ class ResolverVisitor extends MappingVisitor<Element> {
if (node.isConst()) {
compiler.backend.registerConstantMap(mapping);
}
+ compiler.backend.registerRequiredType(mapType, enclosingElement);
node.visitChildren(this);
}
@@ -3112,10 +3097,7 @@ class ResolverVisitor extends MappingVisitor<Element> {
}
Scope blockScope = new BlockScope(scope);
- var wasTypeRequired = typeRequired;
- typeRequired = true;
doInCheckContext(() => visitIn(node.type, blockScope));
- typeRequired = wasTypeRequired;
visitIn(node.formals, blockScope);
var oldInCatchBlock = inCatchBlock;
inCatchBlock = true;
@@ -3173,7 +3155,7 @@ class TypeDefinitionVisitor extends MappingVisitor<DartType> {
TypeVariableElement variableElement = typeVariable.element;
if (typeNode.bound != null) {
DartType boundType = typeResolver.resolveTypeAnnotation(
- this, typeNode.bound, onFailure: dualWarning);
+ this, typeNode.bound);
variableElement.bound = boundType;
void checkTypeVariableBound() {
@@ -3445,7 +3427,7 @@ class ClassResolverVisitor extends TypeDefinitionVisitor {
DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
DartType supertype = typeResolver.resolveTypeAnnotation(
- this, superclass, onFailure: dualError);
+ this, superclass, malformedIsError: true);
if (supertype != null) {
if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) {
// Error has already been reported.
@@ -3467,7 +3449,7 @@ class ClassResolverVisitor extends TypeDefinitionVisitor {
if (interfaces == null) return result;
for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) {
DartType interfaceType = typeResolver.resolveTypeAnnotation(
- this, link.head, onFailure: dualError);
+ this, link.head, malformedIsError: true);
if (interfaceType != null) {
if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) {
// Error has already been reported.
@@ -3583,7 +3565,7 @@ class ClassResolverVisitor extends TypeDefinitionVisitor {
!identical(lib, compiler.coreLibrary) &&
!identical(lib, compiler.jsHelperLibrary) &&
!identical(lib, compiler.interceptorsLibrary) &&
- (identical(type.element, compiler.dynamicClass) ||
+ (identical(type, compiler.types.dynamicType) ||
identical(type.element, compiler.boolClass) ||
identical(type.element, compiler.numClass) ||
identical(type.element, compiler.intClass) ||
@@ -4027,7 +4009,7 @@ class ConstructorResolver extends CommonResolverVisitor<Element> {
}
if (type == null) {
if (Elements.isUnresolved(e)) {
- type = compiler.dynamicClass.computeType(compiler);
+ type = compiler.types.dynamicType;
} else {
type = e.getEnclosingClass().computeType(compiler).asRaw();
}
@@ -4038,7 +4020,8 @@ class ConstructorResolver extends CommonResolverVisitor<Element> {
visitTypeAnnotation(TypeAnnotation node) {
assert(invariant(node, type == null));
- type = resolver.resolveTypeRequired(node);
+ type = resolver.resolveTypeExpression(node);
+ compiler.backend.registerRequiredType(type, resolver.enclosingElement);
return resolver.mapping[node];
}

Powered by Google App Engine
This is Rietveld 408576698