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