Chromium Code Reviews| Index: pkg/compiler/lib/src/js_model/closure.dart |
| diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart |
| index c57647da4fa466b99ccccddd7e3432283aa532ee..ba222a63fdccd34a495e1a8b6bee33c47440ae5e 100644 |
| --- a/pkg/compiler/lib/src/js_model/closure.dart |
| +++ b/pkg/compiler/lib/src/js_model/closure.dart |
| @@ -266,6 +266,7 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> { |
| } |
| class KernelScopeInfo { |
| + // TODO(johnniwinther): Remove this. It seems to be unneeded. |
| final ir.TreeNode node; |
|
Emily Fortuna
2017/08/22 23:47:36
why not just delete it then?
Johnni Winther
2017/08/23 07:47:18
It's good for debugging and it seemed that I might
|
| final Set<ir.VariableDeclaration> localsUsedInTryOrSync; |
| final bool hasThisLocal; |
| @@ -283,10 +284,43 @@ class KernelScopeInfo { |
| KernelScopeInfo.withBoxedVariables(this.node, this.localsUsedInTryOrSync, |
| this.freeVariables, this.hasThisLocal); |
| + bool _printOn(StringBuffer sb, bool needsComma) { |
| + if (node != null) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('node=$node'); |
| + needsComma = true; |
| + } |
| + if (hasThisLocal) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('hasThisLocal'); |
| + needsComma = true; |
| + } |
| + if (localsUsedInTryOrSync.isNotEmpty) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('localsUsedInTryOrSync={${localsUsedInTryOrSync.join(', ')}}'); |
| + needsComma = true; |
| + } |
| + /*if (freeVariables.isNotEmpty) { |
|
Emily Fortuna
2017/08/22 23:47:37
delete or uncomment?
|
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('freeVariables=${freeVariables}'); |
| + needsComma = true; |
| + }*/ |
| + return needsComma; |
| + } |
| + |
| String toString() { |
| StringBuffer sb = new StringBuffer(); |
| - sb.write('this=$hasThisLocal,'); |
| - sb.write('localsUsedInTryOrSync={${localsUsedInTryOrSync.join(', ')}}'); |
| + sb.write('KernelScopeInfo('); |
| + _printOn(sb, false); |
| + sb.write(')'); |
| return sb.toString(); |
| } |
| } |
| @@ -295,25 +329,38 @@ class JsScopeInfo extends ScopeInfo { |
| final Set<Local> localsUsedInTryOrSync; |
| final Local thisLocal; |
| - /// The set of variables that were defined in another scope, but are used in |
| - /// this scope. |
| - final Set<Local> freeVariables; |
| - |
| JsScopeInfo.from(KernelScopeInfo info, KernelToLocalsMap localsMap) |
| : this.thisLocal = |
| info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null, |
| this.localsUsedInTryOrSync = |
| - info.localsUsedInTryOrSync.map(localsMap.getLocalVariable).toSet(), |
| - this.freeVariables = |
| - info.freeVariables.map(localsMap.getLocalVariable).toSet(); |
| + info.localsUsedInTryOrSync.map(localsMap.getLocalVariable).toSet(); |
| bool localIsUsedInTryOrSync(Local variable) => |
| localsUsedInTryOrSync.contains(variable); |
| + bool _printOn(StringBuffer sb, bool needsComma) { |
| + if (thisLocal != null) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('this=$thisLocal'); |
| + needsComma = true; |
| + } |
| + if (localsUsedInTryOrSync.isNotEmpty) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('localsUsedInTryOrSync={${localsUsedInTryOrSync.join(', ')}}'); |
| + needsComma = true; |
| + } |
| + return needsComma; |
| + } |
| + |
| String toString() { |
| StringBuffer sb = new StringBuffer(); |
| - sb.write('this=$thisLocal,'); |
| - sb.write('localsUsedInTryOrSync={${localsUsedInTryOrSync.join(', ')}}'); |
| + sb.write('JsScopeInfo('); |
| + _printOn(sb, false); |
| + sb.write(')'); |
| return sb.toString(); |
| } |
| } |
| @@ -333,23 +380,77 @@ class KernelCapturedScope extends KernelScopeInfo { |
| node, localsUsedInTryOrSync, freeVariables, hasThisLocal); |
| bool get requiresContextBox => boxedVariables.isNotEmpty; |
| + |
| + bool _printOn(StringBuffer sb, bool needsComma) { |
| + needsComma = super._printOn(sb, needsComma); |
| + if (box != null) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('box=${box}'); |
| + needsComma = true; |
| + } |
| + if (boxedVariables.isNotEmpty) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('boxedVariables={${boxedVariables.join(',')}}'); |
| + needsComma = true; |
| + } |
| + return needsComma; |
| + } |
| + |
| + String toString() { |
| + StringBuffer sb = new StringBuffer(); |
| + sb.write('KernelCapturedScope('); |
| + _printOn(sb, false); |
| + sb.write(')'); |
| + return sb.toString(); |
| + } |
| } |
| class JsCapturedScope extends JsScopeInfo implements CapturedScope { |
| - final Local context; |
| + final Local box; |
| final Map<Local, FieldEntity> boxedVariables; |
| JsCapturedScope.from(KernelCapturedScope capturedScope, |
| - KernelToLocalsMap localsMap, this.context, this.boxedVariables) |
| + KernelToLocalsMap localsMap, this.box, this.boxedVariables) |
| : super.from(capturedScope, localsMap); |
| - bool get requiresContextBox => boxedVariables.isNotEmpty; |
| + bool get hasBox => box != null; |
| void forEachBoxedVariable(f(Local local, FieldEntity field)) { |
| boxedVariables.forEach(f); |
| } |
| bool isBoxed(Local variable) => boxedVariables.containsKey(variable); |
| + |
| + bool _printOn(StringBuffer sb, bool needsComma) { |
| + needsComma = super._printOn(sb, needsComma); |
| + if (box != null) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('box=${box}'); |
| + needsComma = true; |
| + } |
| + if (boxedVariables.isNotEmpty) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('boxedVariables=${boxedVariables}'); |
| + needsComma = true; |
| + } |
| + return needsComma; |
| + } |
| + |
| + String toString() { |
| + StringBuffer sb = new StringBuffer(); |
| + sb.write('JsCapturedScope('); |
| + _printOn(sb, false); |
| + sb.write(')'); |
| + return sb.toString(); |
| + } |
| } |
| class KernelCapturedLoopScope extends KernelCapturedScope { |
| @@ -367,6 +468,26 @@ class KernelCapturedLoopScope extends KernelCapturedScope { |
| hasThisLocal); |
| bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty; |
| + |
| + bool _printOn(StringBuffer sb, bool needsComma) { |
| + needsComma = super._printOn(sb, needsComma); |
| + if (boxedLoopVariables.isNotEmpty) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('boxedLoopVariables={${boxedLoopVariables.join(',')}}'); |
| + needsComma = true; |
| + } |
| + return needsComma; |
| + } |
| + |
| + String toString() { |
| + StringBuffer sb = new StringBuffer(); |
| + sb.write('KernelCapturedLoopScope('); |
| + _printOn(sb, false); |
| + sb.write(')'); |
| + return sb.toString(); |
| + } |
| } |
| class JsCapturedLoopScope extends JsCapturedScope implements CapturedLoopScope { |
| @@ -383,6 +504,26 @@ class JsCapturedLoopScope extends JsCapturedScope implements CapturedLoopScope { |
| super.from(capturedScope, localsMap, box, boxedVariables); |
| bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty; |
| + |
| + bool _printOn(StringBuffer sb, bool needsComma) { |
| + needsComma = super._printOn(sb, needsComma); |
| + if (boxedLoopVariables.isNotEmpty) { |
| + if (needsComma) { |
| + sb.write(','); |
| + } |
| + sb.write('boxedLoopVariables={${boxedLoopVariables.join(',')}}'); |
| + needsComma = true; |
| + } |
| + return needsComma; |
| + } |
| + |
| + String toString() { |
| + StringBuffer sb = new StringBuffer(); |
| + sb.write('JsCapturedLoopScope('); |
| + _printOn(sb, false); |
| + sb.write(')'); |
| + return sb.toString(); |
| + } |
| } |
| // TODO(johnniwinther): Add unittest for the computed [ClosureClass]. |
| @@ -422,15 +563,11 @@ class KernelClosureClass extends JsScopeInfo |
| FieldEntity get thisFieldEntity => localToFieldMap[thisLocal]; |
| void forEachBoxedVariable(f(Local from, FieldEntity to)) { |
| - boxedVariables.forEach(f); |
| + throw new UnsupportedError('KernelClosureClass.forEachBoxedVariable'); |
| } |
| void forEachCapturedVariable(f(Local from, FieldEntity to)) { |
| - for (Local local in localToFieldMap.keys) { |
| - FieldEntity field = localToFieldMap[local]; |
| - if (local is! BoxLocal) f(local, field); |
| - } |
| - boxedVariables.forEach(f); |
| + throw new UnsupportedError('KernelClosureClass.forEachCapturedVariable'); |
| } |
| void forEachFreeVariable(f(Local variable, FieldEntity field)) { |
| @@ -438,7 +575,9 @@ class KernelClosureClass extends JsScopeInfo |
| boxedVariables.forEach(f); |
| } |
| - bool isVariableBoxed(Local variable) => boxedVariables.containsKey(variable); |
| + bool isVariableBoxed(Local variable) { |
| + throw new UnsupportedError('KernelClosureClass.isVariableBoxed'); |
| + } |
| bool get isClosure => true; |
| } |
| @@ -450,6 +589,8 @@ class NodeBox { |
| final String name; |
| NodeBox(this.name); |
| + |
| + String toString() => 'NodeBox(name=$name)'; |
| } |
| class JClosureClass extends JClass { |