aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java42
-rw-r--r--src/main/java/org/zwobble/couscous/util/ExtraLists.java2
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java29
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java2
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java5
5 files changed, 65 insertions, 15 deletions
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java
index c3c4f21..e75585f 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java
@@ -1,5 +1,6 @@
package org.zwobble.couscous.frontends.java;
+import com.google.common.collect.Lists;
import org.eclipse.jdt.core.dom.*;
import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.ast.sugar.SwitchCaseNode;
@@ -167,11 +168,24 @@ class JavaStatementReader {
private List<StatementNode> readTryStatement(TryStatement statement) {
@SuppressWarnings("unchecked")
- List<CatchClause> catchClauses = statement.catchClauses();
- return list(tryStatement(
- readStatement(statement.getBody()),
- eagerMap(catchClauses, this::readCatchClause),
- statement.getFinally() == null ? list() : readStatement(statement.getFinally())));
+ List<VariableDeclarationExpression> resources = statement.resources();
+ List<LocalVariableDeclarationNode> resourceDeclarations = eagerFlatMap(resources, this::readVariableDeclarationExpression);
+ List<StatementNode> body = readStatement(statement.getBody());
+ for (LocalVariableDeclarationNode resource : Lists.reverse(resourceDeclarations)) {
+ body = list(
+ resource,
+ tryStatement(body, list(), list(expressionStatement(methodCall(reference(resource), "close", list(), Types.VOID))))
+ );
+ }
+ @SuppressWarnings("unchecked")
+ List<CatchClause> javaCatchClauses = statement.catchClauses();
+ List<ExceptionHandlerNode> catchClauses = eagerMap(javaCatchClauses, this::readCatchClause);
+ List<StatementNode> finallyBody = statement.getFinally() == null ? list() : readStatement(statement.getFinally());
+ if (catchClauses.isEmpty() && finallyBody.isEmpty()) {
+ return body;
+ } else {
+ return list(tryStatement(body, catchClauses, finallyBody));
+ }
}
private ExceptionHandlerNode readCatchClause(CatchClause clause) {
@@ -191,18 +205,16 @@ class JavaStatementReader {
}
private List<StatementNode> readForStatement(ForStatement statement) {
- List javaInitialisers = statement.initializers();
+ @SuppressWarnings("unchecked")
+ List<VariableDeclarationExpression> javaInitialisers = statement.initializers();
if (javaInitialisers.size() != 1) {
throw new UnsupportedOperationException();
}
- VariableDeclarationExpression javaDeclaration = (VariableDeclarationExpression) javaInitialisers.get(0);
- @SuppressWarnings("unchecked")
- List<VariableDeclarationFragment> fragments = javaDeclaration.fragments();
@SuppressWarnings("unchecked")
List<Expression> updaters = statement.updaters();
return append(
- readDeclarationFragments(fragments, typeOf(javaDeclaration.getType())),
+ readVariableDeclarationExpression(javaInitialisers.get(0)),
whileLoop(
readExpression(Types.BOOLEAN, statement.getExpression()),
concat(
@@ -232,10 +244,16 @@ class JavaStatementReader {
@SuppressWarnings("unchecked")
List<VariableDeclarationFragment> fragments = statement.fragments();
Type type = typeOf(statement.getType());
- return readDeclarationFragments(fragments, type);
+ return (List)readDeclarationFragments(fragments, type);
+ }
+
+ private List<LocalVariableDeclarationNode> readVariableDeclarationExpression(VariableDeclarationExpression expression) {
+ @SuppressWarnings("unchecked")
+ List<VariableDeclarationFragment> fragments = expression.fragments();
+ return readDeclarationFragments(fragments, typeOf(expression.getType()));
}
- private List<StatementNode> readDeclarationFragments(
+ private List<LocalVariableDeclarationNode> readDeclarationFragments(
List<VariableDeclarationFragment> fragments,
Type type
) {
diff --git a/src/main/java/org/zwobble/couscous/util/ExtraLists.java b/src/main/java/org/zwobble/couscous/util/ExtraLists.java
index 3ee0ce3..76d3de7 100644
--- a/src/main/java/org/zwobble/couscous/util/ExtraLists.java
+++ b/src/main/java/org/zwobble/couscous/util/ExtraLists.java
@@ -33,7 +33,7 @@ public class ExtraLists {
return concat(list(value), list);
}
- public static <T> List<T> append(List<T> list, T value) {
+ public static <T> List<T> append(List<? extends T> list, T value) {
return Stream.concat(list.stream(), Stream.of(value)).collect(Collectors.toList());
}
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 8225baa..35756f5 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
@@ -10,6 +10,7 @@ import org.zwobble.couscous.types.Types;
import java.util.List;
import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@@ -23,12 +24,14 @@ import static org.zwobble.couscous.ast.FormalTypeParameterNode.formalTypeParamet
import static org.zwobble.couscous.ast.IfStatementNode.ifStatement;
import static org.zwobble.couscous.ast.LiteralNode.literal;
import static org.zwobble.couscous.ast.LocalVariableDeclarationNode.localVariableDeclaration;
+import static org.zwobble.couscous.ast.MethodCallNode.methodCall;
import static org.zwobble.couscous.ast.MethodCallNode.staticMethodCall;
import static org.zwobble.couscous.ast.Operations.boxInt;
import static org.zwobble.couscous.ast.Operations.integerAdd;
import static org.zwobble.couscous.ast.ReturnNode.returns;
import static org.zwobble.couscous.ast.ThisReferenceNode.thisReference;
import static org.zwobble.couscous.ast.ThrowNode.throwNode;
+import static org.zwobble.couscous.ast.TryNode.tryStatement;
import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion;
import static org.zwobble.couscous.ast.VariableReferenceNode.reference;
import static org.zwobble.couscous.ast.WhileNode.whileLoop;
@@ -209,7 +212,31 @@ public class JavaReaderTests {
hasTryBody(list(returns(literal(1)))),
hasFinally(returns(literal(2)))));
}
-
+
+ @Test
+ public void canReadTryWithResourceWithoutOtherClauses() {
+ ScalarType type = ScalarType.of("java.io.ByteArrayOutputStream");
+ Identifier identifier = Identifiers.variable(
+ Identifiers.method(
+ Identifiers.type(Identifiers.TOP, "com.example.Example"),
+ "main"
+ ),
+ "closeable"
+ );
+ LocalVariableDeclarationNode expectedResource = localVariableDeclaration(identifier, "closeable", type, constructorCall(type, list()));
+ assertThat(
+ readStatements("int", "try(java.io.ByteArrayOutputStream closeable = new java.io.ByteArrayOutputStream()) { return 1; }"),
+ equalTo(list(
+ expectedResource,
+ tryStatement(
+ list(returns(literal(1))),
+ list(),
+ list(expressionStatement(methodCall(reference(expectedResource), "close", list(), Types.VOID)))
+ )
+ ))
+ );
+ }
+
@Test
public void canDeclareConstructor() {
ClassNode classNode = readClass(
diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java
index a7dc180..e64de11 100644
--- a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java
@@ -76,7 +76,7 @@ public class JavaReading {
}
static String generateMethodSource(String returnType, String statementsSource) {
- return "public static " + returnType + " main() {" +
+ return "public static " + returnType + " main() throws Exception {" +
statementsSource +
"}";
}
diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
index 5a39e82..e9c77f0 100644
--- a/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
@@ -58,6 +58,11 @@ public class NodeMatchers {
}
@SafeVarargs
+ public static Matcher<StatementNode> isLocalVariableDeclaration(Matcher<? super LocalVariableDeclarationNode>... matchers) {
+ return isInstance(LocalVariableDeclarationNode.class, allOf(matchers));
+ }
+
+ @SafeVarargs
public static Matcher<StatementNode> isTryStatement(Matcher<? super TryNode>... matchers) {
return isInstance(TryNode.class, allOf(matchers));
}