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..13a6823b61597f6f5033edd95968dbe19d9170a9 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/closure.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/closure.dart |
| @@ -477,12 +477,12 @@ class ClosureTranslator extends Visitor { |
| // capture them in the closure. |
| type.forEachTypeVariable((variable) => useLocal(variable.element)); |
| } |
| - // TODO(karlklose): try to get rid of the isField check; there is a bug |
| - // with type variable use in field initializer (in both modes). |
| if (member.isInstanceMember() && !member.isField()) { |
| // 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. |
| + // therefore the closure needs a this-element, if it is not a field; |
|
ngeoffray
2013/06/19 20:03:57
not a field -> not declared in a field initializer
karlklose
2013/06/20 10:18:00
Done.
|
| + // field initatializers are evaluated in a context where the type |
| + // arguments are available in locals. |
| registerNeedsThis(); |
| } |
| } |
| @@ -509,6 +509,12 @@ class ClosureTranslator extends Visitor { |
| registerNeedsThis(); |
| } else if (node.isSuperCall) { |
| registerNeedsThis(); |
| + } else if (node.isIsCheck || node.isIsNotCheck || node.isTypeCast) { |
| + TypeAnnotation annotation = node.typeAnnotationFromIsCheck; |
| + DartType type = elements.getType(annotation); |
| + if (type != null && type.containsTypeVariables) { |
| + registerNeedsThis(); |
| + } |
| } else if (node.isParameterCheck) { |
| Element parameter = elements[node.receiver]; |
| FunctionElement enclosing = parameter.enclosingElement; |
| @@ -542,23 +548,14 @@ class ClosureTranslator extends Visitor { |
| visitNewExpression(NewExpression node) { |
| DartType type = elements.getType(node); |
| - 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); |
| + // Field initializers are inlined and access the type variable as |
| + // normal parameters. |
| + if (!outermostElement.isField()) { |
| + registerNeedsThis(); |
| + } |
| } else if (type is InterfaceType) { |
| InterfaceType ifcType = type; |
| for (DartType argument in ifcType.typeArguments) { |
| @@ -572,7 +569,7 @@ class ClosureTranslator extends Visitor { |
| if (outermostElement.isConstructor() || outermostElement.isField()) { |
| analyzeTypeVariables(type); |
| } else if (outermostElement.isInstanceMember()) { |
| - if (hasTypeVariable(type)) { |
| + if (type.containsTypeVariables) { |
| registerNeedsThis(); |
| } |
| } |