aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-03-01 23:10:04 +0000
committerMichael Williamson <mike@zwobble.org>2016-03-03 18:49:34 +0000
commit7576a7a0afa1bbb6adf9c8be0ad422d99cab4293 (patch)
treeee00ccbbc69864b2774998c3421d0a6e77f24682 /src/main/java/org
parent80284eefe7098c42a0b4736c45f622116fb543e0 (diff)
Enable nested class generation with existing constructor
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ConstructorNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java34
2 files changed, 26 insertions, 10 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/ConstructorNode.java b/src/main/java/org/zwobble/couscous/ast/ConstructorNode.java
index a25a993..1bd33d0 100644
--- a/src/main/java/org/zwobble/couscous/ast/ConstructorNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/ConstructorNode.java
@@ -18,7 +18,7 @@ public class ConstructorNode implements Node {
private final List<FormalArgumentNode> arguments;
private final List<StatementNode> body;
- private ConstructorNode(
+ public ConstructorNode(
List<FormalArgumentNode> arguments,
List<StatementNode> body) {
this.arguments = arguments;
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 6772fdc..d3a763b 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -36,6 +36,7 @@ import static org.zwobble.couscous.util.ExtraLists.*;
import static org.zwobble.couscous.util.ExtraMaps.lookup;
public class JavaReader {
+ // TODO: de-dupe captures (multiple reference nodes may reference the same free variable)
public static List<TypeNode> readClassFromFile(List<Path> sourcePaths, Path sourcePath) throws IOException {
CompilationUnit ast = new JavaParser().parseCompilationUnit(sourcePaths, sourcePath);
@@ -73,8 +74,7 @@ public class JavaReader {
.transformExpression(expression ->
tryCast(ConstructorCallNode.class, expression)
.flatMap(call -> lookup(nestedClasses, call.getType()).map(captures ->
- // TODO: handle existing arguments
- new ConstructorCallNode(call.getType(), captures))))
+ new ConstructorCallNode(call.getType(), ExtraLists.concat(captures, call.getArguments())))))
.build();
return eagerMap(classes, classNode -> classNode.transform(transformer));
}
@@ -146,7 +146,12 @@ public class JavaReader {
return eagerMap(body, statement -> statement.transform(transformer));
}
- private ConstructorNode buildConstructor(Scope outerScope, TypeName type, List<CapturedVariable> freeVariables) {
+ private ConstructorNode buildConstructor(
+ Scope outerScope,
+ TypeName type,
+ List<CapturedVariable> freeVariables,
+ ConstructorNode existing)
+ {
Scope scope = outerScope.enterConstructor();
ImmutableList.Builder<FormalArgumentNode> arguments = ImmutableList.builder();
@@ -158,7 +163,10 @@ public class JavaReader {
body.add(assignStatement(captureAccess(type, variable), reference(argument)));
}
- return constructor(arguments.build(), body.build());
+ arguments.addAll(existing.getArguments());
+ body.addAll(existing.getBody());
+
+ return new ConstructorNode(arguments.build(), body.build());
}
private FieldAccessNode captureAccess(TypeName type, CapturedVariable freeVariable) {
@@ -197,9 +205,12 @@ public class JavaReader {
Scope scope,
ClassNode classNode
) {
- List<ReferenceNode> freeVariables = findFreeVariables(ExtraLists.concat(
- classNode.getFields(),
- classNode.getMethods()));
+ List<ReferenceNode> freeVariables = eagerFilter(
+ findFreeVariables(ExtraLists.concat(
+ classNode.getFields(),
+ classNode.getMethods())),
+ // TODO: check this references work correctly in anonymous classes
+ variable -> !isThisReference(classNode.getName(), variable));
List<CapturedVariable> capturedVariables = ImmutableList.copyOf(transform(
freeVariables,
freeVariable -> new CapturedVariable(freeVariable, fieldForCapture(freeVariable))));
@@ -215,13 +226,18 @@ public class JavaReader {
fields,
// TODO: handle static constructor (or codify that this is a case that never needs handling)
list(),
- // TODO: handle existing constructor
- buildConstructor(scope, classNode.getName(), capturedVariables),
+ buildConstructor(scope, classNode.getName(), capturedVariables, classNode.getConstructor()),
eagerMap(classNode.getMethods(), method ->
method.mapBody(body -> replaceCaptureReferences(classNode.getName(), body, capturedVariables))));
return new GeneratedClosure(generatedClass, freeVariables);
}
+ private boolean isThisReference(TypeName name, ReferenceNode reference) {
+ return tryCast(ThisReferenceNode.class, reference)
+ .map(node -> node.getType().equals(name))
+ .orElse(false);
+ }
+
private GeneratedClosure classWithCapture(
Scope scope,
TypeName className,