diff options
Diffstat (limited to 'src/main/java/org')
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(); |
