diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-04-17 17:17:34 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-04-17 17:17:34 +0100 |
| commit | 936968730c0f882f2ba8dfa91164abb901ac3c95 (patch) | |
| tree | f611b3cbf582c9a3cdb876da3910c12ceb3c6e4f /src | |
| parent | 188051b4be316db4de8b6f48d634f249dd2e4986 (diff) | |
Read finally clauses of try statements
Diffstat (limited to 'src')
7 files changed, 49 insertions, 8 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/TryNode.java b/src/main/java/org/zwobble/couscous/ast/TryNode.java index af0a892..bb276ee 100644 --- a/src/main/java/org/zwobble/couscous/ast/TryNode.java +++ b/src/main/java/org/zwobble/couscous/ast/TryNode.java @@ -8,16 +8,26 @@ import java.util.List; import static org.zwobble.couscous.util.ExtraLists.eagerMap; public class TryNode implements StatementNode { - public static TryNode tryStatement(List<StatementNode> body, List<ExceptionHandlerNode> exceptionHandlers) { - return new TryNode(body, exceptionHandlers); + public static TryNode tryStatement( + List<StatementNode> body, + List<ExceptionHandlerNode> exceptionHandlers, + List<StatementNode> finallyBody) + { + return new TryNode(body, exceptionHandlers, finallyBody); } private final List<StatementNode> body; private final List<ExceptionHandlerNode> exceptionHandlers; + private final List<StatementNode> finallyBody; - public TryNode(List<StatementNode> body, List<ExceptionHandlerNode> exceptionHandlers) { + public TryNode( + List<StatementNode> body, + List<ExceptionHandlerNode> exceptionHandlers, + List<StatementNode> finallyBody) + { this.body = body; this.exceptionHandlers = exceptionHandlers; + this.finallyBody = finallyBody; } public List<StatementNode> getBody() { @@ -28,6 +38,10 @@ public class TryNode implements StatementNode { return exceptionHandlers; } + public List<StatementNode> getFinallyBody() { + return finallyBody; + } + @Override public <T> T accept(StatementNodeMapper<T> visitor) { return visitor.visit(this); @@ -39,7 +53,7 @@ public class TryNode implements StatementNode { transformer.transformStatements(body), eagerMap(exceptionHandlers, handler -> new ExceptionHandlerNode( transformer.transform(handler.getDeclaration()), - transformer.transformStatements(handler.getBody())))); + transformer.transformStatements(handler.getBody()))), finallyBody); } @Override diff --git a/src/main/java/org/zwobble/couscous/frontends/java/FreeVariables.java b/src/main/java/org/zwobble/couscous/frontends/java/FreeVariables.java index dc68db8..9fcec11 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/FreeVariables.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/FreeVariables.java @@ -95,6 +95,10 @@ public class FreeVariables { private static Stream<VariableDeclaration> findDeclarations(Node root) { Stream<VariableNode> declarations = descendantNodesAndSelf(root).flatMap(node -> toStream(tryCast(VariableNode.class, node))); - return declarations.map(VariableNode::getDeclaration); + Stream<TryNode> tryStatements = descendantNodesAndSelf(root).flatMap(node -> toStream(tryCast(TryNode.class, node))); + Stream<ExceptionHandlerNode> handlers = tryStatements.flatMap(statement -> statement.getExceptionHandlers().stream()); + return Stream.concat( + declarations.map(VariableNode::getDeclaration), + handlers.map(ExceptionHandlerNode::getDeclaration)); } } 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 e8483f0..c3c4f21 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java @@ -170,7 +170,8 @@ class JavaStatementReader { List<CatchClause> catchClauses = statement.catchClauses(); return list(tryStatement( readStatement(statement.getBody()), - eagerMap(catchClauses, this::readCatchClause))); + eagerMap(catchClauses, this::readCatchClause), + statement.getFinally() == null ? list() : readStatement(statement.getFinally()))); } private ExceptionHandlerNode readCatchClause(CatchClause clause) { diff --git a/src/main/java/org/zwobble/couscous/util/Optionals.java b/src/main/java/org/zwobble/couscous/util/Optionals.java index 979dc5f..fd57924 100644 --- a/src/main/java/org/zwobble/couscous/util/Optionals.java +++ b/src/main/java/org/zwobble/couscous/util/Optionals.java @@ -6,6 +6,14 @@ import java.util.function.BiFunction; public class Optionals { private Optionals() {} + public static <T> Optional<T> first(Optional<T> first, Optional<T> second) { + if (first.isPresent()) { + return first; + } else { + return second; + } + } + public static <T1, T2, R> Optional<R> flatMap( Optional<T1> first, Optional<T2> second, diff --git a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java index ba69eb4..c0b9899 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java @@ -309,7 +309,8 @@ public class CsharpSerializerTests { list(returns(literal(1))), list( exceptionHandler(varX, list(returns(reference(varX)))), - exceptionHandler(varY, list(returns(reference(varY))))))); + exceptionHandler(varY, list(returns(reference(varY))))), + list())); assertEquals("try {\n return 1;\n} catch (X x) {\n return x;\n} catch (Y y) {\n return y;\n}\n", output); } 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 3aafb56..8225baa 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 @@ -192,7 +192,7 @@ public class JavaReaderTests { } @Test - public void canReadTryStatements() { + public void canReadTryStatementsWithCatchClauses() { assertThat( readStatement("int", "try { return 1; } catch (Exception exception) { return 2; }"), isTryStatement( @@ -200,6 +200,15 @@ public class JavaReaderTests { hasExceptionHandlers( isExceptionHandler(ScalarType.of("java.lang.Exception"), "exception", list(returns(literal(2))))))); } + + @Test + public void canReadTryStatementsWithFinallyClauses() { + assertThat( + readStatement("int", "try { return 1; } finally { return 2; }"), + isTryStatement( + hasTryBody(list(returns(literal(1)))), + hasFinally(returns(literal(2))))); + } @Test public void canDeclareConstructor() { 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 ba356f8..5a39e82 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 @@ -77,4 +77,8 @@ public class NodeMatchers { hasFeature("exception name", ExceptionHandlerNode::getExceptionName, equalTo(name)), hasFeature("body", ExceptionHandlerNode::getBody, equalTo(body))); } + + public static Matcher<TryNode> hasFinally(StatementNode... statements) { + return hasFeature("finally clause", TryNode::getFinallyBody, contains(statements)); + } } |
