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 |