diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-01-10 16:12:32 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-01-10 16:12:32 +0000 |
| commit | 1cca01d385e68aefe2131319c53c4811101f15f7 (patch) | |
| tree | 08fbdf98f3e0d53ce1c64925bef8ad576c52ae64 /src/main/java/org/zwobble/couscous/ast | |
| parent | 29c9a38a112b53e4ca193af27818442493c876cb (diff) | |
Handle both static and instance method calls in one node
Diffstat (limited to 'src/main/java/org/zwobble/couscous/ast')
12 files changed, 199 insertions, 149 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java index c483bcd..ac96c8c 100644 --- a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java @@ -43,11 +43,6 @@ public interface ExpressionNode extends Node { } @Override - public T visit(StaticMethodCallNode staticMethodCall) { - return visitor.visit(staticMethodCall); - } - - @Override public T visit(ConstructorCallNode call) { return visitor.visit(call); } diff --git a/src/main/java/org/zwobble/couscous/ast/InstanceReceiver.java b/src/main/java/org/zwobble/couscous/ast/InstanceReceiver.java new file mode 100644 index 0000000..926af5d --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/InstanceReceiver.java @@ -0,0 +1,59 @@ +package org.zwobble.couscous.ast; + +import org.zwobble.couscous.ast.visitors.NodeMapper; + +import java.util.function.Function; + +public class InstanceReceiver implements Receiver { + public static Receiver instanceReceiver(ExpressionNode expression) { + return new InstanceReceiver(expression); + } + + private final ExpressionNode expression; + + public InstanceReceiver(ExpressionNode expression) { + this.expression = expression; + } + + public ExpressionNode getExpression() { + return expression; + } + + @Override + public Receiver replaceExpressions(Function<ExpressionNode, ExpressionNode> replace) { + return new InstanceReceiver(replace.apply(expression)); + } + + @Override + public <T> T accept(Mapper<T> visitor) { + return visitor.visit(expression); + } + + @Override + public <T> T accept(NodeMapper<T> visitor) { + return visitor.visit(this); + } + + @Override + public String toString() { + return "InstanceReceiver(" + + "expression=" + expression + + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstanceReceiver that = (InstanceReceiver) o; + + return expression.equals(that.expression); + + } + + @Override + public int hashCode() { + return expression.hashCode(); + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java index efeee93..3bae839 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java @@ -8,6 +8,7 @@ import java.util.Collections; import java.util.List; import java.util.function.Function; +import static org.zwobble.couscous.ast.InstanceReceiver.instanceReceiver; import static org.zwobble.couscous.util.ExtraLists.eagerMap; import static org.zwobble.couscous.util.ExtraLists.list; @@ -81,30 +82,41 @@ public class MethodCallNode implements ExpressionNode { } public static MethodCallNode methodCall( - ExpressionNode receiver, - String methodName, - List<ExpressionNode> arguments, - TypeName type) { + ExpressionNode receiver, + String methodName, + List<ExpressionNode> arguments, + TypeName type) + { + return methodCall(instanceReceiver(receiver), methodName, arguments, type); + } + + public static MethodCallNode methodCall( + Receiver receiver, + String methodName, + List<ExpressionNode> arguments, + TypeName type) + { return new MethodCallNode(receiver, methodName, arguments, type); } - private final ExpressionNode receiver; + private final Receiver receiver; private final String methodName; private final List<ExpressionNode> arguments; private final TypeName type; - public MethodCallNode( - ExpressionNode receiver, - String methodName, - List<ExpressionNode> arguments, - TypeName type) { + private MethodCallNode( + Receiver receiver, + String methodName, + List<ExpressionNode> arguments, + TypeName type) + { this.receiver = receiver; this.methodName = methodName; this.arguments = arguments; this.type = type; } - public ExpressionNode getReceiver() { + public Receiver getReceiver() { return receiver; } @@ -132,7 +144,7 @@ public class MethodCallNode implements ExpressionNode { @Override public ExpressionNode replaceExpressions(Function<ExpressionNode, ExpressionNode> replace) { return new MethodCallNode( - replace.apply(receiver), + receiver.replaceExpressions(replace), methodName, eagerMap(arguments, replace::apply), type); diff --git a/src/main/java/org/zwobble/couscous/ast/Node.java b/src/main/java/org/zwobble/couscous/ast/Node.java index c9eed67..a3e7f03 100644 --- a/src/main/java/org/zwobble/couscous/ast/Node.java +++ b/src/main/java/org/zwobble/couscous/ast/Node.java @@ -43,12 +43,6 @@ public interface Node { } @Override - public Void visit(StaticMethodCallNode staticMethodCall) { - visitor.visit(staticMethodCall); - return null; - } - - @Override public Void visit(ConstructorCallNode call) { visitor.visit(call); return null; @@ -67,6 +61,18 @@ public interface Node { } @Override + public Void visit(InstanceReceiver receiver) { + visitor.visit(receiver); + return null; + } + + @Override + public Void visit(StaticReceiver receiver) { + visitor.visit(receiver); + return null; + } + + @Override public Void visit(ReturnNode returnNode) { visitor.visit(returnNode); return null; diff --git a/src/main/java/org/zwobble/couscous/ast/Receiver.java b/src/main/java/org/zwobble/couscous/ast/Receiver.java new file mode 100644 index 0000000..0e0e077 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/Receiver.java @@ -0,0 +1,13 @@ +package org.zwobble.couscous.ast; + +import java.util.function.Function; + +public interface Receiver extends Node { + Receiver replaceExpressions(Function<ExpressionNode, ExpressionNode> replace); + <T> T accept(Mapper<T> mapper); + + interface Mapper<T> { + T visit(ExpressionNode receiver); + T visit(TypeName receiver); + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java index 4676b67..f16005a 100644 --- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java @@ -1,20 +1,17 @@ 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; import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.InternalCouscousValue; import org.zwobble.couscous.values.ObjectValues; -import static java.util.Arrays.asList; +import java.util.List; + +import static org.zwobble.couscous.ast.StaticReceiver.staticReceiver; import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion; -import static org.zwobble.couscous.util.ExtraLists.eagerMap; import static org.zwobble.couscous.util.ExtraLists.list; -public class StaticMethodCallNode implements ExpressionNode { +public class StaticMethodCallNode { public static ExpressionNode same(ExpressionNode left, ExpressionNode right) { return staticMethodCall(InternalCouscousValue.REF, "same", list(left, right), BooleanValue.REF); } @@ -27,7 +24,7 @@ public class StaticMethodCallNode implements ExpressionNode { return typeCoercion(value, IntegerValue.REF); } - public static StaticMethodCallNode staticMethodCall( + public static ExpressionNode staticMethodCall( String className, String methodName, List<ExpressionNode> arguments, @@ -35,114 +32,11 @@ public class StaticMethodCallNode implements ExpressionNode { return staticMethodCall(TypeName.of(className), methodName, arguments, type); } - public static StaticMethodCallNode staticMethodCall( - TypeName className, - String methodName, - List<ExpressionNode> arguments, - TypeName type) { - return new StaticMethodCallNode(className, methodName, arguments, type); - } - - private final TypeName className; - private final String methodName; - private final List<ExpressionNode> arguments; - private final TypeName type; - - public StaticMethodCallNode( + public static ExpressionNode staticMethodCall( TypeName className, String methodName, List<ExpressionNode> arguments, TypeName type) { - this.className = className; - this.methodName = methodName; - this.arguments = arguments; - this.type = type; - } - - public TypeName getClassName() { - return className; - } - - public String getMethodName() { - return methodName; - } - - public List<ExpressionNode> getArguments() { - return arguments; - } - - public TypeName getType() { - return type; - } - - public MethodSignature signature() { - return new MethodSignature(methodName, eagerMap(arguments, argument -> argument.getType())); - } - - @Override - public <T> T accept(ExpressionNodeMapper<T> visitor) { - return visitor.visit(this); - } - - @Override - public ExpressionNode replaceExpressions(Function<ExpressionNode, ExpressionNode> replace) { - return new StaticMethodCallNode( - className, - methodName, - eagerMap(arguments, replace::apply), - type); - } - - @Override - public String toString() { - return "StaticMethodCallNode(className=" + className + ", methodName=" - + methodName + ", arguments=" + arguments + ", type=" + type - + ")"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((arguments == null) ? 0 : arguments.hashCode()); - result = prime * result - + ((className == null) ? 0 : className.hashCode()); - result = prime * result - + ((methodName == null) ? 0 : methodName.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - StaticMethodCallNode other = (StaticMethodCallNode) obj; - if (arguments == null) { - if (other.arguments != null) - return false; - } else if (!arguments.equals(other.arguments)) - return false; - if (className == null) { - if (other.className != null) - return false; - } else if (!className.equals(other.className)) - return false; - if (methodName == null) { - if (other.methodName != null) - return false; - } else if (!methodName.equals(other.methodName)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - return true; + return MethodCallNode.methodCall(staticReceiver(className), methodName, arguments, type); } } diff --git a/src/main/java/org/zwobble/couscous/ast/StaticReceiver.java b/src/main/java/org/zwobble/couscous/ast/StaticReceiver.java new file mode 100644 index 0000000..4d35376 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/StaticReceiver.java @@ -0,0 +1,58 @@ +package org.zwobble.couscous.ast; + +import org.zwobble.couscous.ast.visitors.NodeMapper; + +import java.util.function.Function; + +public class StaticReceiver implements Receiver { + public static Receiver staticReceiver(TypeName type) { + return new StaticReceiver(type); + } + + private final TypeName type; + + public StaticReceiver(TypeName type) { + this.type = type; + } + + public TypeName getType() { + return type; + } + + @Override + public Receiver replaceExpressions(Function<ExpressionNode, ExpressionNode> replace) { + return this; + } + + @Override + public <T> T accept(Mapper<T> mapper) { + return mapper.visit(type); + } + + @Override + public <T> T accept(NodeMapper<T> visitor) { + return visitor.visit(this); + } + + @Override + public String toString() { + return "StaticReceiver(" + + "type=" + type + + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + StaticReceiver that = (StaticReceiver) o; + + return type.equals(that.type); + } + + @Override + public int hashCode() { + return type.hashCode(); + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java index 8b65f35..c2380c7 100644 --- a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java +++ b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java @@ -65,11 +65,6 @@ public class NodeStructure { } @Override - public Stream<ExpressionNode> visit(StaticMethodCallNode staticMethodCall) { - return staticMethodCall.getArguments().stream(); - } - - @Override public Stream<? extends ExpressionNode> visit(ConstructorCallNode call) { return call.getArguments().stream(); } @@ -85,6 +80,16 @@ public class NodeStructure { } @Override + public Stream<? extends Node> visit(InstanceReceiver receiver) { + return Stream.of(receiver.getExpression()); + } + + @Override + public Stream<? extends Node> visit(StaticReceiver receiver) { + return Stream.empty(); + } + + @Override public Stream<Node> visit(ReturnNode returnNode) { return Stream.of(returnNode.getValue()); } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java index 87b8598..6eab8d4 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java @@ -9,7 +9,6 @@ public interface ExpressionNodeMapper<T> { T visit(AssignmentNode assignment); T visit(TernaryConditionalNode ternaryConditional); T visit(MethodCallNode methodCall); - T visit(StaticMethodCallNode staticMethodCall); T visit(ConstructorCallNode call); T visit(FieldAccessNode fieldAccess); T visit(TypeCoercionNode typeCoercion); diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java index 4267c75..fe3b4a2 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java @@ -9,11 +9,13 @@ public interface NodeMapper<T> { T visit(AssignmentNode assignment); T visit(TernaryConditionalNode ternaryConditional); T visit(MethodCallNode methodCall); - T visit(StaticMethodCallNode staticMethodCall); T visit(ConstructorCallNode call); T visit(FieldAccessNode fieldAccess); T visit(TypeCoercionNode typeCoercion); + T visit(InstanceReceiver receiver); + T visit(StaticReceiver receiver); + T visit(ReturnNode returnNode); T visit(ExpressionStatementNode expressionStatement); T visit(LocalVariableDeclarationNode localVariableDeclaration); diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java index 09cfcd3..388acb1 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java @@ -40,11 +40,6 @@ public class NodeMapperWithDefault<T> implements NodeMapper<T> { } @Override - public T visit(StaticMethodCallNode staticMethodCall) { - return defaultValue; - } - - @Override public T visit(ConstructorCallNode call) { return defaultValue; } @@ -60,6 +55,16 @@ public class NodeMapperWithDefault<T> implements NodeMapper<T> { } @Override + public T visit(InstanceReceiver receiver) { + return defaultValue; + } + + @Override + public T visit(StaticReceiver receiver) { + return defaultValue; + } + + @Override public T visit(ReturnNode returnNode) { return defaultValue; } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java index 9f6be92..189a0cd 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java @@ -9,11 +9,13 @@ public interface NodeVisitor { void visit(AssignmentNode assignment); void visit(TernaryConditionalNode ternaryConditional); void visit(MethodCallNode methodCall); - void visit(StaticMethodCallNode staticMethodCall); void visit(ConstructorCallNode call); void visit(FieldAccessNode fieldAccess); void visit(TypeCoercionNode typeCoercion); + void visit(InstanceReceiver receiver); + void visit(StaticReceiver receiver); + void visit(ReturnNode returnNode); void visit(ExpressionStatementNode expressionStatement); void visit(LocalVariableDeclarationNode localVariableDeclaration); |
