| 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 |