aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-03-29 19:30:44 +0100
committerMichael Williamson <mike@zwobble.org>2016-03-29 19:30:44 +0100
commitdf10352d2eea46b3e82cbd7783ed16e3f02fced6 (patch)
treeba629ff24315d39eb3d9c8a97623fd0b0e502550 /src/main/java
parent8dcb59ce2de9ea97e0de55bfe3f04df934a593bb (diff)
Allow binding of parameterised types
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java33
-rw-r--r--src/main/java/org/zwobble/couscous/util/Optionals.java20
2 files changed, 49 insertions, 4 deletions
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 f70ee57..a770108 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
@@ -2,10 +2,11 @@ package org.zwobble.couscous.frontends.java;
import com.google.common.collect.ImmutableSet;
import org.eclipse.jdt.core.dom.*;
-import org.zwobble.couscous.types.ParameterizedType;
import org.zwobble.couscous.types.*;
+import org.zwobble.couscous.types.ParameterizedType;
import org.zwobble.couscous.types.Type;
import org.zwobble.couscous.types.TypeParameter;
+import org.zwobble.couscous.util.Optionals;
import java.util.List;
import java.util.Optional;
@@ -14,6 +15,7 @@ import java.util.Set;
import static com.google.common.collect.Iterables.transform;
import static java.util.Arrays.asList;
import static org.zwobble.couscous.types.Types.erasure;
+import static org.zwobble.couscous.util.Casts.tryCast;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
public class JavaTypes {
@@ -84,10 +86,33 @@ public class JavaTypes {
public static Type bind(Type genericType, Type concreteType) {
if (genericType.equals(concreteType)) {
return concreteType;
- } else if (!(genericType instanceof TypeParameter)) {
- throw new RuntimeException("Type parameter was " + genericType);
+ }
+ return Optionals.flatMap(
+ tryCast(ParameterizedType.class, genericType),
+ tryCast(ParameterizedType.class, concreteType),
+ JavaTypes::bindParameterizedType)
+ .orElseGet(() -> {
+ if (!(genericType instanceof TypeParameter)) {
+ return concreteType;
+ } else {
+ return new BoundTypeParameter((TypeParameter) genericType, concreteType);
+ }
+ });
+ }
+
+ private static Optional<Type> bindParameterizedType(
+ ParameterizedType genericType,
+ ParameterizedType concreteType)
+ {
+ if (genericType.getRawType().equals(concreteType.getRawType())) {
+ return Optional.of(new ParameterizedType(
+ genericType.getRawType(),
+ eagerMap(
+ genericType.getParameters(),
+ concreteType.getParameters(),
+ JavaTypes::bind)));
} else {
- return new BoundTypeParameter((TypeParameter) genericType, concreteType);
+ return Optional.empty();
}
}
}
diff --git a/src/main/java/org/zwobble/couscous/util/Optionals.java b/src/main/java/org/zwobble/couscous/util/Optionals.java
new file mode 100644
index 0000000..979dc5f
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/util/Optionals.java
@@ -0,0 +1,20 @@
+package org.zwobble.couscous.util;
+
+import java.util.Optional;
+import java.util.function.BiFunction;
+
+public class Optionals {
+ private Optionals() {}
+
+ public static <T1, T2, R> Optional<R> flatMap(
+ Optional<T1> first,
+ Optional<T2> second,
+ BiFunction<T1, T2, Optional<R>> function)
+ {
+ if (first.isPresent() && second.isPresent()) {
+ return function.apply(first.get(), second.get());
+ } else {
+ return Optional.empty();
+ }
+ }
+}