diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-07-04 21:58:23 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-07-04 21:58:23 +0100 |
| commit | 5d0a4c4d706bdd3ee0fe3086c94d0ca36c47a313 (patch) | |
| tree | bd318b67b5455c18ce97db8f0d660e2ed515b36d /src/main/java/org | |
| parent | ccdb723a676f66ad6c1d55496e0272195fdd1fcc (diff) | |
Add skeleton for Java transient-0 generator
Diffstat (limited to 'src/main/java/org')
4 files changed, 178 insertions, 0 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java index 2899756..8a2ab9e 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java @@ -3,6 +3,7 @@ package org.zwobble.hobgoblin.compiler.config; import org.zwobble.hobgoblin.compiler.output.generators.Generator; import org.zwobble.hobgoblin.compiler.output.generators.errors.UnknownGeneratorError; import org.zwobble.hobgoblin.compiler.output.generators.javapreciselymatchers.JavaPreciselyMatchersGenerator; +import org.zwobble.hobgoblin.compiler.output.generators.javatransient0.JavaTransient0Generator; import org.zwobble.hobgoblin.compiler.output.generators.javatypes.JavaTypesGenerator; import org.zwobble.hobgoblin.compiler.output.generators.rusttypes.RustTypesGenerator; import org.zwobble.hobgoblin.compiler.sources.FileFragmentSource; @@ -45,6 +46,9 @@ public record ProjectConfig( case JavaPreciselyMatchersGenerator.NAME -> JavaPreciselyMatchersGenerator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); + case JavaTransient0Generator.NAME -> + JavaTransient0Generator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); + case RustTypesGenerator.NAME -> RustTypesGenerator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java new file mode 100644 index 0000000..2649e7c --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java @@ -0,0 +1,165 @@ +package org.zwobble.hobgoblin.compiler.output.generators.javatransient0; + +import org.zwobble.hobgoblin.compiler.ast.DocComment; +import org.zwobble.hobgoblin.compiler.ast.typed.*; +import org.zwobble.hobgoblin.compiler.config.OutputConfig; +import org.zwobble.hobgoblin.compiler.output.generators.Generator; +import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGenerator; +import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGeneratorConfig; +import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*; +import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo; +import org.zwobble.hobgoblin.compiler.util.Casing; +import org.zwobble.json5.reader.Json5ObjectReader; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +public class JavaTransient0Generator implements Generator { + public static final String NAME = "java-transient-0"; + + private static final JavaIdentifier ENCODE_METHOD_NAME = JavaIdentifier.of("encode"); + private static final JavaIdentifier DECODE_METHOD_NAME = JavaIdentifier.of("decode"); + + public static OutputConfig parseGeneratorConfig( + Path projectRoot, + Json5ObjectReader generatorJson, + Optional<Json5ObjectReader> langsJson + ) { + return () -> { + var relativeOutputPath = generatorJson.getString("path").value(); + var outputPath = projectRoot.resolve(relativeOutputPath); + + var javaConfig = JavaGeneratorConfig.parseLangsConfig(langsJson); + + var javaGenerator = new JavaGenerator(javaConfig); + + return new JavaTransient0Generator(outputPath, javaGenerator); + }; + } + + private final Path sourceRootDirectory; + private final JavaGenerator javaGenerator; + + public JavaTransient0Generator(Path sourceRootDirectory, JavaGenerator javaGenerator) { + this.sourceRootDirectory = sourceRootDirectory; + this.javaGenerator = javaGenerator; + } + + @Override + public void generate( + List<TypedNamespaceNode> namespaces, + TypesInfo typesInfo + ) throws IOException { + var context = new Context(typesInfo); + + for (var namespace : namespaces) { + var javaCompilationUnits = generateNamespace(namespace, context); + + JavaGenerator.write(this.sourceRootDirectory, javaCompilationUnits); + } + } + + private List<JavaCompilationUnit> generateNamespace( + TypedNamespaceNode namespace, + Context context + ) { + var packageName = this.javaGenerator.namespaceToJavaPackageName(namespace.namespaceName()); + var namespaceShortName = namespace.namespaceName().shortName(); + var transient0JavaName = this.javaGenerator.generateTypeName( + "HobgoblinTransient0" + Casing.lowerCamelCaseToUpperCamelCase(namespaceShortName) + ); + var transient0JavaTypeRef = JavaTypeRef.topLevel( + packageName, + transient0JavaName + ); + + return List.of( + new JavaCompilationUnit( + packageName, + new JavaCustomArea(transient0JavaTypeRef, "imports"), + new JavaClassDeclaration( + transient0JavaName, + List.of(), + namespace.body().stream() + .flatMap(statement -> generateNamespaceStatement(statement, context)) + .toList(), + new JavaCustomArea(transient0JavaTypeRef, "body"), + DocComment.EMPTY + ) + ) + ); + } + + private Stream<JavaClassBodyDeclaration> generateNamespaceStatement( + TypedNamespaceStatementNode statement, + Context context + ) { + return switch (statement) { + case TypedEnumDefinitionNode enumDefinition -> { + yield Stream.of(); + } + + case TypedNativeTypeDefinitionNode nativeTypeDefinition -> { + yield Stream.of(); + } + + case TypedStructDefinitionNode structDefinition -> { + var valueName = JavaIdentifier.of("value"); + var outputStreamName = JavaIdentifier.of("outputStream"); + var inputStreamName = JavaIdentifier.of("inputStream"); + + var structJavaTypeRef = this.javaGenerator.generateTypeRef(structDefinition.type()); + + yield Stream.of( + new JavaMethodDeclaration( + ENCODE_METHOD_NAME, + JavaVisibility.PUBLIC, + JavaMethodKind.STATIC, + JavaTypeRef.VOID, + List.of( + new JavaParam( + structJavaTypeRef, + valueName + ), + new JavaParam( + JavaTypeRef.OUTPUT_STREAM, + outputStreamName + ) + ), + new JavaBlock(List.of()) + ), + new JavaMethodDeclaration( + DECODE_METHOD_NAME, + JavaVisibility.PUBLIC, + JavaMethodKind.STATIC, + structJavaTypeRef, + List.of( + new JavaParam( + JavaTypeRef.INPUT_STREAM, + inputStreamName + ) + ), + new JavaBlock(List.of( + new JavaReturn(new JavaNullLiteral()) + )) + ) + ); + } + + case TypedSumDefinitionNode sumDefinition -> { + yield Stream.of(); + } + }; + } + + private static class Context { + private final TypesInfo typesInfo; + + public Context(TypesInfo typesInfo) { + this.typesInfo = typesInfo; + } + } +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java index 099518c..b2478ed 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java @@ -33,6 +33,7 @@ public record JavaTypeRef(JavaPackageName packageName, List<JavaIdentifier> type } private static class JavaPackages { + private static final JavaPackageName JAVA_IO = JavaPackageName.of("java", "io"); private static final JavaPackageName JAVA_LANG = JavaPackageName.of("java", "lang"); private static final JavaPackageName JAVA_UTIL = JavaPackageName.of("java", "util"); private static final JavaPackageName JAVA_UTIL_STREAM = JavaPackageName.of("java", "util", "stream"); @@ -55,6 +56,8 @@ public record JavaTypeRef(JavaPackageName packageName, List<JavaIdentifier> type ); } + public static final JavaTypeRef INPUT_STREAM = topLevel(JavaPackages.JAVA_IO, JavaIdentifier.of("InputStream")); + public static final JavaTypeRef LIST = topLevel(JavaPackages.JAVA_UTIL, JavaIdentifier.of("List")); public static JavaTypeRef list(JavaTypeRef elementType) { @@ -69,5 +72,7 @@ public record JavaTypeRef(JavaPackageName packageName, List<JavaIdentifier> type public static final JavaTypeRef OPTIONAL = topLevel(JavaPackages.JAVA_UTIL, JavaIdentifier.of("Optional")); + public static final JavaTypeRef OUTPUT_STREAM = topLevel(JavaPackages.JAVA_IO, JavaIdentifier.of("OutputStream")); + public static final JavaTypeRef STREAM = topLevel(JavaPackages.JAVA_UTIL_STREAM, JavaIdentifier.of("Stream")); } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/NamespaceName.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/NamespaceName.java index 2cb3497..c7f4431 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/types/NamespaceName.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/NamespaceName.java @@ -12,6 +12,10 @@ public record NamespaceName(List<String> parts) { return new NamespaceName(parts.subList(0, parts.size() - 1)); } + public String shortName() { + return parts.getLast(); + } + public boolean isRoot() { return parts.isEmpty(); } |
