aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaFrontend.java2
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java27
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java28
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java29
4 files changed, 62 insertions, 24 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 d5cdd6c..8b92cec 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaFrontend.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaFrontend.java
@@ -16,7 +16,7 @@ public class JavaFrontend {
val reader = new JavaReader();
return findJavaFiles(directoryPath)
- .map(javaFile -> reader.readClassFromFile(javaFile))
+ .map(javaFile -> reader.readClassFromFile(directoryPath, javaFile))
.collect(Collectors.toList());
}
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 1d031c3..d171761 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java
@@ -5,6 +5,7 @@ import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
@@ -18,21 +19,23 @@ public class JavaParser {
public JavaParser() {
parser = ASTParser.newParser(AST.JLS8);
+ parser.setBindingsRecovery(true);
+ parser.setKind(ASTParser.K_COMPILATION_UNIT);
+ parser.setCompilerOptions(JavaCore.getOptions());
+ parser.setEnvironment(
+ new String[] {"/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar"},
+ new String[0],
+ new String[0],
+ false);
parser.setResolveBindings(true);
}
- public CompilationUnit parseCompilationUnit(Path path) throws IOException {
- val javaFileBytes = Files.readAllBytes(path);
- val javaFileChars = Charsets.UTF_8.decode(ByteBuffer.wrap(javaFileBytes));
- return parseCompilationUnit(javaFileChars.array());
- }
-
- public CompilationUnit parseCompilationUnit(String source) {
- return parseCompilationUnit(source.toCharArray());
- }
-
- private CompilationUnit parseCompilationUnit(char[] source) {
- parser.setSource(source);
+ public CompilationUnit parseCompilationUnit(Path root, Path sourcePath) throws IOException {
+ parser.setUnitName("/" + root.relativize(sourcePath).toString());
+
+ val javaFileBytes = Files.readAllBytes(sourcePath);
+ val source = Charsets.UTF_8.decode(ByteBuffer.wrap(javaFileBytes));
+ parser.setSource(source.array());
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
index 1dbb288..a9cef4b 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -1,11 +1,13 @@
package org.zwobble.couscous.frontends.java;
import java.nio.file.Path;
+import java.util.List;
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.MethodInvocation;
import org.eclipse.jdt.core.dom.NumberLiteral;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.Statement;
@@ -15,8 +17,12 @@ 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.MethodCallNode;
import org.zwobble.couscous.ast.ReturnNode;
import org.zwobble.couscous.ast.StatementNode;
+import org.zwobble.couscous.ast.TypeName;
+
+import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import lombok.val;
@@ -25,13 +31,8 @@ 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);
+ public ClassNode readClassFromFile(Path root, Path sourcePath) {
+ val ast = parser.parseCompilationUnit(root, sourcePath);
return readCompilationUnit(ast);
}
@@ -79,6 +80,8 @@ public class JavaReader {
return readNumberLiteral((NumberLiteral)expression);
case ASTNode.STRING_LITERAL:
return readStringLiteral((StringLiteral)expression);
+ case ASTNode.METHOD_INVOCATION:
+ return readMethodInvocation((MethodInvocation)expression);
default:
throw new RuntimeException("Unsupported expression: " + expression.getClass());
}
@@ -96,6 +99,17 @@ public class JavaReader {
return LiteralNode.literal(expression.getLiteralValue());
}
+ @SuppressWarnings("unchecked")
+ private static ExpressionNode readMethodInvocation(MethodInvocation expression) {
+ return MethodCallNode.methodCall(
+ readExpression(expression.getExpression()),
+ expression.getName().getIdentifier(),
+ Lists.transform(
+ (List<Expression>)expression.arguments(),
+ JavaReader::readExpression),
+ TypeName.of(expression.resolveTypeBinding().getQualifiedName()));
+ }
+
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/frontends/java/JavaReaderTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
index d75f16c..1625c83 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,12 +1,18 @@
package org.zwobble.couscous.tests.frontends.java;
+import java.nio.file.Files;
+
import org.junit.Test;
import org.zwobble.couscous.ast.ExpressionNode;
import org.zwobble.couscous.ast.ReturnNode;
+import org.zwobble.couscous.ast.TypeName;
import org.zwobble.couscous.frontends.java.JavaReader;
+import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.zwobble.couscous.ast.LiteralNode.literal;
+import static org.zwobble.couscous.ast.MethodCallNode.methodCall;
+import static org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively;
import lombok.SneakyThrows;
import lombok.val;
@@ -19,6 +25,12 @@ public class JavaReaderTests {
assertEquals(literal(false), readExpression("false"));
assertEquals(literal(42), readExpression("42"));
}
+ @Test
+ public void canReadInstanceMethodCalls() {
+ assertEquals(
+ methodCall(literal("hello"), "startsWith", asList(literal("h")), TypeName.of("boolean")),
+ readExpression("\"hello\".startsWith(\"h\")"));
+ }
@SneakyThrows
private ExpressionNode readExpression(String expressionSource) {
@@ -30,9 +42,18 @@ public class JavaReaderTests {
" }" +
"}";
- val reader = new JavaReader();
- val classNode = reader.readClassFromString(javaClass);
- val returnStatement = (ReturnNode) classNode.getMethods().get(0).getBody().get(0);
- return returnStatement.getValue();
+ val directoryPath = Files.createTempDirectory(null);
+ val sourcePath = directoryPath.resolve("com/example/Example.java");
+ try {
+ Files.createDirectories(directoryPath.resolve("com/example"));
+ Files.write(sourcePath, asList(javaClass));
+
+ val reader = new JavaReader();
+ val classNode = reader.readClassFromFile(directoryPath, sourcePath);
+ val returnStatement = (ReturnNode) classNode.getMethods().get(0).getBody().get(0);
+ return returnStatement.getValue();
+ } finally {
+ deleteRecursively(directoryPath.toFile());
+ }
}
}