From 51e8ff721cc7079212119ba44fcc4bf0f9818d1e Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 6 Dec 2015 11:20:51 +0000 Subject: Replace captured variable references in method bodies --- src/main/java/org/zwobble/couscous/ast/AssignmentNode.java | 9 +++++++++ .../java/org/zwobble/couscous/ast/ConstructorCallNode.java | 8 ++++++++ src/main/java/org/zwobble/couscous/ast/ExpressionNode.java | 4 ++++ .../org/zwobble/couscous/ast/ExpressionStatementNode.java | 7 +++++++ src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java | 7 +++++++ src/main/java/org/zwobble/couscous/ast/IfStatementNode.java | 11 +++++++++++ src/main/java/org/zwobble/couscous/ast/LiteralNode.java | 7 +++++++ .../zwobble/couscous/ast/LocalVariableDeclarationNode.java | 7 +++++++ src/main/java/org/zwobble/couscous/ast/MethodCallNode.java | 12 +++++++++++- src/main/java/org/zwobble/couscous/ast/ReturnNode.java | 7 +++++++ src/main/java/org/zwobble/couscous/ast/StatementNode.java | 4 ++++ .../java/org/zwobble/couscous/ast/StaticMethodCallNode.java | 11 +++++++++++ .../org/zwobble/couscous/ast/TernaryConditionalNode.java | 10 ++++++++++ .../java/org/zwobble/couscous/ast/ThisReferenceNode.java | 7 +++++++ .../java/org/zwobble/couscous/ast/VariableReferenceNode.java | 9 ++++++++- src/main/java/org/zwobble/couscous/ast/WhileNode.java | 10 ++++++++++ 16 files changed, 128 insertions(+), 2 deletions(-) (limited to 'src/main/java/org/zwobble/couscous/ast') diff --git a/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java b/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java index b6c8f9c..15ecf8f 100644 --- a/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java +++ b/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java @@ -2,6 +2,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import java.util.function.Function; + import static org.zwobble.couscous.ast.ExpressionStatementNode.expressionStatement; import static org.zwobble.couscous.ast.VariableReferenceNode.reference; @@ -43,6 +45,13 @@ public class AssignmentNode implements ExpressionNode { return visitor.visit(this); } + @Override + public ExpressionNode replaceExpressions(Function replace) { + return new AssignmentNode( + (AssignableExpressionNode) replace.apply(target), + replace.apply(value)); + } + @Override public TypeName getType() { return value.getType(); diff --git a/src/main/java/org/zwobble/couscous/ast/ConstructorCallNode.java b/src/main/java/org/zwobble/couscous/ast/ConstructorCallNode.java index 6a4655a..ab4b1ea 100644 --- a/src/main/java/org/zwobble/couscous/ast/ConstructorCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ConstructorCallNode.java @@ -1,9 +1,12 @@ package org.zwobble.couscous.ast; import java.util.List; +import java.util.function.Function; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import static org.zwobble.couscous.util.ExtraLists.eagerMap; + public class ConstructorCallNode implements ExpressionNode { public static ConstructorCallNode constructorCall( TypeName type, @@ -35,6 +38,11 @@ public class ConstructorCallNode implements ExpressionNode { return visitor.visit(this); } + @Override + public ExpressionNode replaceExpressions(Function replace) { + return new ConstructorCallNode(type, eagerMap(arguments, replace::apply)); + } + @Override public String toString() { return "ConstructorCallNode(type=" + type + ", arguments=" + arguments diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java index 65757ad..0f1ab4f 100644 --- a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java @@ -3,6 +3,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.ast.visitors.NodeMapper; +import java.util.function.Function; + public interface ExpressionNode extends Node { TypeName getType(); T accept(ExpressionNodeMapper visitor); @@ -56,4 +58,6 @@ public interface ExpressionNode extends Node { } }); } + + ExpressionNode replaceExpressions(Function replace); } diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java index b814076..0ac7381 100644 --- a/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java @@ -2,6 +2,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; +import java.util.function.Function; + public class ExpressionStatementNode implements StatementNode { public static ExpressionStatementNode expressionStatement(ExpressionNode expression) { return new ExpressionStatementNode(expression); @@ -22,6 +24,11 @@ public class ExpressionStatementNode implements StatementNode { return visitor.visit(this); } + @Override + public StatementNode replaceExpressions(Function replace) { + return new ExpressionStatementNode(replace.apply(expression)); + } + @Override public String toString() { return "ExpressionStatementNode(expression=" + expression + ")"; diff --git a/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java b/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java index f3c92f9..9f881b4 100644 --- a/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java +++ b/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java @@ -3,6 +3,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.AssignableExpressionNodeVisitor; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import java.util.function.Function; + public class FieldAccessNode implements AssignableExpressionNode { public static FieldAccessNode fieldAccess( ExpressionNode left, @@ -41,6 +43,11 @@ public class FieldAccessNode implements AssignableExpressionNode { return visitor.visit(this); } + @Override + public ExpressionNode replaceExpressions(Function replace) { + return new FieldAccessNode(replace.apply(left), fieldName, type); + } + @Override public void accept(AssignableExpressionNodeVisitor mapper) { mapper.visit(this); diff --git a/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java b/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java index ae3e29b..cb5eee8 100644 --- a/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java @@ -1,9 +1,12 @@ package org.zwobble.couscous.ast; import java.util.List; +import java.util.function.Function; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; +import static org.zwobble.couscous.util.ExtraLists.eagerMap; + public class IfStatementNode implements StatementNode { public static IfStatementNode ifStatement( ExpressionNode condition, @@ -42,6 +45,14 @@ public class IfStatementNode implements StatementNode { return visitor.visit(this); } + @Override + public StatementNode replaceExpressions(Function replace) { + return new IfStatementNode( + replace.apply(condition), + eagerMap(trueBranch, statement -> statement.replaceExpressions(replace)), + eagerMap(falseBranch, statement -> statement.replaceExpressions(replace))); + } + @Override public String toString() { return "IfStatementNode(condition=" + condition + ", trueBranch=" diff --git a/src/main/java/org/zwobble/couscous/ast/LiteralNode.java b/src/main/java/org/zwobble/couscous/ast/LiteralNode.java index ca005de..1aa3293 100644 --- a/src/main/java/org/zwobble/couscous/ast/LiteralNode.java +++ b/src/main/java/org/zwobble/couscous/ast/LiteralNode.java @@ -6,6 +6,8 @@ import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.PrimitiveValue; import org.zwobble.couscous.values.StringValue; +import java.util.function.Function; + import static org.zwobble.couscous.values.PrimitiveValues.value; public class LiteralNode implements ExpressionNode { @@ -50,6 +52,11 @@ public class LiteralNode implements ExpressionNode { return visitor.visit(this); } + @Override + public ExpressionNode replaceExpressions(Function replace) { + return this; + } + @Override public String toString() { return "LiteralNode(value=" + value + ", type=" + type + ")"; diff --git a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java index bb272fc..3499e26 100644 --- a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java +++ b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java @@ -2,6 +2,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; +import java.util.function.Function; + import static org.zwobble.couscous.ast.VariableDeclaration.var; public class LocalVariableDeclarationNode implements VariableNode, StatementNode { @@ -50,6 +52,11 @@ public class LocalVariableDeclarationNode implements VariableNode, StatementNode return visitor.visit(this); } + @Override + public StatementNode replaceExpressions(Function replace) { + return new LocalVariableDeclarationNode(declaration, replace.apply(initialValue)); + } + @Override public String toString() { return "LocalVariableDeclarationNode(declaration=" + declaration diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java index cce140f..f65a9ae 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java @@ -1,14 +1,15 @@ package org.zwobble.couscous.ast; -import com.sun.org.apache.xpath.internal.operations.Bool; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.IntegerValue; import java.util.Collections; import java.util.List; +import java.util.function.Function; import static java.util.Arrays.asList; +import static org.zwobble.couscous.util.ExtraLists.eagerMap; public class MethodCallNode implements ExpressionNode { public static ExpressionNode not(ExpressionNode value) { @@ -116,6 +117,15 @@ public class MethodCallNode implements ExpressionNode { return visitor.visit(this); } + @Override + public ExpressionNode replaceExpressions(Function replace) { + return new MethodCallNode( + replace.apply(receiver), + methodName, + eagerMap(arguments, replace::apply), + type); + } + @Override public String toString() { return "MethodCallNode(receiver=" + receiver + ", methodName=" diff --git a/src/main/java/org/zwobble/couscous/ast/ReturnNode.java b/src/main/java/org/zwobble/couscous/ast/ReturnNode.java index 008b985..68330af 100644 --- a/src/main/java/org/zwobble/couscous/ast/ReturnNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ReturnNode.java @@ -2,6 +2,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; +import java.util.function.Function; + public class ReturnNode implements StatementNode { public static ReturnNode returns(ExpressionNode value) { return new ReturnNode(value); @@ -22,6 +24,11 @@ public class ReturnNode implements StatementNode { return visitor.visit(this); } + @Override + public StatementNode replaceExpressions(Function replace) { + return new ReturnNode(replace.apply(value)); + } + @Override public String toString() { return "ReturnNode(value=" + value + ")"; diff --git a/src/main/java/org/zwobble/couscous/ast/StatementNode.java b/src/main/java/org/zwobble/couscous/ast/StatementNode.java index a052917..4b9c9de 100644 --- a/src/main/java/org/zwobble/couscous/ast/StatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StatementNode.java @@ -3,6 +3,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.NodeMapper; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; +import java.util.function.Function; + public interface StatementNode extends Node { T accept(StatementNodeMapper visitor); @@ -35,4 +37,6 @@ public interface StatementNode extends Node { } }); } + + StatementNode replaceExpressions(Function replace); } diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java index b33e94c..ccb9854 100644 --- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java @@ -1,6 +1,7 @@ package org.zwobble.couscous.ast; import java.util.List; +import java.util.function.Function; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.BooleanValue; @@ -9,6 +10,7 @@ import org.zwobble.couscous.values.InternalCouscousValue; import org.zwobble.couscous.values.ObjectValues; import static java.util.Arrays.asList; +import static org.zwobble.couscous.util.ExtraLists.eagerMap; public class StaticMethodCallNode implements ExpressionNode { public static ExpressionNode same(ExpressionNode left, ExpressionNode right) { @@ -100,6 +102,15 @@ public class StaticMethodCallNode implements ExpressionNode { return visitor.visit(this); } + @Override + public ExpressionNode replaceExpressions(Function replace) { + return new StaticMethodCallNode( + className, + methodName, + eagerMap(arguments, replace::apply), + type); + } + @Override public String toString() { return "StaticMethodCallNode(className=" + className + ", methodName=" diff --git a/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java b/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java index e9d3f6c..f370b0a 100644 --- a/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java +++ b/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java @@ -2,6 +2,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import java.util.function.Function; + public class TernaryConditionalNode implements ExpressionNode { public static TernaryConditionalNode ternaryConditional( ExpressionNode condition, @@ -40,6 +42,14 @@ public class TernaryConditionalNode implements ExpressionNode { return visitor.visit(this); } + @Override + public ExpressionNode replaceExpressions(Function replace) { + return new TernaryConditionalNode( + replace.apply(condition), + replace.apply(ifTrue), + replace.apply(ifFalse)); + } + @Override public TypeName getType() { return ifTrue.getType(); diff --git a/src/main/java/org/zwobble/couscous/ast/ThisReferenceNode.java b/src/main/java/org/zwobble/couscous/ast/ThisReferenceNode.java index 4e7adc6..3ef5527 100644 --- a/src/main/java/org/zwobble/couscous/ast/ThisReferenceNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ThisReferenceNode.java @@ -2,6 +2,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import java.util.function.Function; + public class ThisReferenceNode implements ExpressionNode { public static ThisReferenceNode thisReference(TypeName type) { return new ThisReferenceNode(type); @@ -22,6 +24,11 @@ public class ThisReferenceNode implements ExpressionNode { return visitor.visit(this); } + @Override + public ExpressionNode replaceExpressions(Function replace) { + return this; + } + @Override public String toString() { return "ThisReferenceNode(type=" + type + ")"; diff --git a/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java b/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java index e95510f..b576389 100644 --- a/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java +++ b/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java @@ -3,6 +3,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.AssignableExpressionNodeVisitor; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import java.util.function.Function; + public class VariableReferenceNode implements AssignableExpressionNode { public static VariableReferenceNode reference(VariableNode variable) { return new VariableReferenceNode(variable.getDeclaration()); @@ -26,7 +28,12 @@ public class VariableReferenceNode implements AssignableExpressionNode { public T accept(ExpressionNodeMapper visitor) { return visitor.visit(this); } - + + @Override + public ExpressionNode replaceExpressions(Function replace) { + return this; + } + public String getReferentId() { return referent.getId(); } diff --git a/src/main/java/org/zwobble/couscous/ast/WhileNode.java b/src/main/java/org/zwobble/couscous/ast/WhileNode.java index 0a67aef..6462821 100644 --- a/src/main/java/org/zwobble/couscous/ast/WhileNode.java +++ b/src/main/java/org/zwobble/couscous/ast/WhileNode.java @@ -4,6 +4,9 @@ import com.google.common.base.Objects; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import java.util.List; +import java.util.function.Function; + +import static org.zwobble.couscous.util.ExtraLists.eagerMap; public class WhileNode implements StatementNode { public static WhileNode whileLoop(ExpressionNode condition, List body) { @@ -31,6 +34,13 @@ public class WhileNode implements StatementNode { return visitor.visit(this); } + @Override + public StatementNode replaceExpressions(Function replace) { + return new WhileNode( + replace.apply(condition), + eagerMap(body, statement -> statement.replaceExpressions(replace))); + } + @Override public boolean equals(Object o) { if (this == o) return true; -- cgit v1.2.3