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

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

Issue 11416144: Produce run-time error when type parameters are accessed from static context. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Throw malformed type exception in checked mode only. Code cleanup changes. Created 8 years, 1 month 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 8f937bceea68cd9effa21784bab6986581875dc8..6986f6ceb6560b00ee2e755d47f6fd299a9924e0 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -1038,6 +1038,18 @@ class TypeResolver {
TypeResolver(this.compiler);
+ bool anyMalformedTypesInThere(Link<DartType> list) {
+ for (Link<DartType> link = list;
+ !link.isEmpty;
+ link = link.tail) {
+ DartType dtype = link.head;
+ if (dtype is MalformedType) {
+ return true;
+ }
+ }
+ return false;
+ }
+
Element resolveTypeName(Scope scope, TypeAnnotation node) {
Identifier typeName = node.typeName.asIdentifier();
Send send = node.typeName.asSend();
@@ -1081,6 +1093,7 @@ class TypeResolver {
DartType resolveTypeAnnotation(
TypeAnnotation node,
Scope scope,
+ bool inStaticContext,
{onFailure(Node node, MessageKind kind, [List arguments]),
whenResolved(Node node, DartType type)}) {
if (onFailure == null) {
@@ -1092,11 +1105,12 @@ class TypeResolver {
if (scope == null) {
compiler.internalError('resolveTypeAnnotation: no scope specified');
}
- return resolveTypeAnnotationInContext(scope, node, onFailure,
- whenResolved);
+ return resolveTypeAnnotationInContext(scope, node, inStaticContext,
+ onFailure, whenResolved);
}
DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node,
+ bool inStaticContext,
onFailure, whenResolved) {
Element element = resolveTypeName(scope, node);
DartType type;
@@ -1115,13 +1129,21 @@ class TypeResolver {
ClassElement cls = element;
cls.ensureResolved(compiler);
Link<DartType> arguments =
- resolveTypeArguments(node, cls.typeVariables, scope,
+ resolveTypeArguments(node, cls.typeVariables,
+ inStaticContext, scope,
onFailure, whenResolved);
if (cls.typeVariables.isEmpty && arguments.isEmpty) {
// Use the canonical type if it has no type parameters.
type = cls.computeType(compiler);
} else {
- type = new InterfaceType(cls.declaration, arguments);
+ // In checked mode malformed-ness of the type argument bubbles up.
+ if (anyMalformedTypesInThere(arguments) &&
+ compiler.enableTypeAssertions) {
+ type = new MalformedType(
+ new MalformedTypeElement(node, element));
+ } else {
+ type = new InterfaceType(cls.declaration, arguments);
+ }
}
} else if (element.isTypedef()) {
TypedefElement typdef = element;
@@ -1129,7 +1151,7 @@ class TypeResolver {
compiler.resolveTypedef(typdef);
typdef.computeType(compiler);
Link<DartType> arguments = resolveTypeArguments(
- node, typdef.typeVariables,
+ node, typdef.typeVariables, inStaticContext,
scope, onFailure, whenResolved);
if (typdef.typeVariables.isEmpty && arguments.isEmpty) {
// Return the canonical type if it has no type parameters.
@@ -1138,7 +1160,14 @@ class TypeResolver {
type = new TypedefType(typdef, arguments);
}
} else if (element.isTypeVariable()) {
- type = element.computeType(compiler);
+ if (inStaticContext) {
+ compiler.reportWarning(node,
+ MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
+ [element]));
+ type = new MalformedType(new MalformedTypeElement(node, element));
+ } else {
+ type = element.computeType(compiler);
+ }
} else {
compiler.cancel("unexpected element kind ${element.kind}",
node: node);
@@ -1150,6 +1179,7 @@ class TypeResolver {
Link<DartType> resolveTypeArguments(TypeAnnotation node,
Link<DartType> typeVariables,
+ bool inStaticContext,
Scope scope, onFailure, whenResolved) {
if (node.typeArguments == null) {
return const Link<DartType>();
@@ -1163,8 +1193,13 @@ class TypeResolver {
}
DartType argType = resolveTypeAnnotationInContext(scope,
typeArguments.head,
+ inStaticContext,
onFailure,
whenResolved);
+ // In production mode malformed type argument is replaced with dynamic.
+ if (argType is MalformedType && !compiler.enableTypeAssertions) {
+ argType = compiler.types.dynamicType;
ahe 2012/11/23 06:16:13 I would rather do this check in the backend. Here
aam-me 2012/11/23 14:02:28 Okay, understand. Started looking for a good place
+ }
arguments.addLast(argType);
if (!typeVariables.isEmpty) {
typeVariables = typeVariables.tail;
@@ -2057,21 +2092,10 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
}
DartType resolveTypeAnnotation(TypeAnnotation node) {
- // TODO(johnniwinther): Remove this together with the named arguments
- // on [TypeResolver.resolveTypeAnnotation].
- void checkAndUseType(TypeAnnotation annotation, DartType type) {
- useType(annotation, type);
- if (type != null &&
- identical(type.kind, TypeKind.TYPE_VARIABLE) &&
- enclosingElement.isInStaticMember()) {
- warning(annotation, MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
- [type]);
- }
- }
-
Function report = typeRequired ? error : warning;
DartType type = typeResolver.resolveTypeAnnotation(
- node, scope, onFailure: report, whenResolved: checkAndUseType);
+ node, scope, enclosingElement.isInStaticMember(),
+ onFailure: report, whenResolved: useType);
if (type == null) return null;
if (inCheckContext) {
compiler.enqueuer.resolution.registerIsCheck(type);
@@ -2438,7 +2462,8 @@ class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> {
TypeVariableElement variableElement = typeVariable.element;
if (typeNode.bound != null) {
DartType boundType = typeResolver.resolveTypeAnnotation(
- typeNode.bound, scope, onFailure: warning);
+ typeNode.bound, scope, element.isInStaticMember(),
+ onFailure: warning);
if (boundType != null && boundType.element == variableElement) {
// TODO(johnniwinther): Check for more general cycles, like
// [: <A extends B, B extends C, C extends B> :].

Powered by Google App Engine
This is Rietveld 408576698