diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-07-30 21:29:52 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-07-30 21:29:52 +0100 |
| commit | 2ff551c30f62283bd9faca4ad8e105b9a951abab (patch) | |
| tree | 057f06a0b1e720e90aaace48e88e8f881d297889 /src/main/java/org/zwobble | |
| parent | 00f2fff352e22fb83c0de38e6e5f70f4d1a0fea1 (diff) | |
Do not write to code file if header is missing
Diffstat (limited to 'src/main/java/org/zwobble')
5 files changed, 81 insertions, 37 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 a0b9005..81fd091 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java @@ -18,6 +18,7 @@ public class CodeWriter implements AutoCloseable { public static class InMemoryCodeWriterFile implements CodeWriterFile { private final Optional<String> originalContents; private final StringWriter stringWriter; + private boolean writerOpened; public InMemoryCodeWriterFile( Optional<String> originalContents, @@ -25,6 +26,7 @@ public class CodeWriter implements AutoCloseable { ) { this.originalContents = originalContents; this.stringWriter = stringWriter; + this.writerOpened = false; } @Override @@ -38,8 +40,13 @@ public class CodeWriter implements AutoCloseable { @Override public Writer openWriter() throws IOException { + this.writerOpened = true; return stringWriter; } + + public boolean isWriterOpened() { + return writerOpened; + } } public record CustomAreas( @@ -90,11 +97,16 @@ public class CodeWriter implements AutoCloseable { } } - public static CodeWriter file( + public interface Write { + void write(CodeWriter writer) throws IOException; + } + + public static void writeTo( Path path, - String lineCommentStart + String lineCommentStart, + Write write ) throws IOException { - return file( + writeTo( new CodeWriterFile() { @Override public String readString() throws IOException { @@ -107,20 +119,31 @@ public class CodeWriter implements AutoCloseable { return new FileWriter(path.toFile()); } }, - lineCommentStart + lineCommentStart, + write ); } - public static CodeWriter file( + public static void writeTo( CodeWriterFile file, - String lineCommentStart + String lineCommentStart, + Write write ) throws IOException { + var originalContents = readFile(file); + + var header = lineCommentStart + " Generated by hobgoblin.\n\n"; + if (originalContents.isPresent() && !originalContents.get().startsWith(header)) { + return; + } + var customAreaStart = lineCommentStart + " Custom area start: "; var customAreaEnd = lineCommentStart + " Custom area end: "; + var customAreas = readCustomAreas(file, customAreaStart, customAreaEnd); - var writer = file.openWriter(); - // TODO: warn if custom areas are unused? - return new CodeWriter(writer, lineCommentStart, customAreas); + try (var writer = file.openWriter()) { + // TODO: warn if custom areas are unused? + write.write(new CodeWriter(writer, header, customAreas)); + } } private static CustomAreas readCustomAreas( @@ -136,23 +159,30 @@ public class CodeWriter implements AutoCloseable { } } + private static Optional<String> readFile(CodeWriterFile file) throws IOException { + try { + return Optional.of(file.readString()); + } catch (NoSuchFileException exception) { + return Optional.empty(); + } + } + private final Writer writer; - private final String lineCommentStart; + private final String header; private final CustomAreas customAreas; private int indent; private boolean pendingIndent; - public CodeWriter(Writer writer, String lineCommentStart, CustomAreas customAreas) { + public CodeWriter(Writer writer, String header, CustomAreas customAreas) { this.writer = writer; - this.lineCommentStart = lineCommentStart; + this.header = header; this.customAreas = customAreas; this.indent = 0; this.pendingIndent = false; } public void writeHeader() throws IOException { - writer.write(lineCommentStart); - writer.write(" Generated by hobgoblin.\n\n"); + writer.write(header); } public void write(String value) throws IOException { diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java index 1325149..d7f4bb0 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java @@ -29,9 +29,11 @@ public class JavaGenerator { var javaCompilationUnitPath = sourceRootDirectory .resolve(javaCompilationUnit.packageName().parts().stream().map(JavaIdentifier::value).collect(Collectors.joining(File.separator))) .resolve(javaCompilationUnit.typeDeclaration().name().value() + ".java"); - try (var writer = JavaWriter.file(javaCompilationUnitPath)) { - writer.writeCompilationUnit(javaCompilationUnit); - } + + JavaWriter.writeTo( + javaCompilationUnitPath, + writer -> writer.writeCompilationUnit(javaCompilationUnit) + ); } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java index 0a0290d..22b6d7d 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java @@ -27,9 +27,9 @@ public class RustGenerator { .map(name -> name.value()) .collect(Collectors.joining(File.separator)) + ".rs" ); - try (var writer = RustWriter.file(path)) { + RustWriter.writeTo(path, writer -> { writer.writeModule(rustModule); - } + }); } public RustPath generateRustTypeExpression(Type type) { 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 b593364..7af7e01 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 @@ -15,18 +15,24 @@ import static org.zwobble.hobgoblin.compiler.output.CodeWriter.writeWithSeparato public class JavaWriter implements AutoCloseable { private static final String LINE_COMMENT_START = "//"; - public static JavaWriter file(CodeWriter.CodeWriterFile file) throws IOException { - return new JavaWriter(CodeWriter.file( - file, - LINE_COMMENT_START - )); + public interface Write { + void write(JavaWriter writer) throws IOException; } - public static JavaWriter file(Path path) throws IOException { - return new JavaWriter(CodeWriter.file( + public static void writeTo(Path path, Write write) throws IOException { + CodeWriter.writeTo( path, - LINE_COMMENT_START - )); + LINE_COMMENT_START, + writer -> write.write(new JavaWriter(writer)) + ); + } + + public static void writeTo(CodeWriter.CodeWriterFile file, Write write) throws IOException { + CodeWriter.writeTo( + file, + LINE_COMMENT_START, + writer -> write.write(new JavaWriter(writer)) + ); } private final CodeWriter writer; diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java index 2d7e9ed..d0552ad 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java @@ -15,18 +15,24 @@ import static org.zwobble.hobgoblin.compiler.output.CodeWriter.writeWithSeparato public class RustWriter implements AutoCloseable { private static final String LINE_COMMENT_START = "//"; - public static RustWriter file(CodeWriter.CodeWriterFile file) throws IOException { - return new RustWriter(CodeWriter.file( - file, - LINE_COMMENT_START - )); + public interface Write { + void write(RustWriter writer) throws IOException; } - public static RustWriter file(Path path) throws IOException { - return new RustWriter(CodeWriter.file( + public static void writeTo(Path path, Write write) throws IOException { + CodeWriter.writeTo( path, - LINE_COMMENT_START - )); + LINE_COMMENT_START, + writer -> write.write(new RustWriter(writer)) + ); + } + + public static void writeTo(CodeWriter.CodeWriterFile file, Write write) throws IOException { + CodeWriter.writeTo( + file, + LINE_COMMENT_START, + writer -> write.write(new RustWriter(writer)) + ); } private final CodeWriter writer; |
