aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodNode.java47
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java2
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java9
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java7
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java19
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java6
6 files changed, 67 insertions, 23 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodNode.java b/src/main/java/org/zwobble/couscous/ast/MethodNode.java
index 8863619..1e682fb 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodNode.java
@@ -11,6 +11,7 @@ import java.util.Optional;
import java.util.function.Function;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
+import static org.zwobble.couscous.util.ExtraLists.list;
public class MethodNode implements Node {
public static Builder staticMethod(String name) {
@@ -83,6 +84,7 @@ public class MethodNode implements Node {
annotations.build(),
isStatic,
name,
+ list(),
arguments.build(),
returnType,
isAbstract ? Optional.empty() : Optional.of(body.build()),
@@ -94,17 +96,19 @@ public class MethodNode implements Node {
List<AnnotationNode> annotations,
boolean isStatic,
String name,
+ List<FormalTypeParameterNode> typeParameters,
List<FormalArgumentNode> arguments,
Type returnType,
Optional<List<StatementNode>> body,
List<MethodSignature> overrides)
{
- return new MethodNode(annotations, isStatic, name, arguments, returnType, body, overrides);
+ return new MethodNode(annotations, isStatic, name, typeParameters, arguments, returnType, body, overrides);
}
private final List<AnnotationNode> annotations;
private final boolean isStatic;
private final String name;
+ private final List<FormalTypeParameterNode> typeParameters;
private final List<FormalArgumentNode> arguments;
private final Type returnType;
private final Optional<List<StatementNode>> body;
@@ -114,6 +118,7 @@ public class MethodNode implements Node {
List<AnnotationNode> annotations,
boolean isStatic,
String name,
+ List<FormalTypeParameterNode> typeParameters,
List<FormalArgumentNode> arguments,
Type returnType,
Optional<List<StatementNode>> body,
@@ -122,6 +127,7 @@ public class MethodNode implements Node {
this.annotations = annotations;
this.isStatic = isStatic;
this.name = name;
+ this.typeParameters = typeParameters;
this.arguments = arguments;
this.returnType = returnType;
this.body = body;
@@ -139,7 +145,11 @@ public class MethodNode implements Node {
public String getName() {
return name;
}
-
+
+ public List<FormalTypeParameterNode> getTypeParameters() {
+ return typeParameters;
+ }
+
public List<FormalArgumentNode> getArguments() {
return arguments;
}
@@ -168,7 +178,7 @@ public class MethodNode implements Node {
}
public MethodNode mapBody(Function<List<StatementNode>, List<StatementNode>> function) {
- return new MethodNode(annotations, isStatic, name, arguments, returnType, body.map(function), overrides);
+ return new MethodNode(annotations, isStatic, name, typeParameters, arguments, returnType, body.map(function), overrides);
}
@Override
@@ -181,6 +191,7 @@ public class MethodNode implements Node {
transformer.transformAnnotations(annotations),
isStatic,
transformer.transformMethodName(signature()),
+ transformer.transformFormalTypeParameters(typeParameters),
transformer.transformFormalArguments(arguments),
transformer.transform(returnType),
body.map(transformer::transformStatements),
@@ -188,6 +199,20 @@ public class MethodNode implements Node {
}
@Override
+ public String toString() {
+ return "MethodNode(" +
+ "annotations=" + annotations +
+ ", isStatic=" + isStatic +
+ ", name=" + name +
+ ", typeParameters=" + typeParameters +
+ ", arguments=" + arguments +
+ ", returnType=" + returnType +
+ ", body=" + body +
+ ", overrides=" + overrides +
+ ')';
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -197,6 +222,7 @@ public class MethodNode implements Node {
if (isStatic != that.isStatic) return false;
if (!annotations.equals(that.annotations)) return false;
if (!name.equals(that.name)) return false;
+ if (!typeParameters.equals(that.typeParameters)) return false;
if (!arguments.equals(that.arguments)) return false;
if (!returnType.equals(that.returnType)) return false;
if (!body.equals(that.body)) return false;
@@ -209,24 +235,11 @@ public class MethodNode implements Node {
int result = annotations.hashCode();
result = 31 * result + (isStatic ? 1 : 0);
result = 31 * result + name.hashCode();
+ result = 31 * result + typeParameters.hashCode();
result = 31 * result + arguments.hashCode();
result = 31 * result + returnType.hashCode();
result = 31 * result + body.hashCode();
result = 31 * result + overrides.hashCode();
return result;
}
-
- @Override
- public String toString() {
- return "MethodNode(" +
- "annotations=" + annotations +
- ", isStatic=" + isStatic +
- ", name=" + name +
- ", arguments=" + arguments +
- ", returnType=" + returnType +
- ", body=" + body +
- ", overrides=" + overrides +
- ')';
- }
-
}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
index 73e6ced..4036a85 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
@@ -208,6 +208,8 @@ public class PythonCodeGenerator {
methodNode.getAnnotations(),
methodNode.isStatic(),
methodNode.getName(),
+ // TODO: should get type parameters from signature
+ list(),
arguments,
override.getReturnType(),
Optional.of(list(body)),
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 d4366c2..063ffc6 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -117,8 +117,12 @@ public class JavaReader {
}
private List<FormalTypeParameterNode> readTypeParameters(TypeDeclaration typeDeclaration) {
+ return readTypeParameters(typeDeclaration.resolveBinding().getTypeParameters());
+ }
+
+ private List<FormalTypeParameterNode> readTypeParameters(ITypeBinding[] typeParameters) {
return eagerMap(
- asList(typeDeclaration.resolveBinding().getTypeParameters()),
+ asList(typeParameters),
parameter -> formalTypeParameter(parameter.getName()));
}
@@ -156,6 +160,8 @@ public class JavaReader {
emptyList(),
false,
functionalInterfaceMethod.getName(),
+ // TODO: should get formal type parameters from the lambda
+ list(),
lambda.getFormalArguments(),
typeOf(functionalInterfaceMethod.getReturnType()),
Optional.of(lambda.getBody()),
@@ -414,6 +420,7 @@ public class JavaReader {
annotations,
isStatic,
methodName,
+ readTypeParameters(method.resolveBinding().getTypeParameters()),
formalArguments,
returnType.get(),
body,
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
index d63ec89..3b7a472 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
@@ -41,8 +41,11 @@ public class JavaTypes {
return Types.array(typeOf(typeBinding.getElementType()));
}
ITypeBinding outerClass = typeBinding.getDeclaringClass();
- // TODO: handle type variables for methods
- if (typeBinding.isTypeVariable() && outerClass != null) {
+ if (typeBinding.isTypeVariable()) {
+ if (outerClass == null) {
+ // TODO: handle type variables for methods properly
+ outerClass = typeBinding.getDeclaringMethod().getDeclaringClass();
+ }
return new TypeParameter(erasure(typeOf(outerClass)), typeBinding.getName());
}
ScalarType rawType = outerClass == null
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 5bcb044..4a05385 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
@@ -29,7 +29,9 @@ import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion;
import static org.zwobble.couscous.ast.VariableReferenceNode.reference;
import static org.zwobble.couscous.ast.WhileNode.whileLoop;
import static org.zwobble.couscous.tests.frontends.java.JavaReading.*;
-import static org.zwobble.couscous.tests.frontends.java.NodeMatchers.isArgument;
+import static org.zwobble.couscous.tests.frontends.java.NodeMatchers.isFormalArgument;
+import static org.zwobble.couscous.tests.frontends.java.NodeMatchers.isFormalTypeParameter;
+import static org.zwobble.couscous.types.TypeParameter.typeParameter;
import static org.zwobble.couscous.util.ExtraLists.list;
import static org.zwobble.couscous.util.ExtraSets.set;
@@ -75,11 +77,24 @@ public class JavaReaderTests {
"}");
MethodNode method = classNode.getMethods().get(0);
- assertThat(method.getArguments(), contains(isArgument("value", ScalarType.of("int"))));
+ assertThat(method.getArguments(), contains(isFormalArgument("value", ScalarType.of("int"))));
ReturnNode returnNode = (ReturnNode)method.getBody().get().get(0);
assertEquals(reference(method.getArguments().get(0)), returnNode.getValue());
}
+
+ @Test
+ public void canReadTypeParametersForMethod() {
+ ClassNode classNode = readClass(
+ "public <T> T identity(T value) {" +
+ " return value;" +
+ "}");
+
+ MethodNode method = classNode.getMethods().get(0);
+ assertThat(method.getTypeParameters(), contains(isFormalTypeParameter("T")));
+ // TODO: typeParameter should be declared on method, not class
+ assertThat(method.getArguments(), contains(isFormalArgument("value", typeParameter(classNode.getName(), "T"))));
+ }
@Test
public void canReadExpressionStatements() {
diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
index efd4eb4..104cf8b 100644
--- a/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
@@ -14,7 +14,11 @@ public class NodeMatchers {
return hasFeature("initial value", node -> node.getInitialValue(), matcher);
}
- public static Matcher<FormalArgumentNode> isArgument(String name, Type type) {
+ public static Matcher<FormalTypeParameterNode> isFormalTypeParameter(String name) {
+ return hasFeature("name", node -> node.getName(), equalTo(name));
+ }
+
+ public static Matcher<FormalArgumentNode> isFormalArgument(String name, Type type) {
return allOf(
hasFeature("name", node -> node.getName(), equalTo(name)),
hasFeature("type", node -> node.getType(), equalTo(type)));