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 dbfd5b8c6bdec51f25fbbf8d339420c8504a9780..2ab87f67a7b77e0db093241be2d359ac5436352a 100644 |
--- a/sdk/lib/_internal/compiler/implementation/closure.dart |
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart |
@@ -432,6 +432,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/03/22 13:17:46
I would really like to encapsulate this pattern. I
Johnni Winther
2013/06/12 14:39:10
I looked. They are all slightly different.
|
+ DartType type = elements.getType(node.arguments.head); |
+ analyzeType(type); |
+ } |
} |
node.visitChildren(this); |
} |
@@ -446,42 +452,34 @@ 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) { |
+ if (type is TypeVariableType) { |
+ useLocal(type.element); |
+ } else if (type is InterfaceType) { |
+ InterfaceType ifcType = type; |
+ for (DartType argument in ifcType.typeArguments) { |
+ analyzeTypeVariables(argument); |
} |
} |
+ } |
+ void analyzeType(DartType type) { |
+ if (type == null) return; |
karlklose
2013/03/22 13:17:46
How can this happen?
Johnni Winther
2013/06/21 12:19:14
Bad handling of is!
Now fixed.
|
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)) useLocal(closureData.thisElement); |
+ if (type.containsTypeVariables) { |
+ useLocal(closureData.thisElement); |
+ } |
} |
} |
- |
- node.visitChildren(this); |
} |
// If variables that are declared in the [node] scope are captured and need |
@@ -646,6 +644,13 @@ class ClosureTranslator extends Visitor { |
}); |
} |
+ // Ensure that closure that need runtime type information has access to |
+ // this of the enclosing class. |
+ if (closureData.thisElement != null && |
+ compiler.backend.methodNeedsRti(element)) { |
+ useLocal(closureData.thisElement); |
+ } |
+ |
visitChildren(); |
}); |