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 | |
| parent | 29c9a38a112b53e4ca193af27818442493c876cb (diff) | |
Handle both static and instance method calls in one node
Diffstat (limited to 'src/main')
15 files changed, 253 insertions, 195 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); diff --git a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java index db3cd2e..403e7ac 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java @@ -130,10 +130,6 @@ public class PrimitiveMethods { ImmutableMap.<TypeName, Map<String, PrimitiveStaticMethodGenerator>>builder() .put(InternalCouscousValue.REF, INTERNAL_METHODS) .build(); - - public static boolean isPrimitive(TypeName type) { - return METHODS.containsKey(type); - } public static Optional<PrimitiveMethodGenerator> getPrimitiveMethod(TypeName type, String methodName) { return Optional.ofNullable(METHODS.get(type)) diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java index 32910f3..4390207 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -10,14 +10,10 @@ import org.zwobble.couscous.ast.structure.NodeStructure; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.ast.visitors.NodeMapperWithDefault; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; -import org.zwobble.couscous.backends.python.PrimitiveMethods.PrimitiveMethodGenerator; import org.zwobble.couscous.backends.python.ast.*; import org.zwobble.couscous.values.*; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -92,8 +88,8 @@ public class PythonCodeGenerator { return NodeStructure.descendantNodes(classNode) .flatMap(node -> node.accept(new NodeMapperWithDefault<Stream<TypeName>>(Stream.empty()) { @Override - public Stream<TypeName> visit(StaticMethodCallNode staticMethodCall) { - return Stream.of(staticMethodCall.getClassName()); + public Stream<TypeName> visit(StaticReceiver receiver) { + return Stream.of(receiver.getType()); } @Override @@ -238,27 +234,31 @@ public class PythonCodeGenerator { @Override public PythonExpressionNode visit(MethodCallNode methodCall) { - PythonExpressionNode receiver = generateExpression(methodCall.getReceiver()); + PythonExpressionNode receiver = generateReceiver(methodCall.getReceiver()); List<PythonExpressionNode> arguments = generateExpressions(methodCall.getArguments()); - if (isPrimitive(methodCall.getReceiver())) { - PrimitiveMethodGenerator primitiveMethodGenerator = PrimitiveMethods.getPrimitiveMethod(methodCall.getReceiver().getType(), methodCall.getMethodName()).get(); - return primitiveMethodGenerator.generate(receiver, arguments); - } else { - return pythonCall(pythonAttributeAccess(receiver, toName(methodCall.signature())), arguments); - } + + return getPrimitiveMethod(methodCall, receiver, arguments) + .orElseGet(() -> pythonCall(pythonAttributeAccess(receiver, toName(methodCall.signature())), arguments)); } - @Override - public PythonExpressionNode visit(StaticMethodCallNode staticMethodCall) { - TypeName className = staticMethodCall.getClassName(); - PythonVariableReferenceNode classReference = pythonVariableReference(className.getSimpleName()); - PythonAttributeAccessNode methodReference = - pythonAttributeAccess(classReference, toName(staticMethodCall.signature())); - List<PythonExpressionNode> arguments = generateExpressions(staticMethodCall.getArguments()); - - return PrimitiveMethods.getPrimitiveStaticMethod(className, staticMethodCall.getMethodName()) - .map(generator -> generator.generate(arguments)) - .orElseGet(() -> pythonCall(methodReference, arguments)); + private Optional<PythonExpressionNode> getPrimitiveMethod( + MethodCallNode methodCall, + PythonExpressionNode pythonReceiver, + List<PythonExpressionNode> pythonArguments + ) { + return methodCall.getReceiver().accept(new Receiver.Mapper<Optional<PythonExpressionNode>>() { + @Override + public Optional<PythonExpressionNode> visit(ExpressionNode receiver) { + return PrimitiveMethods.getPrimitiveMethod(receiver.getType(), methodCall.getMethodName()) + .map(generator -> generator.generate(pythonReceiver, pythonArguments)); + } + + @Override + public Optional<PythonExpressionNode> visit(TypeName receiver) { + return PrimitiveMethods.getPrimitiveStaticMethod(receiver, methodCall.getMethodName()) + .map(generator -> generator.generate(pythonArguments)); + } + }); } @Override @@ -290,6 +290,20 @@ public class PythonCodeGenerator { } } + private static PythonExpressionNode generateReceiver(Receiver receiver) { + return receiver.accept(new Receiver.Mapper<PythonExpressionNode>() { + @Override + public PythonExpressionNode visit(ExpressionNode receiver) { + return generateExpression(receiver); + } + + @Override + public PythonExpressionNode visit(TypeName receiver) { + return pythonVariableReference(receiver.getSimpleName()); + } + }); + } + private static boolean isIntegerBox(TypeCoercionNode typeCoercion) { return isInteger(typeCoercion.getExpression().getType()) && !isInteger(typeCoercion.getType()); } @@ -307,8 +321,4 @@ public class PythonCodeGenerator { list(signature.getName()), transform(signature.getArguments(), argument -> argument.getQualifiedName().replace('.', '_')))); } - - private static boolean isPrimitive(ExpressionNode value) { - return PrimitiveMethods.isPrimitive(value.getType()); - } }
\ No newline at end of file diff --git a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java index 059f2ad..e319353 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java @@ -75,23 +75,25 @@ public class Evaluator implements ExpressionNodeMapper<InterpreterValue> { @Override public InterpreterValue visit(MethodCallNode methodCall) { - InterpreterValue receiver = eval(methodCall.getReceiver()); - ConcreteType type = receiver.getType(); List<InterpreterValue> arguments = evalArguments(methodCall.getArguments()); MethodSignature signature = new MethodSignature( methodCall.getMethodName(), eagerMap(methodCall.getArguments(), argument -> argument.getType())); - return type.callMethod(environment, receiver, signature, arguments); - } - - @Override - public InterpreterValue visit(StaticMethodCallNode staticMethodCall) { - ConcreteType clazz = environment.findClass(staticMethodCall.getClassName()); - List<InterpreterValue> arguments = evalArguments(staticMethodCall.getArguments()); - MethodSignature signature = new MethodSignature( - staticMethodCall.getMethodName(), - eagerMap(arguments, argument -> argument.getType().getName())); - return clazz.callStaticMethod(environment, signature, arguments); + + return methodCall.getReceiver().accept(new Receiver.Mapper<InterpreterValue>() { + @Override + public InterpreterValue visit(ExpressionNode receiverExpression) { + InterpreterValue receiver = eval(receiverExpression); + ConcreteType type = receiver.getType(); + return type.callMethod(environment, receiver, signature, arguments); + } + + @Override + public InterpreterValue visit(TypeName receiver) { + ConcreteType clazz = environment.findClass(receiver); + return clazz.callStaticMethod(environment, signature, arguments); + } + }); } @Override |
