diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-02-28 11:53:28 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-02-28 11:53:28 +0000 |
| commit | 8eda91c53e2df91b7b8022b80476513ac8116955 (patch) | |
| tree | b9973720d615c3c32aa62ff05a1f8727d8ea8e51 /src | |
| parent | 4330f93c6e694b546b7f3e7bfd2e18b93b15fbab (diff) | |
Allow reading of methods without body
Diffstat (limited to 'src')
4 files changed, 49 insertions, 14 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodNode.java b/src/main/java/org/zwobble/couscous/ast/MethodNode.java index dd970c5..967b2b1 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodNode.java @@ -6,6 +6,7 @@ import org.zwobble.couscous.ast.visitors.NodeTransformer; import org.zwobble.couscous.values.UnitValue; import java.util.List; +import java.util.Optional; import java.util.function.Function; import static org.zwobble.couscous.util.ExtraLists.eagerMap; @@ -22,6 +23,7 @@ public class MethodNode implements CallableNode { private final ImmutableList.Builder<AnnotationNode> annotations = ImmutableList.builder(); private boolean isStatic = false; + private boolean isAbstract = false; private final String name; private final ImmutableList.Builder<FormalArgumentNode> arguments = ImmutableList.builder(); @@ -42,6 +44,11 @@ public class MethodNode implements CallableNode { this.isStatic = isStatic; return this; } + + public Builder isAbstract() { + this.isAbstract = true; + return this; + } public Builder argument(FormalArgumentNode argument) { arguments.add(argument); @@ -75,7 +82,7 @@ public class MethodNode implements CallableNode { name, arguments.build(), returnType, - body.build()); + isAbstract ? Optional.empty() : Optional.of(body.build())); } } @@ -85,7 +92,7 @@ public class MethodNode implements CallableNode { String name, List<FormalArgumentNode> arguments, TypeName returnType, - List<StatementNode> body) + Optional<List<StatementNode>> body) { return new MethodNode(annotations, isStatic, name, arguments, returnType, body); } @@ -95,7 +102,7 @@ public class MethodNode implements CallableNode { private final String name; private final List<FormalArgumentNode> arguments; private final TypeName returnType; - private final List<StatementNode> body; + private final Optional<List<StatementNode>> body; private MethodNode( List<AnnotationNode> annotations, @@ -103,7 +110,7 @@ public class MethodNode implements CallableNode { String name, List<FormalArgumentNode> arguments, TypeName returnType, - List<StatementNode> body) + Optional<List<StatementNode>> body) { this.annotations = annotations; this.isStatic = isStatic; @@ -134,7 +141,7 @@ public class MethodNode implements CallableNode { } public List<StatementNode> getBody() { - return body; + return body.get(); } public MethodSignature signature() { @@ -145,7 +152,7 @@ public class MethodNode implements CallableNode { } public MethodNode mapBody(Function<List<StatementNode>, List<StatementNode>> function) { - return new MethodNode(annotations, isStatic, name, arguments, returnType, function.apply(body)); + return new MethodNode(annotations, isStatic, name, arguments, returnType, body.map(function)); } @Override @@ -160,7 +167,7 @@ public class MethodNode implements CallableNode { transformer.transformMethodName(signature()), transformer.transformFormalArguments(arguments), transformer.transform(returnType), - transformer.transformStatements(body)); + body.map(transformer::transformStatements)); } @Override 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 4eb7c7d..ccc37e0 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -114,7 +114,7 @@ public class JavaReader { functionalInterfaceMethod.getName(), lambda.getFormalArguments(), typeOf(functionalInterfaceMethod.getReturnType()), - lambda.getBody()); + Optional.of(lambda.getBody())); return new AnonymousClass( superTypesAndSelf(functionalInterfaceMethod.getDeclaringClass()), @@ -286,12 +286,12 @@ public class JavaReader { List<AnnotationNode> annotations = readAnnotations(method); Optional<TypeName> returnType = Optional.ofNullable(method.getReturnType2()) .map(JavaTypes::typeOf); - List<StatementNode> body = readBody(scope, method, returnType); + Optional<List<StatementNode>> body = readBody(scope, method, returnType); if (method.isConstructor()) { builder.constructor(constructor( formalArguments, - body)); + body.get())); } else { builder.addMethod(MethodNode.method( annotations, @@ -317,10 +317,14 @@ public class JavaReader { return eagerMap(parameters, parameter -> JavaVariableDeclarationReader.read(scope, parameter)); } - private List<StatementNode> readBody(Scope scope, MethodDeclaration method, Optional<TypeName> returnType) { - @SuppressWarnings("unchecked") - List<Statement> statements = method.getBody().statements(); - return readStatements(scope, statements, returnType); + private Optional<List<StatementNode>> readBody(Scope scope, MethodDeclaration method, Optional<TypeName> returnType) { + if (method.getBody() == null) { + return Optional.empty(); + } else { + @SuppressWarnings("unchecked") + List<Statement> statements = method.getBody().statements(); + return Optional.of(readStatements(scope, statements, returnType)); + } } List<StatementNode> readStatement(Scope scope, Statement statement) { diff --git a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java index e30f1ef..66a7a63 100644 --- a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java +++ b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java @@ -16,6 +16,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.IntStream; @@ -133,6 +134,8 @@ public class ValueObjectTests { return "[string 1]"; } else if (type.equals(boolean.class)) { return true; + } else if (type.equals(Optional.class)) { + return Optional.of("[optional 1]"); } else if (type.equals(List.class)) { return list("[list 1]"); } else if (type.equals(Set.class)) { @@ -159,6 +162,8 @@ public class ValueObjectTests { return "[string 2]"; } else if (type.equals(boolean.class)) { return false; + } else if (type.equals(Optional.class)) { + return Optional.of("[optional 2]"); } else if (type.equals(List.class)) { return list("[list 2]"); } else if (type.equals(Set.class)) { @@ -185,6 +190,8 @@ public class ValueObjectTests { return "[string]"; } else if (type.equals(boolean.class)) { return true; + } else if (type.equals(Optional.class)) { + return Optional.of("[optional]"); } else if (type.equals(List.class)) { return list("[list]"); } else if (type.equals(Set.class)) { 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 e6a7a3e..3c88424 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 @@ -311,4 +311,21 @@ public class JavaReaderTests { assertEquals(list(), classNode.getMethods()); assertEquals(set(ObjectValues.OBJECT), classNode.getSuperTypes()); } + + @Test + public void canReadInterfaceWithMethod() { + String source = "package com.example;" + + "public interface Example {" + + "int get();" + + "}"; + List<TypeNode> classes = readSource("com/example/Example.java", source); + assertThat(classes, hasSize(1)); + InterfaceNode classNode = (InterfaceNode) classes.get(0); + + MethodNode expectedMethod = MethodNode.builder("get") + .isAbstract() + .returns(IntegerValue.REF) + .build(); + assertEquals(list(expectedMethod), classNode.getMethods()); + } } |
