aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/zwobble/couscous/frontends')
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java12
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java54
2 files changed, 48 insertions, 18 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 4c27a75..0d19cd1 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
@@ -18,7 +18,6 @@ import static org.zwobble.couscous.ast.ConstructorCallNode.constructorCall;
import static org.zwobble.couscous.ast.InstanceReceiver.instanceReceiver;
import static org.zwobble.couscous.ast.LiteralNode.literal;
import static org.zwobble.couscous.ast.MethodCallNode.methodCall;
-import static org.zwobble.couscous.ast.MethodCallNode.staticMethodCall;
import static org.zwobble.couscous.ast.OperationNode.operation;
import static org.zwobble.couscous.ast.Operations.not;
import static org.zwobble.couscous.ast.StaticReceiver.staticReceiver;
@@ -210,24 +209,27 @@ public class JavaExpressionReader {
List<ExpressionNode> arguments = readArguments(
expression.resolveMethodBinding(),
expression.arguments());
- MethodSignature signature = JavaMethods.signature(expression.resolveMethodBinding());
+ Type returnType = typeOf(expression);
+ MethodSignature signature = JavaMethods.signature(expression.resolveMethodBinding().getMethodDeclaration());
IMethodBinding methodBinding = expression.resolveMethodBinding();
Type receiverType = typeOf(methodBinding.getDeclaringClass());
if ((Modifier.isStatic(methodBinding.getModifiers()))) {
- return staticMethodCall(
- erasure(receiverType),
+ return methodCall(
+ staticReceiver(erasure(receiverType)),
methodName,
arguments,
+ returnType,
signature);
} else {
ExpressionNode receiver = expression.getExpression() == null
? thisReference(receiverType)
: readExpressionWithoutBoxing(expression.getExpression());
return methodCall(
- receiver,
+ instanceReceiver(receiver),
methodName,
arguments,
+ returnType,
signature);
}
}
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java
index b52110f..014e4ae 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java
@@ -4,12 +4,16 @@ import com.google.common.collect.Iterables;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.zwobble.couscous.ast.MethodSignature;
+import org.zwobble.couscous.ast.identifiers.Identifier;
+import org.zwobble.couscous.ast.identifiers.Identifiers;
import org.zwobble.couscous.types.Type;
+import org.zwobble.couscous.types.TypeParameter;
import java.util.List;
import static java.util.Arrays.asList;
import static org.zwobble.couscous.frontends.java.JavaTypes.typeOf;
+import static org.zwobble.couscous.types.Types.erasure;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
import static org.zwobble.couscous.util.ExtraLists.list;
@@ -17,26 +21,50 @@ class JavaMethods {
static MethodSignature signature(IMethodBinding method) {
ITypeBinding declaringClass = method.getDeclaringClass();
ITypeBinding erasedDeclaringClass = declaringClass.getErasure();
+ IMethodBinding declaringMethod = method.getMethodDeclaration();
- List<Type> argumentTypes = eagerMap(asList(method.getParameterTypes()), JavaTypes::typeOf);
- Type returnType = typeOf(method.getReturnType());
+ MethodSignature unboundSignature = unboundSignature(method);
- if (declaringClass.isEqualTo(erasedDeclaringClass)) {
- return new MethodSignature(method.getName(), list(), argumentTypes, returnType);
- } else {
+ if (!declaringMethod.isEqualTo(method)) {
+ return bind(unboundSignature(declaringMethod), unboundSignature);
+ } else if (!declaringClass.isEqualTo(erasedDeclaringClass)) {
IMethodBinding[] erasedMethods = erasedDeclaringClass.getDeclaredMethods();
IMethodBinding erasedMethod = Iterables.getOnlyElement(Iterables.filter(
asList(erasedMethods),
m -> m.isSubsignature(method)));
- return new MethodSignature(
- method.getName(),
- list(),
- eagerMap(
- argumentTypes,
- asList(erasedMethod.getParameterTypes()),
- (argumentType, erasedParameterType) -> JavaTypes.bind(typeOf(erasedParameterType), argumentType)),
- JavaTypes.bind(typeOf(erasedMethod.getReturnType()), returnType));
+ return bind(unboundSignature(erasedMethod), unboundSignature);
+ } else {
+ return unboundSignature;
+ }
+ }
+
+ private static MethodSignature bind(MethodSignature genericSignature, MethodSignature concreteSignature) {
+ if (!genericSignature.getTypeParameters().isEmpty()) {
+ throw new UnsupportedOperationException();
}
+ return new MethodSignature(
+ concreteSignature.getName(),
+ list(),
+ eagerMap(
+ genericSignature.getArguments(),
+ concreteSignature.getArguments(),
+ JavaTypes::bind),
+ JavaTypes.bind(genericSignature.getReturnType(), concreteSignature.getReturnType()));
+ }
+
+ private static MethodSignature unboundSignature(IMethodBinding method) {
+ List<TypeParameter> typeParameters = eagerMap(
+ asList(method.getTypeParameters()),
+ parameter -> new TypeParameter(identifierFor(method), parameter.getName()));
+ List<Type> argumentTypes = eagerMap(asList(method.getParameterTypes()), JavaTypes::typeOf);
+ Type returnType = typeOf(method.getReturnType());
+ return new MethodSignature(method.getName(), typeParameters, argumentTypes, returnType);
}
+ private static Identifier identifierFor(IMethodBinding method) {
+ // TODO: disambiguate overloads
+ return Identifiers.method(
+ Identifiers.forType(erasure(typeOf(method.getDeclaringClass()))),
+ method.getName());
+ }
}