aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-01-01 16:32:31 +0000
committerMichael Williamson <mike@zwobble.org>2016-01-01 16:32:31 +0000
commit02aa9530cf8d96f2d651b47e93961591b8060b8b (patch)
treea423171c75729c6950d69034316fa21f98b09e23 /src/main/java
parentfd0769bde1ffad49ca74a404f18aae5d7226c558 (diff)
Add reading of references to static methods
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java12
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java47
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java9
3 files changed, 66 insertions, 2 deletions
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
index a7592a9..2c0ab22 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
@@ -33,7 +33,7 @@ public class JavaExpressionReader {
return handleBoxing(targetType, couscousExpression);
}
- private static ExpressionNode handleBoxing(TypeName targetType, ExpressionNode couscousExpression) {
+ static ExpressionNode handleBoxing(TypeName targetType, ExpressionNode couscousExpression) {
if (isIntegerBox(targetType, couscousExpression)) {
return StaticMethodCallNode.boxInt(couscousExpression);
} else if (isIntegerUnbox(targetType, couscousExpression)) {
@@ -106,6 +106,9 @@ public class JavaExpressionReader {
case ASTNode.LAMBDA_EXPRESSION:
return readLambdaExpression((LambdaExpression)expression);
+ case ASTNode.EXPRESSION_METHOD_REFERENCE:
+ return readExpressionMethodReference((ExpressionMethodReference)expression);
+
case ASTNode.INFIX_EXPRESSION:
return readInfixExpression((InfixExpression)expression);
@@ -214,6 +217,13 @@ public class JavaExpressionReader {
captureArguments(closure));
}
+ private ExpressionNode readExpressionMethodReference(ExpressionMethodReference expression) {
+ GeneratedClosure closure = javaReader.readExpressionMethodReference(expression);
+ return constructorCall(
+ closure.getType(),
+ captureArguments(closure));
+ }
+
private List<ExpressionNode> captureArguments(GeneratedClosure closure) {
return eagerMap(closure.getCaptures(), VariableReferenceNode::reference);
}
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 2963fd6..1044be0 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -26,6 +26,7 @@ import static org.zwobble.couscous.ast.FieldAccessNode.fieldAccess;
import static org.zwobble.couscous.ast.FieldDeclarationNode.field;
import static org.zwobble.couscous.ast.FormalArgumentNode.formalArg;
import static org.zwobble.couscous.ast.ReturnNode.returns;
+import static org.zwobble.couscous.ast.StaticMethodCallNode.staticMethodCall;
import static org.zwobble.couscous.ast.ThisReferenceNode.thisReference;
import static org.zwobble.couscous.ast.VariableDeclaration.var;
import static org.zwobble.couscous.ast.VariableReferenceNode.reference;
@@ -66,6 +67,52 @@ public class JavaReader {
body.getMethods());
}
+ GeneratedClosure readExpressionMethodReference(ExpressionMethodReference expression) {
+ IMethodBinding functionalInterfaceMethod = expression.resolveTypeBinding().getFunctionalInterfaceMethod();
+
+ List<FormalArgumentNode> formalArguments = formalArguments(functionalInterfaceMethod);
+
+ MethodNode method = MethodNode.method(
+ emptyList(),
+ false,
+ functionalInterfaceMethod.getName(),
+ formalArguments,
+ ImmutableList.of(returns(JavaExpressionReader.handleBoxing(
+ typeOf(functionalInterfaceMethod.getReturnType()),
+ staticMethodCall(
+ typeOf(expression.resolveMethodBinding().getDeclaringClass()),
+ expression.getName().getIdentifier(),
+ eagerMap(formalArguments, VariableReferenceNode::reference),
+ typeOf(expression.resolveMethodBinding().getReturnType()))))));
+
+ GeneratedClosure closure = classWithCapture(
+ generateAnonymousClassName(findDeclaringClass(expression)),
+ superTypes(expression),
+ emptyList(),
+ ImmutableList.of(method));
+ classes.add(closure.getClassNode());
+ return closure;
+ }
+
+ private ITypeBinding findDeclaringClass(ASTNode node) {
+ while (!(node instanceof AbstractTypeDeclaration)) {
+ node = node.getParent();
+ }
+ return ((AbstractTypeDeclaration)node).resolveBinding();
+ }
+
+ private List<FormalArgumentNode> formalArguments(IMethodBinding functionalInterfaceMethod) {
+ ImmutableList.Builder<FormalArgumentNode> arguments = ImmutableList.builder();
+
+ ITypeBinding[] parameterTypes = functionalInterfaceMethod.getParameterTypes();
+ for (int index = 0; index < parameterTypes.length; index++) {
+ ITypeBinding parameterType = parameterTypes[index];
+ arguments.add(formalArg(var("arg" + index, "arg" + index, typeOf(parameterType))));
+ }
+
+ return arguments.build();
+ }
+
GeneratedClosure readLambda(LambdaExpression expression) {
IMethodBinding functionalInterfaceMethod = expression.resolveTypeBinding().getFunctionalInterfaceMethod();
TypeName className = generateClassName(expression);
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 4b62a17..b7b003b 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
@@ -36,8 +36,15 @@ class JavaTypes {
}
static Set<TypeName> superTypes(LambdaExpression expression) {
+ return superTypesAndSelf(expression.resolveTypeBinding());
+ }
+
+ static Set<TypeName> superTypes(ExpressionMethodReference expression) {
+ return superTypesAndSelf(expression.resolveTypeBinding());
+ }
+
+ static Set<TypeName> superTypesAndSelf(ITypeBinding typeBinding) {
ImmutableSet.Builder<TypeName> superTypes = ImmutableSet.builder();
- ITypeBinding typeBinding = expression.resolveTypeBinding();
superTypes.addAll(superTypes(typeBinding));
superTypes.add(typeOf(typeBinding));
return superTypes.build();