| Index: dart/sdk/lib/_internal/compiler/implementation/js/nodes.dart
|
| diff --git a/dart/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/dart/sdk/lib/_internal/compiler/implementation/js/nodes.dart
|
| index da8cd445101840db456220c271eda22617c5f724..54af9c5f97d00d3306e8822bde0a22985e234859 100644
|
| --- a/dart/sdk/lib/_internal/compiler/implementation/js/nodes.dart
|
| +++ b/dart/sdk/lib/_internal/compiler/implementation/js/nodes.dart
|
| @@ -151,6 +151,10 @@ abstract class Node {
|
| void visitChildren(NodeVisitor visitor);
|
|
|
| VariableUse asVariableUse() => null;
|
| +
|
| + Statement toStatement() {
|
| + throw new UnsupportedError('toStatement');
|
| + }
|
| }
|
|
|
| class Program extends Node {
|
| @@ -164,6 +168,7 @@ class Program extends Node {
|
| }
|
|
|
| abstract class Statement extends Node {
|
| + Statement toStatement() => this;
|
| }
|
|
|
| class Block extends Statement {
|
| @@ -432,8 +437,71 @@ class LiteralStatement extends Statement {
|
| abstract class Expression extends Node {
|
| int get precedenceLevel;
|
|
|
| - PropertyAccess dot(String name) => new PropertyAccess.field(this, name);
|
| Call callWith(List<Expression> arguments) => new Call(this, arguments);
|
| +
|
| + New newWith(List<Expression> arguments) => new New(this, arguments);
|
| +
|
| + PropertyAccess operator [](expression) {
|
| + if (expression is Expression) {
|
| + return new PropertyAccess(this, expression);
|
| + } else if (expression is int) {
|
| + return new PropertyAccess.indexed(this, expression);
|
| + } else if (expression is String) {
|
| + return new PropertyAccess.field(this, expression);
|
| + } else {
|
| + throw new ArgumentError('Expected an int, String, or Expression');
|
| + }
|
| + }
|
| +
|
| + Statement toStatement() => new ExpressionStatement(this);
|
| +
|
| + Call call([expression]) {
|
| + List<Expression> arguments;
|
| + if (expression == null) {
|
| + arguments = <Expression>[];
|
| + } else if (expression is List) {
|
| + arguments = expression.map(js.toExpression).toList();
|
| + } else {
|
| + arguments = <Expression>[js.toExpression(expression)];
|
| + }
|
| + return callWith(arguments);
|
| + }
|
| +
|
| + Expression equals(expression) => binary('==', expression);
|
| +
|
| + Expression strictEquals(expression) => binary('===', expression);
|
| +
|
| + Expression notEquals(expression) => binary('!=', expression);
|
| +
|
| + Expression operator +(expression) => binary('+', expression);
|
| +
|
| + Expression operator -(expression) => binary('-', expression);
|
| +
|
| + Expression operator &(expression) => binary('&', expression);
|
| +
|
| + Expression operator <(expression) => binary('<', expression);
|
| +
|
| + Expression operator >(expression) => binary('>', expression);
|
| +
|
| + Expression operator >=(expression) => binary('>=', expression);
|
| +
|
| + Expression binary(String operator, expression) {
|
| + return new Binary(operator, this, js.toExpression(expression));
|
| + }
|
| +
|
| + Expression assign(expression) {
|
| + return new Assignment(this, js.toExpression(expression));
|
| + }
|
| +
|
| + Expression update(String operator, expression) {
|
| + return new Assignment.compound(this, operator, js.toExpression(expression));
|
| + }
|
| +
|
| + Expression get plusPlus => new Postfix('++', this);
|
| +
|
| + Prefix get typeof => new Prefix('typeof', this);
|
| +
|
| + Prefix get not => new Prefix('!', this);
|
| }
|
|
|
| class LiteralExpression extends Expression {
|
| @@ -661,6 +729,8 @@ class VariableUse extends VariableReference {
|
| accept(NodeVisitor visitor) => visitor.visitVariableUse(this);
|
|
|
| VariableUse asVariableUse() => this;
|
| +
|
| + VariableDeclarationList def([initializer]) => js.defineVar(name, initializer);
|
| }
|
|
|
| class VariableDeclaration extends VariableReference {
|
| @@ -859,48 +929,124 @@ class RegExpLiteral extends Expression {
|
| int get precedenceLevel => PRIMARY;
|
| }
|
|
|
| -Prefix typeOf(Expression argument) => new Prefix('typeof', argument);
|
| +class JsBuilder {
|
| + const JsBuilder();
|
|
|
| -Binary equals(Expression left, Expression right) {
|
| - return new Binary('==', left, right);
|
| -}
|
| + VariableUse operator [](String name) => new VariableUse(name);
|
|
|
| -Binary strictEquals(Expression left, Expression right) {
|
| - return new Binary('===', left, right);
|
| -}
|
| + // TODO(ahe): Remove this method.
|
| + Binary equals(Expression left, Expression right) {
|
| + return new Binary('==', left, right);
|
| + }
|
|
|
| -LiteralString string(String value) => new LiteralString('"$value"');
|
| + // TODO(ahe): Remove this method.
|
| + Binary strictEquals(Expression left, Expression right) {
|
| + return new Binary('===', left, right);
|
| + }
|
|
|
| -If if_(Expression condition, Node then, [Node otherwise]) {
|
| - return (otherwise == null)
|
| - ? new If.noElse(condition, then)
|
| - : new If(condition, then, otherwise);
|
| -}
|
| + LiteralString string(String value) => new LiteralString('"$value"');
|
|
|
| -Return return_([Expression value]) => new Return(value);
|
| + If if_(condition, thenPart, [elsePart]) {
|
| + condition = toExpression(condition);
|
| + return (elsePart == null)
|
| + ? new If.noElse(condition, toStatement(thenPart))
|
| + : new If(condition, toStatement(thenPart), toStatement(elsePart));
|
| + }
|
|
|
| -VariableUse use(String name) => new VariableUse(name);
|
| + Return return_([value]) {
|
| + return new Return(value == null ? null : toExpression(value));
|
| + }
|
|
|
| -PropertyAccess fieldAccess(Expression receiver, String fieldName) {
|
| - return new PropertyAccess.field(receiver, fieldName);
|
| -}
|
| + Block block(statement) {
|
| + if (statement is Block) {
|
| + return statement;
|
| + } else if (statement is List) {
|
| + return new Block(statement.map(toStatement).toList());
|
| + } else {
|
| + return new Block(<Statement>[toStatement(statement)]);
|
| + }
|
| + }
|
|
|
| -Block emptyBlock() => new Block.empty();
|
| + Fun fun(parameters, body) {
|
| + Parameter toParameter(parameter) {
|
| + if (parameter is String) {
|
| + return new Parameter(parameter);
|
| + } else if (parameter is Parameter) {
|
| + return parameter;
|
| + } else {
|
| + throw new ArgumentError('parameter should be a String or a Parameter');
|
| + }
|
| + }
|
| + if (parameters is! List) {
|
| + parameters = [parameters];
|
| + }
|
| + return new Fun(parameters.map(toParameter).toList(), block(body));
|
| + }
|
|
|
| -Block block1(Statement statement) => new Block(<Statement>[statement]);
|
| + Assignment assign(Expression leftHandSide, Expression value) {
|
| + return new Assignment(leftHandSide, value);
|
| + }
|
|
|
| -Block block2(Statement s1, Statement s2) => new Block(<Statement>[s1, s2]);
|
| + Expression undefined() => new Prefix('void', new LiteralNumber('0'));
|
|
|
| -Call call(Expression target, List<Expression> arguments) {
|
| - return new Call(target, arguments);
|
| -}
|
| + VariableDeclarationList defineVar(String name, [initializer]) {
|
| + if (initializer != null) {
|
| + initializer = toExpression(initializer);
|
| + }
|
| + var declaration = new VariableDeclaration(name);
|
| + var initialization = [new VariableInitialization(declaration, initializer)];
|
| + return new VariableDeclarationList(initialization);
|
| + }
|
|
|
| -Fun fun(List<String> parameterNames, Block body) {
|
| - return new Fun(parameterNames.map((n) => new Parameter(n)).toList(), body);
|
| -}
|
| + Statement toStatement(statement) {
|
| + if (statement is List) {
|
| + return new Block(statement.map(toStatement).toList());
|
| + } else if (statement is Node) {
|
| + return statement.toStatement();
|
| + } else {
|
| + throw new ArgumentError('statement');
|
| + }
|
| + }
|
|
|
| -Assignment assign(Expression leftHandSide, Expression value) {
|
| - return new Assignment(leftHandSide, value);
|
| + Expression toExpression(expression) {
|
| + if (expression is Expression) {
|
| + return expression;
|
| + } else if (expression is String) {
|
| + return this[expression];
|
| + } else if (expression is num) {
|
| + return new LiteralNumber('$expression');
|
| + } else if (expression is bool) {
|
| + return new LiteralBool(expression);
|
| + } else if (expression is Map) {
|
| + if (!expression.isEmpty) {
|
| + throw new ArgumentError('expression should be an empty Map');
|
| + }
|
| + return new ObjectInitializer([]);
|
| + } else {
|
| + throw new ArgumentError('expression should be an Expression, '
|
| + 'a String, a num, a bool, or a Map');
|
| + }
|
| + }
|
| +
|
| + ForIn forIn(String name, object, statement) {
|
| + return new ForIn(defineVar(name),
|
| + toExpression(object),
|
| + toStatement(statement));
|
| + }
|
| +
|
| + For for_(init, condition, update, statement) {
|
| + return new For(
|
| + toExpression(init), toExpression(condition), toExpression(update),
|
| + toStatement(statement));
|
| + }
|
| +
|
| + Try try_(body, {catchPart, finallyPart}) {
|
| + if (catchPart != null) catchPart = toStatement(catchPart);
|
| + if (finallyPart != null) finallyPart = toStatement(finallyPart);
|
| + return new Try(toStatement(body), catchPart, finallyPart);
|
| + }
|
| }
|
|
|
| -Expression undefined() => new Prefix('void', new LiteralNumber('0'));
|
| +const JsBuilder js = const JsBuilder();
|
| +
|
| +LiteralString string(String value) => js.string(value);
|
|
|