| 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..520a7c5faf748ae2899afaea54e66e57dfaa66e9 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/closure.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/closure.dart
|
| @@ -523,6 +523,12 @@ class ClosureTranslator extends Visitor {
|
| useLocal(newElement);
|
| cached.parametersWithSentinel[parameter] = newElement;
|
| }
|
| + } else if (node.isTypeTest) {
|
| + DartType type = elements.getType(node.typeAnnotationFromIsCheck);
|
| + analyzeType(type);
|
| + } else if (node.isTypeCast) {
|
| + DartType type = elements.getType(node.arguments.head);
|
| + analyzeType(type);
|
| }
|
| node.visitChildren(this);
|
| }
|
| @@ -541,44 +547,28 @@ 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) {
|
| + type.forEachTypeVariable((TypeVariableType typeVariable) {
|
| + useLocal(typeVariable.element);
|
| + });
|
| + }
|
|
|
| + void analyzeType(DartType type) {
|
| if (outermostElement.isMember() &&
|
| - compiler.backend.needsRti(outermostElement.getEnclosingClass())) {
|
| - if (outermostElement.isConstructor() || outermostElement.isField()) {
|
| + compiler.backend.classNeedsRti(outermostElement.getEnclosingClass())) {
|
| + if (outermostElement.isConstructor() ||
|
| + outermostElement.isField()) {
|
| analyzeTypeVariables(type);
|
| } else if (outermostElement.isInstanceMember()) {
|
| - if (hasTypeVariable(type)) {
|
| + if (type.containsTypeVariables) {
|
| registerNeedsThis();
|
| }
|
| }
|
| }
|
| -
|
| - node.visitChildren(this);
|
| }
|
|
|
| // If variables that are declared in the [node] scope are captured and need
|
| @@ -737,7 +727,7 @@ class ClosureTranslator extends Visitor {
|
| }
|
|
|
| if (currentElement.isFactoryConstructor() &&
|
| - compiler.backend.needsRti(currentElement.enclosingElement)) {
|
| + compiler.backend.classNeedsRti(currentElement.enclosingElement)) {
|
| // Declare the type parameters in the scope. Generative
|
| // constructors just use 'this'.
|
| ClassElement cls = currentElement.enclosingElement;
|
| @@ -751,6 +741,13 @@ class ClosureTranslator extends Visitor {
|
| if (element.computeType(compiler).containsTypeVariables) {
|
| registerNeedsThis();
|
| }
|
| + // Ensure that closure that need runtime type information has access to
|
| + // this of the enclosing class.
|
| + if (element is FunctionElement &&
|
| + closureData.thisElement != null &&
|
| + compiler.backend.methodNeedsRti(element)) {
|
| + registerNeedsThis();
|
| + }
|
|
|
| visitChildren();
|
| });
|
|
|