diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-11-14 17:18:57 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-11-14 17:18:57 +0000 |
| commit | 4c9a1c8d062c849e34ce0176e60b5cccca65c127 (patch) | |
| tree | e7cbbf81554e76db6724ab7c09cfa625f20312a5 | |
| parent | 196321f77a224909bcda8bed834a9fee4265a8df (diff) | |
Handle boxing correctly in compound assignments
| -rw-r--r-- | src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java | 36 | ||||
| -rw-r--r-- | src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java | 38 |
2 files changed, 67 insertions, 7 deletions
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java index bf66092..2bf6048 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -152,6 +152,10 @@ public class JavaReader { private static ExpressionNode readExpression(TypeName targetType, Expression expression) { ExpressionNode couscousExpression = readExpressionWithoutBoxing(expression); + return handleBoxing(targetType, couscousExpression); + } + + private static ExpressionNode handleBoxing(TypeName targetType, ExpressionNode couscousExpression) { if (isIntegerBox(targetType, couscousExpression)) { return StaticMethodCallNode.boxInt(couscousExpression); } else if (isIntegerUnbox(targetType, couscousExpression)) { @@ -165,6 +169,16 @@ public class JavaReader { } } + private static TypeName unboxedType(TypeName type) { + if (type.equals(ObjectValues.BOXED_INT)) { + return IntegerValue.REF; + } else if (type.equals(ObjectValues.BOXED_BOOLEAN)) { + return BooleanValue.REF; + } else { + return type; + } + } + private static boolean isIntegerBox(TypeName targetType, ExpressionNode expression) { return expression.getType().equals(IntegerValue.REF) && !targetType.equals(IntegerValue.REF); @@ -396,23 +410,31 @@ public class JavaReader { } private static ExpressionNode readAssignment(Assignment expression) { - // TODO: fix boxing AssignableExpressionNode left = (AssignableExpressionNode)readExpressionWithoutBoxing(expression.getLeftHandSide()); - ExpressionNode right = readExpression(left.getType(), expression.getRightHandSide()); if (expression.getOperator() == Assignment.Operator.ASSIGN) { + ExpressionNode right = readExpression(left.getType(), expression.getRightHandSide()); return AssignmentNode.assign(left, right); } else { + ExpressionNode right = readUnboxedExpression(expression.getRightHandSide()); Operator operator = readOperator(expression.getOperator()); return AssignmentNode.assign( left, - MethodCallNode.methodCall( - left, - operator.getMethodName(), - asList(right), - left.getType())); + handleBoxing( + left.getType(), + MethodCallNode.methodCall( + readUnboxedExpression(expression.getLeftHandSide()), + operator.getMethodName(), + asList(right), + unboxedType(left.getType())))); } } + private static ExpressionNode readUnboxedExpression(Expression expression) { + return readExpression( + unboxedType(typeOf(expression)), + expression); + } + private static Operator readOperator(Assignment.Operator operator) { if (operator == Assignment.Operator.PLUS_ASSIGN) { return Operator.ADD; diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java index 6f116cc..c08035f 100644 --- a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java +++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java @@ -380,6 +380,44 @@ public class JavaReaderTests { } @Test + public void rightOperandOfCompoundAssignmentsIsUnboxedIfNecessary() { + ClassNode classNode = readClass( + "public void go(int left, Integer right) {" + + " left += right;" + + "}"); + + MethodNode method = classNode.getMethods().get(0); + FormalArgumentNode left = method.getArguments().get(0); + FormalArgumentNode right = method.getArguments().get(1); + ExpressionStatementNode statement = (ExpressionStatementNode) + classNode.getMethods().get(0).getBody().get(0); + assertEquals( + assign( + reference(left), + integerAdd(reference(left), unboxInt(reference(right)))), + statement.getExpression()); + } + + @Test + public void leftOperandOfCompoundAssignmentsIsUnboxedIfNecessary() { + ClassNode classNode = readClass( + "public void go(Integer left, int right) {" + + " left += right;" + + "}"); + + MethodNode method = classNode.getMethods().get(0); + FormalArgumentNode left = method.getArguments().get(0); + FormalArgumentNode right = method.getArguments().get(1); + ExpressionStatementNode statement = (ExpressionStatementNode) + classNode.getMethods().get(0).getBody().get(0); + assertEquals( + assign( + reference(left), + boxInt(integerAdd(unboxInt(reference(left)), reference(right)))), + statement.getExpression()); + } + + @Test public void canReadPrefixDecrement() { ClassNode classNode = readClass( "public void go(int value) {" + |
