aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ExpressionNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/ast/Node.java6
-rw-r--r--src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java25
-rw-r--r--src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java87
-rw-r--r--src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java5
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java11
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java1
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java5
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java1
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java16
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionMethodReferenceReader.java2
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java39
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/Evaluator.java37
-rw-r--r--src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java4
-rw-r--r--src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java1
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java71
16 files changed, 181 insertions, 135 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
index 0f1ab4f..c483bcd 100644
--- a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
@@ -56,6 +56,11 @@ public interface ExpressionNode extends Node {
public T visit(FieldAccessNode fieldAccess) {
return visitor.visit(fieldAccess);
}
+
+ @Override
+ public T visit(TypeCoercionNode typeCoercion) {
+ return visitor.visit(typeCoercion);
+ }
});
}
diff --git a/src/main/java/org/zwobble/couscous/ast/Node.java b/src/main/java/org/zwobble/couscous/ast/Node.java
index 7c4d347..c9eed67 100644
--- a/src/main/java/org/zwobble/couscous/ast/Node.java
+++ b/src/main/java/org/zwobble/couscous/ast/Node.java
@@ -61,6 +61,12 @@ public interface Node {
}
@Override
+ public Void visit(TypeCoercionNode typeCoercion) {
+ visitor.visit(typeCoercion);
+ return null;
+ }
+
+ @Override
public Void visit(ReturnNode returnNode) {
visitor.visit(returnNode);
return null;
diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
index ccb9854..7c3b90b 100644
--- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
@@ -10,6 +10,7 @@ import org.zwobble.couscous.values.InternalCouscousValue;
import org.zwobble.couscous.values.ObjectValues;
import static java.util.Arrays.asList;
+import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
public class StaticMethodCallNode implements ExpressionNode {
@@ -18,35 +19,19 @@ public class StaticMethodCallNode implements ExpressionNode {
}
public static ExpressionNode boxInt(ExpressionNode value) {
- return staticMethodCall(
- InternalCouscousValue.REF,
- "boxInt",
- asList(value),
- ObjectValues.BOXED_INT);
+ return typeCoercion(value, ObjectValues.BOXED_INT);
}
public static ExpressionNode unboxInt(ExpressionNode value) {
- return staticMethodCall(
- InternalCouscousValue.REF,
- "unboxInt",
- asList(value),
- IntegerValue.REF);
+ return typeCoercion(value, IntegerValue.REF);
}
public static ExpressionNode boxBoolean(ExpressionNode value) {
- return staticMethodCall(
- InternalCouscousValue.REF,
- "boxBoolean",
- asList(value),
- ObjectValues.BOXED_BOOLEAN);
+ return typeCoercion(value, ObjectValues.BOXED_BOOLEAN);
}
public static ExpressionNode unboxBoolean(ExpressionNode value) {
- return staticMethodCall(
- InternalCouscousValue.REF,
- "unboxBoolean",
- asList(value),
- BooleanValue.REF);
+ return typeCoercion(value, BooleanValue.REF);
}
public static StaticMethodCallNode staticMethodCall(
diff --git a/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java b/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java
new file mode 100644
index 0000000..2c7b68e
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java
@@ -0,0 +1,87 @@
+package org.zwobble.couscous.ast;
+
+import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
+import org.zwobble.couscous.values.BooleanValue;
+import org.zwobble.couscous.values.IntegerValue;
+
+import java.util.function.Function;
+
+public class TypeCoercionNode implements ExpressionNode {
+ public static TypeCoercionNode typeCoercion(ExpressionNode expression, TypeName type) {
+ return new TypeCoercionNode(expression, type);
+ }
+
+ private final ExpressionNode expression;
+ private final TypeName type;
+
+ private TypeCoercionNode(ExpressionNode expression, TypeName type) {
+ this.expression = expression;
+ this.type = type;
+ }
+
+ public ExpressionNode getExpression() {
+ return expression;
+ }
+
+ @Override
+ public TypeName getType() {
+ return type;
+ }
+
+ public boolean isIntegerBox() {
+ return expression.getType().equals(IntegerValue.REF) &&
+ !type.equals(IntegerValue.REF);
+ }
+
+ public boolean isIntegerUnbox() {
+ return !expression.getType().equals(IntegerValue.REF) &&
+ type.equals(IntegerValue.REF);
+ }
+
+ public boolean isBooleanBox() {
+ return expression.getType().equals(BooleanValue.REF) &&
+ !type.equals(BooleanValue.REF);
+ }
+
+ public boolean isBooleanUnbox() {
+ return !expression.getType().equals(BooleanValue.REF) &&
+ type.equals(BooleanValue.REF);
+ }
+
+ @Override
+ public <T> T accept(ExpressionNodeMapper<T> visitor) {
+ return visitor.visit(this);
+ }
+
+ @Override
+ public ExpressionNode replaceExpressions(Function<ExpressionNode, ExpressionNode> replace) {
+ return new TypeCoercionNode(replace.apply(expression), type);
+ }
+
+ @Override
+ public String toString() {
+ return "TypeCoercionNode(" +
+ "expression=" + expression +
+ ", type=" + type +
+ ')';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ TypeCoercionNode that = (TypeCoercionNode) o;
+
+ if (!expression.equals(that.expression)) return false;
+ return type.equals(that.type);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = expression.hashCode();
+ result = 31 * result + type.hashCode();
+ return result;
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java
index 47ba9b6..8b65f35 100644
--- a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java
+++ b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java
@@ -80,6 +80,11 @@ public class NodeStructure {
}
@Override
+ public Stream<? extends Node> visit(TypeCoercionNode typeCoercion) {
+ return Stream.of(typeCoercion.getExpression());
+ }
+
+ @Override
public Stream<Node> visit(ReturnNode returnNode) {
return Stream.of(returnNode.getValue());
}
diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java
index c1c3e88..87b8598 100644
--- a/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java
+++ b/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java
@@ -1,14 +1,6 @@
package org.zwobble.couscous.ast.visitors;
-import org.zwobble.couscous.ast.AssignmentNode;
-import org.zwobble.couscous.ast.ConstructorCallNode;
-import org.zwobble.couscous.ast.FieldAccessNode;
-import org.zwobble.couscous.ast.LiteralNode;
-import org.zwobble.couscous.ast.MethodCallNode;
-import org.zwobble.couscous.ast.StaticMethodCallNode;
-import org.zwobble.couscous.ast.TernaryConditionalNode;
-import org.zwobble.couscous.ast.ThisReferenceNode;
-import org.zwobble.couscous.ast.VariableReferenceNode;
+import org.zwobble.couscous.ast.*;
public interface ExpressionNodeMapper<T> {
T visit(LiteralNode literal);
@@ -20,4 +12,5 @@ public interface ExpressionNodeMapper<T> {
T visit(StaticMethodCallNode staticMethodCall);
T visit(ConstructorCallNode call);
T visit(FieldAccessNode fieldAccess);
+ T visit(TypeCoercionNode typeCoercion);
}
diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java
index d38d7fa..4267c75 100644
--- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java
+++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java
@@ -12,6 +12,7 @@ public interface NodeMapper<T> {
T visit(StaticMethodCallNode staticMethodCall);
T visit(ConstructorCallNode call);
T visit(FieldAccessNode fieldAccess);
+ T visit(TypeCoercionNode typeCoercion);
T visit(ReturnNode returnNode);
T visit(ExpressionStatementNode expressionStatement);
diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java
index e4203e0..09cfcd3 100644
--- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java
+++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java
@@ -55,6 +55,11 @@ public class NodeMapperWithDefault<T> implements NodeMapper<T> {
}
@Override
+ public T visit(TypeCoercionNode typeCoercion) {
+ return defaultValue;
+ }
+
+ @Override
public T visit(ReturnNode returnNode) {
return defaultValue;
}
diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java
index 75e6da5..9f6be92 100644
--- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java
+++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java
@@ -12,6 +12,7 @@ public interface NodeVisitor {
void visit(StaticMethodCallNode staticMethodCall);
void visit(ConstructorCallNode call);
void visit(FieldAccessNode fieldAccess);
+ void visit(TypeCoercionNode typeCoercion);
void visit(ReturnNode returnNode);
void visit(ExpressionStatementNode expressionStatement);
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
index 913b1b7..ada7dea 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
@@ -261,6 +261,22 @@ public class PythonCodeGenerator {
public PythonExpressionNode visit(FieldAccessNode fieldAccess) {
return pythonAttributeAccess(generateExpression(fieldAccess.getLeft()), fieldAccess.getFieldName());
}
+
+ @Override
+ public PythonExpressionNode visit(TypeCoercionNode typeCoercion) {
+ PythonExpressionNode value = generateExpression(typeCoercion.getExpression());
+ if (typeCoercion.isIntegerBox()) {
+ return internalMethod("boxInt", asList(value));
+ } else if (typeCoercion.isIntegerUnbox()) {
+ return internalMethod("unboxInt", asList(value));
+ } else {
+ return value;
+ }
+ }
+
+ private PythonExpressionNode internalMethod(String name, List<PythonExpressionNode> arguments) {
+ return pythonCall(pythonAttributeAccess(pythonVariableReference("_couscous"), name), arguments);
+ }
}
private static boolean isPrimitive(ExpressionNode value) {
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionMethodReferenceReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionMethodReferenceReader.java
index 6c49d4e..d9a55e3 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionMethodReferenceReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionMethodReferenceReader.java
@@ -30,7 +30,7 @@ public class JavaExpressionMethodReferenceReader {
return lambda(
formalArguments,
- ImmutableList.of(returns(JavaExpressionReader.handleBoxing(
+ ImmutableList.of(returns(JavaExpressionReader.coerceExpression(
typeOf(functionalInterfaceMethod.getReturnType()),
generateValue(scope, expression, formalArguments)))));
}
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
index 367a34f..0e910a1 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
@@ -14,6 +14,7 @@ import static java.util.Arrays.asList;
import static org.zwobble.couscous.ast.ConstructorCallNode.constructorCall;
import static org.zwobble.couscous.ast.LiteralNode.literal;
import static org.zwobble.couscous.ast.MethodCallNode.not;
+import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion;
import static org.zwobble.couscous.frontends.java.JavaOperators.readOperator;
import static org.zwobble.couscous.frontends.java.JavaTypes.typeOf;
import static org.zwobble.couscous.util.ExtraLists.concat;
@@ -29,20 +30,14 @@ public class JavaExpressionReader {
ExpressionNode readExpression(TypeName targetType, Expression expression) {
ExpressionNode couscousExpression = readExpressionWithoutBoxing(expression);
- return handleBoxing(targetType, couscousExpression);
+ return coerceExpression(targetType, couscousExpression);
}
- static ExpressionNode handleBoxing(TypeName targetType, ExpressionNode couscousExpression) {
- 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 {
+ static ExpressionNode coerceExpression(TypeName targetType, ExpressionNode couscousExpression) {
+ if (targetType.equals(couscousExpression.getType())) {
return couscousExpression;
+ } else {
+ return typeCoercion(couscousExpression, targetType);
}
}
@@ -56,26 +51,6 @@ public class JavaExpressionReader {
}
}
- private static boolean isIntegerBox(TypeName targetType, ExpressionNode expression) {
- return expression.getType().equals(IntegerValue.REF) &&
- !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);
- }
-
ExpressionNode readExpressionWithoutBoxing(Expression expression) {
switch (expression.getNodeType()) {
case ASTNode.BOOLEAN_LITERAL:
@@ -308,7 +283,7 @@ public class JavaExpressionReader {
Operator operator = readOperator(expression.getOperator());
return AssignmentNode.assign(
left,
- handleBoxing(
+ coerceExpression(
left.getType(),
readPrimitiveOperation(operator, expression.getLeftHandSide(), expression.getRightHandSide())));
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
index 3e01f36..bee536a 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
@@ -1,23 +1,12 @@
package org.zwobble.couscous.interpreter;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.zwobble.couscous.ast.AssignmentNode;
-import org.zwobble.couscous.ast.ConstructorCallNode;
-import org.zwobble.couscous.ast.ExpressionNode;
-import org.zwobble.couscous.ast.FieldAccessNode;
-import org.zwobble.couscous.ast.LiteralNode;
-import org.zwobble.couscous.ast.MethodCallNode;
-import org.zwobble.couscous.ast.StaticMethodCallNode;
-import org.zwobble.couscous.ast.TernaryConditionalNode;
-import org.zwobble.couscous.ast.ThisReferenceNode;
-import org.zwobble.couscous.ast.VariableReferenceNode;
+import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.ast.visitors.AssignableExpressionNodeVisitor;
import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
-import org.zwobble.couscous.interpreter.values.BooleanInterpreterValue;
-import org.zwobble.couscous.interpreter.values.ConcreteType;
-import org.zwobble.couscous.interpreter.values.InterpreterValue;
-import org.zwobble.couscous.interpreter.values.InterpreterValues;
+import org.zwobble.couscous.interpreter.values.*;
+
+import java.util.List;
+import java.util.stream.Collectors;
public class Evaluator implements ExpressionNodeMapper<InterpreterValue> {
public static InterpreterValue eval(Environment environment, ExpressionNode expression) {
@@ -107,7 +96,21 @@ public class Evaluator implements ExpressionNodeMapper<InterpreterValue> {
InterpreterValue left = eval(fieldAccess.getLeft());
return left.getField(fieldAccess.getFieldName());
}
-
+
+ @Override
+ public InterpreterValue visit(TypeCoercionNode typeCoercion) {
+ // TODO: check that the type coercion is valid
+ // TODO: boxing booleans
+ InterpreterValue value = eval(typeCoercion.getExpression());
+ if (typeCoercion.isIntegerBox()) {
+ return ((IntegerInterpreterValue)value).box();
+ } else if (typeCoercion.isIntegerUnbox()) {
+ return value.getField("value");
+ } else {
+ return value;
+ }
+ }
+
private List<InterpreterValue> evalArguments(List<? extends ExpressionNode> arguments) {
return arguments.stream()
.map(argument -> eval(argument))
diff --git a/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java b/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
index 3e10586..2c8dfeb 100644
--- a/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
@@ -1,5 +1,6 @@
package org.zwobble.couscous.tests;
+import org.junit.Test;
import org.zwobble.couscous.CouscousCompiler;
import org.zwobble.couscous.ast.TypeName;
import org.zwobble.couscous.backends.python.PythonBackend;
@@ -8,13 +9,12 @@ import org.zwobble.couscous.tests.backends.python.PythonMethodRunner;
import org.zwobble.couscous.values.PrimitiveValue;
import java.io.IOException;
+import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
-import static org.junit.Assert.assertEquals;
import static org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively;
-import static org.zwobble.couscous.values.PrimitiveValues.value;
public class JavaToPythonTests extends CompilerTests {
protected PrimitiveValue execProgram(
diff --git a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
index b9ca169..4366ac4 100644
--- a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
@@ -57,6 +57,7 @@ public class ValueObjectTests {
{StaticMethodCallNode.class},
{TernaryConditionalNode.class},
{ThisReferenceNode.class},
+ {TypeCoercionNode.class},
{TypeName.class},
{VariableDeclaration.class},
{VariableReferenceNode.class},
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 0e929d8..2e61fe0 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
@@ -1,6 +1,5 @@
package org.zwobble.couscous.tests.frontends.java;
-import org.junit.Ignore;
import org.junit.Test;
import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.frontends.java.JavaReader;
@@ -33,6 +32,7 @@ import static org.zwobble.couscous.ast.ReturnNode.returns;
import static org.zwobble.couscous.ast.StaticMethodCallNode.*;
import static org.zwobble.couscous.ast.TernaryConditionalNode.ternaryConditional;
import static org.zwobble.couscous.ast.ThisReferenceNode.thisReference;
+import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion;
import static org.zwobble.couscous.ast.VariableReferenceNode.reference;
import static org.zwobble.couscous.ast.WhileNode.whileLoop;
import static org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively;
@@ -40,7 +40,7 @@ import static org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively;
public class JavaReaderTests {
@Test
public void canReadLiterals() {
- assertEquals(literal("hello"), readObjectExpression("\"hello\""));
+ assertEquals(literal("hello"), readExpression("String", "\"hello\""));
assertEquals(literal(true), readBooleanExpression("true"));
assertEquals(literal(false), readBooleanExpression("false"));
assertEquals(literal(42), readIntExpression("42"));
@@ -51,7 +51,7 @@ public class JavaReaderTests {
public void canReadThisReference() {
assertEquals(
thisReference(TypeName.of("com.example.Example")),
- readExpressionInInstanceMethod("this"));
+ readExpressionInInstanceMethod("com.example.Example", "this"));
}
@Test
@@ -153,7 +153,7 @@ public class JavaReaderTests {
public void canReadConstructorCalls() {
assertEquals(
constructorCall(TypeName.of("java.lang.String"), asList(literal("_"))),
- readObjectExpression("new String(\"_\")"));
+ readExpression("String", "new String(\"_\")"));
}
@Test
@@ -207,10 +207,11 @@ public class JavaReaderTests {
@Test
public void argumentIsBoxedIfNecessary() {
- StaticMethodCallNode expression = (StaticMethodCallNode) readObjectExpression(
+ StaticMethodCallNode expression = (StaticMethodCallNode) readExpression(
+ "String",
"java.util.Objects.toString(42)");
assertEquals(
- boxInt(literal(42)),
+ typeCoercion(literal(42), ObjectValues.OBJECT),
expression.getArguments().get(0));
}
@@ -286,14 +287,14 @@ public class JavaReaderTests {
public void equalityOperatorDoesNotUnboxIfBothOperandsAreBoxed() {
assertEquals(
same(
- constructorCall(TypeName.of("java.lang.Integer"), asList(literal(1))),
- constructorCall(TypeName.of("java.lang.Integer"), asList(literal(2)))),
+ typeCoercion(constructorCall(ObjectValues.BOXED_INT, asList(literal(1))), ObjectValues.OBJECT),
+ typeCoercion(constructorCall(ObjectValues.BOXED_INT, asList(literal(2))), ObjectValues.OBJECT)),
readBooleanExpression("new Integer(1) == new Integer(2)"));
assertEquals(
not(same(
- constructorCall(TypeName.of("java.lang.Integer"), asList(literal(1))),
- constructorCall(TypeName.of("java.lang.Integer"), asList(literal(2))))),
+ typeCoercion(constructorCall(ObjectValues.BOXED_INT, asList(literal(1))), ObjectValues.OBJECT),
+ typeCoercion(constructorCall(ObjectValues.BOXED_INT, asList(literal(2))), ObjectValues.OBJECT))),
readBooleanExpression("new Integer(1) != new Integer(2)"));
}
@@ -333,7 +334,7 @@ public class JavaReaderTests {
}
@Test
- public void valuesOfAssignmentsAreBoxedIfNecessary() {
+ public void valuesOfAssignmentsAreTypeCoercedIfNecessary() {
ClassNode classNode = readClass(
"private Object value;" +
"public Object getValue() {" +
@@ -347,7 +348,7 @@ public class JavaReaderTests {
thisReference(TypeName.of("com.example.Example")),
"value",
ObjectValues.OBJECT),
- boxInt(literal(4))),
+ typeCoercion(literal(4), ObjectValues.OBJECT)),
returnNode.getValue());
}
@@ -366,45 +367,11 @@ public class JavaReaderTests {
}
@Test
- public void initialValueOfLocalVariableDeclarationsAreBoxedIfNecessary() {
+ public void initialValueOfLocalVariableDeclarationsAreTypeCoercedIfNecessary() {
List<StatementNode> statements = readStatements("Object x = 4;");
LocalVariableDeclarationNode declaration = (LocalVariableDeclarationNode) statements.get(0);
- assertEquals(boxInt(literal(4)), declaration.getInitialValue());
- }
-
- @Test
- 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(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());
+ assertEquals(typeCoercion(literal(4), ObjectValues.OBJECT), declaration.getInitialValue());
}
@Test
@@ -621,9 +588,9 @@ public class JavaReaderTests {
method.getBody());
}
- private ExpressionNode readExpressionInInstanceMethod(String expressionSource) {
+ private ExpressionNode readExpressionInInstanceMethod(String returnType, String expressionSource) {
String javaClass =
- "public Object main() {" +
+ "public " + returnType + " main() {" +
" return " + expressionSource + ";" +
"}";
@@ -632,10 +599,6 @@ public class JavaReaderTests {
return returnStatement.getValue();
}
- private ExpressionNode readObjectExpression(String expressionSource) {
- return readExpression("Object", expressionSource);
- }
-
private ExpressionNode readBooleanExpression(String expressionSource) {
return readExpression("boolean", expressionSource);
}