Index: sdk/lib/_internal/compiler/implementation/closure.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart |
index 35b227e9862e3c9d690735ce189511ff116007de..29ba4f5b065b66b626a45d408f6d4bd9e3baeb26 100644 |
--- a/sdk/lib/_internal/compiler/implementation/closure.dart |
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart |
@@ -523,6 +523,12 @@ class ClosureTranslator extends Visitor { |
useLocal(newElement); |
cached.parametersWithSentinel[parameter] = newElement; |
} |
+ } else if (node.isOperator) { |
+ String operatorString = node.selector.asOperator().source.stringValue; |
+ if (operatorString == 'is' || operatorString == 'as') { |
karlklose
2013/06/20 07:32:55
Use predicates on the node?
Johnni Winther
2013/06/21 12:19:15
Done.
|
+ DartType type = elements.getType(node.arguments.head); |
+ analyzeType(type); |
+ } |
} |
node.visitChildren(this); |
} |
@@ -541,44 +547,29 @@ class ClosureTranslator extends Visitor { |
visitNewExpression(NewExpression node) { |
DartType type = elements.getType(node); |
+ analyzeType(type); |
+ node.visitChildren(this); |
+ } |
- bool hasTypeVariable(DartType type) { |
- if (type is TypeVariableType) { |
- return true; |
- } else if (type is InterfaceType) { |
- InterfaceType ifcType = type; |
- for (DartType argument in ifcType.typeArguments) { |
- if (hasTypeVariable(argument)) { |
- return true; |
- } |
- } |
- } |
- return false; |
- } |
- |
- void analyzeTypeVariables(DartType type) { |
- if (type is TypeVariableType) { |
- useLocal(type.element); |
- } else if (type is InterfaceType) { |
- InterfaceType ifcType = type; |
- for (DartType argument in ifcType.typeArguments) { |
- analyzeTypeVariables(argument); |
- } |
- } |
- } |
+ void analyzeTypeVariables(DartType type) { |
+ type.forEachTypeVariable((TypeVariableType typeVariable) { |
+ useLocal(typeVariable.element); |
+ }); |
+ } |
+ void analyzeType(DartType type) { |
+ if (type == null) return; |
if (outermostElement.isMember() && |
compiler.backend.needsRti(outermostElement.getEnclosingClass())) { |
- if (outermostElement.isConstructor() || outermostElement.isField()) { |
+ if (outermostElement.isConstructor() || |
+ outermostElement.isField()) { |
analyzeTypeVariables(type); |
} else if (outermostElement.isInstanceMember()) { |
- if (hasTypeVariable(type)) { |
+ if (type.containsTypeVariables) { |
registerNeedsThis(); |
} |
} |
} |
- |
- node.visitChildren(this); |
} |
// If variables that are declared in the [node] scope are captured and need |
@@ -751,6 +742,12 @@ class ClosureTranslator extends Visitor { |
if (element.computeType(compiler).containsTypeVariables) { |
registerNeedsThis(); |
} |
+ // Ensure that closure that need runtime type information has access to |
+ // this of the enclosing class. |
+ if (closureData.thisElement != null && |
+ compiler.backend.methodNeedsRti(element)) { |
+ registerNeedsThis(); |
+ } |
visitChildren(); |
}); |