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, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 /// } | 86 /// } |
87 /// } | 87 /// } |
88 /// | 88 /// |
89 /// Here the parameter shouldn't be captured into a context in the | 89 /// Here the parameter shouldn't be captured into a context in the |
90 /// initializer. However, [currentFunction] is `null` if not set, and | 90 /// initializer. However, [currentFunction] is `null` if not set, and |
91 /// `function[node.variable]` in this case points to the [FunctionNode] of | 91 /// `function[node.variable]` in this case points to the [FunctionNode] of |
92 /// the constructor (which is not `null`). It leads to `x` being treated as | 92 /// the constructor (which is not `null`). It leads to `x` being treated as |
93 /// captured, because it's seen as used outside of the function where it is | 93 /// captured, because it's seen as used outside of the function where it is |
94 /// declared. In turn, it leads to unnecessary context creation and usage. | 94 /// declared. In turn, it leads to unnecessary context creation and usage. |
95 /// | 95 /// |
96 /// We also need to visit the parameters to the function node before the | 96 /// Another consideration is the order of visiting children of the |
97 /// initializer list. Since the default [visitChildren] method of | 97 /// constructor: [node.function] should be visited before |
98 /// [Constructor] will visit initializers first, we manually visit the | 98 /// [node.initializers], because [node.function] contains declarations of |
99 /// parameters here. | 99 /// the parameters that may be used in the initializers. If the nodes are |
100 /// | 100 /// visited in another order, the encountered parameters in initializers |
101 /// TODO(sjindel): Don't visit the parameters twice. | 101 /// are treated as captured, because they are not yet associated with the |
102 /// | 102 /// function. |
103 beginMember(node, node.function); | 103 beginMember(node, node.function); |
104 saveCurrentFunction(() { | 104 saveCurrentFunction(() { |
105 currentFunction = currentMemberFunction; | 105 currentFunction = currentMemberFunction; |
106 visitList(node.function.positionalParameters, this); | 106 |
107 visitList(node.function.namedParameters, this); | 107 visitList(node.annotations, this); |
108 super.visitConstructor(node); | 108 node.name?.accept(this); |
| 109 node.function?.accept(this); |
| 110 visitList(node.initializers, this); |
109 }); | 111 }); |
110 endMember(); | 112 endMember(); |
111 } | 113 } |
112 | 114 |
113 visitProcedure(Procedure node) { | 115 visitProcedure(Procedure node) { |
114 beginMember(node, node.function); | 116 beginMember(node, node.function); |
115 super.visitProcedure(node); | 117 super.visitProcedure(node); |
116 endMember(); | 118 endMember(); |
117 } | 119 } |
118 | 120 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 | 206 |
205 saveCurrentFunction(void f()) { | 207 saveCurrentFunction(void f()) { |
206 var saved = currentFunction; | 208 var saved = currentFunction; |
207 try { | 209 try { |
208 f(); | 210 f(); |
209 } finally { | 211 } finally { |
210 currentFunction = saved; | 212 currentFunction = saved; |
211 } | 213 } |
212 } | 214 } |
213 } | 215 } |
OLD | NEW |