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 48fa3b3179a952a017a6840514296f8084cb26f4..b7caa38702e7906331ae6508c3c07955e25589e5 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/closure.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/closure.dart |
| @@ -390,11 +390,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) { |
| @@ -417,13 +426,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 |
| + // therefore the closure needs a this-element. |
| + // 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/05/13 09:10:59
So for foo(T a), we don't resolve the "T" ?
karlklose
2013/05/14 13:49:41
I updated the comment to be more precise.
ngeoffray
2013/05/15 08:45:32
Thank you. I still find it a bit obscure: what is
|
| + 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); |
| @@ -435,9 +459,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; |
| @@ -461,6 +485,12 @@ class ClosureTranslator extends Visitor { |
| if (Elements.isLocal(element)) { |
| mutatedVariables.add(element); |
| } |
| + if (element != null && element is VariableElement) { |
|
ngeoffray
2013/05/13 09:10:59
Should that be Elements.isLocal(element) ?
karlklose
2013/05/14 13:49:41
Done.
karlklose
2013/05/14 13:49:41
Done.
|
| + VariableElement variable = element; |
| + if (variable.variables.type.containsTypeVariables) { |
|
ngeoffray
2013/05/13 09:10:59
Change to element.computeType(compiler).containsTy
karlklose
2013/05/14 13:49:41
Done.
|
| + registerNeedsThis(); |
| + } |
| + } |
| super.visitSendSet(node); |
| } |
| @@ -497,7 +527,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(); |
| + } |
| } |
| } |
| @@ -666,6 +698,12 @@ class ClosureTranslator extends Visitor { |
| }); |
| } |
| + // Compute the function type and check for type variables in return or |
| + // parameter types. |
| + if (element.computeType(compiler).containsTypeVariables) { |
| + registerNeedsThis(); |
| + } |
| + |
| visitChildren(); |
| }); |