aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/GeneratedClosure.java17
-rw-r--r--src/main/java/org/zwobble/couscous/transforms/ClosureGenerator.java45
-rw-r--r--src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java7
-rw-r--r--src/main/java/org/zwobble/couscous/util/ExtraLists.java4
4 files changed, 46 insertions, 27 deletions
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/GeneratedClosure.java b/src/main/java/org/zwobble/couscous/frontends/java/GeneratedClosure.java
index 0bf7649..9e0e4bb 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/GeneratedClosure.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/GeneratedClosure.java
@@ -1,27 +1,22 @@
package org.zwobble.couscous.frontends.java;
-import com.google.common.collect.ImmutableList;
import org.zwobble.couscous.ast.ClassNode;
import org.zwobble.couscous.ast.ConstructorCallNode;
import org.zwobble.couscous.ast.ExpressionNode;
import org.zwobble.couscous.ast.ReferenceNode;
import org.zwobble.couscous.types.ScalarType;
-import org.zwobble.couscous.types.TypeParameter;
import org.zwobble.couscous.util.InsertionOrderSet;
import static org.zwobble.couscous.ast.ConstructorCallNode.constructorCall;
import static org.zwobble.couscous.types.Types.addTypeParameters;
-import static org.zwobble.couscous.util.ExtraLists.concat;
-import static org.zwobble.couscous.util.ExtraLists.list;
+import static org.zwobble.couscous.util.ExtraLists.*;
public class GeneratedClosure {
private final ClassNode classNode;
- private final InsertionOrderSet<TypeParameter> capturedTypes;
private final InsertionOrderSet<ReferenceNode> capturedVariables;
- public GeneratedClosure(ClassNode classNode, InsertionOrderSet<TypeParameter> capturedTypes, InsertionOrderSet<ReferenceNode> capturedVariables) {
+ public GeneratedClosure(ClassNode classNode, InsertionOrderSet<ReferenceNode> capturedVariables) {
this.classNode = classNode;
- this.capturedTypes = capturedTypes;
this.capturedVariables = capturedVariables;
}
@@ -36,19 +31,15 @@ public class GeneratedClosure {
public ConstructorCallNode generateConstructor(Iterable<ExpressionNode> arguments) {
return constructorCall(
// TODO: tidy up type parameters to avoid copy
- addTypeParameters(getType(), ImmutableList.copyOf(capturedTypes.asList())),
+ addTypeParameters(getType(), eagerMap(classNode.getTypeParameters(), parameter -> parameter.getType())),
concat(capturedVariables, arguments));
}
public boolean hasCaptures() {
- return !capturedTypes.isEmpty() || !capturedVariables.isEmpty();
+ return !capturedVariables.isEmpty();
}
private ScalarType getType() {
return classNode.getName();
}
-
- public InsertionOrderSet<TypeParameter> getCapturedTypes() {
- return capturedTypes;
- }
}
diff --git a/src/main/java/org/zwobble/couscous/transforms/ClosureGenerator.java b/src/main/java/org/zwobble/couscous/transforms/ClosureGenerator.java
index dd54946..5599254 100644
--- a/src/main/java/org/zwobble/couscous/transforms/ClosureGenerator.java
+++ b/src/main/java/org/zwobble/couscous/transforms/ClosureGenerator.java
@@ -7,9 +7,8 @@ import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.ast.visitors.NodeTransformer;
import org.zwobble.couscous.frontends.java.GeneratedClosure;
import org.zwobble.couscous.frontends.java.Scope;
-import org.zwobble.couscous.types.ScalarType;
-import org.zwobble.couscous.types.Type;
-import org.zwobble.couscous.types.TypeParameter;
+import org.zwobble.couscous.types.*;
+import org.zwobble.couscous.util.ExtraIterables;
import org.zwobble.couscous.util.ExtraLists;
import org.zwobble.couscous.util.InsertionOrderSet;
@@ -28,6 +27,7 @@ import static org.zwobble.couscous.frontends.java.FreeVariables.findFreeTypePara
import static org.zwobble.couscous.frontends.java.FreeVariables.findFreeVariables;
import static org.zwobble.couscous.types.Types.erasure;
import static org.zwobble.couscous.util.Casts.tryCast;
+import static org.zwobble.couscous.util.ExtraIterables.lazyFlatMap;
import static org.zwobble.couscous.util.ExtraIterables.lazyMap;
import static org.zwobble.couscous.util.ExtraLists.list;
@@ -36,8 +36,6 @@ public class ClosureGenerator {
Scope scope,
ClassNode classNode
) {
- InsertionOrderSet<TypeParameter> freeTypeParameters = InsertionOrderSet.copyOf(
- findFreeTypeParameters(classNode));
InsertionOrderSet<ReferenceNode> freeVariables = InsertionOrderSet.copyOf(Iterables.filter(
findFreeVariables(ExtraLists.copyOf(classNode.childNodes())),
@@ -58,10 +56,19 @@ public class ClosureGenerator {
NodeTransformer transformer = replaceCaptureReferencesTransformer(classNode.getName(), capturedVariables);
+
+ InsertionOrderSet<TypeParameter> freeTypeParameters = InsertionOrderSet.copyOf(
+ findFreeTypeParameters(classNode));
+ List<FormalTypeParameterNode> typeParameters = InsertionOrderSet.copyOf(ExtraLists.concat(
+ lazyMap(freeTypeParameters, parameter -> formalTypeParameter(parameter)),
+ lazyMap(lazyFlatMap(capturedVariables, variable -> findTypeParameters(variable.field.getType())), parameter -> formalTypeParameter(parameter)),
+ classNode.getTypeParameters()
+ )).asList();
+
ClassNode generatedClass = transformer.transformClass(new ClassNode(
classNode.getName(),
// TODO: generate fresh type parameter and replace in body
- ExtraLists.concat(lazyMap(freeTypeParameters, parameter -> formalTypeParameter(parameter)), classNode.getTypeParameters()),
+ typeParameters,
classNode.getSuperTypes(),
fields,
list(),
@@ -69,7 +76,31 @@ public class ClosureGenerator {
classNode.getMethods(),
classNode.getInnerTypes()
));
- return new GeneratedClosure(generatedClass, freeTypeParameters, freeVariables);
+ return new GeneratedClosure(generatedClass, freeVariables);
+ }
+
+ private static Iterable<TypeParameter> findTypeParameters(Type type) {
+ return type.accept(new Type.Visitor<Iterable<TypeParameter>>() {
+ @Override
+ public Iterable<TypeParameter> visit(ScalarType type) {
+ return ExtraIterables.empty();
+ }
+
+ @Override
+ public Iterable<TypeParameter> visit(TypeParameter parameter) {
+ return ExtraIterables.of(parameter);
+ }
+
+ @Override
+ public Iterable<TypeParameter> visit(ParameterizedType type) {
+ return lazyFlatMap(type.getParameters(), parameter -> parameter.accept(this));
+ }
+
+ @Override
+ public Iterable<TypeParameter> visit(BoundTypeParameter type) {
+ return type.getValue().accept(this);
+ }
+ });
}
private static boolean isThisReference(ScalarType name, ReferenceNode reference) {
diff --git a/src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java b/src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java
index 9d252d2..568d501 100644
--- a/src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java
+++ b/src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java
@@ -7,14 +7,12 @@ import org.zwobble.couscous.frontends.java.Scope;
import org.zwobble.couscous.types.ScalarType;
import org.zwobble.couscous.types.Type;
import org.zwobble.couscous.types.Types;
-import org.zwobble.couscous.util.ExtraLists;
import org.zwobble.couscous.util.ExtraSets;
import java.util.List;
import java.util.Optional;
import java.util.Set;
-import static org.zwobble.couscous.ast.FormalTypeParameterNode.formalTypeParameter;
import static org.zwobble.couscous.ast.MethodCallNode.methodCall;
import static org.zwobble.couscous.ast.ReturnNode.returns;
import static org.zwobble.couscous.ast.ThisReferenceNode.thisReference;
@@ -156,11 +154,10 @@ public class HoistNestedTypes {
// TODO: use scope of outer class
argument -> scope.formalArgument(argument.getName(), argument.getType()));
// TODO: test addition of type parameters (both captured and on type)
- List<FormalTypeParameterNode> typeParameters = ExtraLists.concat(lazyMap(closure.getCapturedTypes(), parameter -> formalTypeParameter(parameter)), node.getTypeParameters());
MethodNode method = MethodNode.builder(createMethodName(type))
.arguments(methodArguments)
- .typeParameters(typeParameters)
- .returns(addTypeParameters(type, eagerMap(typeParameters, parameter -> parameter.getType())))
+ .typeParameters(node.getTypeParameters())
+ .returns(addTypeParameters(type, eagerMap(node.getTypeParameters(), parameter -> parameter.getType())))
.statement(returns(closure.generateConstructor(lazyMap(methodArguments, argument -> reference(argument)))))
.build();
return Optional.of(new HoistedType(
diff --git a/src/main/java/org/zwobble/couscous/util/ExtraLists.java b/src/main/java/org/zwobble/couscous/util/ExtraLists.java
index b84afcd..3c14a45 100644
--- a/src/main/java/org/zwobble/couscous/util/ExtraLists.java
+++ b/src/main/java/org/zwobble/couscous/util/ExtraLists.java
@@ -45,8 +45,8 @@ public class ExtraLists {
return ImmutableList.copyOf(Iterables.concat(first, second));
}
- public static <T> List<T> concat(List<? extends T> first, List<? extends T> second, List<? extends T> third) {
- return Stream.concat(Stream.concat(first.stream(), second.stream()), third.stream()).collect(Collectors.toList());
+ public static <T> List<T> concat(Iterable<? extends T> first, Iterable<? extends T> second, Iterable<? extends T> third) {
+ return ImmutableList.copyOf(Iterables.concat(first, second, third));
}
@SuppressWarnings("unchecked")