summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/05-custom-code/hobgoblin.json59
-rw-r--r--examples/05-custom-code/output/java/.gitignore2
-rw-r--r--examples/05-custom-code/output/java/pom.xml39
-rw-r--r--examples/05-custom-code/output/java/src/main/java/org/zwobble/example/Main.java10
-rw-r--r--examples/05-custom-code/output/java/src/main/java/org/zwobble/example/types/shapes/Square.java28
-rw-r--r--examples/05-custom-code/src/shapes.hob3
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java92
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java9
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java47
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaCustomArea.java8
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java161
11 files changed, 288 insertions, 120 deletions
diff --git a/examples/05-custom-code/hobgoblin.json5 b/examples/05-custom-code/hobgoblin.json5
new file mode 100644
index 0000000..19cd31b
--- /dev/null
+++ b/examples/05-custom-code/hobgoblin.json5
@@ -0,0 +1,9 @@
+{
+ outputs: [
+ {
+ generator: "java-types",
+ path: "output/java/src/main/java",
+ packageName: "org.zwobble.example.types"
+ },
+ ],
+}
diff --git a/examples/05-custom-code/output/java/.gitignore b/examples/05-custom-code/output/java/.gitignore
new file mode 100644
index 0000000..ff511d4
--- /dev/null
+++ b/examples/05-custom-code/output/java/.gitignore
@@ -0,0 +1,2 @@
+/src/gen/
+/target/
diff --git a/examples/05-custom-code/output/java/pom.xml b/examples/05-custom-code/output/java/pom.xml
new file mode 100644
index 0000000..7493667
--- /dev/null
+++ b/examples/05-custom-code/output/java/pom.xml
@@ -0,0 +1,39 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.zwobble.hobgoblin.examples</groupId>
+ <artifactId>example</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>25</maven.compiler.source>
+ <maven.compiler.target>25</maven.compiler.target>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>3.6.1</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>src/gen/java</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/examples/05-custom-code/output/java/src/main/java/org/zwobble/example/Main.java b/examples/05-custom-code/output/java/src/main/java/org/zwobble/example/Main.java
new file mode 100644
index 0000000..2d2366d
--- /dev/null
+++ b/examples/05-custom-code/output/java/src/main/java/org/zwobble/example/Main.java
@@ -0,0 +1,10 @@
+package org.zwobble.example;
+
+import org.zwobble.example.types.shapes.Square;
+
+public class Main {
+ public static void main() {
+ Square square = new Square(10);
+ assert square.area() == 100;
+ }
+}
diff --git a/examples/05-custom-code/output/java/src/main/java/org/zwobble/example/types/shapes/Square.java b/examples/05-custom-code/output/java/src/main/java/org/zwobble/example/types/shapes/Square.java
new file mode 100644
index 0000000..dd48603
--- /dev/null
+++ b/examples/05-custom-code/output/java/src/main/java/org/zwobble/example/types/shapes/Square.java
@@ -0,0 +1,28 @@
+package org.zwobble.example.types.shapes;
+
+public record Square(int width) {
+ public static org.zwobble.example.types.shapes.Square.Builder arbitrary() {
+ return new org.zwobble.example.types.shapes.Square.Builder(0);
+ }
+
+ public record Builder(int width) {
+ public org.zwobble.example.types.shapes.Square build() {
+ return new org.zwobble.example.types.shapes.Square(width);
+ }
+
+ public org.zwobble.example.types.shapes.Square.Builder withWidth(int width) {
+ return new org.zwobble.example.types.shapes.Square.Builder(width);
+ }
+
+ // Custom area start: org.zwobble.example.types.shapes.Square.Builder body
+ // Custom area end: org.zwobble.example.types.shapes.Square.Builder body
+ }
+
+ // Custom area start: org.zwobble.example.types.shapes.Square body
+
+ public int area() {
+ return this.width * this.width;
+ }
+
+ // Custom area end: org.zwobble.example.types.shapes.Square body
+}
diff --git a/examples/05-custom-code/src/shapes.hob b/examples/05-custom-code/src/shapes.hob
new file mode 100644
index 0000000..5dfe833
--- /dev/null
+++ b/examples/05-custom-code/src/shapes.hob
@@ -0,0 +1,3 @@
+struct Square {
+ field width: Int32;
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
index 3e08c85..b8b0709 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
@@ -4,21 +4,92 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
+import java.util.*;
public class CodeWriter implements AutoCloseable {
- public static CodeWriter file(Path path) throws IOException {
+ public record CustomAreas(
+ Map<String, List<String>> existing,
+ String customAreaStart,
+ String customAreaEnd
+ ) {
+ public static CustomAreas read(
+ String existingString,
+ String customAreaStart,
+ String customAreaEnd
+ ) {
+ var existing = new HashMap<String, List<String>>();
+
+ Iterable<String> lines = () -> existingString.lines().iterator();
+ Optional<String> name = Optional.empty();
+ var customAreaLines = new ArrayList<String>();
+ for (var line : lines) {
+ var trimmedLine = line.trim();
+ if (trimmedLine.startsWith(customAreaStart)) {
+ name = Optional.of(trimmedLine.substring(customAreaStart.length()));
+ } else if (name.isPresent() && trimmedLine.startsWith(customAreaEnd + name.get())) {
+ existing.put(name.get(), customAreaLines);
+ customAreaLines = new ArrayList<>();
+ name = Optional.empty();
+ } else if (name.isPresent()) {
+ customAreaLines.add(line);
+ }
+ }
+
+ return new CustomAreas(existing, customAreaStart, customAreaEnd);
+ }
+
+ public static CustomAreas empty(
+ String customAreaStart,
+ String customAreaEnd
+ ) {
+ return new CustomAreas(Map.of(), customAreaStart, customAreaEnd);
+ }
+
+ public Iterable<String> lines(String name) {
+ var lines = this.existing.get(name);
+ if (lines == null) {
+ return List.of();
+ } else {
+ return lines;
+ }
+ }
+ }
+
+ public static CodeWriter file(
+ Path path,
+ String customAreaStart,
+ String customAreaEnd
+ ) throws IOException {
+ var customAreas = readCustomAreas(path, customAreaStart, customAreaEnd);
Files.createDirectories(path.getParent());
var writer = new FileWriter(path.toFile());
- return new CodeWriter(writer);
+ // TODO: warn if custom areas are unused?
+ return new CodeWriter(writer, customAreas);
+ }
+
+ private static CustomAreas readCustomAreas(
+ Path path,
+ String customAreaStart,
+ String customAreaEnd
+ ) throws IOException {
+ try {
+ var contents = Files.readString(path);
+ return CustomAreas.read(contents, customAreaStart, customAreaEnd);
+ } catch (NoSuchFileException exception) {
+ return CustomAreas.empty(customAreaStart, customAreaEnd);
+ }
}
private final Writer writer;
+ private final CustomAreas customAreas;
private int indent;
private boolean pendingIndent;
- public CodeWriter(Writer writer) {
+ public CodeWriter(Writer writer, CustomAreas customAreas) {
this.writer = writer;
+ this.customAreas = customAreas;
this.indent = 0;
this.pendingIndent = false;
}
@@ -47,6 +118,21 @@ public class CodeWriter implements AutoCloseable {
this.indent -= 1;
}
+ public void writeCustomArea(String name) throws IOException {
+ this.write(this.customAreas.customAreaStart);
+ this.write(name);
+
+ for (var line : this.customAreas.lines(name)) {
+ this.writer.write("\n");
+ this.write(line);
+ }
+
+ this.newLine();
+ this.write(this.customAreas.customAreaEnd);
+ this.write(name);
+ this.newLine();
+ }
+
@Override
public void close() throws Exception {
this.writer.close();
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
index 77c2ecd..9356519 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
@@ -4,7 +4,6 @@ import org.zwobble.hobgoblin.compiler.ast.DocComment;
import org.zwobble.hobgoblin.compiler.ast.typed.*;
import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
-import org.zwobble.hobgoblin.compiler.output.CodeWriter;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.lang.java.JavaWriter;
import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*;
@@ -78,7 +77,7 @@ public class JavaTypesGenerator implements Generator {
var javaCompilationUnitPath = this.sourceRootDirectory
.resolve(String.join(File.separator, javaCompilationUnit.packageName()))
.resolve(javaCompilationUnit.typeDeclaration().name() + ".java");
- try (var writer = new JavaWriter(CodeWriter.file(javaCompilationUnitPath))) {
+ try (var writer = JavaWriter.file(javaCompilationUnitPath)) {
writer.writeCompilationUnit(javaCompilationUnit);
} catch (Exception e) {
// TODO: better handling
@@ -115,7 +114,7 @@ public class JavaTypesGenerator implements Generator {
sumDefinition.variants().stream()
.map(variant -> generateTypeRef(variant.type(), context))
.toList(),
- JavaCustomArea.EMPTY,
+ JavaCustomArea.type(generateTypeRef(sumDefinition.type(), context), "body"),
sumDefinition.docComment()
)
);
@@ -168,7 +167,7 @@ public class JavaTypesGenerator implements Generator {
),
generateStructDefinitionBuilder(structDefinition, components, context)
),
- JavaCustomArea.EMPTY,
+ JavaCustomArea.type(generateTypeRef(structDefinition.type(), context), "body"),
structDefinition.docComment()
);
}
@@ -216,7 +215,7 @@ public class JavaTypesGenerator implements Generator {
components,
List.of(),
body,
- JavaCustomArea.EMPTY,
+ JavaCustomArea.type(builderJavaTypeRef, "body"),
DocComment.EMPTY
);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
index 9f87e0f..82c2f9b 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
@@ -5,8 +5,18 @@ import org.zwobble.hobgoblin.compiler.output.CodeWriter;
import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*;
import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.file.Path;
public class JavaWriter implements AutoCloseable {
+ public static JavaWriter file(Path path) throws IOException {
+ return new JavaWriter(CodeWriter.file(
+ path,
+ "// Custom area start: ",
+ "// Custom area end: "
+ ));
+ }
+
private final CodeWriter writer;
public JavaWriter(CodeWriter writer) {
@@ -84,7 +94,7 @@ public class JavaWriter implements AutoCloseable {
}
this.writer.newLine();
- this.writeCustomArea("body", classDeclaration.customArea());
+ this.writeCustomArea(classDeclaration.customArea());
this.writer.dedent();
this.writer.write("}");
@@ -102,19 +112,12 @@ public class JavaWriter implements AutoCloseable {
}
}
- private void writeCustomArea(String name, JavaCustomArea javaCustomArea) throws IOException {
- this.writer.write("// Custom area start: ");
- this.writer.write(name);
- this.writer.newLine();
-
- for (var line : javaCustomArea.lines()) {
- this.writer.write(line);
- this.writer.newLine();
- }
-
- this.writer.write("// Custom area end: ");
- this.writer.write(name);
- this.writer.newLine();
+ private void writeCustomArea(JavaCustomArea customArea) throws IOException {
+ var customAreaName = new StringWriter();
+ writeTypeRef(customArea.type(), customAreaName::write);
+ customAreaName.write(" ");
+ customAreaName.write(customArea.name());
+ this.writer.writeCustomArea(customAreaName.toString());
}
void writeExpression(JavaExpression expression) throws IOException {
@@ -165,7 +168,7 @@ public class JavaWriter implements AutoCloseable {
this.writer.write("{");
this.writer.indent();
this.writer.newLine();
- this.writeCustomArea("body", interfaceDeclaration.customArea());
+ this.writeCustomArea(interfaceDeclaration.customArea());
this.writer.dedent();
this.writer.write("}");
}
@@ -271,7 +274,7 @@ public class JavaWriter implements AutoCloseable {
}
this.writer.newLine();
- this.writeCustomArea("body", recordDeclaration.customArea());
+ this.writeCustomArea(recordDeclaration.customArea());
this.writer.dedent();
this.writer.write("}");
@@ -301,6 +304,10 @@ public class JavaWriter implements AutoCloseable {
}
void writeTypeRef(JavaTypeRef type) throws IOException {
+ writeTypeRef(type, writer::write);
+ }
+
+ private static void writeTypeRef(JavaTypeRef type, WriteString writer) throws IOException {
for (var part : type.packageName()) {
writer.write(part);
writer.write(".");
@@ -316,14 +323,14 @@ public class JavaWriter implements AutoCloseable {
writer.write("<");
writeWithSeparator(
type.args(),
- this::writeTypeRef,
+ arg -> writeTypeRef(arg, writer),
() -> writer.write(", ")
);
writer.write(">");
}
}
- private <T> void writeWithSeparator(
+ private static <T> void writeWithSeparator(
Iterable<T> iterable,
WriteElement<T> writeElement,
WriteSeparator writeSeparator
@@ -349,4 +356,8 @@ public class JavaWriter implements AutoCloseable {
interface WriteSeparator {
void write() throws IOException;
}
+
+ interface WriteString {
+ void write(String string) throws IOException;
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaCustomArea.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaCustomArea.java
index 42d38d1..51e3096 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaCustomArea.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaCustomArea.java
@@ -1,7 +1,7 @@
package org.zwobble.hobgoblin.compiler.output.lang.java.ast;
-import java.util.List;
-
-public record JavaCustomArea(List<String> lines) {
- public static final JavaCustomArea EMPTY = new JavaCustomArea(List.of());
+public record JavaCustomArea(JavaTypeRef type, String name) {
+ public static JavaCustomArea type(JavaTypeRef type, String name) {
+ return new JavaCustomArea(type, name);
+ }
}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java
index e13c3dd..beef2ca 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java
@@ -8,6 +8,7 @@ import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
+import java.util.Optional;
import static org.zwobble.precisely.AssertThat.assertThat;
import static org.zwobble.precisely.Matchers.equalTo;
@@ -18,7 +19,7 @@ public class JavaWriterTests {
var java = new JavaClassDeclaration(
"Rectangle",
List.of(),
- JavaCustomArea.EMPTY,
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Rectangle"), "body"),
DocComment.EMPTY
);
@@ -26,8 +27,8 @@ public class JavaWriterTests {
assertThat(string, equalTo("""
public class Rectangle {
- // Custom area start: body
- // Custom area end: body
+ // Custom area start: Rectangle body
+ // Custom area end: Rectangle body
}"""
));
}
@@ -52,7 +53,7 @@ public class JavaWriterTests {
JavaBlock.EMPTY
)
),
- JavaCustomArea.EMPTY,
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Rectangle"), "body"),
DocComment.EMPTY
);
@@ -66,28 +67,8 @@ public class JavaWriterTests {
public void b() {
}
- // Custom area start: body
- // Custom area end: body
- }"""
- ));
- }
-
- @Test
- public void classDeclarationWithCustomArea() throws IOException {
- var java = new JavaClassDeclaration(
- "Point",
- List.of(),
- new JavaCustomArea(List.of("// <custom area>")),
- DocComment.EMPTY
- );
-
- var string = write(writer -> writer.writeTypeDeclaration(java));
-
- assertThat(string, equalTo("""
- public class Point {
- // Custom area start: body
- // <custom area>
- // Custom area end: body
+ // Custom area start: Rectangle body
+ // Custom area end: Rectangle body
}"""
));
}
@@ -97,7 +78,7 @@ public class JavaWriterTests {
var java = new JavaClassDeclaration(
"Point",
List.of(),
- JavaCustomArea.EMPTY,
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Point"), "body"),
new DocComment("A 2D point.")
);
@@ -106,8 +87,8 @@ public class JavaWriterTests {
assertThat(string, equalTo("""
/// A 2D point.
public class Point {
- // Custom area start: body
- // Custom area end: body
+ // Custom area start: Point body
+ // Custom area end: Point body
}"""
));
}
@@ -117,7 +98,7 @@ public class JavaWriterTests {
var java = new JavaInterfaceDeclaration(
"Shape",
List.of(),
- JavaCustomArea.EMPTY,
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Shape"), "body"),
DocComment.EMPTY
);
@@ -125,8 +106,8 @@ public class JavaWriterTests {
assertThat(string, equalTo("""
public sealed interface Shape {
- // Custom area start: body
- // Custom area end: body
+ // Custom area start: Shape body
+ // Custom area end: Shape body
}"""
));
}
@@ -139,7 +120,7 @@ public class JavaWriterTests {
JavaTypeRef.topLevel(List.of("abc", "def"), "One"),
JavaTypeRef.topLevel(List.of("abc", "def"), "Two")
),
- JavaCustomArea.EMPTY,
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Shape"), "body"),
DocComment.EMPTY
);
@@ -147,28 +128,8 @@ public class JavaWriterTests {
assertThat(string, equalTo("""
public sealed interface Shape permits abc.def.One, abc.def.Two {
- // Custom area start: body
- // Custom area end: body
- }"""
- ));
- }
-
- @Test
- public void interfaceDeclarationWithCustomArea() throws IOException {
- var java = new JavaInterfaceDeclaration(
- "Shape",
- List.of(),
- new JavaCustomArea(List.of("// <custom area>")),
- DocComment.EMPTY
- );
-
- var string = write(writer -> writer.writeTypeDeclaration(java));
-
- assertThat(string, equalTo("""
- public sealed interface Shape {
- // Custom area start: body
- // <custom area>
- // Custom area end: body
+ // Custom area start: Shape body
+ // Custom area end: Shape body
}"""
));
}
@@ -178,7 +139,7 @@ public class JavaWriterTests {
var java = new JavaInterfaceDeclaration(
"Shape",
List.of(),
- JavaCustomArea.EMPTY,
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Shape"), "body"),
new DocComment("A 2D shape.")
);
@@ -187,8 +148,8 @@ public class JavaWriterTests {
assertThat(string, equalTo("""
/// A 2D shape.
public sealed interface Shape {
- // Custom area start: body
- // Custom area end: body
+ // Custom area start: Shape body
+ // Custom area end: Shape body
}"""
));
}
@@ -200,28 +161,7 @@ public class JavaWriterTests {
List.of(),
List.of(),
List.of(),
- JavaCustomArea.EMPTY,
- DocComment.EMPTY
- );
-
- var string = write(writer -> writer.writeTypeDeclaration(java));
-
- assertThat(string, equalTo("""
- public record Point() {
- // Custom area start: body
- // Custom area end: body
- }"""
- ));
- }
-
- @Test
- public void recordDeclarationWithCustomArea() throws IOException {
- var java = new JavaRecordDeclaration(
- "Point",
- List.of(),
- List.of(),
- List.of(),
- new JavaCustomArea(List.of("// <custom area>")),
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Point"), "body"),
DocComment.EMPTY
);
@@ -229,9 +169,8 @@ public class JavaWriterTests {
assertThat(string, equalTo("""
public record Point() {
- // Custom area start: body
- // <custom area>
- // Custom area end: body
+ // Custom area start: Point body
+ // Custom area end: Point body
}"""
));
}
@@ -243,7 +182,7 @@ public class JavaWriterTests {
List.of(),
List.of(),
List.of(),
- JavaCustomArea.EMPTY,
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Point"), "body"),
new DocComment("A 2D point.")
);
@@ -252,8 +191,8 @@ public class JavaWriterTests {
assertThat(string, equalTo("""
/// A 2D point.
public record Point() {
- // Custom area start: body
- // Custom area end: body
+ // Custom area start: Point body
+ // Custom area end: Point body
}"""
));
}
@@ -280,7 +219,7 @@ public class JavaWriterTests {
JavaBlock.EMPTY
)
),
- JavaCustomArea.EMPTY,
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Rectangle"), "body"),
DocComment.EMPTY
);
@@ -294,8 +233,8 @@ public class JavaWriterTests {
public void b() {
}
- // Custom area start: body
- // Custom area end: body
+ // Custom area start: Rectangle body
+ // Custom area end: Rectangle body
}"""
));
}
@@ -463,9 +402,51 @@ public class JavaWriterTests {
assertThat(string, equalTo("abc.def.One.Two"));
}
+ @Test
+ public void customAreaContentsArePreserved() throws IOException {
+ var java = new JavaRecordDeclaration(
+ "Point",
+ List.of(),
+ List.of(),
+ List.of(),
+ new JavaCustomArea(JavaTypeRef.topLevel(List.of(), "Point"), "body"),
+ DocComment.EMPTY
+ );
+
+ var string = write(
+ writer -> writer.writeTypeDeclaration(java),
+ """
+ public class Point {
+ // Custom area start: Point body
+ // <custom area>
+ // Custom area end: Point body
+ }
+ """
+ );
+
+ assertThat(string, equalTo("""
+ public record Point() {
+ // Custom area start: Point body
+ // <custom area>
+ // Custom area end: Point body
+ }"""
+ ));
+ }
+
private String write(Write write) throws IOException {
+ return write(write, Optional.empty());
+ }
+
+ private String write(Write write, String originalContents) throws IOException {
+ return write(write, Optional.of(originalContents));
+ }
+
+ private String write(Write write, Optional<String> originalContents) throws IOException {
var stringWriter = new StringWriter();
- var javaWriter = new JavaWriter(new CodeWriter(stringWriter));
+ var javaWriter = new JavaWriter(new CodeWriter(
+ stringWriter,
+ CodeWriter.CustomAreas.read(originalContents.orElse(""), "// Custom area start: ", "// Custom area end: ")
+ ));
write.write(javaWriter);
return stringWriter.toString();
}