| 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 Name, | 15 Name, |
| 16 Procedure, | 16 Procedure, |
| 17 ProcedureKind, | 17 ProcedureKind, |
| 18 PropertyGet, | 18 PropertyGet, |
| 19 ThisExpression, | 19 ThisExpression, |
| 20 TypeParameter, | 20 TypeParameter, |
| 21 TypeParameterType, | 21 TypeParameterType, |
| 22 VariableDeclaration, | 22 VariableDeclaration, |
| 23 VariableGet, | 23 VariableGet, |
| 24 VariableSet; | 24 VariableSet, |
| 25 visitList; |
| 25 | 26 |
| 26 import '../../visitor.dart' show RecursiveVisitor; | 27 import '../../visitor.dart' show RecursiveVisitor; |
| 27 | 28 |
| 28 class ClosureInfo extends RecursiveVisitor { | 29 class ClosureInfo extends RecursiveVisitor { |
| 29 FunctionNode currentFunction; | 30 FunctionNode currentFunction; |
| 30 final Map<VariableDeclaration, FunctionNode> function = | 31 final Map<VariableDeclaration, FunctionNode> function = |
| 31 <VariableDeclaration, FunctionNode>{}; | 32 <VariableDeclaration, FunctionNode>{}; |
| 32 | 33 |
| 33 final Set<VariableDeclaration> variables = new Set<VariableDeclaration>(); | 34 final Set<VariableDeclaration> variables = new Set<VariableDeclaration>(); |
| 34 | 35 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 /// /* Constructor body. */ | 113 /// /* Constructor body. */ |
| 113 /// } | 114 /// } |
| 114 /// } | 115 /// } |
| 115 /// | 116 /// |
| 116 /// Here the parameter shouldn't be captured into a context in the | 117 /// Here the parameter shouldn't be captured into a context in the |
| 117 /// initializer. However, [currentFunction] is `null` if not set, and | 118 /// initializer. However, [currentFunction] is `null` if not set, and |
| 118 /// `function[node.variable]` in this case points to the [FunctionNode] of | 119 /// `function[node.variable]` in this case points to the [FunctionNode] of |
| 119 /// the constructor (which is not `null`). It leads to `x` being treated as | 120 /// the constructor (which is not `null`). It leads to `x` being treated as |
| 120 /// captured, because it's seen as used outside of the function where it is | 121 /// captured, because it's seen as used outside of the function where it is |
| 121 /// declared. In turn, it leads to unnecessary context creation and usage. | 122 /// declared. In turn, it leads to unnecessary context creation and usage. |
| 123 /// |
| 124 /// We also need to visit the parameters to the function node before the |
| 125 /// initializer list. Since the default [visitChildren] method of |
| 126 /// [Constructor] will visit initializers first, we manually visit the |
| 127 /// parameters here. |
| 128 /// |
| 129 /// TODO(sjindel): Don't visit the parameters twice. |
| 130 /// |
| 122 beginMember(node, node.function); | 131 beginMember(node, node.function); |
| 123 saveCurrentFunction(() { | 132 saveCurrentFunction(() { |
| 124 currentFunction = currentMemberFunction; | 133 currentFunction = currentMemberFunction; |
| 134 visitList(node.function.positionalParameters, this); |
| 135 visitList(node.function.namedParameters, this); |
| 125 super.visitConstructor(node); | 136 super.visitConstructor(node); |
| 126 }); | 137 }); |
| 127 endMember(); | 138 endMember(); |
| 128 } | 139 } |
| 129 | 140 |
| 130 visitProcedure(Procedure node) { | 141 visitProcedure(Procedure node) { |
| 131 beginMember(node, node.function); | 142 beginMember(node, node.function); |
| 132 if (node.isInstanceMember && node.kind == ProcedureKind.Method) { | 143 if (node.isInstanceMember && node.kind == ProcedureKind.Method) { |
| 133 // Ignore the `length` method of [File] subclasses for now, as they | 144 // Ignore the `length` method of [File] subclasses for now, as they |
| 134 // will force us to rename the `length` getter (kernel issue #43). | 145 // will force us to rename the `length` getter (kernel issue #43). |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 | 247 |
| 237 saveCurrentFunction(void f()) { | 248 saveCurrentFunction(void f()) { |
| 238 var saved = currentFunction; | 249 var saved = currentFunction; |
| 239 try { | 250 try { |
| 240 f(); | 251 f(); |
| 241 } finally { | 252 } finally { |
| 242 currentFunction = saved; | 253 currentFunction = saved; |
| 243 } | 254 } |
| 244 } | 255 } |
| 245 } | 256 } |
| OLD | NEW |