diff options
Diffstat (limited to 'src')
4 files changed, 66 insertions, 9 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java index 6294e38..61fd9a3 100644 --- a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java +++ b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java @@ -18,6 +18,14 @@ public class LocalVariableDeclarationNode implements VariableNode, StatementNode VariableDeclaration declaration; ExpressionNode initialValue; + + public String getName() { + return declaration.getName(); + } + + public TypeName getType() { + return declaration.getType(); + } @Override public <T> T accept(StatementNodeMapper<T> visitor) { diff --git a/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java b/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java index 6fc00f6..a53d099 100644 --- a/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java +++ b/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java @@ -5,7 +5,7 @@ import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import lombok.Value; -@Value +@Value(staticConstructor="reference") public class VariableReferenceNode implements AssignableExpressionNode { public static VariableReferenceNode reference(VariableNode variable) { return new VariableReferenceNode(variable.getDeclaration()); 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 26936ee..b8a3b62 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -27,6 +27,7 @@ import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.ThisExpression; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.zwobble.couscous.ast.AssignableExpressionNode; import org.zwobble.couscous.ast.AssignmentNode; import org.zwobble.couscous.ast.ClassNode; @@ -46,6 +47,11 @@ import org.zwobble.couscous.ast.TypeName; import com.google.common.collect.Lists; +import static java.util.Arrays.asList; +import static org.zwobble.couscous.ast.LocalVariableDeclarationNode.localVariableDeclaration; +import static org.zwobble.couscous.ast.VariableDeclaration.var; +import static org.zwobble.couscous.ast.VariableReferenceNode.reference; + import lombok.SneakyThrows; import lombok.val; @@ -97,18 +103,23 @@ public class JavaReader { true, builder -> { for (Object statement : method.getBody().statements()) { - builder.statement(readStatement((Statement)statement)); + for (StatementNode intermediateStatement : readStatement((Statement)statement)) { + builder.statement(intermediateStatement); + } + } return builder; }); } - private static StatementNode readStatement(Statement statement) { + private static List<StatementNode> readStatement(Statement statement) { switch (statement.getNodeType()) { case ASTNode.RETURN_STATEMENT: - return readReturnStatement((ReturnStatement)statement); + return asList(readReturnStatement((ReturnStatement)statement)); case ASTNode.EXPRESSION_STATEMENT: - return readExpressionStatement((ExpressionStatement)statement); + return asList(readExpressionStatement((ExpressionStatement)statement)); + case ASTNode.VARIABLE_DECLARATION_STATEMENT: + return readVariableDeclarationStatement((VariableDeclarationStatement)statement); default: throw new RuntimeException("Unsupported statement: " + statement.getClass()); } @@ -122,6 +133,18 @@ public class JavaReader { return new ExpressionStatementNode(readExpression(statement.getExpression())); } + private static List<StatementNode> readVariableDeclarationStatement(VariableDeclarationStatement statement) { + @SuppressWarnings("unchecked") + val fragments = (List<VariableDeclarationFragment>)statement.fragments(); + val type = typeOf(statement.getType().resolveBinding()); + return Lists.transform(fragments, fragment -> + localVariableDeclaration( + fragment.resolveBinding().getKey(), + fragment.getName().getIdentifier(), + type, + readExpression(fragment.getInitializer()))); + } + private static ExpressionNode readExpression(Expression expression) { switch (expression.getNodeType()) { case ASTNode.BOOLEAN_LITERAL: @@ -171,13 +194,17 @@ public class JavaReader { } private static ExpressionNode readVariableBinding(IVariableBinding binding) { + val type = typeOf(binding.getType()); if (binding.getDeclaringClass() == null) { - throw new RuntimeException("Cannot read variables"); + return reference(var( + binding.getKey(), + binding.getName(), + type)); } else { return FieldAccessNode.fieldAccess( ThisReferenceNode.thisReference(typeOf(binding.getDeclaringClass())), binding.getName(), - typeOf(binding.getType())); + type); } } 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 c9867be..98a6138 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,11 +1,13 @@ package org.zwobble.couscous.tests.frontends.java; import java.nio.file.Files; +import java.util.List; import org.junit.Test; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.ExpressionNode; import org.zwobble.couscous.ast.ExpressionStatementNode; +import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.ReturnNode; import org.zwobble.couscous.ast.StatementNode; import org.zwobble.couscous.ast.TernaryConditionalNode; @@ -13,6 +15,7 @@ import org.zwobble.couscous.ast.ThisReferenceNode; import org.zwobble.couscous.ast.TypeName; import org.zwobble.couscous.frontends.java.JavaReader; import org.zwobble.couscous.values.BooleanValue; +import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.StringValue; import static java.util.Arrays.asList; @@ -25,6 +28,7 @@ import static org.zwobble.couscous.ast.LiteralNode.literal; import static org.zwobble.couscous.ast.MethodCallNode.methodCall; import static org.zwobble.couscous.ast.StaticMethodCallNode.staticMethodCall; import static org.zwobble.couscous.ast.ThisReferenceNode.thisReference; +import static org.zwobble.couscous.ast.VariableReferenceNode.reference; import static org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively; import lombok.SneakyThrows; @@ -163,6 +167,20 @@ public class JavaReaderTests { } @Test + public void canDeclareAndReferenceLocalVariables() { + val statements = readStatements("int x = 4; return x;"); + + val declaration = (LocalVariableDeclarationNode) statements.get(0); + assertEquals("x", declaration.getName()); + assertEquals(IntegerValue.REF, declaration.getType()); + assertEquals(literal(4), declaration.getInitialValue()); + val returnNode = (ReturnNode) statements.get(1); + assertEquals( + reference(declaration), + returnNode.getValue()); + } + + @Test public void canReadExpressionStatements() { assertEquals( new ExpressionStatementNode( @@ -190,13 +208,17 @@ public class JavaReaderTests { } private StatementNode readStatement(String statementSource) { + return readStatements(statementSource).get(0); + } + + private List<StatementNode> readStatements(String statementsSource) { val javaClass = "public static Object main() {" + - statementSource + + statementsSource + "}"; val classNode = readClass(javaClass); - return classNode.getMethods().get(0).getBody().get(0); + return classNode.getMethods().get(0).getBody(); } @SneakyThrows |
