Index: sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart |
index 2026ca8a956367298ef8ac6763569688831b3fc3..8738ec6421d19e08451d471aba754bb729f66542 100644 |
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart |
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart |
@@ -108,6 +108,49 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> { |
return new Parameters(params.map(emitParameter).toList(growable:false)); |
} |
+ /// True if the two expressions are a reference to the same variable. |
+ bool isSameVariable(Expression e1, Expression e2) { |
+ // TODO(asgerf): Using the annotated element isn't the best way to do this |
+ // since elements are supposed to go away from codegen when we discard the |
+ // old backend. |
+ return e1 is Identifier && |
+ e2 is Identifier && |
+ e1.element is VariableElement && |
+ e1.element == e2.element; |
+ } |
+ |
+ Expression makeAssignment(Expression target, Expression value) { |
+ // Try to print as compound assignment or increment |
+ if (value is BinaryOperator && isCompoundableOperator(value.operator)) { |
+ Expression leftOperand = value.left; |
+ Expression rightOperand = value.right; |
+ bool valid = false; |
+ if (isSameVariable(target, leftOperand)) { |
+ valid = true; |
+ } else if (target is FieldExpression && |
+ leftOperand is FieldExpression && |
+ isSameVariable(target.object, leftOperand.object) && |
+ target.fieldName == leftOperand.fieldName) { |
+ valid = true; |
+ } else if (target is IndexExpression && |
+ leftOperand is IndexExpression && |
+ isSameVariable(target.object, leftOperand.object) && |
+ isSameVariable(target.index, leftOperand.index)) { |
+ valid = true; |
+ } |
+ if (valid) { |
+ if (rightOperand is Literal && rightOperand.value.isOne && |
+ (value.operator == '+' || value.operator == '-')) { |
+ return new Increment.prefix(target, value.operator + value.operator); |
+ } else { |
+ return new Assignment(target, value.operator + '=', rightOperand); |
+ } |
+ } |
+ } |
+ // Fall back to regular assignment |
+ return new Assignment(target, '=', value); |
+ } |
+ |
void visitExpressionStatement(tree.ExpressionStatement stmt) { |
Expression e = visitExpression(stmt.expression); |
statementBuffer.add(new ExpressionStatement(e)); |
@@ -145,11 +188,9 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> { |
variables.add(new VariableDeclaration(stmt.variable.name) |
..element = stmt.variable.element); |
} |
- Expression def = visitExpression(stmt.definition); |
- statementBuffer.add(new ExpressionStatement(new Assignment( |
+ statementBuffer.add(new ExpressionStatement(makeAssignment( |
visitVariable(stmt.variable), |
- '=', |
- def))); |
+ visitExpression(stmt.definition)))); |
visitStatement(stmt.next); |
} |
@@ -260,15 +301,14 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> { |
return new FieldExpression(receiver, exp.selector.name); |
case SelectorKind.SETTER: |
- return new Assignment( |
+ return makeAssignment( |
new FieldExpression(receiver, exp.selector.name), |
- '=', |
args[0]); |
case SelectorKind.INDEX: |
Expression e = new IndexExpression(receiver, args[0]); |
if (args.length == 2) { |
- e = new Assignment(e, '=', args[1]); |
+ e = makeAssignment(e, args[1]); |
} |
return e; |