aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-10-07 19:16:48 +0100
committerMichael Williamson <mike@zwobble.org>2015-10-07 19:16:48 +0100
commit814afa129ff03c3c6396afcf5f87ea6ae5b6413f (patch)
treeeb8f53aaf3c6a1b1d3c00fcf45e6785f36fe3e5e
parent08fa3c8b03ba9b8054ae2c7d4e110c968eebc203 (diff)
Split off JavaReader and test separately
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaFrontend.java89
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java15
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java103
-rw-r--r--src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java2
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java38
5 files changed, 154 insertions, 93 deletions
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaFrontend.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaFrontend.java
index 53525ce..d5cdd6c 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaFrontend.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaFrontend.java
@@ -7,106 +7,21 @@ import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.BooleanLiteral;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.Expression;
-import org.eclipse.jdt.core.dom.NumberLiteral;
-import org.eclipse.jdt.core.dom.ReturnStatement;
-import org.eclipse.jdt.core.dom.Statement;
-import org.eclipse.jdt.core.dom.StringLiteral;
-import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.zwobble.couscous.ast.ClassNode;
-import org.zwobble.couscous.ast.ClassNodeBuilder;
-import org.zwobble.couscous.ast.ExpressionNode;
-import org.zwobble.couscous.ast.LiteralNode;
-import org.zwobble.couscous.ast.ReturnNode;
-import org.zwobble.couscous.ast.StatementNode;
-import lombok.SneakyThrows;
import lombok.val;
public class JavaFrontend {
-
public static List<ClassNode> readSourceDirectory(Path directoryPath) throws IOException {
- val parser = new JavaParser();
+ val reader = new JavaReader();
return findJavaFiles(directoryPath)
- .map(javaFile -> readClassFromFile(parser, javaFile))
+ .map(javaFile -> reader.readClassFromFile(javaFile))
.collect(Collectors.toList());
}
- @SneakyThrows
- private static ClassNode readClassFromFile(JavaParser parser, Path path) {
- val ast = parser.parseCompilationUnit(path);
- val name = generateClassName(ast);
-
- val classBuilder = new ClassNodeBuilder(name);
-
- val type = (TypeDeclaration)ast.types().get(0);
-
- for (val method : type.getMethods()) {
- classBuilder.method(
- method.getName().getIdentifier(),
- true,
- builder -> {
- for (Object statement : method.getBody().statements()) {
- builder.statement(readStatement((Statement)statement));
- }
- return builder;
- });
- }
-
- return classBuilder
- .build();
- }
-
- private static StatementNode readStatement(Statement statement) {
- switch (statement.getNodeType()) {
- case ASTNode.RETURN_STATEMENT:
- return readReturnStatement((ReturnStatement)statement);
- default:
- throw new RuntimeException("Unsupported statement: " + statement.getClass());
- }
- }
-
- private static StatementNode readReturnStatement(ReturnStatement statement) {
- return new ReturnNode(readExpression(statement.getExpression()));
- }
-
- private static ExpressionNode readExpression(Expression expression) {
- switch (expression.getNodeType()) {
- case ASTNode.BOOLEAN_LITERAL:
- return readBooleanLiteral((BooleanLiteral)expression);
- case ASTNode.NUMBER_LITERAL:
- return readNumberLiteral((NumberLiteral)expression);
- case ASTNode.STRING_LITERAL:
- return readStringLiteral((StringLiteral)expression);
- default:
- throw new RuntimeException("Unsupported expression: " + expression.getClass());
- }
- }
-
- private static ExpressionNode readBooleanLiteral(BooleanLiteral expression) {
- return LiteralNode.literal(expression.booleanValue());
- }
-
- private static LiteralNode readNumberLiteral(NumberLiteral expression) {
- return LiteralNode.literal(Integer.parseInt(expression.getToken()));
- }
-
- private static ExpressionNode readStringLiteral(StringLiteral expression) {
- return LiteralNode.literal(expression.getLiteralValue());
- }
-
- private static String generateClassName(CompilationUnit ast) {
- val type = (TypeDeclaration)ast.types().get(0);
- return ast.getPackage().getName().getFullyQualifiedName() + "." + type.getName().getFullyQualifiedName();
- }
-
private static Stream<Path> findJavaFiles(Path directoryPath) throws IOException {
return Files.walk(directoryPath)
.filter(path -> path.toFile().isFile() && path.toString().endsWith(".java"));
}
-
}
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java
index 5be2487..1d031c3 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java
@@ -1,5 +1,6 @@
package org.zwobble.couscous.frontends.java;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -10,7 +11,6 @@ import org.eclipse.jdt.core.dom.CompilationUnit;
import com.google.common.base.Charsets;
-import lombok.SneakyThrows;
import lombok.val;
public class JavaParser {
@@ -21,11 +21,18 @@ public class JavaParser {
parser.setResolveBindings(true);
}
- @SneakyThrows
- public CompilationUnit parseCompilationUnit(Path path) {
+ public CompilationUnit parseCompilationUnit(Path path) throws IOException {
val javaFileBytes = Files.readAllBytes(path);
val javaFileChars = Charsets.UTF_8.decode(ByteBuffer.wrap(javaFileBytes));
- parser.setSource(javaFileChars.array());
+ return parseCompilationUnit(javaFileChars.array());
+ }
+
+ public CompilationUnit parseCompilationUnit(String source) {
+ return parseCompilationUnit(source.toCharArray());
+ }
+
+ private CompilationUnit parseCompilationUnit(char[] source) {
+ parser.setSource(source);
return (CompilationUnit)parser.createAST(null);
}
}
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
new file mode 100644
index 0000000..1dbb288
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -0,0 +1,103 @@
+package org.zwobble.couscous.frontends.java;
+
+import java.nio.file.Path;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.BooleanLiteral;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.NumberLiteral;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.StringLiteral;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.zwobble.couscous.ast.ClassNode;
+import org.zwobble.couscous.ast.ClassNodeBuilder;
+import org.zwobble.couscous.ast.ExpressionNode;
+import org.zwobble.couscous.ast.LiteralNode;
+import org.zwobble.couscous.ast.ReturnNode;
+import org.zwobble.couscous.ast.StatementNode;
+
+import lombok.SneakyThrows;
+import lombok.val;
+
+public class JavaReader {
+ private final JavaParser parser = new JavaParser();
+
+ @SneakyThrows
+ public ClassNode readClassFromFile(Path path) {
+ val ast = parser.parseCompilationUnit(path);
+ return readCompilationUnit(ast);
+ }
+
+ public ClassNode readClassFromString(String source) {
+ val ast = parser.parseCompilationUnit(source);
+ return readCompilationUnit(ast);
+ }
+
+ private static ClassNode readCompilationUnit(CompilationUnit ast) {
+ val name = generateClassName(ast);
+
+ val classBuilder = new ClassNodeBuilder(name);
+
+ val type = (TypeDeclaration)ast.types().get(0);
+
+ for (val method : type.getMethods()) {
+ classBuilder.method(
+ method.getName().getIdentifier(),
+ true,
+ builder -> {
+ for (Object statement : method.getBody().statements()) {
+ builder.statement(readStatement((Statement)statement));
+ }
+ return builder;
+ });
+ }
+
+ return classBuilder
+ .build();
+ }
+
+ private static StatementNode readStatement(Statement statement) {
+ switch (statement.getNodeType()) {
+ case ASTNode.RETURN_STATEMENT:
+ return readReturnStatement((ReturnStatement)statement);
+ default:
+ throw new RuntimeException("Unsupported statement: " + statement.getClass());
+ }
+ }
+
+ private static StatementNode readReturnStatement(ReturnStatement statement) {
+ return new ReturnNode(readExpression(statement.getExpression()));
+ }
+
+ private static ExpressionNode readExpression(Expression expression) {
+ switch (expression.getNodeType()) {
+ case ASTNode.BOOLEAN_LITERAL:
+ return readBooleanLiteral((BooleanLiteral)expression);
+ case ASTNode.NUMBER_LITERAL:
+ return readNumberLiteral((NumberLiteral)expression);
+ case ASTNode.STRING_LITERAL:
+ return readStringLiteral((StringLiteral)expression);
+ default:
+ throw new RuntimeException("Unsupported expression: " + expression.getClass());
+ }
+ }
+
+ private static ExpressionNode readBooleanLiteral(BooleanLiteral expression) {
+ return LiteralNode.literal(expression.booleanValue());
+ }
+
+ private static LiteralNode readNumberLiteral(NumberLiteral expression) {
+ return LiteralNode.literal(Integer.parseInt(expression.getToken()));
+ }
+
+ private static ExpressionNode readStringLiteral(StringLiteral expression) {
+ return LiteralNode.literal(expression.getLiteralValue());
+ }
+
+ private static String generateClassName(CompilationUnit ast) {
+ val type = (TypeDeclaration)ast.types().get(0);
+ return ast.getPackage().getName().getFullyQualifiedName() + "." + type.getName().getFullyQualifiedName();
+ }
+}
diff --git a/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java b/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
index cbd8ca5..6732f47 100644
--- a/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
@@ -20,8 +20,6 @@ public class JavaToPythonTests {
@Test
public void canEvaluateLiterals() {
assertEquals(value("hello"), evalExpression("\"hello\""));
- assertEquals(value(true), evalExpression("true"));
- assertEquals(value(false), evalExpression("false"));
assertEquals(value(42), evalExpression("42"));
}
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
new file mode 100644
index 0000000..d75f16c
--- /dev/null
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
@@ -0,0 +1,38 @@
+package org.zwobble.couscous.tests.frontends.java;
+
+import org.junit.Test;
+import org.zwobble.couscous.ast.ExpressionNode;
+import org.zwobble.couscous.ast.ReturnNode;
+import org.zwobble.couscous.frontends.java.JavaReader;
+
+import static org.junit.Assert.assertEquals;
+import static org.zwobble.couscous.ast.LiteralNode.literal;
+
+import lombok.SneakyThrows;
+import lombok.val;
+
+public class JavaReaderTests {
+ @Test
+ public void canReadLiterals() {
+ assertEquals(literal("hello"), readExpression("\"hello\""));
+ assertEquals(literal(true), readExpression("true"));
+ assertEquals(literal(false), readExpression("false"));
+ assertEquals(literal(42), readExpression("42"));
+ }
+
+ @SneakyThrows
+ private ExpressionNode readExpression(String expressionSource) {
+ val javaClass =
+ "package com.example;" +
+ "public class Example {" +
+ " public static Object main() {" +
+ " return " + expressionSource + ";" +
+ " }" +
+ "}";
+
+ val reader = new JavaReader();
+ val classNode = reader.readClassFromString(javaClass);
+ val returnStatement = (ReturnNode) classNode.getMethods().get(0).getBody().get(0);
+ return returnStatement.getValue();
+ }
+}