From 3b79d116965efc20e1065cbb24e7ad32ad038a0a Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 13 Jul 2026 20:50:25 +0100 Subject: Add static field declarations to Java AST --- hobgoblin/src/output/lang/java/ast.hob | 1 + .../JavaPreciselyMatchersGenerator.java | 1 + .../compiler/output/lang/java/JavaWriter.java | 9 ++++++++ .../output/lang/java/ast/JavaFieldDeclaration.java | 20 +++++++++------- .../compiler/output/lang/java/JavaWriterTests.java | 27 +++++++++++++++++----- .../lang/java/ast/JavaFieldDeclarationMatcher.java | 6 +++++ 6 files changed, 50 insertions(+), 14 deletions(-) diff --git a/hobgoblin/src/output/lang/java/ast.hob b/hobgoblin/src/output/lang/java/ast.hob index 65397a9..c90dafd 100644 --- a/hobgoblin/src/output/lang/java/ast.hob +++ b/hobgoblin/src/output/lang/java/ast.hob @@ -81,6 +81,7 @@ struct JavaConstructorDeclaration { struct JavaFieldDeclaration { field visibility: JavaVisibility; + field kind: JavaMemberKind; field type: JavaTypeRef; field name: JavaIdentifier; } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java index e4d2e95..8bc0efd 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java @@ -118,6 +118,7 @@ public class JavaPreciselyMatchersGenerator implements Generator { ), new JavaFieldDeclaration( JavaVisibility.PRIVATE, + JavaMemberKind.INSTANCE, JavaTypeRef.list(genericMatcherRef(JavaTypeArg.superType(javaStructTypeRef))), submatchersIdentifier ), 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 297bd27..07904d9 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 @@ -272,6 +272,15 @@ public class JavaWriter implements AutoCloseable { private void writeFieldDeclaration(JavaFieldDeclaration fieldDeclaration) throws IOException { this.writeVisibility(fieldDeclaration.visibility()); + + switch (fieldDeclaration.kind()) { + case STATIC -> { + this.writer.write(" static"); + } + case INSTANCE -> { + } + } + this.writer.write(" final "); this.writeTypeRef(fieldDeclaration.type()); this.writer.write(" "); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaFieldDeclaration.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaFieldDeclaration.java index f4c05a7..5ef6954 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaFieldDeclaration.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaFieldDeclaration.java @@ -5,30 +5,34 @@ package org.zwobble.hobgoblin.compiler.output.lang.java.ast; // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration imports // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration imports -public record JavaFieldDeclaration(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaVisibility visibility, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaTypeRef type, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaIdentifier name) implements org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaClassBodyDeclaration { +public record JavaFieldDeclaration(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaVisibility visibility, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMemberKind kind, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaTypeRef type, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaIdentifier name) implements org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaClassBodyDeclaration { public static org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder arbitrary() { - return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaVisibility.PUBLIC, org.zwobble.hobgoblin.compiler.output.lang.java.ast.HobgoblinNativeAst.arbitraryJavaTypeRef(), org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaIdentifier.arbitrary().build()); + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaVisibility.PUBLIC, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMemberKind.STATIC, org.zwobble.hobgoblin.compiler.output.lang.java.ast.HobgoblinNativeAst.arbitraryJavaTypeRef(), org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaIdentifier.arbitrary().build()); } - public record Builder(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaVisibility visibility, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaTypeRef type, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaIdentifier name) implements org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaClassBodyDeclaration.Builder { + public record Builder(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaVisibility visibility, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMemberKind kind, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaTypeRef type, org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaIdentifier name) implements org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaClassBodyDeclaration.Builder { public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration build() { - return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration(visibility, type, name); + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration(visibility, kind, type, name); } public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder withVisibility(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaVisibility visibility) { - return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, type, name); + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, kind, type, name); + } + + public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder withKind(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMemberKind kind) { + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, kind, type, name); } public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder withType(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaTypeRef type) { - return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, type, name); + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, kind, type, name); } public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaIdentifier name) { - return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, type, name); + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, kind, type, name); } public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaIdentifier.Builder name) { - return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, type, name.build()); + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder(visibility, kind, type, name.build()); } // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration.Builder body 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 15c294f..cd4fdfc 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 @@ -589,18 +589,33 @@ public class JavaWriterTests { // === Field declarations === @Test - public void fieldDeclaration() throws IOException { - var java = new JavaFieldDeclaration( - JavaVisibility.PRIVATE, - JavaTypeRef.INT, - JavaIdentifier.of("count") - ); + public void fieldDeclarationInstance() throws IOException { + var java = JavaFieldDeclaration.arbitrary() + .withVisibility(JavaVisibility.PRIVATE) + .withKind(JavaMemberKind.INSTANCE) + .withType(JavaTypeRef.INT) + .withName(JavaIdentifier.of("count")) + .build(); var string = write(writer -> writer.writeClassBodyDeclaration(java)); assertThat(string, equalTo("private final int count;")); } + @Test + public void fieldDeclarationInstanceStatic() throws IOException { + var java = JavaFieldDeclaration.arbitrary() + .withVisibility(JavaVisibility.PRIVATE) + .withKind(JavaMemberKind.STATIC) + .withType(JavaTypeRef.INT) + .withName(JavaIdentifier.of("count")) + .build(); + + var string = write(writer -> writer.writeClassBodyDeclaration(java)); + + assertThat(string, equalTo("private static final int count;")); + } + // === Method declarations === @Test diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaFieldDeclarationMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaFieldDeclarationMatcher.java index db4bbcb..1eac6ef 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaFieldDeclarationMatcher.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaFieldDeclarationMatcher.java @@ -34,6 +34,12 @@ public class JavaFieldDeclarationMatcher implements org.zwobble.precisely.Matche return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclarationMatcher(submatchers); } + public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclarationMatcher withKind(org.zwobble.precisely.Matcher kind) { + var submatchers = new java.util.ArrayList>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("kind", org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration::kind, kind)); + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclarationMatcher(submatchers); + } + public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclarationMatcher withType(org.zwobble.precisely.Matcher type) { var submatchers = new java.util.ArrayList>(this.submatchers); submatchers.add(org.zwobble.precisely.Matchers.has("type", org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaFieldDeclaration::type, type)); -- cgit v1.2.3