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 '../common.dart'; | 8 import '../common.dart'; |
9 import '../common/tasks.dart'; | 9 import '../common/tasks.dart'; |
10 import '../constants/expressions.dart'; | 10 import '../constants/expressions.dart'; |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 final bool hasThisLocal; | 246 final bool hasThisLocal; |
247 final Set<ir.VariableDeclaration> boxedVariables; | 247 final Set<ir.VariableDeclaration> boxedVariables; |
248 // If boxedVariables is empty, this will be null, because no variables will | 248 // If boxedVariables is empty, this will be null, because no variables will |
249 // need to be boxed. | 249 // need to be boxed. |
250 final NodeBox capturedVariablesAccessor; | 250 final NodeBox capturedVariablesAccessor; |
251 | 251 |
252 /// The set of variables that were defined in another scope, but are used in | 252 /// The set of variables that were defined in another scope, but are used in |
253 /// this scope. | 253 /// this scope. |
254 Set<ir.VariableDeclaration> freeVariables = new Set<ir.VariableDeclaration>(); | 254 Set<ir.VariableDeclaration> freeVariables = new Set<ir.VariableDeclaration>(); |
255 | 255 |
| 256 /// If true, `this` is used as a free variable, in this scope. It is stored |
| 257 /// separately from [freeVariables] because there is no single |
| 258 /// `VariableDeclaration` node that represents `this`. |
| 259 bool thisUsedAsFreeVariable = false; |
| 260 |
256 KernelScopeInfo(this.hasThisLocal) | 261 KernelScopeInfo(this.hasThisLocal) |
257 : localsUsedInTryOrSync = new Set<ir.VariableDeclaration>(), | 262 : localsUsedInTryOrSync = new Set<ir.VariableDeclaration>(), |
258 boxedVariables = new Set<ir.VariableDeclaration>(), | 263 boxedVariables = new Set<ir.VariableDeclaration>(), |
259 capturedVariablesAccessor = null; | 264 capturedVariablesAccessor = null; |
260 | 265 |
261 KernelScopeInfo.from(this.hasThisLocal, KernelScopeInfo info) | 266 KernelScopeInfo.from(this.hasThisLocal, KernelScopeInfo info) |
262 : localsUsedInTryOrSync = info.localsUsedInTryOrSync, | 267 : localsUsedInTryOrSync = info.localsUsedInTryOrSync, |
263 boxedVariables = info.boxedVariables, | 268 boxedVariables = info.boxedVariables, |
264 capturedVariablesAccessor = null; | 269 capturedVariablesAccessor = null; |
265 | 270 |
(...skipping 21 matching lines...) Expand all Loading... |
287 /// this scope. | 292 /// this scope. |
288 final Set<Local> freeVariables; | 293 final Set<Local> freeVariables; |
289 | 294 |
290 JsScopeInfo.from( | 295 JsScopeInfo.from( |
291 this.boxedVariables, KernelScopeInfo info, KernelToLocalsMap localsMap) | 296 this.boxedVariables, KernelScopeInfo info, KernelToLocalsMap localsMap) |
292 : this.thisLocal = | 297 : this.thisLocal = |
293 info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null, | 298 info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null, |
294 this.localsUsedInTryOrSync = | 299 this.localsUsedInTryOrSync = |
295 info.localsUsedInTryOrSync.map(localsMap.getLocalVariable).toSet(), | 300 info.localsUsedInTryOrSync.map(localsMap.getLocalVariable).toSet(), |
296 this.freeVariables = | 301 this.freeVariables = |
297 info.freeVariables.map(localsMap.getLocalVariable).toSet(); | 302 info.freeVariables.map(localsMap.getLocalVariable).toSet() { |
| 303 if (info.thisUsedAsFreeVariable) { |
| 304 this.freeVariables.add(this.thisLocal); |
| 305 } |
| 306 } |
298 | 307 |
299 void forEachBoxedVariable(f(Local local, FieldEntity field)) { | 308 void forEachBoxedVariable(f(Local local, FieldEntity field)) { |
300 boxedVariables.forEach((Local l, JRecordField box) { | 309 boxedVariables.forEach((Local l, JRecordField box) { |
301 f(l, box); | 310 f(l, box); |
302 }); | 311 }); |
303 } | 312 } |
304 | 313 |
305 bool localIsUsedInTryOrSync(Local variable) => | 314 bool localIsUsedInTryOrSync(Local variable) => |
306 localsUsedInTryOrSync.contains(variable); | 315 localsUsedInTryOrSync.contains(variable); |
307 | 316 |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 KernelScopeInfo scopeInfo; | 628 KernelScopeInfo scopeInfo; |
620 | 629 |
621 /// Collected [CapturedScope] data for nodes. | 630 /// Collected [CapturedScope] data for nodes. |
622 Map<ir.Node, KernelCapturedScope> capturedScopesMap = | 631 Map<ir.Node, KernelCapturedScope> capturedScopesMap = |
623 <ir.Node, KernelCapturedScope>{}; | 632 <ir.Node, KernelCapturedScope>{}; |
624 | 633 |
625 /// Collected [ScopeInfo] data for nodes. | 634 /// Collected [ScopeInfo] data for nodes. |
626 Map<ir.TreeNode, KernelScopeInfo> closuresToGenerate = | 635 Map<ir.TreeNode, KernelScopeInfo> closuresToGenerate = |
627 <ir.TreeNode, KernelScopeInfo>{}; | 636 <ir.TreeNode, KernelScopeInfo>{}; |
628 } | 637 } |
OLD | NEW |