| 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 'common.dart'; | 7 import 'common.dart'; |
| 8 import 'common/names.dart' show | 8 import 'common/names.dart' show |
| 9 Identifiers; | 9 Identifiers; |
| 10 import 'common/resolution.dart' show | 10 import 'common/resolution.dart' show |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 scopeVariables = oldScopeVariables; | 899 scopeVariables = oldScopeVariables; |
| 900 } | 900 } |
| 901 | 901 |
| 902 visitLoop(Loop node) { | 902 visitLoop(Loop node) { |
| 903 inNewScope(node, () { | 903 inNewScope(node, () { |
| 904 node.visitChildren(this); | 904 node.visitChildren(this); |
| 905 }); | 905 }); |
| 906 } | 906 } |
| 907 | 907 |
| 908 visitFor(For node) { | 908 visitFor(For node) { |
| 909 List<LocalVariableElement> boxedLoopVariables = <LocalVariableElement>[]; |
| 909 inNewScope(node, () { | 910 inNewScope(node, () { |
| 910 // First visit initializer and update so we can easily check if a loop | 911 // First visit initializer and update so we can easily check if a loop |
| 911 // variable was captured in one of these subexpressions. | 912 // variable was captured in one of these subexpressions. |
| 912 if (node.initializer != null) visit(node.initializer); | 913 if (node.initializer != null) visit(node.initializer); |
| 913 if (node.update != null) visit(node.update); | 914 if (node.update != null) visit(node.update); |
| 914 | 915 |
| 915 // Loop variables that have not been captured yet can safely be flagged as | 916 // Loop variables that have not been captured yet can safely be flagged as |
| 916 // non-mutated, because no nested function can observe the mutation. | 917 // non-mutated, because no nested function can observe the mutation. |
| 917 if (node.initializer is VariableDefinitions) { | 918 if (node.initializer is VariableDefinitions) { |
| 918 VariableDefinitions definitions = node.initializer; | 919 VariableDefinitions definitions = node.initializer; |
| 919 definitions.definitions.nodes.forEach((Node node) { | 920 definitions.definitions.nodes.forEach((Node node) { |
| 920 LocalVariableElement local = elements[node]; | 921 LocalVariableElement local = elements[node]; |
| 921 if (!isCapturedVariable(local)) { | 922 if (!isCapturedVariable(local)) { |
| 922 mutatedVariables.remove(local); | 923 mutatedVariables.remove(local); |
| 923 } | 924 } |
| 924 }); | 925 }); |
| 925 } | 926 } |
| 926 | 927 |
| 927 // Visit condition and body. | 928 // Visit condition and body. |
| 928 // This must happen after the above, so any loop variables mutated in the | 929 // This must happen after the above, so any loop variables mutated in the |
| 929 // condition or body are indeed flagged as mutated. | 930 // condition or body are indeed flagged as mutated. |
| 930 if (node.conditionStatement != null) visit(node.conditionStatement); | 931 if (node.conditionStatement != null) visit(node.conditionStatement); |
| 931 if (node.body != null) visit(node.body); | 932 if (node.body != null) visit(node.body); |
| 933 |
| 934 // See if we have declared loop variables that need to be boxed. |
| 935 if (node.initializer == null) return; |
| 936 VariableDefinitions definitions = |
| 937 node.initializer.asVariableDefinitions(); |
| 938 if (definitions == null) return; |
| 939 for (Link<Node> link = definitions.definitions.nodes; |
| 940 !link.isEmpty; |
| 941 link = link.tail) { |
| 942 Node definition = link.head; |
| 943 LocalVariableElement element = elements[definition]; |
| 944 // Non-mutated variables should not be boxed. The mutatedVariables set |
| 945 // gets cleared when 'inNewScope' returns, so check it here. |
| 946 if (isCapturedVariable(element) && mutatedVariables.contains(element)) { |
| 947 boxedLoopVariables.add(element); |
| 948 } |
| 949 } |
| 932 }); | 950 }); |
| 933 // See if we have declared loop variables that need to be boxed. | |
| 934 if (node.initializer == null) return; | |
| 935 VariableDefinitions definitions = node.initializer.asVariableDefinitions(); | |
| 936 if (definitions == null) return; | |
| 937 ClosureScope scopeData = closureData.capturingScopes[node]; | 951 ClosureScope scopeData = closureData.capturingScopes[node]; |
| 938 if (scopeData == null) return; | 952 if (scopeData == null) return; |
| 939 List<LocalVariableElement> result = <LocalVariableElement>[]; | 953 scopeData.boxedLoopVariables = boxedLoopVariables; |
| 940 for (Link<Node> link = definitions.definitions.nodes; | |
| 941 !link.isEmpty; | |
| 942 link = link.tail) { | |
| 943 Node definition = link.head; | |
| 944 LocalVariableElement element = elements[definition]; | |
| 945 if (isCapturedVariable(element)) { | |
| 946 result.add(element); | |
| 947 } | |
| 948 } | |
| 949 scopeData.boxedLoopVariables = result; | |
| 950 } | 954 } |
| 951 | 955 |
| 952 /** Returns a non-unique name for the given closure element. */ | 956 /** Returns a non-unique name for the given closure element. */ |
| 953 String computeClosureName(Element element) { | 957 String computeClosureName(Element element) { |
| 954 Link<String> parts = const Link<String>(); | 958 Link<String> parts = const Link<String>(); |
| 955 String ownName = element.name; | 959 String ownName = element.name; |
| 956 if (ownName == null || ownName == "") { | 960 if (ownName == null || ownName == "") { |
| 957 parts = parts.prepend("closure"); | 961 parts = parts.prepend("closure"); |
| 958 } else { | 962 } else { |
| 959 parts = parts.prepend(ownName); | 963 parts = parts.prepend(ownName); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1123 | 1127 |
| 1124 String get name => typeVariable.name; | 1128 String get name => typeVariable.name; |
| 1125 | 1129 |
| 1126 int get hashCode => typeVariable.hashCode; | 1130 int get hashCode => typeVariable.hashCode; |
| 1127 | 1131 |
| 1128 bool operator ==(other) { | 1132 bool operator ==(other) { |
| 1129 if (other is! TypeVariableLocal) return false; | 1133 if (other is! TypeVariableLocal) return false; |
| 1130 return typeVariable == other.typeVariable; | 1134 return typeVariable == other.typeVariable; |
| 1131 } | 1135 } |
| 1132 } | 1136 } |
| OLD | NEW |