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 aa17a0079bdad5ed78f786bf586684ab1a367b41..f369e5adffb22cc8976740f7273fdc55ced16129 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/closure.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/closure.dart |
| @@ -375,11 +375,20 @@ class ClosureTranslator extends Visitor { |
| scopeVariables.add(element); |
| } |
| + void registerNeedsThis() { |
| + if (closureData.thisElement != null) { |
| + useLocal(closureData.thisElement); |
| + } |
| + } |
| + |
| visit(Node node) => node.accept(this); |
| visitNode(Node node) => node.visitChildren(this); |
| visitVariableDefinitions(VariableDefinitions node) { |
| + if (node.type != null) { |
| + visit(node.type); |
| + } |
| for (Link<Node> link = node.definitions.nodes; |
| !link.isEmpty; |
| link = link.tail) { |
| @@ -402,13 +411,28 @@ class ClosureTranslator extends Visitor { |
| } |
| } |
| + visitTypeAnnotation(TypeAnnotation node) { |
| + if (compiler.enableTypeAssertions && currentElement.isInstanceMember()) { |
| + DartType type = elements.getType(node); |
| + // In checked mode, using a type variable in a type annotation may lead |
| + // to a runtime type check that needs to access the type argument and |
| + // therefor the closure needs a this-element. |
|
ngeoffray
2013/04/15 10:59:14
therefore
karlklose
2013/05/02 15:04:54
Done.
|
| + // TODO(karlklose,johnniwinther): if the type is null, the annotation is |
| + // from a parameter; in checked mode, we need to resolve all types. |
|
ngeoffray
2013/04/15 10:59:14
I don't understand this TODO. How can it be null?
karlklose
2013/05/02 15:04:54
Maybe we do not store the result in the TreeElemen
|
| + if (type != null && type.containsTypeVariables) { |
| + registerNeedsThis(); |
| + } |
| + } |
| + node.visitChildren(this); |
| + } |
| + |
| visitIdentifier(Identifier node) { |
| if (node.isThis()) { |
| - useLocal(closureData.thisElement); |
| + registerNeedsThis(); |
| } else { |
| Element element = elements[node]; |
| if (element != null && element.kind == ElementKind.TYPE_VARIABLE) { |
| - useLocal(closureData.thisElement); |
| + registerNeedsThis(); |
| } |
| } |
| node.visitChildren(this); |
| @@ -420,9 +444,9 @@ class ClosureTranslator extends Visitor { |
| useLocal(element); |
| } else if (node.receiver == null && |
| Elements.isInstanceSend(node, elements)) { |
| - useLocal(closureData.thisElement); |
| + registerNeedsThis(); |
| } else if (node.isSuperCall) { |
| - useLocal(closureData.thisElement); |
| + registerNeedsThis(); |
| } else if (node.isParameterCheck) { |
| Element parameter = elements[node.receiver]; |
| FunctionElement enclosing = parameter.enclosingElement; |
| @@ -446,6 +470,12 @@ class ClosureTranslator extends Visitor { |
| if (Elements.isLocal(element)) { |
| mutatedVariables.add(element); |
| } |
| + if (element != null && element is VariableElement) { |
| + VariableElement variable = element; |
| + if (variable.variables.type.containsTypeVariables) { |
| + registerNeedsThis(); |
|
ngeoffray
2013/04/15 10:59:14
Not sure you need this:
- If element is a field, t
karlklose
2013/05/02 15:04:54
It is needed.
|
| + } |
| + } |
| super.visitSendSet(node); |
| } |
| @@ -482,7 +512,9 @@ class ClosureTranslator extends Visitor { |
| if (outermostElement.isConstructor() || outermostElement.isField()) { |
| analyzeTypeVariables(type); |
| } else if (outermostElement.isInstanceMember()) { |
| - if (hasTypeVariable(type)) useLocal(closureData.thisElement); |
| + if (hasTypeVariable(type)) { |
| + registerNeedsThis(); |
| + } |
| } |
| } |
| @@ -651,6 +683,10 @@ class ClosureTranslator extends Visitor { |
| }); |
| } |
| + if (element.computeType(compiler).containsTypeVariables) { |
|
ngeoffray
2013/04/15 10:59:14
So that's the function type if the element? It mat
karlklose
2013/05/02 15:04:54
Done.
|
| + registerNeedsThis(); |
| + } |
| + |
| visitChildren(); |
| }); |