diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-04-10 22:39:04 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-04-10 22:39:04 +0100 |
| commit | 85bcbfd70fff22169916c9fc1464afd00c376a2a (patch) | |
| tree | 31bb49917d69a0179e2433066e567db343e3ca55 | |
| parent | b04445f384b6fbb1e77a4c35af25e9311aafdb8d (diff) | |
Split classes with type parameters into static and instance classes
3 files changed, 66 insertions, 17 deletions
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 4fab81b..a2c77b5 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Set; import static java.util.Arrays.asList; +import static org.zwobble.couscous.util.ExtraIterables.lazyFilter; import static org.zwobble.couscous.util.ExtraLists.list; import static org.zwobble.couscous.util.ExtraSets.set; @@ -448,17 +449,41 @@ public class CsharpSerializer implements NodeVisitor { @Override public void visit(ClassNode classNode) { - writeType(classNode, "class", () -> { - writeAll(classNode.getFields()); - writeStaticConstructor(classNode); - writeConstructor(classNode, classNode.getConstructor()); - writeAll(classNode.getMethods()); - }); + if (classNode.getTypeParameters().isEmpty()) { + writeInstanceType(classNode, "class", () -> { + writeAll(classNode.getFields()); + writeStaticConstructor(classNode); + writeConstructor(classNode, classNode.getConstructor()); + writeAll(classNode.getMethods()); + }); + } else { + writeInNamespace(classNode, () -> { + writer.writeStatement(() -> { + writer.writeKeyword("internal"); + writer.writeSpace(); + writer.writeKeyword("static"); + writer.writeSpace(); + writer.writeKeyword("class"); + writer.writeSpace(); + writer.writeIdentifier(classNode.getName().getSimpleName()); + writer.startBlock(); + writeAll(lazyFilter(classNode.getFields(), field -> field.isStatic())); + writeStaticConstructor(classNode); + writeAll(lazyFilter(classNode.getMethods(), method -> method.isStatic())); + writer.endBlock(); + }); + }); + writeInstanceType(classNode, "class", () -> { + writeAll(lazyFilter(classNode.getFields(), field -> !field.isStatic())); + writeConstructor(classNode, classNode.getConstructor()); + writeAll(lazyFilter(classNode.getMethods(), method -> !method.isStatic())); + }); + } } @Override public void visit(InterfaceNode interfaceNode) { - writeType(interfaceNode, "interface", () -> { + writeInstanceType(interfaceNode, "interface", () -> { interfaceNode.getMethods().forEach(method -> { writer.writeStatement(() -> { writeSignature(method); @@ -470,7 +495,7 @@ public class CsharpSerializer implements NodeVisitor { @Override public void visit(EnumNode enumNode) { - writeType(enumNode, "enum", () -> { + writeInstanceType(enumNode, "enum", () -> { writer.writeStatement(() -> { writer.writeCommaSeparated( enumNode.getValues(), @@ -479,12 +504,8 @@ public class CsharpSerializer implements NodeVisitor { }); } - private void writeType(TypeNode node, String keyword, Action writeBody) { - writer.writeStatement(() -> { - writer.writeKeyword("namespace"); - writer.writeSpace(); - writeQualifiedName(node.getName().getPackage().get()); - writer.startBlock(); + private void writeInstanceType(TypeNode node, String keyword, Action writeBody) { + writeInNamespace(node, () -> { writer.writeStatement(() -> { writer.writeKeyword("internal"); writer.writeSpace(); @@ -497,7 +518,20 @@ public class CsharpSerializer implements NodeVisitor { writeBody.run(); writer.endBlock(); }); + }); + } + + private void writeInNamespace(TypeNode typeNode, Action writeBody) { + writeInNamespace(typeNode.getName().getPackage().get(), writeBody); + } + private void writeInNamespace(String namespace, Action writeBody) { + writer.writeStatement(() -> { + writer.writeKeyword("namespace"); + writer.writeSpace(); + writeQualifiedName(namespace); + writer.startBlock(); + writeBody.run(); writer.endBlock(); }); } @@ -553,7 +587,7 @@ public class CsharpSerializer implements NodeVisitor { writer.endBlock(); } - private void writeAll(List<? extends Node> nodes) { + private void writeAll(Iterable<? extends Node> nodes) { for (Node node : nodes) { write(node); } diff --git a/src/main/java/org/zwobble/couscous/util/ExtraIterables.java b/src/main/java/org/zwobble/couscous/util/ExtraIterables.java index 0fcc9af..4b8b802 100644 --- a/src/main/java/org/zwobble/couscous/util/ExtraIterables.java +++ b/src/main/java/org/zwobble/couscous/util/ExtraIterables.java @@ -86,6 +86,15 @@ public class ExtraIterables { return Iterables.concat(list(head), tails); } + public static <T> Iterable<T> lazyFilter(Iterable<T> iterable, java.util.function.Predicate<T> predicate) { + return new Iterable<T>() { + @Override + public Iterator<T> iterator() { + return stream(iterable).filter(predicate).iterator(); + } + }; + } + public static <T, R> Iterable<R> lazyMap(Iterable<T> iterable, Function<T, R> function) { return new Iterable<R>() { @Override diff --git a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java index d7cce40..6b221ff 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java @@ -386,15 +386,21 @@ public class CsharpSerializerTests { } @Test - public void classWithTypeParameters() { + public void classWithTypeParametersIsSplitIntoStaticAndInstanceClasses() { ClassNode classNode = ClassNode.builder("com.example.Example") .addTypeParameter("T") .addTypeParameter("U") + .field("x", ScalarType.of("X")) + .staticField("y", ScalarType.of("Y")) .build(); String output = serialize(classNode); - assertEquals("namespace com.example {\n internal class Example<T, U> {\n }\n}\n", output); + assertEquals( + "namespace com.example {" + + "\n internal static class Example {\n internal static Y y;\n }\n}" + + "\nnamespace com.example {" + + "\n internal class Example<T, U> {\n internal X x;\n }\n}\n", output); } @Test |
