aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/zwobble')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/sugar/Lambda.java28
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/ExpressionMethodReferenceReader.java48
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java66
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) {