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

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: 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 3868400ccd7c7b51a99919dccae9147776a184fb..27216e80eb79ea09b0e883472e4e915700d05688 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -1407,21 +1407,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, MessageKind kind, [Map arguments])}) {
- if (onFailure == null) {
- onFailure = (n, k, [arguments]) {};
- }
- return resolveTypeAnnotationInContext(visitor, node, onFailure);
- }
-
- DartType resolveTypeAnnotationInContext(MappingVisitor visitor,
- TypeAnnotation node,
- onFailure) {
+ DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
+ {bool malformedIsError: false,
+ bool ambiguousIsError: false}) {
Identifier typeName;
SourceString prefixName;
Send send = node.typeName.asSend();
@@ -1437,24 +1425,31 @@ class TypeResolver {
DartType type;
DartType reportFailureAndCreateType(MessageKind messageKind,
- Map messageArguments) {
- onFailure(node, messageKind, messageArguments);
+ Map messageArguments,
+ {DartType userProvidedBadType,
+ bool isError: false,
+ bool isAmbiguous: false}) {
+ if (isError) {
+ visitor.error(node, messageKind, messageArguments);
+ } else {
+ visitor.warning(node, messageKind, messageArguments);
+ }
var erroneousElement = new ErroneousElementX(
messageKind, 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),
@@ -1465,31 +1460,31 @@ 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),
+ bool hasTypeArgumentMismatch = resolveTypeArguments(
+ visitor, node, cls.typeVariables, arguments);
+ if (hasTypeArgumentMismatch) {
+ type = new BadInterfaceType(cls.declaration,
new InterfaceType.userProvidedBadType(cls.declaration,
arguments.toLink()));
} else {
@@ -1504,13 +1499,10 @@ 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),
+ bool hasTypeArgumentMismatch = resolveTypeArguments(
+ visitor, node, typdef.typeVariables, arguments);
+ if (hasTypeArgumentMismatch) {
+ type = new BadTypedefType(typdef,
new TypedefType.userProvidedBadType(typdef, arguments.toLink()));
} else {
if (arguments.isEmpty) {
@@ -1528,16 +1520,11 @@ class TypeResolver {
!outer.isTypedef() &&
!isInFactoryConstructor &&
Elements.isInStaticContext(visitor.enclosingElement)) {
- compiler.backend.registerThrowRuntimeError(visitor.mapping);
- compiler.reportWarning(node,
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
- {'typeVariableName': node}));
- type = new MalformedType(
- new ErroneousElementX(
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
- {'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);
}
@@ -1561,8 +1548,8 @@ class TypeResolver {
MappingVisitor visitor,
TypeAnnotation node,
Link<DartType> typeVariables,
- onFailure,
- LinkBuilder<DartType> arguments) {
+ LinkBuilder<DartType> arguments,
+ {bool ambiguousIsError: false}) {
if (node.typeArguments == null) {
return false;
}
@@ -1571,19 +1558,19 @@ 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);
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);
typeArgumentCountMismatch = true;
}
return typeArgumentCountMismatch;
@@ -1639,7 +1626,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
@@ -2258,13 +2244,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);
}
@@ -2674,23 +2660,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 ? error : warning;
+ 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;
@@ -2707,12 +2687,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);
} 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);
- resolveTypeRequired(nodes.head);
+ warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
+ resolveTypeAnnotation(nodes.head);
}
}
}
@@ -2730,6 +2711,7 @@ class ResolverVisitor extends MappingVisitor<Element> {
}
mapping.setType(node, listType);
world.registerInstantiatedType(listType, mapping);
+ compiler.backend.registerRequiredType(listType, enclosingElement);
visit(node.elements);
}
@@ -2911,17 +2893,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);
} else {
- keyTypeArgument = resolveTypeRequired(nodes.head);
+ keyTypeArgument = resolveTypeExpression(nodes.head);
nodes = nodes.tail;
if (nodes.isEmpty) {
- error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
+ warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
} 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);
- resolveTypeRequired(nodes.head);
+ warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
+ resolveTypeAnnotation(nodes.head);
}
}
}
@@ -2943,6 +2926,7 @@ class ResolverVisitor extends MappingVisitor<Element> {
if (node.isConst()) {
compiler.backend.registerConstantMap(mapping);
}
+ compiler.backend.registerRequiredType(mapType, enclosingElement);
node.visitChildren(this);
}
@@ -3083,10 +3067,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;
@@ -3144,7 +3125,7 @@ class TypeDefinitionVisitor extends MappingVisitor<DartType> {
TypeVariableElement variableElement = typeVariable.element;
if (typeNode.bound != null) {
DartType boundType = typeResolver.resolveTypeAnnotation(
- this, typeNode.bound, onFailure: warning);
+ this, typeNode.bound);
variableElement.bound = boundType;
void checkTypeVariableBound() {
@@ -3409,7 +3390,7 @@ class ClassResolverVisitor extends TypeDefinitionVisitor {
DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
DartType supertype = typeResolver.resolveTypeAnnotation(
- this, superclass, onFailure: error);
+ this, superclass, malformedIsError: true);
if (supertype != null) {
if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) {
// Error has already been reported.
@@ -3431,7 +3412,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: error);
+ this, link.head, malformedIsError: true);
if (interfaceType != null) {
if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) {
// Error has already been reported.
@@ -3513,7 +3494,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) ||
@@ -3955,7 +3936,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();
}
@@ -3966,7 +3947,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