Remove closure_conversion.dart from pkg/kernel.

This file is not strong-mode clean, but since a more recent version
of closure conversion still exists in a branch on the kernel github
repo, there is not much point in fixing this version of it.

BUG=
R=ahe@google.com

Review URL: https://codereview.chromium.org/2526793002 .
This commit is contained in:
Asger Feldthaus 2016-11-23 15:34:35 +01:00
parent f13881ac08
commit 5d310431bd
2 changed files with 3 additions and 449 deletions

View file

@ -12,7 +12,6 @@ import 'package:kernel/checks.dart' as checks;
import 'package:kernel/transformations/continuation.dart' as cont;
import 'package:kernel/transformations/infer_values.dart' as infer_values;
import 'package:kernel/transformations/mixin_full_resolution.dart' as mix;
import 'package:kernel/transformations/closure_conversion.dart' as closures;
import 'package:kernel/transformations/treeshaker.dart' as treeshaker;
import 'batch_util.dart';
@ -23,10 +22,7 @@ ArgParser parser = new ArgParser()
allowed: ['text', 'bin'],
defaultsTo: 'bin',
help: 'Output format.')
..addOption('out',
abbr: 'o',
help: 'Output file.',
defaultsTo: null)
..addOption('out', abbr: 'o', help: 'Output file.', defaultsTo: null)
..addFlag('verbose',
abbr: 'v',
negatable: false,
@ -76,13 +72,11 @@ Future<CompilerOutcome> runTransformation(List<String> arguments) async {
case 'resolve-mixins':
program = mix.transformProgram(program);
break;
case 'closures':
program = closures.transformProgram(program);
break;
case 'treeshake':
program = treeshaker.transformProgram(program);
break;
default: throw 'Unknown transformation';
default:
throw 'Unknown transformation';
}
program.accept(new checks.CheckParentPointers());

View file

@ -1,440 +0,0 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library kernel.transformations.closure_conversion;
import '../ast.dart';
import '../core_types.dart';
import '../visitor.dart';
Program transformProgram(Program program) {
var captured = new CapturedVariables();
captured.visitProgram(program);
var convert =
new ClosureConverter(new CoreTypes(program), captured.variables);
return convert.visitProgram(program);
}
class CapturedVariables extends RecursiveVisitor {
FunctionNode _currentFunction;
final Map<VariableDeclaration, FunctionNode> _function =
<VariableDeclaration, FunctionNode>{};
final Set<VariableDeclaration> variables = new Set<VariableDeclaration>();
visitFunctionNode(FunctionNode node) {
var saved = _currentFunction;
_currentFunction = node;
node.visitChildren(this);
_currentFunction = saved;
}
visitVariableDeclaration(VariableDeclaration node) {
_function[node] = _currentFunction;
node.visitChildren(this);
}
visitVariableGet(VariableGet node) {
if (_function[node.variable] != _currentFunction) {
variables.add(node.variable);
}
node.visitChildren(this);
}
visitVariableSet(VariableSet node) {
if (_function[node.variable] != _currentFunction) {
variables.add(node.variable);
}
node.visitChildren(this);
}
}
abstract class Context {
Expression get expression;
void extend(VariableDeclaration variable, Expression value);
Expression lookup(VariableDeclaration variable);
Expression assign(VariableDeclaration variable, Expression value);
Context toClosureContext(VariableDeclaration parameter);
}
class NoContext extends Context {
final ClosureConverter converter;
NoContext(this.converter);
Expression get expression => new NullLiteral();
void extend(VariableDeclaration variable, Expression value) {
converter.context =
new LocalContext(converter, this)..extend(variable, value);
}
Expression lookup(VariableDeclaration variable) {
throw 'Unbound NoContext.lookup($variable)';
}
Expression assign(VariableDeclaration variable, Expression value) {
throw 'Unbound NoContext.assign($variable, ...)';
}
Context toClosureContext(VariableDeclaration parameter) {
return new ClosureContext(converter, parameter,
<List<VariableDeclaration>>[]);
}
}
class LocalContext extends Context {
final ClosureConverter converter;
final Context parent;
final VariableDeclaration self;
final IntLiteral size;
final List<VariableDeclaration> variables = <VariableDeclaration>[];
LocalContext._internal(this.converter, this.parent, this.self, this.size);
factory LocalContext(ClosureConverter converter, Context parent) {
Class contextClass = converter.internalContextClass;
assert(contextClass.constructors.length == 1);
IntLiteral zero = new IntLiteral(0);
VariableDeclaration declaration =
new VariableDeclaration.forValue(
new ConstructorInvocation(contextClass.constructors.first,
new Arguments(<Expression>[zero])),
type: new InterfaceType(contextClass));
converter.insert(declaration);
converter.insert(new ExpressionStatement(
new PropertySet(new VariableGet(declaration),
new Name('parent'),
parent.expression)));
return new LocalContext._internal(converter, parent, declaration, zero);
}
Expression get expression => new VariableGet(self);
void extend(VariableDeclaration variable, Expression value) {
converter.insert(
new ExpressionStatement(
new MethodInvocation(
expression,
new Name('[]='),
new Arguments(
<Expression>[new IntLiteral(variables.length), value]))));
++size.value;
variables.add(variable);
}
Expression lookup(VariableDeclaration variable) {
var index = variables.indexOf(variable);
return index == -1
? parent.lookup(variable)
: new MethodInvocation(
expression,
new Name('[]'),
new Arguments(<Expression>[new IntLiteral(index)]));
}
Expression assign(VariableDeclaration variable, Expression value) {
var index = variables.indexOf(variable);
return index == -1
? parent.assign(variable, value)
: new MethodInvocation(
expression,
new Name('[]='),
new Arguments(<Expression>[new IntLiteral(index), value]));
}
Context toClosureContext(VariableDeclaration parameter) {
List<List<VariableDeclaration>> variabless = <List<VariableDeclaration>>[];
var current = this;
while (current != null && current is! NoContext) {
if (current is LocalContext) {
variabless.add(current.variables);
current = current.parent;
} else if (current is ClosureContext) {
variabless.addAll(current.variabless);
current = null;
} else if (current is LoopContext) {
// TODO.
current = current.parent;
}
}
return new ClosureContext(converter, parameter, variabless);
}
}
class LoopContext {
final ClosureConverter converter;
final Context parent;
LoopContext(this.converter, this.parent);
void extend(VariableDeclaration variable, Expression value) {
converter.context =
new LocalContext(converter, parent)..extend(variable, value);
}
}
class ClosureContext extends Context {
final ClosureConverter converter;
final VariableDeclaration self;
final List<List<VariableDeclaration>> variabless;
ClosureContext(this.converter, this.self, this.variabless);
Expression get expression => new VariableGet(self);
void extend(VariableDeclaration variable, Expression value) {
converter.context =
new LocalContext(converter, this)..extend(variable, value);
}
Expression lookup(VariableDeclaration variable) {
var context = expression;
for (var variables in variabless) {
var index = variables.indexOf(variable);
if (index != -1) {
return new MethodInvocation(
context,
new Name('[]'),
new Arguments(<Expression>[new IntLiteral(index)]));
}
context = new PropertyGet(context, new Name('parent'));
}
throw 'Unbound ClosureContext.lookup($variable)';
}
Expression assign(VariableDeclaration variable, Expression value) {
var context = expression;
for (var variables in variabless) {
var index = variables.indexOf(variable);
if (index != -1) {
return new MethodInvocation(
context,
new Name('[]='),
new Arguments(<Expression>[new IntLiteral(index), value]));
}
context = new PropertyGet(context, new Name('parent'));
}
throw 'Unbound ClosureContext.lookup($variable)';
}
Context toClosureContext(VariableDeclaration parameter) {
return new ClosureContext(converter, parameter, variabless);
}
}
class ClosureConverter extends Transformer {
final CoreTypes coreTypes;
Class internalContextClass;
final Set<VariableDeclaration> captured;
Block _currentBlock;
int _insertionIndex = 0;
Context context;
ClosureConverter(this.coreTypes, this.captured) {
internalContextClass = coreTypes.getCoreClass('dart:_internal', 'Context');
}
void insert(Statement statement) {
_currentBlock.statements.insert(_insertionIndex++, statement);
statement.parent = _currentBlock;
}
TreeNode visitConstructor(Constructor node) {
return node;
}
TreeNode visitFunctionDeclaration(FunctionDeclaration node) {
if (captured.contains(node.variable)) {
context.extend(node.variable,
new FunctionExpression(node.function));
}
Block savedBlock = _currentBlock;
int savedIndex = _insertionIndex;
Context savedContext = context;
Statement body = node.function.body;
assert(body != null);
if (body is Block) {
_currentBlock = body;
} else {
_currentBlock = new Block(<Statement>[body]);
node.function.body = body.parent = _currentBlock;
}
_insertionIndex = 0;
// TODO: This is really the closure, not the context.
VariableDeclaration parameter =
new VariableDeclaration(null,
type: internalContextClass.rawType,
isFinal: true);
node.function.positionalParameters.insert(0, parameter);
parameter.parent = node.function;
++node.function.requiredParameterCount;
context = context.toClosureContext(parameter);
// Don't visit the children, because that included a variable declaration.
node.function = node.function.accept(this);
_currentBlock = savedBlock;
_insertionIndex = savedIndex;
context = savedContext;
return captured.contains(node.variable) ? null : node;
}
TreeNode visitFunctionExpression(FunctionExpression node) {
Block savedBlock = _currentBlock;
int savedIndex = _insertionIndex;
Context savedContext = context;
Statement body = node.function.body;
assert(body != null);
if (body is Block) {
_currentBlock = body;
} else {
_currentBlock = new Block(<Statement>[body]);
node.function.body = body.parent = _currentBlock;
}
_insertionIndex = 0;
// TODO: This is really the closure, not the context.
VariableDeclaration parameter =
new VariableDeclaration(null,
type: internalContextClass.rawType,
isFinal: true);
node.function.positionalParameters.insert(0, parameter);
parameter.parent = node.function;
++node.function.requiredParameterCount;
context = context.toClosureContext(parameter);
node.transformChildren(this);
_currentBlock = savedBlock;
_insertionIndex = savedIndex;
context = savedContext;
return node;
}
TreeNode visitProcedure(Procedure node) {
assert(_currentBlock == null);
assert(_insertionIndex == 0);
assert(context == null);
Statement body = node.function.body;
if (body == null) return node;
// Ensure that the body is a block which becomes the current block.
if (body is Block) {
_currentBlock = body;
} else {
_currentBlock = new Block(<Statement>[body]);
node.function.body = body.parent = _currentBlock;
}
_insertionIndex = 0;
// Start with no context. This happens after setting up _currentBlock
// so statements can be emitted into _currentBlock if necessary.
context = new NoContext(this);
node.transformChildren(this);
_currentBlock = null;
_insertionIndex = 0;
context = null;
return node;
}
TreeNode visitLocalInitializer(LocalInitializer node) {
assert(!captured.contains(node.variable));
node.transformChildren(this);
return node;
}
TreeNode visitFunctionNode(FunctionNode node) {
transformList(node.typeParameters, this, node);
void extend(VariableDeclaration parameter) {
context.extend(parameter, new VariableGet(parameter));
}
// TODO: Can parameters contain initializers (e.g., for optional ones) that
// need to be closure converted?
node.positionalParameters.where(captured.contains).forEach(extend);
node.namedParameters.where(captured.contains).forEach(extend);
assert(node.body != null);
node.body = node.body.accept(this);
node.body.parent = node;
return node;
}
TreeNode visitBlock(Block node) {
Block savedBlock;
int savedIndex;
if (_currentBlock != node) {
savedBlock = _currentBlock;
savedIndex = _insertionIndex;
_currentBlock = node;
_insertionIndex = 0;
}
while (_insertionIndex < _currentBlock.statements.length) {
assert(_currentBlock == node);
var original = _currentBlock.statements[_insertionIndex];
var transformed = original.accept(this);
assert(_currentBlock.statements[_insertionIndex] == original);
if (transformed == null) {
_currentBlock.statements.removeAt(_insertionIndex);
} else {
_currentBlock.statements[_insertionIndex++] = transformed;
transformed.parent = _currentBlock;
}
}
if (savedBlock != null) {
_currentBlock = savedBlock;
_insertionIndex = savedIndex;
}
return node;
}
TreeNode visitVariableDeclaration(VariableDeclaration node) {
node.transformChildren(this);
if (!captured.contains(node)) return node;
context.extend(node, node.initializer ?? new NullLiteral());
// TODO(ahe): Return null here when the parent has been correctly
// rewritten. So far, only for-in is known to use this return value.
return new VariableDeclaration(null, initializer: new InvalidExpression());
}
TreeNode visitVariableGet(VariableGet node) {
return captured.contains(node.variable)
? context.lookup(node.variable)
: node;
}
TreeNode visitVariableSet(VariableSet node) {
node.transformChildren(this);
return captured.contains(node.variable)
? context.assign(node.variable, node.value)
: node;
}
}