| OLD | NEW | 
|    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file |    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|    2 // for details. All rights reserved. Use of this source code is governed by a |    2 // for details. All rights reserved. Use of this source code is governed by a | 
|    3 // BSD-style license that can be found in the LICENSE file. |    3 // BSD-style license that can be found in the LICENSE file. | 
|    4  |    4  | 
|    5 library closureToClassMapper; |    5 library closureToClassMapper; | 
|    6  |    6  | 
|    7 import "elements/elements.dart"; |    7 import "elements/elements.dart"; | 
|    8 import "dart2jslib.dart"; |    8 import "dart2jslib.dart"; | 
|    9 import "dart_types.dart"; |    9 import "dart_types.dart"; | 
|   10 import "scanner/scannerlib.dart" show Token; |   10 import "scanner/scannerlib.dart" show Token; | 
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  516       ClosureClassMap cached = closureMappingCache[function]; |  516       ClosureClassMap cached = closureMappingCache[function]; | 
|  517       if (!cached.parametersWithSentinel.containsKey(parameter)) { |  517       if (!cached.parametersWithSentinel.containsKey(parameter)) { | 
|  518         SourceString parameterName = parameter.name; |  518         SourceString parameterName = parameter.name; | 
|  519         String name = '${parameterName.slowToString()}_check'; |  519         String name = '${parameterName.slowToString()}_check'; | 
|  520         Element newElement = new CheckVariableElement(new SourceString(name), |  520         Element newElement = new CheckVariableElement(new SourceString(name), | 
|  521                                                       parameter, |  521                                                       parameter, | 
|  522                                                       enclosing); |  522                                                       enclosing); | 
|  523         useLocal(newElement); |  523         useLocal(newElement); | 
|  524         cached.parametersWithSentinel[parameter] = newElement; |  524         cached.parametersWithSentinel[parameter] = newElement; | 
|  525       } |  525       } | 
 |  526     } else if (node.isOperator) { | 
 |  527       String operatorString = node.selector.asOperator().source.stringValue; | 
 |  528       if (operatorString == 'is' || operatorString == 'as') { | 
 |  529         DartType type = elements.getType(node.arguments.head); | 
 |  530         analyzeType(type); | 
 |  531       } | 
|  526     } |  532     } | 
|  527     node.visitChildren(this); |  533     node.visitChildren(this); | 
|  528   } |  534   } | 
|  529  |  535  | 
|  530   visitSendSet(SendSet node) { |  536   visitSendSet(SendSet node) { | 
|  531     Element element = elements[node]; |  537     Element element = elements[node]; | 
|  532     if (Elements.isLocal(element)) { |  538     if (Elements.isLocal(element)) { | 
|  533       mutatedVariables.add(element); |  539       mutatedVariables.add(element); | 
|  534     } |  540     } | 
|  535     if (Elements.isLocal(element) && |  541     if (Elements.isLocal(element) && | 
|  536         element.computeType(compiler).containsTypeVariables) { |  542         element.computeType(compiler).containsTypeVariables) { | 
|  537       registerNeedsThis(); |  543       registerNeedsThis(); | 
|  538     } |  544     } | 
|  539     super.visitSendSet(node); |  545     super.visitSendSet(node); | 
|  540   } |  546   } | 
|  541  |  547  | 
|  542   visitNewExpression(NewExpression node) { |  548   visitNewExpression(NewExpression node) { | 
|  543     DartType type = elements.getType(node); |  549     DartType type = elements.getType(node); | 
 |  550     analyzeType(type); | 
 |  551     node.visitChildren(this); | 
 |  552   } | 
|  544  |  553  | 
|  545     bool hasTypeVariable(DartType type) { |  554   void analyzeTypeVariables(DartType type) { | 
|  546       if (type is TypeVariableType) { |  555     type.forEachTypeVariable((TypeVariableType typeVariable) { | 
|  547         return true; |  556       useLocal(typeVariable.element); | 
|  548       } else if (type is InterfaceType) { |  557     }); | 
|  549         InterfaceType ifcType = type; |  558   } | 
|  550         for (DartType argument in ifcType.typeArguments) { |  | 
|  551           if (hasTypeVariable(argument)) { |  | 
|  552             return true; |  | 
|  553           } |  | 
|  554         } |  | 
|  555       } |  | 
|  556       return false; |  | 
|  557     } |  | 
|  558  |  559  | 
|  559     void analyzeTypeVariables(DartType type) { |  560   void analyzeType(DartType type) { | 
|  560       if (type is TypeVariableType) { |  561     if (type == null) return; | 
|  561         useLocal(type.element); |  | 
|  562       } else if (type is InterfaceType) { |  | 
|  563         InterfaceType ifcType = type; |  | 
|  564         for (DartType argument in ifcType.typeArguments) { |  | 
|  565           analyzeTypeVariables(argument); |  | 
|  566         } |  | 
|  567       } |  | 
|  568     } |  | 
|  569  |  | 
|  570     if (outermostElement.isMember() && |  562     if (outermostElement.isMember() && | 
|  571         compiler.backend.needsRti(outermostElement.getEnclosingClass())) { |  563         compiler.backend.needsRti(outermostElement.getEnclosingClass())) { | 
|  572       if (outermostElement.isConstructor() || outermostElement.isField()) { |  564       if (outermostElement.isConstructor() || | 
 |  565           outermostElement.isField()) { | 
|  573         analyzeTypeVariables(type); |  566         analyzeTypeVariables(type); | 
|  574       } else if (outermostElement.isInstanceMember()) { |  567       } else if (outermostElement.isInstanceMember()) { | 
|  575         if (hasTypeVariable(type)) { |  568         if (type.containsTypeVariables) { | 
|  576           registerNeedsThis(); |  569           registerNeedsThis(); | 
|  577         } |  570         } | 
|  578       } |  571       } | 
|  579     } |  572     } | 
|  580  |  | 
|  581     node.visitChildren(this); |  | 
|  582   } |  573   } | 
|  583  |  574  | 
|  584   // If variables that are declared in the [node] scope are captured and need |  575   // If variables that are declared in the [node] scope are captured and need | 
|  585   // to be boxed create a box-element and update the [capturingScopes] in the |  576   // to be boxed create a box-element and update the [capturingScopes] in the | 
|  586   // current [closureData]. |  577   // current [closureData]. | 
|  587   // The boxed variables are updated in the [capturedVariableMapping]. |  578   // The boxed variables are updated in the [capturedVariableMapping]. | 
|  588   void attachCapturedScopeVariables(Node node) { |  579   void attachCapturedScopeVariables(Node node) { | 
|  589     Element box = null; |  580     Element box = null; | 
|  590     Map<Element, Element> scopeMapping = new Map<Element, Element>(); |  581     Map<Element, Element> scopeMapping = new Map<Element, Element>(); | 
|  591     for (Element element in scopeVariables) { |  582     for (Element element in scopeVariables) { | 
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  744         cls.typeVariables.forEach((TypeVariableType typeVariable) { |  735         cls.typeVariables.forEach((TypeVariableType typeVariable) { | 
|  745           declareLocal(typeVariable.element); |  736           declareLocal(typeVariable.element); | 
|  746         }); |  737         }); | 
|  747       } |  738       } | 
|  748  |  739  | 
|  749       // Compute the function type and check for type variables in return or |  740       // Compute the function type and check for type variables in return or | 
|  750       // parameter types. |  741       // parameter types. | 
|  751       if (element.computeType(compiler).containsTypeVariables) { |  742       if (element.computeType(compiler).containsTypeVariables) { | 
|  752         registerNeedsThis(); |  743         registerNeedsThis(); | 
|  753       } |  744       } | 
 |  745       // Ensure that closure that need runtime type information has access to | 
 |  746       // this of the enclosing class. | 
 |  747       if (closureData.thisElement != null && | 
 |  748           compiler.backend.methodNeedsRti(element)) { | 
 |  749         registerNeedsThis(); | 
 |  750       } | 
|  754  |  751  | 
|  755       visitChildren(); |  752       visitChildren(); | 
|  756     }); |  753     }); | 
|  757  |  754  | 
|  758  |  755  | 
|  759     ClosureClassMap savedClosureData = closureData; |  756     ClosureClassMap savedClosureData = closureData; | 
|  760     bool savedInsideClosure = insideClosure; |  757     bool savedInsideClosure = insideClosure; | 
|  761  |  758  | 
|  762     // Restore old values. |  759     // Restore old values. | 
|  763     insideClosure = oldInsideClosure; |  760     insideClosure = oldInsideClosure; | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  802   } |  799   } | 
|  803  |  800  | 
|  804   visitTryStatement(TryStatement node) { |  801   visitTryStatement(TryStatement node) { | 
|  805     // TODO(ngeoffray): implement finer grain state. |  802     // TODO(ngeoffray): implement finer grain state. | 
|  806     bool oldInTryStatement = inTryStatement; |  803     bool oldInTryStatement = inTryStatement; | 
|  807     inTryStatement = true; |  804     inTryStatement = true; | 
|  808     node.visitChildren(this); |  805     node.visitChildren(this); | 
|  809     inTryStatement = oldInTryStatement; |  806     inTryStatement = oldInTryStatement; | 
|  810   } |  807   } | 
|  811 } |  808 } | 
| OLD | NEW |