Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 kernel.transformations.closure.info; | 5 library kernel.transformations.closure.info; |
| 6 | 6 |
| 7 import '../../ast.dart' | 7 import '../../ast.dart' |
| 8 show | 8 show |
| 9 Class, | 9 Class, |
| 10 Constructor, | 10 Constructor, |
| 11 Field, | 11 Field, |
| 12 FunctionDeclaration, | 12 FunctionDeclaration, |
| 13 FunctionNode, | 13 FunctionNode, |
| 14 Member, | 14 Member, |
| 15 Procedure, | 15 Procedure, |
| 16 ThisExpression, | 16 ThisExpression, |
| 17 TypeParameter, | 17 TypeParameter, |
| 18 TypeParameterType, | 18 TypeParameterType, |
| 19 VariableDeclaration, | 19 VariableDeclaration, |
| 20 VariableGet, | 20 VariableGet, |
| 21 VariableSet, | 21 VariableSet, |
| 22 visitList; | 22 visitList; |
| 23 | 23 |
| 24 import '../../visitor.dart' show RecursiveVisitor; | 24 import '../../visitor.dart' show RecursiveVisitor; |
| 25 | 25 |
| 26 class ClosureInfo extends RecursiveVisitor { | 26 class ClosureInfo extends RecursiveVisitor { |
| 27 FunctionNode currentFunction; | 27 FunctionNode currentFunction; |
| 28 | |
| 29 static const int OUTSIDE_INITIALIZER = 1; | |
| 30 static const int INSIDE_INITIALIZER = 2; | |
| 31 | |
| 32 int captureFlags = OUTSIDE_INITIALIZER; | |
| 33 | |
| 34 // For function parameters, we need to distinquish the following states: | |
| 35 // | |
| 36 // - captured inside initializers, not used in body (INSIDE_INITIALIZER) | |
| 37 // - only used in body (OUTSIDE_INITIALIZER) | |
| 38 // - captured inside initializers and used in body (OUTSIDE_INITIALIZER | | |
| 39 // INSIDE_INITIALIZER) | |
| 40 // | |
|
Dmitry Stefantsov
2017/08/01 09:36:14
Please, remove the empty comment line here.
sjindel
2017/08/01 14:58:25
Done.
| |
| 41 final Map<VariableDeclaration, int> variables = <VariableDeclaration, int>{}; | |
|
Dmitry Stefantsov
2017/08/01 09:36:14
How about adding helper functions to hide the inte
sjindel
2017/08/01 14:58:25
I would prefer the second approach over the first,
Dmitry Stefantsov
2017/08/03 09:28:26
I guess it depends on the definition of "significa
| |
| 42 | |
| 28 final Map<VariableDeclaration, FunctionNode> function = | 43 final Map<VariableDeclaration, FunctionNode> function = |
| 29 <VariableDeclaration, FunctionNode>{}; | 44 <VariableDeclaration, FunctionNode>{}; |
| 30 | 45 |
| 31 final Set<VariableDeclaration> variables = new Set<VariableDeclaration>(); | |
| 32 | |
| 33 /// Map from functions to set of type variables captured within them. | 46 /// Map from functions to set of type variables captured within them. |
| 34 final Map<FunctionNode, Set<TypeParameter>> typeVariables = | 47 final Map<FunctionNode, Set<TypeParameter>> typeVariables = |
| 35 <FunctionNode, Set<TypeParameter>>{}; | 48 <FunctionNode, Set<TypeParameter>>{}; |
| 36 | 49 |
| 37 /// Map from members to synthetic variables for accessing `this` in a local | 50 /// Map from members to synthetic variables for accessing `this` in a local |
| 38 /// function. | 51 /// function. |
| 39 final Map<FunctionNode, VariableDeclaration> thisAccess = | 52 final Map<FunctionNode, VariableDeclaration> thisAccess = |
| 40 <FunctionNode, VariableDeclaration>{}; | 53 <FunctionNode, VariableDeclaration>{}; |
| 41 | 54 |
| 42 final Set<String> currentMemberLocalNames = new Set<String>(); | 55 final Set<String> currentMemberLocalNames = new Set<String>(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 /// the parameters that may be used in the initializers. If the nodes are | 113 /// the parameters that may be used in the initializers. If the nodes are |
| 101 /// visited in another order, the encountered parameters in initializers | 114 /// visited in another order, the encountered parameters in initializers |
| 102 /// are treated as captured, because they are not yet associated with the | 115 /// are treated as captured, because they are not yet associated with the |
| 103 /// function. | 116 /// function. |
| 104 beginMember(node, node.function); | 117 beginMember(node, node.function); |
| 105 saveCurrentFunction(() { | 118 saveCurrentFunction(() { |
| 106 currentFunction = currentMemberFunction; | 119 currentFunction = currentMemberFunction; |
| 107 | 120 |
| 108 visitList(node.annotations, this); | 121 visitList(node.annotations, this); |
| 109 node.name?.accept(this); | 122 node.name?.accept(this); |
| 110 node.function?.accept(this); | 123 |
| 124 visitList(node.function.typeParameters, this); | |
| 125 visitList(node.function.positionalParameters, this); | |
| 126 visitList(node.function.namedParameters, this); | |
| 127 | |
| 128 assert(captureFlags == OUTSIDE_INITIALIZER); | |
| 129 captureFlags = INSIDE_INITIALIZER; | |
| 111 visitList(node.initializers, this); | 130 visitList(node.initializers, this); |
| 131 captureFlags = OUTSIDE_INITIALIZER; | |
| 132 | |
| 133 node.function.accept(this); | |
| 112 }); | 134 }); |
| 113 endMember(); | 135 endMember(); |
| 114 } | 136 } |
| 115 | 137 |
| 116 visitProcedure(Procedure node) { | 138 visitProcedure(Procedure node) { |
| 117 beginMember(node, node.function); | 139 beginMember(node, node.function); |
| 118 super.visitProcedure(node); | 140 super.visitProcedure(node); |
| 119 endMember(); | 141 endMember(); |
| 120 } | 142 } |
| 121 | 143 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 } | 196 } |
| 175 } | 197 } |
| 176 | 198 |
| 177 visitVariableDeclaration(VariableDeclaration node) { | 199 visitVariableDeclaration(VariableDeclaration node) { |
| 178 function[node] = currentFunction; | 200 function[node] = currentFunction; |
| 179 node.visitChildren(this); | 201 node.visitChildren(this); |
| 180 } | 202 } |
| 181 | 203 |
| 182 visitVariableGet(VariableGet node) { | 204 visitVariableGet(VariableGet node) { |
| 183 if (function[node.variable] != currentFunction) { | 205 if (function[node.variable] != currentFunction) { |
| 184 variables.add(node.variable); | 206 variables.putIfAbsent(node.variable, () => 0); |
| 207 } | |
| 208 if (variables.containsKey(node.variable)) { | |
| 209 variables[node.variable] |= captureFlags; | |
| 185 } | 210 } |
| 186 node.visitChildren(this); | 211 node.visitChildren(this); |
| 187 } | 212 } |
| 188 | 213 |
| 189 visitVariableSet(VariableSet node) { | 214 visitVariableSet(VariableSet node) { |
| 190 if (function[node.variable] != currentFunction) { | 215 if (function[node.variable] != currentFunction) { |
| 191 variables.add(node.variable); | 216 variables.putIfAbsent(node.variable, () => 0); |
| 217 } | |
| 218 if (variables.containsKey(node.variable)) { | |
| 219 variables[node.variable] |= captureFlags; | |
| 192 } | 220 } |
| 193 node.visitChildren(this); | 221 node.visitChildren(this); |
| 194 } | 222 } |
| 195 | 223 |
| 196 visitTypeParameterType(TypeParameterType node) { | 224 visitTypeParameterType(TypeParameterType node) { |
| 197 if (!isOuterMostContext && node.parameter.parent != currentFunction) { | 225 if (!isOuterMostContext && node.parameter.parent != currentFunction) { |
| 198 typeVariables | 226 typeVariables |
| 199 .putIfAbsent(currentFunction, () => new Set<TypeParameter>()) | 227 .putIfAbsent(currentFunction, () => new Set<TypeParameter>()) |
| 200 .add(node.parameter); | 228 .add(node.parameter); |
| 201 } | 229 } |
| 202 } | 230 } |
| 203 | 231 |
| 204 visitThisExpression(ThisExpression node) { | 232 visitThisExpression(ThisExpression node) { |
| 205 if (!isOuterMostContext) { | 233 if (!isOuterMostContext) { |
| 206 thisAccess.putIfAbsent( | 234 thisAccess.putIfAbsent( |
| 207 currentMemberFunction, () => new VariableDeclaration("#self")); | 235 currentMemberFunction, () => new VariableDeclaration("#self")); |
| 208 } | 236 } |
| 209 } | 237 } |
| 210 | 238 |
| 211 saveCurrentFunction(void f()) { | 239 saveCurrentFunction(void f()) { |
| 212 var saved = currentFunction; | 240 var saved = currentFunction; |
| 213 try { | 241 try { |
| 214 f(); | 242 f(); |
| 215 } finally { | 243 } finally { |
| 216 currentFunction = saved; | 244 currentFunction = saved; |
| 217 } | 245 } |
| 218 } | 246 } |
| 219 } | 247 } |
| OLD | NEW |