| Index: pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
|
| diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
|
| index d9d3f3faa16d017e9c67c010e53fa431f80011ad..8a86eda794f38ae280b234949db7f41412ce990d 100644
|
| --- a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
|
| +++ b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
|
| @@ -15,7 +15,7 @@ import '../universe/universe.dart';
|
| import '../tree/tree.dart' as tree show Modifiers;
|
|
|
| /// Translates the dart_tree IR to Dart backend AST.
|
| -Expression emit(tree.FunctionDefinition definition) {
|
| +ExecutableDefinition emit(tree.ExecutableDefinition definition) {
|
| return new ASTEmitter().emit(definition);
|
| }
|
|
|
| @@ -41,8 +41,8 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> {
|
| /// Statements emitted by the most recent call to [visitStatement].
|
| List<Statement> statementBuffer = <Statement>[];
|
|
|
| - /// The function currently being emitted.
|
| - FunctionElement functionElement;
|
| + /// The element currently being emitted.
|
| + ExecutableElement currentElement;
|
|
|
| /// Bookkeeping object needed to synthesize a variable declaration.
|
| modelx.VariableList variableList
|
| @@ -70,8 +70,53 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> {
|
| : this.parent = parent,
|
| usedVariableNames = parent.usedVariableNames;
|
|
|
| - FunctionExpression emit(tree.FunctionDefinition definition) {
|
| - functionElement = definition.element;
|
| + ExecutableDefinition emit(tree.ExecutableDefinition definition) {
|
| + if (definition is tree.FieldDefinition) {
|
| + return emitField(definition);
|
| + }
|
| + assert(definition is tree.FunctionDefinition);
|
| + return emitFunction(definition);
|
| + }
|
| +
|
| + FieldDefinition emitField(tree.FieldDefinition definition) {
|
| + currentElement = definition.element;
|
| + visitStatement(definition.body);
|
| + List<Statement> bodyParts;
|
| + for (tree.Variable variable in variableNames.keys) {
|
| + if (!declaredVariables.contains(variable)) {
|
| + addDeclaration(variable);
|
| + }
|
| + }
|
| + if (variables.length > 0) {
|
| + bodyParts = new List<Statement>();
|
| + bodyParts.add(new VariableDeclarations(variables));
|
| + bodyParts.addAll(statementBuffer);
|
| + } else {
|
| + bodyParts = statementBuffer;
|
| + }
|
| +
|
| + return new FieldDefinition(definition.element, ensureExpression(bodyParts));
|
| + }
|
| +
|
| + /// Returns an expression that will evaluate all of [bodyParts].
|
| + /// If [bodyParts] is a single [Return] return its value.
|
| + /// Otherwise wrap the body-parts in an immediately invoked closure.
|
| + Expression ensureExpression(List<Statement> bodyParts) {
|
| + if (bodyParts.length == 1) {
|
| + Statement onlyStatement = bodyParts.single;
|
| + if (onlyStatement is Return) {
|
| + return onlyStatement.expression;
|
| + }
|
| + }
|
| + Statement body = new Block(bodyParts);
|
| + FunctionExpression function =
|
| + new FunctionExpression(new Parameters([]), body);
|
| + function.element = null;
|
| + return new CallFunction(function, []);
|
| + }
|
| +
|
| + FunctionExpression emitFunction(tree.FunctionDefinition definition) {
|
| + currentElement = definition.element;
|
|
|
| Parameters parameters = emitRootParameters(definition);
|
|
|
| @@ -122,16 +167,16 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> {
|
|
|
| body = new Block(bodyParts);
|
| }
|
| - FunctionType functionType = functionElement.type;
|
| + FunctionType functionType = currentElement.type;
|
|
|
| return new FunctionExpression(
|
| parameters,
|
| body,
|
| - name: functionElement.name,
|
| + name: currentElement.name,
|
| returnType: emitOptionalType(functionType.returnType),
|
| - isGetter: functionElement.isGetter,
|
| - isSetter: functionElement.isSetter)
|
| - ..element = functionElement;
|
| + isGetter: currentElement.isGetter,
|
| + isSetter: currentElement.isSetter)
|
| + ..element = currentElement;
|
| }
|
|
|
| void addDeclaration(tree.Variable variable, [Expression initializer]) {
|
| @@ -304,7 +349,7 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> {
|
| String getVariableName(tree.Variable variable) {
|
| // If the variable belongs to an enclosing function, ask the parent emitter
|
| // for the variable name.
|
| - if (variable.host.element != functionElement) {
|
| + if (variable.host != currentElement) {
|
| return parent.getVariableName(variable);
|
| }
|
|
|
| @@ -333,7 +378,7 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> {
|
| // TODO(johnniwinther): Replace by synthetic [Entity].
|
| variable.element = new _SyntheticLocalVariableElement(
|
| name,
|
| - functionElement,
|
| + currentElement,
|
| variableList);
|
| }
|
| return name;
|
| @@ -341,7 +386,7 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> {
|
|
|
| String getConstantName(VariableElement element) {
|
| assert(element.kind == ElementKind.VARIABLE);
|
| - if (element.enclosingElement != functionElement) {
|
| + if (element.enclosingElement != currentElement) {
|
| return parent.getConstantName(element);
|
| }
|
| String name = constantNames[element];
|
| @@ -377,7 +422,7 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> {
|
| }
|
|
|
| bool isFirstOccurrence = (variableNames[stmt.variable] == null);
|
| - bool isDeclaredHere = stmt.variable.host.element == functionElement;
|
| + bool isDeclaredHere = stmt.variable.host == currentElement;
|
| String name = getVariableName(stmt.variable);
|
| Expression definition = visitExpression(stmt.definition);
|
|
|
| @@ -858,13 +903,14 @@ class UnshadowParameters extends tree.RecursiveVisitor {
|
| /// Parameters that are used in a context where it is shadowed.
|
| Set<tree.Variable> hasShadowedUse = new Set<tree.Variable>();
|
|
|
| - void unshadow(tree.FunctionDefinition definition) {
|
| - if (definition.isAbstract) return;
|
| -
|
| + void unshadow(tree.ExecutableDefinition definition) {
|
| + // Fields have no parameters.
|
| + if (definition is tree.FieldDefinition) return;
|
| visitFunctionDefinition(definition);
|
| }
|
|
|
| visitFunctionDefinition(tree.FunctionDefinition definition) {
|
| + if (definition.isAbstract) return;
|
| var oldShadow = shadowedParameters;
|
| var oldEnvironment = environment;
|
| environment = new Map<String, tree.Variable>.from(environment);
|
| @@ -883,7 +929,8 @@ class UnshadowParameters extends tree.RecursiveVisitor {
|
| for (int i=0; i<definition.parameters.length; i++) {
|
| tree.Variable param = definition.parameters[i];
|
| if (hasShadowedUse.remove(param)) {
|
| - tree.Variable newParam = new tree.Variable(definition, param.element);
|
| + tree.Variable newParam = new tree.Variable(definition.element,
|
| + param.element);
|
| definition.parameters[i] = newParam;
|
| definition.body = new tree.Assign(param, newParam, definition.body);
|
| newParam.writeCount = 1; // Being a parameter counts as a write.
|
|
|