aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java17
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java14
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java38
3 files changed, 64 insertions, 5 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
index 06c63da..b33e94c 100644
--- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
@@ -4,6 +4,7 @@ import java.util.List;
import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
import org.zwobble.couscous.values.BooleanValue;
+import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.InternalCouscousValue;
import org.zwobble.couscous.values.ObjectValues;
@@ -21,6 +22,14 @@ public class StaticMethodCallNode implements ExpressionNode {
asList(value),
ObjectValues.BOXED_INT);
}
+
+ public static ExpressionNode unboxInt(ExpressionNode value) {
+ return staticMethodCall(
+ InternalCouscousValue.REF,
+ "unboxInt",
+ asList(value),
+ IntegerValue.REF);
+ }
public static ExpressionNode boxBoolean(ExpressionNode value) {
return staticMethodCall(
@@ -29,6 +38,14 @@ public class StaticMethodCallNode implements ExpressionNode {
asList(value),
ObjectValues.BOXED_BOOLEAN);
}
+
+ public static ExpressionNode unboxBoolean(ExpressionNode value) {
+ return staticMethodCall(
+ InternalCouscousValue.REF,
+ "unboxBoolean",
+ asList(value),
+ BooleanValue.REF);
+ }
public static StaticMethodCallNode staticMethodCall(
String className,
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 99d0268..a47c4e9 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -168,8 +168,12 @@ public class JavaReader {
ExpressionNode couscousExpression = readExpressionWithoutBoxing(expression);
if (isIntegerBox(targetType, couscousExpression)) {
return StaticMethodCallNode.boxInt(couscousExpression);
+ } else if (isIntegerUnbox(targetType, couscousExpression)) {
+ return StaticMethodCallNode.unboxInt(couscousExpression);
} else if (isBooleanBox(targetType, couscousExpression)) {
return StaticMethodCallNode.boxBoolean(couscousExpression);
+ } else if (isBooleanUnbox(targetType, couscousExpression)) {
+ return StaticMethodCallNode.unboxBoolean(couscousExpression);
} else {
return couscousExpression;
}
@@ -180,11 +184,21 @@ public class JavaReader {
!targetType.equals(IntegerValue.REF);
}
+ private static boolean isIntegerUnbox(TypeName targetType, ExpressionNode expression) {
+ return !expression.getType().equals(IntegerValue.REF) &&
+ targetType.equals(IntegerValue.REF);
+ }
+
private static boolean isBooleanBox(TypeName targetType, ExpressionNode expression) {
return expression.getType().equals(BooleanValue.REF) &&
!targetType.equals(BooleanValue.REF);
}
+ private static boolean isBooleanUnbox(TypeName targetType, ExpressionNode expression) {
+ return !expression.getType().equals(BooleanValue.REF) &&
+ targetType.equals(BooleanValue.REF);
+ }
+
private static ExpressionNode readExpressionWithoutBoxing(Expression expression) {
switch (expression.getNodeType()) {
case ASTNode.BOOLEAN_LITERAL:
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 cc95f0f..b8309b3 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
@@ -35,9 +35,11 @@ import static org.zwobble.couscous.ast.FieldDeclarationNode.field;
import static org.zwobble.couscous.ast.LiteralNode.literal;
import static org.zwobble.couscous.ast.MethodCallNode.methodCall;
import static org.zwobble.couscous.ast.MethodCallNode.not;
+import static org.zwobble.couscous.ast.StaticMethodCallNode.boxBoolean;
import static org.zwobble.couscous.ast.StaticMethodCallNode.boxInt;
import static org.zwobble.couscous.ast.StaticMethodCallNode.same;
import static org.zwobble.couscous.ast.StaticMethodCallNode.staticMethodCall;
+import static org.zwobble.couscous.ast.StaticMethodCallNode.unboxInt;
import static org.zwobble.couscous.ast.TernaryConditionalNode.ternaryConditional;
import static org.zwobble.couscous.ast.ThisReferenceNode.thisReference;
import static org.zwobble.couscous.ast.VariableReferenceNode.reference;
@@ -250,7 +252,7 @@ public class JavaReaderTests {
}
@Test
- public void integersAreBoxedIfAssignedToObjectVariable() {
+ public void valuesOfAssignmentsAreBoxedIfNecessary() {
ClassNode classNode = readClass(
"private Object value;" +
"public Object getValue() {" +
@@ -283,19 +285,45 @@ public class JavaReaderTests {
}
@Test
- public void integersAreBoxedIfDeclaredAsObjectVariable() {
+ public void initialValueOfLocalVariableDeclarationsAreBoxedIfNecessary() {
List<StatementNode> statements = readStatements("Object x = 4;");
LocalVariableDeclarationNode declaration = (LocalVariableDeclarationNode) statements.get(0);
- assertEquals(StaticMethodCallNode.boxInt(literal(4)), declaration.getInitialValue());
+ assertEquals(boxInt(literal(4)), declaration.getInitialValue());
}
@Test
- public void booleansAreBoxedIfDeclaredAsObjectVariable() {
+ public void integersAreBoxedWhenTargetTypeIsObject() {
+ List<StatementNode> statements = readStatements("Object x = 4;");
+
+ LocalVariableDeclarationNode declaration = (LocalVariableDeclarationNode) statements.get(0);
+ assertEquals(boxInt(literal(4)), declaration.getInitialValue());
+ }
+
+ @Test
+ public void booleansAreBoxedWhenTargetTypeIsObject() {
List<StatementNode> statements = readStatements("Object x = true;");
LocalVariableDeclarationNode declaration = (LocalVariableDeclarationNode) statements.get(0);
- assertEquals(StaticMethodCallNode.boxBoolean(literal(true)), declaration.getInitialValue());
+ assertEquals(boxBoolean(literal(true)), declaration.getInitialValue());
+ }
+
+ @Test
+ public void integersAreUnboxedIfTargetTypeIsPrimitive() {
+ List<StatementNode> statements = readStatements("Integer x = 4; int y = x;");
+
+ LocalVariableDeclarationNode boxedDeclaration = (LocalVariableDeclarationNode) statements.get(0);
+ LocalVariableDeclarationNode unboxedDeclaration = (LocalVariableDeclarationNode) statements.get(1);
+ assertEquals(unboxInt(reference(boxedDeclaration)), unboxedDeclaration.getInitialValue());
+ }
+
+ @Test
+ public void booleansAreUnboxedIfTargetTypeIsPrimitive() {
+ List<StatementNode> statements = readStatements("Boolean x = false; boolean y = x;");
+
+ LocalVariableDeclarationNode boxedDeclaration = (LocalVariableDeclarationNode) statements.get(0);
+ LocalVariableDeclarationNode unboxedDeclaration = (LocalVariableDeclarationNode) statements.get(1);
+ assertEquals(StaticMethodCallNode.unboxBoolean(reference(boxedDeclaration)), unboxedDeclaration.getInitialValue());
}
@Test