aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-03-17 22:33:15 +0000
committerMichael Williamson <mike@zwobble.org>2016-03-18 08:00:10 +0000
commitcea82209e5aa312f4a513308c148d3e944004cb4 (patch)
tree6f7e5fa7bb1656b4650bb227866195f35bc962e0 /src/main/java/org
parent5687fd7f88485f95e970b3d93fbf2800e84eb3b8 (diff)
Improve support for generics
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodCallNode.java78
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodSignature.java4
-rw-r--r--src/main/java/org/zwobble/couscous/ast/types/TypeParameter.java4
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java9
-rw-r--r--src/main/java/org/zwobble/couscous/backends/Names.java2
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java5
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java10
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonExpressionStatement.java25
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java4
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java5
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java15
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java2
12 files changed, 130 insertions, 33 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
index 43993b8..0078002 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
@@ -16,16 +16,36 @@ public class MethodCallNode implements ExpressionNode {
String className,
String methodName,
List<ExpressionNode> arguments,
- Type type) {
+ Type type)
+ {
return staticMethodCall(ScalarType.of(className), methodName, arguments, type);
}
public static ExpressionNode staticMethodCall(
+ String className,
+ String methodName,
+ List<ExpressionNode> arguments,
+ MethodSignature signature)
+ {
+ return staticMethodCall(ScalarType.of(className), methodName, arguments, signature);
+ }
+
+ public static ExpressionNode staticMethodCall(
ScalarType className,
String methodName,
List<ExpressionNode> arguments,
- Type type) {
- return MethodCallNode.methodCall(staticReceiver(className), methodName, arguments, type);
+ Type type)
+ {
+ return methodCall(staticReceiver(className), methodName, arguments, type);
+ }
+
+ public static ExpressionNode staticMethodCall(
+ ScalarType className,
+ String methodName,
+ List<ExpressionNode> arguments,
+ MethodSignature signature)
+ {
+ return methodCall(staticReceiver(className), methodName, arguments, signature);
}
public static MethodCallNode methodCall(
@@ -38,29 +58,51 @@ public class MethodCallNode implements ExpressionNode {
}
public static MethodCallNode methodCall(
+ ExpressionNode receiver,
+ String methodName,
+ List<ExpressionNode> arguments,
+ MethodSignature signature)
+ {
+ return methodCall(instanceReceiver(receiver), methodName, arguments, signature);
+ }
+
+ public static MethodCallNode methodCall(
Receiver receiver,
String methodName,
List<ExpressionNode> arguments,
Type type)
{
- return new MethodCallNode(receiver, methodName, arguments, type);
+ MethodSignature signature = new MethodSignature(
+ methodName,
+ eagerMap(arguments, argument -> argument.getType()),
+ type);
+ return methodCall(receiver, methodName, arguments, signature);
+ }
+
+ public static MethodCallNode methodCall(
+ Receiver receiver,
+ String methodName,
+ List<ExpressionNode> arguments,
+ MethodSignature signature)
+ {
+ return new MethodCallNode(receiver, methodName, arguments, signature);
}
private final Receiver receiver;
private final String methodName;
private final List<ExpressionNode> arguments;
- private final Type type;
+ private final MethodSignature signature;
private MethodCallNode(
Receiver receiver,
String methodName,
List<ExpressionNode> arguments,
- Type type)
+ MethodSignature signature)
{
this.receiver = receiver;
this.methodName = methodName;
this.arguments = arguments;
- this.type = type;
+ this.signature = signature;
}
public Receiver getReceiver() {
@@ -74,16 +116,14 @@ public class MethodCallNode implements ExpressionNode {
public List<ExpressionNode> getArguments() {
return arguments;
}
-
+
+ @Override
public Type getType() {
- return type;
+ return signature.getReturnType();
}
public MethodSignature signature() {
- return new MethodSignature(
- methodName,
- eagerMap(arguments, argument -> argument.getType()),
- type);
+ return signature;
}
@Override
@@ -97,13 +137,13 @@ public class MethodCallNode implements ExpressionNode {
transformer.transformReceiver(receiver),
transformer.transformMethodName(signature()),
transformer.transformExpressions(arguments),
- transformer.transform(type));
+ transformer.transform(signature));
}
@Override
public String toString() {
return "MethodCallNode(receiver=" + receiver + ", methodName="
- + methodName + ", arguments=" + arguments + ", type=" + type
+ + methodName + ", arguments=" + arguments + ", signature=" + signature
+ ")";
}
@@ -117,7 +157,7 @@ public class MethodCallNode implements ExpressionNode {
+ ((methodName == null) ? 0 : methodName.hashCode());
result = prime * result
+ ((receiver == null) ? 0 : receiver.hashCode());
- result = prime * result + ((type == null) ? 0 : type.hashCode());
+ result = prime * result + ((signature == null) ? 0 : signature.hashCode());
return result;
}
@@ -145,10 +185,10 @@ public class MethodCallNode implements ExpressionNode {
return false;
} else if (!receiver.equals(other.receiver))
return false;
- if (type == null) {
- if (other.type != null)
+ if (signature == null) {
+ if (other.signature != null)
return false;
- } else if (!type.equals(other.type))
+ } else if (!signature.equals(other.signature))
return false;
return true;
}
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodSignature.java b/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
index 93d4f58..4cb04fb 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
@@ -5,6 +5,10 @@ import org.zwobble.couscous.ast.types.Type;
import java.util.List;
public class MethodSignature {
+ public static MethodSignature signature(String name, List<Type> arguments, Type returnType) {
+ return new MethodSignature(name, arguments, returnType);
+ }
+
private final String name;
private final List<Type> arguments;
private final Type returnType;
diff --git a/src/main/java/org/zwobble/couscous/ast/types/TypeParameter.java b/src/main/java/org/zwobble/couscous/ast/types/TypeParameter.java
index 0dee75e..9cda882 100644
--- a/src/main/java/org/zwobble/couscous/ast/types/TypeParameter.java
+++ b/src/main/java/org/zwobble/couscous/ast/types/TypeParameter.java
@@ -13,6 +13,10 @@ public class TypeParameter implements Type {
this.name = name;
}
+ public ScalarType getDeclaringType() {
+ return declaringType;
+ }
+
public String getName() {
return name;
}
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 38c5709..0998564 100644
--- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java
+++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java
@@ -13,6 +13,8 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import static org.zwobble.couscous.util.ExtraLists.eagerMap;
+
public class NodeTransformer {
public static NodeTransformer replaceExpressions(Map<ExpressionNode, ExpressionNode> replacements) {
return builder().
@@ -197,6 +199,13 @@ public class NodeTransformer {
this.transformMethodName = transformMethodName;
}
+ public MethodSignature transform(MethodSignature signature) {
+ return new MethodSignature(
+ transformMethodName(signature),
+ eagerMap(signature.getArguments(), this::transform),
+ transform(signature.getReturnType()));
+ }
+
public Type transform(Type type) {
return transformType.apply(type);
}
diff --git a/src/main/java/org/zwobble/couscous/backends/Names.java b/src/main/java/org/zwobble/couscous/backends/Names.java
index 1e9600a..4adbec3 100644
--- a/src/main/java/org/zwobble/couscous/backends/Names.java
+++ b/src/main/java/org/zwobble/couscous/backends/Names.java
@@ -25,7 +25,7 @@ public class Names {
@Override
public String visit(TypeParameter parameter) {
- return parameter.getName();
+ return typeToString(parameter.getDeclaringType()) + "_" + parameter.getName();
}
@Override
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 49e7b80..fc3aa98 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
@@ -39,6 +39,7 @@ import static org.zwobble.couscous.backends.python.ast.PythonReturnNode.pythonRe
import static org.zwobble.couscous.backends.python.ast.PythonStringLiteralNode.pythonStringLiteral;
import static org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode.pythonVariableReference;
import static org.zwobble.couscous.backends.python.ast.PythonWhileNode.pythonWhile;
+import static org.zwobble.couscous.backends.python.ast.visitors.PythonExpressionStatement.pythonExpressionStatement;
import static org.zwobble.couscous.util.Casts.tryCast;
import static org.zwobble.couscous.util.ExtraLists.list;
@@ -195,10 +196,10 @@ public class PythonCodeGenerator {
@Override
public PythonStatementNode visit(ExpressionStatementNode expressionStatement) {
if (expressionStatement.getExpression() instanceof AssignmentNode) {
- final org.zwobble.couscous.ast.AssignmentNode assignment = (AssignmentNode)expressionStatement.getExpression();
+ AssignmentNode assignment = (AssignmentNode)expressionStatement.getExpression();
return pythonAssignment(assignment.getTarget().accept(EXPRESSION_GENERATOR), generateExpression(assignment.getValue()));
} else {
- throw new UnsupportedOperationException();
+ return pythonExpressionStatement(generateExpression(expressionStatement.getExpression()));
}
}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
index d3771d3..7732a87 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.backends.python;
import org.zwobble.couscous.backends.SourceCodeWriter;
import org.zwobble.couscous.backends.python.ast.*;
+import org.zwobble.couscous.backends.python.ast.visitors.PythonExpressionStatement;
import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor;
public class PythonSerializer implements PythonNodeVisitor {
@@ -101,7 +102,14 @@ public class PythonSerializer implements PythonNodeVisitor {
writer.writeSpace();
writeParenthesised(operation.getRight(), operation);
}
-
+
+ @Override
+ public void visit(PythonExpressionStatement statement) {
+ writer.writeStatement(() -> {
+ write(statement.getExpression());
+ });
+ }
+
@Override
public void visit(PythonReturnNode pythonReturn) {
writer.writeStatement(() -> {
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonExpressionStatement.java b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonExpressionStatement.java
new file mode 100644
index 0000000..0ba1c38
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonExpressionStatement.java
@@ -0,0 +1,25 @@
+package org.zwobble.couscous.backends.python.ast.visitors;
+
+import org.zwobble.couscous.backends.python.ast.PythonExpressionNode;
+import org.zwobble.couscous.backends.python.ast.PythonStatementNode;
+
+public class PythonExpressionStatement implements PythonStatementNode {
+ public static PythonExpressionStatement pythonExpressionStatement(PythonExpressionNode expression) {
+ return new PythonExpressionStatement(expression);
+ }
+
+ private final PythonExpressionNode expression;
+
+ public PythonExpressionStatement(PythonExpressionNode expression) {
+ this.expression = expression;
+ }
+
+ public PythonExpressionNode getExpression() {
+ return expression;
+ }
+
+ @Override
+ public void accept(PythonNodeVisitor visitor) {
+ visitor.visit(this);
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java
index 8f04787..d43691d 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java
@@ -13,7 +13,8 @@ public interface PythonNodeVisitor {
void visit(PythonGetSliceNode getSlice);
void visit(PythonNotNode notOperation);
void visit(PythonBinaryOperation operation);
-
+
+ void visit(PythonExpressionStatement statement);
void visit(PythonReturnNode pythonReturn);
void visit(PythonPassNode pass);
void visit(PythonClassNode pythonClass);
@@ -24,5 +25,4 @@ public interface PythonNodeVisitor {
void visit(PythonWhileNode whileLoop);
void visit(PythonModuleNode module);
-
}
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
index 096162f..46d2ab4 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
@@ -185,7 +185,6 @@ public class JavaExpressionReader {
expression.resolveMethodBinding(),
expression.arguments());
MethodSignature signature = JavaMethods.signature(expression.resolveMethodBinding());
- final Type type = signature.getReturnType();
IMethodBinding methodBinding = expression.resolveMethodBinding();
Type receiverType = typeOf(methodBinding.getDeclaringClass());
@@ -194,7 +193,7 @@ public class JavaExpressionReader {
Types.erasure(receiverType),
methodName,
arguments,
- type);
+ signature);
} else {
ExpressionNode receiver = expression.getExpression() == null
? ThisReferenceNode.thisReference(receiverType)
@@ -203,7 +202,7 @@ public class JavaExpressionReader {
receiver,
methodName,
arguments,
- type);
+ signature);
}
}
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java
index 42211fe..0273faa 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaMethods.java
@@ -34,10 +34,17 @@ class JavaMethods {
eagerMap(
argumentTypes,
asList(erasedMethod.getParameterTypes()),
- (argumentType, erasedParameterType) -> new BoundTypeParameter((TypeParameter) typeOf(erasedParameterType), argumentType)),
- new BoundTypeParameter(
- (TypeParameter) typeOf(erasedMethod.getReturnType()),
- returnType));
+ (argumentType, erasedParameterType) -> typeParameterForGeneric(erasedParameterType, argumentType)),
+ typeParameterForGeneric(erasedMethod.getReturnType(), returnType));
+ }
+ }
+
+ private static Type typeParameterForGeneric(ITypeBinding erasedTypeBinding, Type type) {
+ Type erasedType = typeOf(erasedTypeBinding);
+ if (erasedType.equals(type)) {
+ return type;
+ } else {
+ return new BoundTypeParameter((TypeParameter) typeOf(erasedTypeBinding), type);
}
}
}
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 4afe02b..42d8f28 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -417,7 +417,7 @@ public class JavaReader {
thisReference(type),
methodNode.getName(),
eagerMap(arguments, argument -> reference(argument)),
- methodNode.getReturnType()),
+ methodNode.signature()),
override.getReturnType()))
)));
});