aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/AssignmentNode.java4
-rw-r--r--src/main/java/org/zwobble/couscous/ast/CastNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ClassNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ExpressionNode.java11
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/IfStatementNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/InstanceReceiver.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodCallNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ReturnNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/StatementNode.java10
-rw-r--r--src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java6
-rw-r--r--src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/WhileNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java322
-rw-r--r--src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java22
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java19
18 files changed, 232 insertions, 184 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java b/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java
index b027399..ec781b3 100644
--- a/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java
@@ -47,8 +47,8 @@ public class AssignmentNode implements ExpressionNode {
@Override
public ExpressionNode transform(NodeTransformer transformer) {
return new AssignmentNode(
- (AssignableExpressionNode) transformer.visit(target),
- transformer.visit(value));
+ (AssignableExpressionNode) transformer.transformExpression(target),
+ transformer.transformExpression(value));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/CastNode.java b/src/main/java/org/zwobble/couscous/ast/CastNode.java
index 858779e..20ae9c6 100644
--- a/src/main/java/org/zwobble/couscous/ast/CastNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/CastNode.java
@@ -32,7 +32,7 @@ public class CastNode implements ExpressionNode {
@Override
public ExpressionNode transform(NodeTransformer transformer) {
- return new CastNode(transformer.visit(expression), transformer.transform(type));
+ return new CastNode(transformer.transformExpression(expression), transformer.transform(type));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/ClassNode.java b/src/main/java/org/zwobble/couscous/ast/ClassNode.java
index 8b54be6..ac304e6 100644
--- a/src/main/java/org/zwobble/couscous/ast/ClassNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/ClassNode.java
@@ -72,7 +72,7 @@ public class ClassNode implements Node {
transformer.transform(name),
transformer.transformTypes(superTypes),
transformer.transformFields(fields),
- transformer.visit(constructor),
+ transformer.transformConstructor(constructor),
transformer.transformMethods(methods));
}
diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
index e46ca0a..a7842d3 100644
--- a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
@@ -4,8 +4,6 @@ import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
import org.zwobble.couscous.ast.visitors.NodeMapper;
import org.zwobble.couscous.ast.visitors.NodeTransformer;
-import java.util.function.Function;
-
public interface ExpressionNode extends Node {
TypeName getType();
<T> T accept(ExpressionNodeMapper<T> visitor);
@@ -71,13 +69,4 @@ public interface ExpressionNode extends Node {
}
ExpressionNode transform(NodeTransformer transformer);
-
- default ExpressionNode replaceExpressions(Function<ExpressionNode, ExpressionNode> replace) {
- return transform(new NodeTransformer() {
- @Override
- public ExpressionNode defaultTransformExpression(ExpressionNode value) {
- return replace.apply(value);
- }
- });
- }
}
diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java
index 1720fc5..aa69ea1 100644
--- a/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java
@@ -25,7 +25,7 @@ public class ExpressionStatementNode implements StatementNode {
@Override
public StatementNode transform(NodeTransformer transformer) {
- return new ExpressionStatementNode(transformer.visit(expression));
+ return new ExpressionStatementNode(transformer.transformExpression(expression));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java b/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java
index 6d88d28..d05a06a 100644
--- a/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java
@@ -45,7 +45,7 @@ public class FieldAccessNode implements AssignableExpressionNode {
@Override
public ExpressionNode transform(NodeTransformer transformer) {
return new FieldAccessNode(
- transformer.visit(left),
+ transformer.transformExpression(left),
fieldName,
transformer.transform(type));
}
diff --git a/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java b/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java
index 2a34a47..a3a94ad 100644
--- a/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java
@@ -46,7 +46,7 @@ public class IfStatementNode implements StatementNode {
@Override
public StatementNode transform(NodeTransformer transformer) {
return new IfStatementNode(
- transformer.visit(condition),
+ transformer.transformExpression(condition),
transformer.transformStatements(trueBranch),
transformer.transformStatements(falseBranch));
}
diff --git a/src/main/java/org/zwobble/couscous/ast/InstanceReceiver.java b/src/main/java/org/zwobble/couscous/ast/InstanceReceiver.java
index ed32dc4..6a3f42c 100644
--- a/src/main/java/org/zwobble/couscous/ast/InstanceReceiver.java
+++ b/src/main/java/org/zwobble/couscous/ast/InstanceReceiver.java
@@ -31,7 +31,7 @@ public class InstanceReceiver implements Receiver {
}
public Receiver transform(NodeTransformer transformer) {
- return new InstanceReceiver(transformer.visit(expression));
+ return new InstanceReceiver(transformer.transformExpression(expression));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java
index 145b37f..03e4226 100644
--- a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java
@@ -56,7 +56,7 @@ public class LocalVariableDeclarationNode implements VariableNode, StatementNode
public StatementNode transform(NodeTransformer transformer) {
return new LocalVariableDeclarationNode(
transformer.transform(declaration),
- transformer.visit(initialValue));
+ transformer.transformExpression(initialValue));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
index b622d24..358b4a8 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
@@ -89,7 +89,7 @@ public class MethodCallNode implements ExpressionNode {
@Override
public ExpressionNode transform(NodeTransformer transformer) {
return new MethodCallNode(
- transformer.visit(receiver),
+ transformer.transformReceiver(receiver),
methodName,
transformer.transformExpressions(arguments),
transformer.transform(type));
diff --git a/src/main/java/org/zwobble/couscous/ast/ReturnNode.java b/src/main/java/org/zwobble/couscous/ast/ReturnNode.java
index c1f0124..136f343 100644
--- a/src/main/java/org/zwobble/couscous/ast/ReturnNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/ReturnNode.java
@@ -25,7 +25,7 @@ public class ReturnNode implements StatementNode {
@Override
public StatementNode transform(NodeTransformer transformer) {
- return new ReturnNode(transformer.visit(value));
+ return new ReturnNode(transformer.transformExpression(value));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/StatementNode.java b/src/main/java/org/zwobble/couscous/ast/StatementNode.java
index c200715..d756534 100644
--- a/src/main/java/org/zwobble/couscous/ast/StatementNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/StatementNode.java
@@ -4,8 +4,6 @@ import org.zwobble.couscous.ast.visitors.NodeMapper;
import org.zwobble.couscous.ast.visitors.NodeTransformer;
import org.zwobble.couscous.ast.visitors.StatementNodeMapper;
-import java.util.function.Function;
-
public interface StatementNode extends Node {
<T> T accept(StatementNodeMapper<T> visitor);
@@ -40,12 +38,4 @@ public interface StatementNode extends Node {
}
StatementNode transform(NodeTransformer transformer);
- default StatementNode replaceExpressions(Function<ExpressionNode, ExpressionNode> replace) {
- return transform(new NodeTransformer() {
- @Override
- public ExpressionNode defaultTransformExpression(ExpressionNode value) {
- return replace.apply(value);
- }
- });
- }
}
diff --git a/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java b/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java
index 6364e94..3caec58 100644
--- a/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java
@@ -44,9 +44,9 @@ public class TernaryConditionalNode implements ExpressionNode {
@Override
public ExpressionNode transform(NodeTransformer transformer) {
return new TernaryConditionalNode(
- transformer.visit(condition),
- transformer.visit(ifTrue),
- transformer.visit(ifFalse));
+ transformer.transformExpression(condition),
+ transformer.transformExpression(ifTrue),
+ transformer.transformExpression(ifFalse));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java b/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java
index db58deb..680ecea 100644
--- a/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java
@@ -33,7 +33,7 @@ public class TypeCoercionNode implements ExpressionNode {
@Override
public ExpressionNode transform(NodeTransformer transformer) {
return new TypeCoercionNode(
- transformer.visit(expression),
+ transformer.transformExpression(expression),
transformer.transform(type));
}
diff --git a/src/main/java/org/zwobble/couscous/ast/WhileNode.java b/src/main/java/org/zwobble/couscous/ast/WhileNode.java
index 82e2e87..8ea693f 100644
--- a/src/main/java/org/zwobble/couscous/ast/WhileNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/WhileNode.java
@@ -35,7 +35,7 @@ public class WhileNode implements StatementNode {
@Override
public StatementNode transform(NodeTransformer transformer) {
return new WhileNode(
- transformer.visit(condition),
+ transformer.transformExpression(condition),
transformer.transformStatements(body));
}
diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java
index 79a409c..4f7f819 100644
--- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java
+++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java
@@ -7,159 +7,237 @@ import com.google.common.collect.Iterables;
import org.zwobble.couscous.ast.*;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.Set;
-public class NodeTransformer implements ExpressionNodeMapper<ExpressionNode>, StatementNodeMapper<StatementNode>, NodeMapper<Node> {
- // TODO: tidy up transform vs visit
- // TODO: don't expose specific statement/expression visit methods
- // (require passing through visit(ExpressionNode) and visit(StatementNode) for callers
- public TypeName transform(TypeName type) {
- return type;
- }
-
- public final ExpressionNode visit(ExpressionNode value) {
- return value.accept((ExpressionNodeMapper<ExpressionNode>)this);
- }
-
- @Override
- public ExpressionNode visit(LiteralNode literal) {
- return defaultTransformExpression(literal);
- }
-
- @Override
- public ExpressionNode visit(VariableReferenceNode variableReference) {
- return defaultTransformExpression(variableReference);
- }
-
- @Override
- public ExpressionNode visit(ThisReferenceNode reference) {
- return defaultTransformExpression(reference);
- }
-
- @Override
- public ExpressionNode visit(AssignmentNode assignment) {
- return defaultTransformExpression(assignment);
- }
-
- @Override
- public ExpressionNode visit(TernaryConditionalNode ternaryConditional) {
- return defaultTransformExpression(ternaryConditional);
- }
-
- @Override
- public ExpressionNode visit(MethodCallNode methodCall) {
- return defaultTransformExpression(methodCall);
- }
-
- @Override
- public ExpressionNode visit(ConstructorCallNode call) {
- return defaultTransformExpression(call);
- }
-
- @Override
- public ExpressionNode visit(OperationNode operationNode) {
- return defaultTransformExpression(operationNode);
+public class NodeTransformer {
+ public static NodeTransformer replaceExpressions(Map<ExpressionNode, ExpressionNode> replacements) {
+ return builder().
+ transformExpression(expression ->
+ Optional.ofNullable(replacements.get(expression)))
+ .build();
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public Node transform(Node node) {
+ return node.accept(new NodeMapper<Node>() {
+ @Override
+ public Node visit(LiteralNode literal) {
+ return transformExpression(literal);
+ }
+
+ @Override
+ public Node visit(VariableReferenceNode variableReference) {
+ return transformExpression(variableReference);
+ }
+
+ @Override
+ public Node visit(ThisReferenceNode reference) {
+ return transformExpression(reference);
+ }
+
+ @Override
+ public Node visit(AssignmentNode assignment) {
+ return transformExpression(assignment);
+ }
+
+ @Override
+ public Node visit(TernaryConditionalNode ternaryConditional) {
+ return transformExpression(ternaryConditional);
+ }
+
+ @Override
+ public Node visit(MethodCallNode methodCall) {
+ return transformExpression(methodCall);
+ }
+
+ @Override
+ public Node visit(ConstructorCallNode call) {
+ return transformExpression(call);
+ }
+
+ @Override
+ public Node visit(OperationNode operation) {
+ return transformExpression(operation);
+ }
+
+ @Override
+ public Node visit(FieldAccessNode fieldAccess) {
+ return transformExpression(fieldAccess);
+ }
+
+ @Override
+ public Node visit(TypeCoercionNode typeCoercion) {
+ return transformExpression(typeCoercion);
+ }
+
+ @Override
+ public Node visit(CastNode cast) {
+ return transformExpression(cast);
+ }
+
+ @Override
+ public Node visit(InstanceReceiver receiver) {
+ return transformReceiver(receiver);
+ }
+
+ @Override
+ public Node visit(StaticReceiver receiver) {
+ return transformReceiver(receiver);
+ }
+
+ @Override
+ public Node visit(ReturnNode returnNode) {
+ return transformStatement(returnNode);
+ }
+
+ @Override
+ public Node visit(ExpressionStatementNode expressionStatement) {
+ return transformStatement(expressionStatement);
+ }
+
+ @Override
+ public Node visit(LocalVariableDeclarationNode localVariableDeclaration) {
+ return transformStatement(localVariableDeclaration);
+ }
+
+ @Override
+ public Node visit(IfStatementNode ifStatement) {
+ return transformStatement(ifStatement);
+ }
+
+ @Override
+ public Node visit(WhileNode whileLoop) {
+ return transformStatement(whileLoop);
+ }
+
+ @Override
+ public Node visit(FormalArgumentNode formalArgumentNode) {
+ return transformFormalArgument(formalArgumentNode);
+ }
+
+ @Override
+ public Node visit(AnnotationNode annotation) {
+ return transformAnnotation(annotation);
+ }
+
+ @Override
+ public Node visit(MethodNode methodNode) {
+ return transformMethod(methodNode);
+ }
+
+ @Override
+ public Node visit(ConstructorNode constructorNode) {
+ return transformConstructor(constructorNode);
+ }
+
+ @Override
+ public Node visit(FieldDeclarationNode declaration) {
+ return transformField(declaration);
+ }
+
+ @Override
+ public Node visit(ClassNode classNode) {
+ return transformClass(classNode);
+ }
+ });
+ }
+
+ public static class Builder {
+ private Function<ExpressionNode, Optional<ExpressionNode>> transformExpression = expression -> Optional.empty();
+ private Function<TypeName, TypeName> transformType = type -> type;
+
+ public Builder transformExpression(
+ Function<ExpressionNode, Optional<ExpressionNode>> transformExpression)
+ {
+ this.transformExpression = transformExpression;
+ return this;
+ }
+
+ public Builder transformType(
+ Function<TypeName, TypeName> transformType)
+ {
+ this.transformType = transformType;
+ return this;
+ }
+
+ public NodeTransformer build() {
+ return new NodeTransformer(transformExpression, transformType);
+ }
+ }
+
+ private final Function<ExpressionNode, Optional<ExpressionNode>> transformExpression;
+ private final Function<TypeName, TypeName> transformType;
+
+ private NodeTransformer(
+ Function<ExpressionNode, Optional<ExpressionNode>> transformExpression,
+ Function<TypeName, TypeName> transformType)
+ {
+ this.transformExpression = transformExpression;
+ this.transformType = transformType;
}
- @Override
- public ExpressionNode visit(FieldAccessNode fieldAccess) {
- return defaultTransformExpression(fieldAccess);
- }
-
- @Override
- public ExpressionNode visit(TypeCoercionNode typeCoercion) {
- return defaultTransformExpression(typeCoercion);
- }
-
- @Override
- public ExpressionNode visit(CastNode cast) {
- return defaultTransformExpression(cast);
- }
-
- protected ExpressionNode defaultTransformExpression(ExpressionNode expression) {
- return expression.transform(this);
+ public TypeName transform(TypeName type) {
+ return transformType.apply(type);
}
- public Receiver visit(Receiver receiver) {
- // TODO: remove cast
- return (Receiver) receiver.accept(this);
+ public ExpressionNode transformExpression(ExpressionNode expression) {
+ return transformExpression.apply(expression)
+ .orElseGet(() -> expression.transform(this));
}
- @Override
- public Node visit(InstanceReceiver receiver) {
- return receiver.transform(this);
- }
+ public Receiver transformReceiver(Receiver receiver) {
+ return receiver.accept(new Receiver.Mapper<Receiver>() {
+ @Override
+ public Receiver visit(ExpressionNode receiver) {
+ return new InstanceReceiver(receiver.transform(NodeTransformer.this));
+ }
- @Override
- public Node visit(StaticReceiver receiver) {
- return receiver.transform(this);
+ @Override
+ public Receiver visit(TypeName receiver) {
+ return new StaticReceiver(transform(receiver));
+ }
+ });
}
public VariableDeclaration transform(VariableDeclaration declaration) {
return VariableDeclaration.var(declaration.getId(), declaration.getName(), transform(declaration.getType()));
}
- public final StatementNode visit(StatementNode statement) {
- return statement.accept((StatementNodeMapper<StatementNode>)this);
- }
-
- @Override
- public StatementNode visit(ReturnNode returnNode) {
- return returnNode.transform(this);
- }
-
- @Override
- public StatementNode visit(ExpressionStatementNode expressionStatement) {
- return expressionStatement.transform(this);
- }
-
- @Override
- public StatementNode visit(LocalVariableDeclarationNode localVariableDeclaration) {
- return localVariableDeclaration.transform(this);
- }
-
- @Override
- public StatementNode visit(IfStatementNode ifStatement) {
- return ifStatement.transform(this);
- }
-
- @Override
- public StatementNode visit(WhileNode whileLoop) {
- return whileLoop.transform(this);
+ public final StatementNode transformStatement(StatementNode statement) {
+ return statement.transform(this);
}
- @Override
- public FormalArgumentNode visit(FormalArgumentNode formalArgumentNode) {
+ public FormalArgumentNode transformFormalArgument(FormalArgumentNode formalArgumentNode) {
return formalArgumentNode.transform(this);
}
- @Override
- public AnnotationNode visit(AnnotationNode annotation) {
+ public AnnotationNode transformAnnotation(AnnotationNode annotation) {
return annotation.transform(this);
}
- @Override
- public MethodNode visit(MethodNode method) {
+ public MethodNode transformMethod(MethodNode method) {
return method.transform(this);
}
- @Override
- public ConstructorNode visit(ConstructorNode constructor) {
+ public ConstructorNode transformConstructor(ConstructorNode constructor) {
return constructor.transform(this);
}
- @Override
- public FieldDeclarationNode visit(FieldDeclarationNode field) {
+ public FieldDeclarationNode transformField(FieldDeclarationNode field) {
return field.transform(this);
}
- @Override
- public ClassNode visit(ClassNode classNode) {
+ public ClassNode transformClass(ClassNode classNode) {
return classNode.transform(this);
}
public List<AnnotationNode> transformAnnotations(List<AnnotationNode> annotations) {
- return transformList(annotations, this::visit);
+ return transformList(annotations, this::transformAnnotation);
}
public Set<TypeName> transformTypes(Set<TypeName> superTypes) {
@@ -167,23 +245,23 @@ public class NodeTransformer implements ExpressionNodeMapper<ExpressionNode>, St
}
public List<FieldDeclarationNode> transformFields(List<FieldDeclarationNode> fields) {
- return transformList(fields, this::visit);
+ return transformList(fields, this::transformField);
}
public List<MethodNode> transformMethods(List<MethodNode> methods) {
- return transformList(methods, this::visit);
+ return transformList(methods, this::transformMethod);
}
public List<StatementNode> transformStatements(List<StatementNode> body) {
- return transformList(body, this::visit);
+ return transformList(body, this::transformStatement);
}
public List<ExpressionNode> transformExpressions(List<? extends ExpressionNode> expressions) {
- return transformList(expressions, this::visit);
+ return transformList(expressions, this::transformExpression);
}
public List<FormalArgumentNode> transformFormalArguments(List<FormalArgumentNode> arguments) {
- return transformList(arguments, this::visit);
+ return transformList(arguments, this::transformFormalArgument);
}
private <T> Set<T> transformSet(Set<T> values, Function<T, T> function) {
diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java
index ab55e0d..2ba7470 100644
--- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java
@@ -8,7 +8,9 @@ import org.zwobble.couscous.values.*;
import java.util.Map;
import java.util.Optional;
-public class CsharpCodeGenerator extends NodeTransformer {
+import static org.zwobble.couscous.util.Casts.tryCast;
+
+public class CsharpCodeGenerator {
private final static Map<TypeName, TypeName> PRIMITIVES = ImmutableMap.<TypeName, TypeName>builder()
.put(IntegerValue.REF, TypeName.of("int"))
.put(StringValue.REF, TypeName.of("string"))
@@ -29,11 +31,14 @@ public class CsharpCodeGenerator extends NodeTransformer {
}
private Node generateCode(Node node) {
- return node.accept(this);
+ return NodeTransformer.builder()
+ .transformType(this::transformType)
+ .transformExpression(this::transformExpression)
+ .build()
+ .transform(node);
}
- @Override
- public TypeName transform(TypeName type) {
+ private TypeName transformType(TypeName type) {
if (PRIMITIVES.containsKey(type)) {
return PRIMITIVES.get(type);
} else {
@@ -41,12 +46,12 @@ public class CsharpCodeGenerator extends NodeTransformer {
}
}
- @Override
- public ExpressionNode visit(MethodCallNode call) {
- return toPrimitiveMethod(call).orElseGet(() -> super.visit(call));
+ private Optional<ExpressionNode> transformExpression(ExpressionNode expression) {
+ return tryCast(MethodCallNode.class, expression)
+ .flatMap(this::transformMethodCall);
}
- private Optional<ExpressionNode> toPrimitiveMethod(MethodCallNode call) {
+ private Optional<ExpressionNode> transformMethodCall(MethodCallNode call) {
return call.getReceiver().accept(new Receiver.Mapper<Optional<ExpressionNode>>() {
@Override
public Optional<ExpressionNode> visit(ExpressionNode receiver) {
@@ -60,7 +65,6 @@ public class CsharpCodeGenerator extends NodeTransformer {
.map(generator -> generator.generate(call.getArguments()));
}
});
-
}
private TypeName addPrefix(TypeName name, String namespace) {
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 f9cfd85..35ed03e 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -7,6 +7,7 @@ import org.eclipse.jdt.core.dom.*;
import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.ast.sugar.AnonymousClass;
import org.zwobble.couscous.ast.sugar.Lambda;
+import org.zwobble.couscous.ast.visitors.NodeTransformer;
import org.zwobble.couscous.util.ExtraLists;
import java.io.IOException;
@@ -117,22 +118,8 @@ public class JavaReader {
Map<ExpressionNode, ExpressionNode> replacements = Maps.transformValues(
Maps.uniqueIndex(freeVariables, variable -> variable.freeVariable),
freeVariable -> captureAccess(className, freeVariable));
- Function<ExpressionNode, ExpressionNode> replaceExpression = new CaptureReplacer(replacements);
- return eagerMap(body, statement -> statement.replaceExpressions(replaceExpression));
- }
-
- private class CaptureReplacer implements Function<ExpressionNode, ExpressionNode> {
- private final Map<ExpressionNode, ExpressionNode> replacements;
-
- public CaptureReplacer(Map<ExpressionNode, ExpressionNode> replacements) {
- this.replacements = replacements;
- }
-
- @Override
- public ExpressionNode apply(ExpressionNode expression) {
- return Optional.ofNullable(replacements.get(expression))
- .orElseGet(() -> expression.replaceExpressions(this));
- }
+ NodeTransformer transformer = NodeTransformer.replaceExpressions(replacements);
+ return eagerMap(body, statement -> statement.transform(transformer));
}
private ConstructorNode buildConstructor(Scope outerScope, TypeName type, List<CapturedVariable> freeVariables) {