diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-01-01 17:02:05 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-01-01 17:02:05 +0000 |
| commit | 65d04d8faa839c76b3a3841b937b8353da261d19 (patch) | |
| tree | c6248bb72da048e9d4e93ce0d0f968bbfd1eedef /src/main | |
| parent | 02aa9530cf8d96f2d651b47e93961591b8060b8b (diff) | |
Extract code for turning method reference into a lambda
Diffstat (limited to 'src/main')
3 files changed, 95 insertions, 47 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/sugar/Lambda.java b/src/main/java/org/zwobble/couscous/ast/sugar/Lambda.java new file mode 100644 index 0000000..25d6746 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/sugar/Lambda.java @@ -0,0 +1,28 @@ +package org.zwobble.couscous.ast.sugar; + +import org.zwobble.couscous.ast.FormalArgumentNode; +import org.zwobble.couscous.ast.StatementNode; + +import java.util.List; + +public class Lambda { + public static Lambda lambda(List<FormalArgumentNode> formalArguments, List<StatementNode> body) { + return new Lambda(formalArguments, body); + } + + private final List<FormalArgumentNode> formalArguments; + private final List<StatementNode> body; + + private Lambda(List<FormalArgumentNode> formalArguments, List<StatementNode> body) { + this.formalArguments = formalArguments; + this.body = body; + } + + public List<FormalArgumentNode> getFormalArguments() { + return formalArguments; + } + + public List<StatementNode> getBody() { + return body; + } +} diff --git a/src/main/java/org/zwobble/couscous/frontends/java/ExpressionMethodReferenceReader.java b/src/main/java/org/zwobble/couscous/frontends/java/ExpressionMethodReferenceReader.java new file mode 100644 index 0000000..aa6f078 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/frontends/java/ExpressionMethodReferenceReader.java @@ -0,0 +1,48 @@ +package org.zwobble.couscous.frontends.java; + +import com.google.common.collect.ImmutableList; +import org.eclipse.jdt.core.dom.ExpressionMethodReference; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.zwobble.couscous.ast.FormalArgumentNode; +import org.zwobble.couscous.ast.VariableReferenceNode; +import org.zwobble.couscous.ast.sugar.Lambda; + +import java.util.List; + +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.VariableDeclaration.var; +import static org.zwobble.couscous.ast.sugar.Lambda.lambda; +import static org.zwobble.couscous.frontends.java.JavaTypes.typeOf; +import static org.zwobble.couscous.util.ExtraLists.eagerMap; + +public class ExpressionMethodReferenceReader { + public static Lambda toLambda(ExpressionMethodReference expression) { + IMethodBinding functionalInterfaceMethod = expression.resolveTypeBinding().getFunctionalInterfaceMethod(); + List<FormalArgumentNode> formalArguments = formalArguments(functionalInterfaceMethod); + + return lambda( + 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())))))); + } + + private static 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(); + } +} 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 1044be0..4b84011 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -5,6 +5,7 @@ import com.google.common.collect.Maps; import org.eclipse.jdt.core.dom.*; import org.zwobble.couscous.ast.*; import org.zwobble.couscous.ast.VariableDeclaration; +import org.zwobble.couscous.ast.sugar.Lambda; import org.zwobble.couscous.util.ExtraLists; import java.io.IOException; @@ -30,9 +31,10 @@ 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; +import static org.zwobble.couscous.ast.sugar.Lambda.lambda; +import static org.zwobble.couscous.frontends.java.ExpressionMethodReferenceReader.toLambda; import static org.zwobble.couscous.frontends.java.FreeVariables.findFreeVariables; -import static org.zwobble.couscous.frontends.java.JavaTypes.superTypes; -import static org.zwobble.couscous.frontends.java.JavaTypes.typeOf; +import static org.zwobble.couscous.frontends.java.JavaTypes.*; import static org.zwobble.couscous.util.Casts.tryCast; import static org.zwobble.couscous.util.ExtraLists.*; @@ -70,28 +72,10 @@ public class JavaReader { 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; + return generateClosure( + expression, + functionalInterfaceMethod, + toLambda(expression)); } private ITypeBinding findDeclaringClass(ASTNode node) { @@ -101,23 +85,19 @@ public class JavaReader { 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); FunctionDeclaration lambda = functionDeclaration(expression); + return generateClosure( + expression, + functionalInterfaceMethod, + lambda( + lambda.getFormalArguments(), + lambda.getBody())); + } + + GeneratedClosure generateClosure(ASTNode node, IMethodBinding functionalInterfaceMethod, Lambda lambda) { MethodNode method = MethodNode.method( emptyList(), false, @@ -126,8 +106,8 @@ public class JavaReader { lambda.getBody()); GeneratedClosure closure = classWithCapture( - className, - superTypes(expression), + generateAnonymousClassName(findDeclaringClass(node)), + superTypesAndSelf(functionalInterfaceMethod.getDeclaringClass()), emptyList(), ImmutableList.of(method)); @@ -179,10 +159,6 @@ public class JavaReader { return fieldAccess(thisReference(type), freeVariable.getName(), freeVariable.getType()); } - private TypeName generateClassName(LambdaExpression expression) { - return generateAnonymousClassName(expression.resolveMethodBinding().getDeclaringClass()); - } - GeneratedClosure readAnonymousClass(AnonymousClassDeclaration declaration) { TypeName className = generateClassName(declaration); TypeDeclarationBody bodyDeclarations = readTypeDeclarationBody(declaration.bodyDeclarations()); @@ -252,10 +228,6 @@ public class JavaReader { public List<MethodNode> getMethods() { return methods; } - - public List<Node> getNodes() { - return ExtraLists.concat(fields, asList(constructor), methods); - } } private TypeDeclarationBody readTypeDeclarationBody(List<Object> bodyDeclarations) { |
