diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-03-09 18:11:17 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-03-09 18:11:17 +0000 |
| commit | 20dc1e124d606cf4298d5112b6d3c4f6c74e9b68 (patch) | |
| tree | 47914e8b0356b2f40e3723eae650d3bb6f100dd4 /src/main/java/org/zwobble/couscous/backends | |
| parent | 8ac6cb16b727b5e3d28ab89fee1d169a4f74d9a1 (diff) | |
Introduce Type interface
Diffstat (limited to 'src/main/java/org/zwobble/couscous/backends')
7 files changed, 71 insertions, 51 deletions
diff --git a/src/main/java/org/zwobble/couscous/backends/Names.java b/src/main/java/org/zwobble/couscous/backends/Names.java index d467296..094de02 100644 --- a/src/main/java/org/zwobble/couscous/backends/Names.java +++ b/src/main/java/org/zwobble/couscous/backends/Names.java @@ -3,9 +3,10 @@ package org.zwobble.couscous.backends; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; import org.zwobble.couscous.ast.MethodSignature; -import org.zwobble.couscous.ast.TypeName; +import org.zwobble.couscous.ast.types.Type; import static com.google.common.collect.Iterables.transform; +import static org.zwobble.couscous.ast.types.Types.erasure; import static org.zwobble.couscous.util.ExtraLists.list; public class Names { @@ -16,7 +17,7 @@ public class Names { list(typeToString(signature.getReturnType())))); } - private static String typeToString(TypeName argument) { - return argument.getQualifiedName().replace('.', '_'); + private static String typeToString(Type argument) { + return erasure(argument).getQualifiedName().replace('.', '_'); } } diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java index e98a526..3c58dae 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java @@ -33,7 +33,7 @@ public class CsharpBackend implements Backend { public void compile(List<TypeNode> classes) throws IOException { Files.write( directoryPath.resolve("Program.cs"), - Iterables.concat( + Iterables.<String>concat( transform( classes, classNode -> compileClass(classNode)), 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 5a90dc7..8388421 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java @@ -2,6 +2,8 @@ package org.zwobble.couscous.backends.csharp; import com.google.common.collect.ImmutableMap; import org.zwobble.couscous.ast.*; +import org.zwobble.couscous.ast.types.ScalarType; +import org.zwobble.couscous.ast.types.Type; import org.zwobble.couscous.ast.visitors.NodeTransformer; import org.zwobble.couscous.backends.Names; import org.zwobble.couscous.values.*; @@ -9,15 +11,16 @@ import org.zwobble.couscous.values.*; import java.util.Map; import java.util.Optional; +import static org.zwobble.couscous.ast.types.Types.erasure; 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")) - .put(BooleanValue.REF, TypeName.of("bool")) - .put(ObjectValues.CLASS, TypeName.of("System.Type")) - .put(UnitValue.REF, TypeName.of("void")) + private final static Map<ScalarType, ScalarType> PRIMITIVES = ImmutableMap.<ScalarType, ScalarType>builder() + .put(IntegerValue.REF, ScalarType.of("int")) + .put(StringValue.REF, ScalarType.of("string")) + .put(BooleanValue.REF, ScalarType.of("bool")) + .put(ObjectValues.CLASS, ScalarType.of("System.Type")) + .put(UnitValue.REF, ScalarType.of("void")) .build(); private final String namespace; @@ -40,7 +43,7 @@ public class CsharpCodeGenerator { return nodeTransformer.transform(node); } - private TypeName transformType(TypeName type) { + private Type transformType(Type type) { if (PRIMITIVES.containsKey(type)) { return PRIMITIVES.get(type); } else { @@ -61,21 +64,26 @@ public class CsharpCodeGenerator { return call.getReceiver().accept(new Receiver.Mapper<Optional<ExpressionNode>>() { @Override public Optional<ExpressionNode> visit(ExpressionNode receiver) { - return CsharpPrimitiveMethods.getPrimitiveMethod(receiver.getType(), call.getMethodName()) + return CsharpPrimitiveMethods.getPrimitiveMethod(erasure(receiver.getType()), call.getMethodName()) .map(generator -> generator.generate( nodeTransformer.transformExpression(receiver), nodeTransformer.transformExpressions(call.getArguments()))); } @Override - public Optional<ExpressionNode> visit(TypeName receiver) { + public Optional<ExpressionNode> visit(ScalarType receiver) { return CsharpPrimitiveMethods.getPrimitiveStaticMethod(receiver, call.getMethodName()) .map(generator -> generator.generate(nodeTransformer.transformExpressions(call.getArguments()))); } }); } - private TypeName addPrefix(TypeName name, String namespace) { - return TypeName.of(namespace + "." + name.getQualifiedName()); + private Type addPrefix(Type type, String namespace) { + return type.accept(new Type.Visitor<Type>() { + @Override + public Type visit(ScalarType type) { + return ScalarType.of(namespace + "." + type.getQualifiedName()); + } + }); } } diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpPrimitiveMethods.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpPrimitiveMethods.java index 72aa528..ced0a82 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpPrimitiveMethods.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpPrimitiveMethods.java @@ -2,7 +2,7 @@ package org.zwobble.couscous.backends.csharp; import com.google.common.collect.ImmutableMap; import org.zwobble.couscous.ast.ExpressionNode; -import org.zwobble.couscous.ast.TypeName; +import org.zwobble.couscous.ast.types.ScalarType; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.ObjectValues; @@ -67,8 +67,8 @@ public class CsharpPrimitiveMethods { STRING_METHODS = methods.build(); } - private static final Map<TypeName, Map<String, PrimitiveMethodGenerator>> METHODS = - ImmutableMap.<TypeName, Map<String, PrimitiveMethodGenerator>>builder() + private static final Map<ScalarType, Map<String, PrimitiveMethodGenerator>> METHODS = + ImmutableMap.<ScalarType, Map<String, PrimitiveMethodGenerator>>builder() .put(BooleanValue.REF, BOOLEAN_METHODS) .put(StringValue.REF, STRING_METHODS) .put(ObjectValues.BOXED_INT, BOXED_INT_METHODS) @@ -78,19 +78,19 @@ public class CsharpPrimitiveMethods { ImmutableMap.<String, PrimitiveStaticMethodGenerator>builder() .put("parseInt", arguments -> staticMethodCall( - TypeName.of("int"), + ScalarType.of("int"), "Parse", list(arguments.get(0)), - TypeName.of("int"))) + ScalarType.of("int"))) .build(); - private static final Map<TypeName, Map<String, PrimitiveStaticMethodGenerator>> STATIC_METHODS = - ImmutableMap.<TypeName, Map<String, PrimitiveStaticMethodGenerator>>builder() + private static final Map<ScalarType, Map<String, PrimitiveStaticMethodGenerator>> STATIC_METHODS = + ImmutableMap.<ScalarType, Map<String, PrimitiveStaticMethodGenerator>>builder() .put(ObjectValues.BOXED_INT, STATIC_INT_METHODS) .build(); - public static Optional<PrimitiveMethodGenerator> getPrimitiveMethod(TypeName type, String methodName) { + public static Optional<PrimitiveMethodGenerator> getPrimitiveMethod(ScalarType type, String methodName) { return Optional.ofNullable(METHODS.get(type)) .flatMap(methodsForType -> Optional.ofNullable(methodsForType.get(methodName))); } @@ -100,7 +100,7 @@ public class CsharpPrimitiveMethods { ExpressionNode generate(ExpressionNode receiver, List<ExpressionNode> arguments); } - public static Optional<PrimitiveStaticMethodGenerator> getPrimitiveStaticMethod(TypeName type, String methodName) { + public static Optional<PrimitiveStaticMethodGenerator> getPrimitiveStaticMethod(ScalarType type, String methodName) { return Optional.ofNullable(STATIC_METHODS.get(type)) .flatMap(methodsForType -> Optional.ofNullable(methodsForType.get(methodName))); } diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java index 39cd443..c898525 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java @@ -1,6 +1,8 @@ package org.zwobble.couscous.backends.csharp; import org.zwobble.couscous.ast.*; +import org.zwobble.couscous.ast.types.ScalarType; +import org.zwobble.couscous.ast.types.Type; import org.zwobble.couscous.ast.visitors.NodeVisitor; import org.zwobble.couscous.backends.SourceCodeWriter; import org.zwobble.couscous.util.Action; @@ -66,7 +68,7 @@ public class CsharpSerializer implements NodeVisitor { } @Override - public Void visitType(TypeName value) { + public Void visitType(ScalarType value) { writer.writeKeyword("typeof"); writer.writeSymbol("("); writeTypeReference(value); @@ -413,11 +415,17 @@ public class CsharpSerializer implements NodeVisitor { } } - private void writeTypeReference(TypeName value) { - writer.writeIdentifier(typeReference(value)); + private void writeTypeReference(Type value) { + value.accept(new Type.Visitor<Void>() { + @Override + public Void visit(ScalarType type) { + writer.writeIdentifier(typeReference(type)); + return null; + } + }); } - private String typeReference(TypeName value) { + private String typeReference(ScalarType value) { return value.getQualifiedName(); } } 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 7d134ef..49e7b80 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -6,6 +6,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import org.zwobble.couscous.ast.*; import org.zwobble.couscous.ast.structure.NodeStructure; +import org.zwobble.couscous.ast.types.ScalarType; +import org.zwobble.couscous.ast.types.Type; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.ast.visitors.NodeMapperWithDefault; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; @@ -20,6 +22,7 @@ import java.util.stream.Stream; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Iterators.singletonIterator; +import static org.zwobble.couscous.ast.types.Types.erasure; import static org.zwobble.couscous.backends.python.ast.PythonAssignmentNode.pythonAssignment; import static org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode.pythonAttributeAccess; import static org.zwobble.couscous.backends.python.ast.PythonBooleanLiteralNode.pythonBooleanLiteral; @@ -72,7 +75,7 @@ public class PythonCodeGenerator { } private static Stream<PythonImportNode> generateImports(TypeNode classNode) { - Set<TypeName> classes = findReferencedClasses(classNode); + Set<ScalarType> classes = findReferencedClasses(classNode); return classes.stream() .filter(name -> !name.equals(InternalCouscousValue.REF)) .map(name -> pythonImport(importPathToRoot(classNode) + name.getQualifiedName(), list(pythonImportAlias(name.getSimpleName())))); @@ -93,21 +96,21 @@ public class PythonCodeGenerator { return depth; } - private static Set<TypeName> findReferencedClasses(TypeNode classNode) { + private static Set<ScalarType> findReferencedClasses(TypeNode classNode) { return NodeStructure.descendantNodes(classNode) - .flatMap(node -> node.accept(new NodeMapperWithDefault<Stream<TypeName>>(Stream.empty()) { + .flatMap(node -> node.accept(new NodeMapperWithDefault<Stream<ScalarType>>(Stream.empty()) { @Override - public Stream<TypeName> visit(StaticReceiver receiver) { + public Stream<ScalarType> visit(StaticReceiver receiver) { return Stream.of(receiver.getType()); } @Override - public Stream<TypeName> visit(ConstructorCallNode call) { - return Stream.of(call.getType()); + public Stream<ScalarType> visit(ConstructorCallNode call) { + return Stream.of(erasure(call.getType())); } @Override - public Stream<TypeName> visit(TypeCoercionNode typeCoercion) { + public Stream<ScalarType> visit(TypeCoercionNode typeCoercion) { if (isIntegerBox(typeCoercion)) { return Stream.of(ObjectValues.BOXED_INT); } else { @@ -116,7 +119,7 @@ public class PythonCodeGenerator { } @Override - public Stream<TypeName> visit(LiteralNode literal) { + public Stream<ScalarType> visit(LiteralNode literal) { if (literal.getValue() instanceof TypeValue) { return Stream.of(((TypeValue)literal.getValue()).getValue()); } else { @@ -151,7 +154,7 @@ public class PythonCodeGenerator { } @Override - public PythonExpressionNode visitType(TypeName value) { + public PythonExpressionNode visitType(ScalarType value) { return typeReference(value); } }); @@ -272,12 +275,12 @@ public class PythonCodeGenerator { return methodCall.getReceiver().accept(new Receiver.Mapper<Optional<PythonExpressionNode>>() { @Override public Optional<PythonExpressionNode> visit(ExpressionNode receiver) { - return PythonPrimitiveMethods.getPrimitiveMethod(receiver.getType(), methodCall.getMethodName()) + return PythonPrimitiveMethods.getPrimitiveMethod(erasure(receiver.getType()), methodCall.getMethodName()) .map(generator -> generator.generate(pythonReceiver, pythonArguments)); } @Override - public Optional<PythonExpressionNode> visit(TypeName receiver) { + public Optional<PythonExpressionNode> visit(ScalarType receiver) { return PythonPrimitiveMethods.getPrimitiveStaticMethod(receiver, methodCall.getMethodName()) .map(generator -> generator.generate(pythonArguments)); } @@ -286,7 +289,7 @@ public class PythonCodeGenerator { @Override public PythonExpressionNode visit(ConstructorCallNode call) { - final org.zwobble.couscous.ast.TypeName className = call.getType(); + final Type className = call.getType(); final org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode classReference = typeReference(className); final java.util.List<org.zwobble.couscous.backends.python.ast.PythonExpressionNode> arguments = generateExpressions(call.getArguments()); return pythonCall(classReference, arguments); @@ -334,7 +337,7 @@ public class PythonCodeGenerator { } @Override - public PythonExpressionNode visit(TypeName receiver) { + public PythonExpressionNode visit(ScalarType receiver) { return typeReference(receiver); } }); @@ -348,11 +351,11 @@ public class PythonCodeGenerator { return !isInteger(typeCoercion.getExpression().getType()) && isInteger(typeCoercion.getType()); } - private static boolean isInteger(TypeName type) { + private static boolean isInteger(Type type) { return type.equals(IntegerValue.REF) || type.equals(ObjectValues.BOXED_INT); } - private static PythonVariableReferenceNode typeReference(TypeName className) { - return pythonVariableReference(className.getSimpleName()); + private static PythonVariableReferenceNode typeReference(Type className) { + return pythonVariableReference(erasure(className).getSimpleName()); } }
\ No newline at end of file diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonPrimitiveMethods.java b/src/main/java/org/zwobble/couscous/backends/python/PythonPrimitiveMethods.java index 87fc0ac..49d9abf 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonPrimitiveMethods.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonPrimitiveMethods.java @@ -3,7 +3,7 @@ package org.zwobble.couscous.backends.python; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import org.zwobble.couscous.ast.Operator; -import org.zwobble.couscous.ast.TypeName; +import org.zwobble.couscous.ast.types.ScalarType; import org.zwobble.couscous.backends.python.ast.PythonBinaryOperation; import org.zwobble.couscous.backends.python.ast.PythonExpressionNode; import org.zwobble.couscous.backends.python.ast.PythonNotNode; @@ -110,8 +110,8 @@ public class PythonPrimitiveMethods { build.apply(receiver, arguments.get(0))); } - private static final Map<TypeName, Map<String, PrimitiveMethodGenerator>> METHODS = - ImmutableMap.<TypeName, Map<String, PrimitiveMethodGenerator>>builder() + private static final Map<ScalarType, Map<String, PrimitiveMethodGenerator>> METHODS = + ImmutableMap.<ScalarType, Map<String, PrimitiveMethodGenerator>>builder() .put(StringValue.REF, STRING_METHODS) .put(BooleanValue.REF, BOOLEAN_METHODS) .put(IntegerValue.REF, INT_METHODS) @@ -132,13 +132,13 @@ public class PythonPrimitiveMethods { .build(); - private static final Map<TypeName, Map<String, PrimitiveStaticMethodGenerator>> STATIC_METHODS = - ImmutableMap.<TypeName, Map<String, PrimitiveStaticMethodGenerator>>builder() + private static final Map<ScalarType, Map<String, PrimitiveStaticMethodGenerator>> STATIC_METHODS = + ImmutableMap.<ScalarType, Map<String, PrimitiveStaticMethodGenerator>>builder() .put(InternalCouscousValue.REF, INTERNAL_METHODS) .put(ObjectValues.BOXED_INT, BOXED_INT_STATIC_METHODS) .build(); - public static Optional<PrimitiveMethodGenerator> getPrimitiveMethod(TypeName type, String methodName) { + public static Optional<PrimitiveMethodGenerator> getPrimitiveMethod(ScalarType type, String methodName) { return Optional.ofNullable(METHODS.get(type)) .flatMap(methodsForType -> Optional.ofNullable(methodsForType.get(methodName))); } @@ -148,7 +148,7 @@ public class PythonPrimitiveMethods { PythonExpressionNode generate(PythonExpressionNode receiver, List<PythonExpressionNode> arguments); } - public static Optional<PrimitiveStaticMethodGenerator> getPrimitiveStaticMethod(TypeName type, String methodName) { + public static Optional<PrimitiveStaticMethodGenerator> getPrimitiveStaticMethod(ScalarType type, String methodName) { return Optional.ofNullable(STATIC_METHODS.get(type)) .flatMap(methodsForType -> Optional.ofNullable(methodsForType.get(methodName))); } |
