OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
6 | 6 |
7 import '../closure.dart'; | 7 import '../closure.dart'; |
8 import 'closure.dart'; | 8 import 'closure.dart'; |
9 | 9 |
10 /// This builder walks the code to determine what variables are captured/free at | 10 /// This builder walks the code to determine what variables are captured/free at |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 // parameters, and type parameters are declared in the class, not | 171 // parameters, and type parameters are declared in the class, not |
172 // the factory. | 172 // the factory. |
173 _currentScopeInfo.freeVariables.add(variable); | 173 _currentScopeInfo.freeVariables.add(variable); |
174 } | 174 } |
175 if (_inTry) { | 175 if (_inTry) { |
176 _currentScopeInfo.localsUsedInTryOrSync.add(variable); | 176 _currentScopeInfo.localsUsedInTryOrSync.add(variable); |
177 } | 177 } |
178 } | 178 } |
179 | 179 |
180 @override | 180 @override |
| 181 void visitThisExpression(ir.ThisExpression thisExpression) { |
| 182 if (_hasThisLocal) _registerNeedsThis(); |
| 183 } |
| 184 |
| 185 @override |
| 186 void visitTypeParameter(ir.TypeParameter typeParameter) { |
| 187 ir.TreeNode context = _executableContext; |
| 188 if (_isInsideClosure && context is ir.Procedure && context.isFactory) { |
| 189 // This is a closure in a factory constructor. Since there is no |
| 190 // [:this:], we have to mark the type arguments as free variables to |
| 191 // capture them in the closure. |
| 192 // TODO(efortuna): Implement for in the case of RTI. |
| 193 // useTypeVariableAsLocal(typeParameter.bound); |
| 194 } |
| 195 |
| 196 if (_executableContext is ir.Member && |
| 197 _executableContext is! ir.Field && |
| 198 _hasThisLocal) { |
| 199 // In checked mode, using a type variable in a type annotation may lead |
| 200 // to a runtime type check that needs to access the type argument and |
| 201 // therefore the closure needs a this-element, if it is not in a field |
| 202 // initializer; field initializers are evaluated in a context where |
| 203 // the type arguments are available in locals. |
| 204 _registerNeedsThis(); |
| 205 } |
| 206 } |
| 207 |
| 208 /// Add `this` as a variable that needs to be accessed (and thus may become a |
| 209 /// free/captured variable. |
| 210 void _registerNeedsThis() { |
| 211 if (_isInsideClosure) { |
| 212 _currentScopeInfo.thisUsedAsFreeVariable = true; |
| 213 } |
| 214 } |
| 215 |
| 216 @override |
181 void visitForStatement(ir.ForStatement node) { | 217 void visitForStatement(ir.ForStatement node) { |
182 List<ir.VariableDeclaration> boxedLoopVariables = | 218 List<ir.VariableDeclaration> boxedLoopVariables = |
183 <ir.VariableDeclaration>[]; | 219 <ir.VariableDeclaration>[]; |
184 enterNewScope(node, () { | 220 enterNewScope(node, () { |
185 // First visit initialized variables and update steps so we can easily | 221 // First visit initialized variables and update steps so we can easily |
186 // check if a loop variable was captured in one of these subexpressions. | 222 // check if a loop variable was captured in one of these subexpressions. |
187 node.variables | 223 node.variables |
188 .forEach((ir.VariableDeclaration variable) => variable.accept(this)); | 224 .forEach((ir.VariableDeclaration variable) => variable.accept(this)); |
189 node.updates | 225 node.updates |
190 .forEach((ir.Expression expression) => expression.accept(this)); | 226 .forEach((ir.Expression expression) => expression.accept(this)); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 @override | 332 @override |
297 void visitFunctionExpression(ir.FunctionExpression functionExpression) { | 333 void visitFunctionExpression(ir.FunctionExpression functionExpression) { |
298 visitInvokable(functionExpression); | 334 visitInvokable(functionExpression); |
299 } | 335 } |
300 | 336 |
301 @override | 337 @override |
302 void visitFunctionDeclaration(ir.FunctionDeclaration functionDeclaration) { | 338 void visitFunctionDeclaration(ir.FunctionDeclaration functionDeclaration) { |
303 visitInvokable(functionDeclaration); | 339 visitInvokable(functionDeclaration); |
304 } | 340 } |
305 } | 341 } |
OLD | NEW |