From 814afa129ff03c3c6396afcf5f87ea6ae5b6413f Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 7 Oct 2015 19:16:48 +0100 Subject: Split off JavaReader and test separately --- .../couscous/frontends/java/JavaFrontend.java | 89 +----------------- .../couscous/frontends/java/JavaParser.java | 15 ++- .../couscous/frontends/java/JavaReader.java | 103 +++++++++++++++++++++ 3 files changed, 116 insertions(+), 91 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java (limited to 'src/main') 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 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 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(); + } +} -- cgit v1.2.3