summaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org')
-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
4 files changed, 126 insertions, 30 deletions
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);
+ }
}