Chromium Code Reviews| 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(); |
| }); |