diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-08-08 23:06:06 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-08-08 23:06:06 +0100 |
| commit | 765357e0d65c3f869344d8e86321fbed72edbcd6 (patch) | |
| tree | 5d278dfa4c29a069ae3edccacad74b9f3c094276 | |
| parent | 39e34d4f524f5492065ba47b6cd33d5f272cd515 (diff) | |
Support nested constructed native types in java-transient-0
7 files changed, 203 insertions, 53 deletions
diff --git a/examples/15-transient-0/output/java/src/main/java/org/zwobble/example/types/data/transient0/HobgoblinTransient0Data.java b/examples/15-transient-0/output/java/src/main/java/org/zwobble/example/types/data/transient0/HobgoblinTransient0Data.java index 0044a4a..1eea54c 100644 --- a/examples/15-transient-0/output/java/src/main/java/org/zwobble/example/types/data/transient0/HobgoblinTransient0Data.java +++ b/examples/15-transient-0/output/java/src/main/java/org/zwobble/example/types/data/transient0/HobgoblinTransient0Data.java @@ -276,11 +276,13 @@ public final class HobgoblinTransient0Data { public static void encodeStructWithGenericNative(org.zwobble.example.types.data.StructWithGenericNative value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value.a(), outputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeInt32, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString); + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value.b(), outputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$1); } public static org.zwobble.example.types.data.StructWithGenericNative decodeStructWithGenericNative(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { var a = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeInt32, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString); - return new org.zwobble.example.types.data.StructWithGenericNative(a); + var b = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$1); + return new org.zwobble.example.types.data.StructWithGenericNative(a, b); } public static void encodeStructWithBox(org.zwobble.example.types.data.StructWithBox value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { @@ -498,6 +500,43 @@ public final class HobgoblinTransient0Data { return new org.zwobble.example.types.data.StructWithSharedSumAndVariant(a, b); } + private static void encode$constructedType$0(java.util.Optional<String> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { + org.zwobble.example.types.transient0.HobgoblinTransient0Builtins.encodeBool(value.isPresent(), outputStream, sharedValues); + if (value.isPresent()) { + org.zwobble.example.types.transient0.HobgoblinTransient0Builtins.encodeString(value.get(), outputStream, sharedValues); + } + } + + private static java.util.Optional<String> decode$constructedType$0(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { + var value$isPresent = org.zwobble.example.types.transient0.HobgoblinTransient0Builtins.decodeBool(inputStream, sharedValues); + java.util.Optional<String> value; + if (value$isPresent) { + var value$element = org.zwobble.example.types.transient0.HobgoblinTransient0Builtins.decodeString(inputStream, sharedValues); + value = java.util.Optional.of(value$element); + } else { + value = java.util.Optional.empty(); + } + return value; + } + + private static void encode$constructedType$1(org.zwobble.example.types.data.GenericNative<java.util.Optional<String>, org.zwobble.example.types.data.GenericNative<String, String>> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value, outputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$2); + } + + private static org.zwobble.example.types.data.GenericNative<java.util.Optional<String>, org.zwobble.example.types.data.GenericNative<String, String>> decode$constructedType$1(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { + var value = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$2); + return value; + } + + private static void encode$constructedType$2(org.zwobble.example.types.data.GenericNative<String, String> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value, outputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString); + } + + private static org.zwobble.example.types.data.GenericNative<String, String> decode$constructedType$2(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { + var value = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString); + return value; + } + // Custom area start: org.zwobble.example.types.data.transient0.HobgoblinTransient0Data body public static void encodeNative( Native value, diff --git a/examples/15-transient-0/output/rust/src/gen/data.rs b/examples/15-transient-0/output/rust/src/gen/data.rs index 856d60f..6f1d5b5 100644 --- a/examples/15-transient-0/output/rust/src/gen/data.rs +++ b/examples/15-transient-0/output/rust/src/gen/data.rs @@ -124,6 +124,7 @@ pub struct StructWithNative { #[derive(Clone, Debug, Hash, PartialEq)] pub struct StructWithGenericNative { pub a: crate::data::GenericNative::<::core::primitive::i32, ::std::string::String>, + pub b: crate::data::GenericNative::<::std::option::Option::<::std::string::String>, crate::data::GenericNative::<::std::option::Option::<::std::string::String>, crate::data::GenericNative::<::std::string::String, ::std::string::String>>>, } #[derive(Clone, Debug, Hash, PartialEq)] diff --git a/examples/15-transient-0/output/rust/src/gen/data/transient_0.rs b/examples/15-transient-0/output/rust/src/gen/data/transient_0.rs index c497b57..383a564 100644 --- a/examples/15-transient-0/output/rust/src/gen/data/transient_0.rs +++ b/examples/15-transient-0/output/rust/src/gen/data/transient_0.rs @@ -276,12 +276,14 @@ pub fn decode_struct_with_native(reader: &mut impl std::io::Read, shared_values: pub fn encode_struct_with_generic_native(value: &crate::data::StructWithGenericNative, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { todo!(); + todo!(); ::std::io::Result::Ok(()) } pub fn decode_struct_with_generic_native(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithGenericNative> { let a = todo!(); - ::std::io::Result::Ok(crate::data::StructWithGenericNative { a: a }) + let b = todo!(); + ::std::io::Result::Ok(crate::data::StructWithGenericNative { a: a, b: b }) } pub fn encode_struct_with_box(value: &crate::data::StructWithBox, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { diff --git a/examples/15-transient-0/src/data.hob b/examples/15-transient-0/src/data.hob index 1fb173e..df96916 100644 --- a/examples/15-transient-0/src/data.hob +++ b/examples/15-transient-0/src/data.hob @@ -88,6 +88,7 @@ native GenericNative[A, B] { struct StructWithGenericNative { field a: GenericNative[Int32, String]; + field b: GenericNative[Option[String], GenericNative[Option[String], GenericNative[String, String]]]; } struct StructWithBox { 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 index b0f63e7..c9c4ea0 100644 --- 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 @@ -60,12 +60,11 @@ public class JavaTransient0Generator implements Generator { List<TypedNamespaceNode> namespaces, TypesInfo typesInfo ) throws IOException { - var context = new Context(typesInfo); - write(generateSupportTypes()); - write(generateBuiltins(context)); + write(generateBuiltins(new Context(NamespaceName.of(), typesInfo))); for (var namespace : namespaces) { + var context = new Context(namespace.namespaceName(), typesInfo); var javaCompilationUnits = generateNamespace(namespace, context); write(javaCompilationUnits); @@ -268,7 +267,7 @@ public class JavaTransient0Generator implements Generator { generateEncodeInt64Method(), generateDecodeInt64Method(), generateEncodeStringMethod(context), - generateDecodeStringMethod() + generateDecodeStringMethod(context) ), DocComment.EMPTY ) @@ -446,7 +445,7 @@ public class JavaTransient0Generator implements Generator { ); } - private JavaMethodDeclaration generateDecodeStringMethod() { + private JavaMethodDeclaration generateDecodeStringMethod(Context context) { var bytesLengthVariableName = JavaIdentifier.of("bytesLength"); var bytesVariableName = JavaIdentifier.of("bytes"); @@ -454,7 +453,8 @@ public class JavaTransient0Generator implements Generator { statements.addAll(generateDecode( bytesLengthVariableName, - NativeTypes.INT_64 + NativeTypes.INT_64, + context )); statements.add(generateAssertLessThanIntMax( @@ -506,14 +506,36 @@ public class JavaTransient0Generator implements Generator { transient0JavaName ); + var body = new ArrayList<JavaClassBodyDeclaration>(); + + for (var statement : namespace.body()) { + body.addAll(generateNamespaceStatement(statement, context)); + } + + for ( + var constructedTypeIndex = 0; + constructedTypeIndex < context.constructedTypes.size(); + constructedTypeIndex++ + ) { + var constructedType = context.constructedTypes.get(constructedTypeIndex); + body.add(generateEncodeConstructedTypeMethod( + constructedType, + constructedTypeIndex, + context + )); + body.add(generateDecodeConstructedTypeMethod( + constructedType, + constructedTypeIndex, + context + )); + } + return List.of( new JavaCompilationUnit( new JavaClassDeclaration( transient0JavaTypeRef, List.of(), - namespace.body().stream() - .flatMap(statement -> generateNamespaceStatement(statement, context)) - .toList(), + body, DocComment.EMPTY ) ) @@ -537,33 +559,33 @@ public class JavaTransient0Generator implements Generator { ); } - private Stream<JavaClassBodyDeclaration> generateNamespaceStatement( + private List<JavaClassBodyDeclaration> generateNamespaceStatement( TypedNamespaceStatementNode statement, Context context ) { return switch (statement) { case TypedEnumDefinitionNode enumDefinition -> { - yield Stream.concat( - Stream.of(generateEncodeEnumMethod(enumDefinition, context)), - generateDecodeEnumMethod(enumDefinition) - ); + yield Lists.concat(List.of( + List.of(generateEncodeEnumMethod(enumDefinition, context)), + generateDecodeEnumMethod(enumDefinition, context) + )); } case TypedNativeTypeDefinitionNode _ -> { - yield Stream.of(); + yield List.of(); } case TypedStructDefinitionNode structDefinition -> { - yield Stream.of( + yield List.of( generateEncodeStructMethod(structDefinition, context), - generateDecodeStructMethod(structDefinition) + generateDecodeStructMethod(structDefinition, context) ); } case TypedSumDefinitionNode sumDefinition -> { - yield Stream.of( + yield List.of( generateEncodeSumMethod(sumDefinition, context), - generateDecodeSumMethod(sumDefinition, context.typesInfo) + generateDecodeSumMethod(sumDefinition, context) ); } }; @@ -587,12 +609,15 @@ public class JavaTransient0Generator implements Generator { ); } - private Stream<JavaClassBodyDeclaration> generateDecodeEnumMethod(TypedEnumDefinitionNode enumDefinition) { + private List<JavaClassBodyDeclaration> generateDecodeEnumMethod( + TypedEnumDefinitionNode enumDefinition, + Context context + ) { var enumJavaTypeRef = this.javaGenerator.generateTypeRef(enumDefinition.type()); var ordinal = JavaIdentifier.of("ordinal"); var enumValues = JavaIdentifier.of(this.javaGenerator.generateTypeName(enumDefinition.type().name()).value() + "$values"); - return Stream.of( + return List.of( new JavaFieldDeclaration( JavaVisibility.PRIVATE, JavaMemberKind.STATIC, @@ -608,7 +633,7 @@ public class JavaTransient0Generator implements Generator { generateDecodeMethod( enumDefinition.type(), new JavaBlock(Stream.concat( - generateDecode(ordinal, NativeTypes.INT_32).stream(), + generateDecode(ordinal, NativeTypes.INT_32, context).stream(), Stream.of(new JavaReturn(new JavaArrayAccess( new JavaRef(enumValues), new JavaRef(ordinal) @@ -640,7 +665,10 @@ public class JavaTransient0Generator implements Generator { ); } - private JavaMethodDeclaration generateDecodeStructMethod(TypedStructDefinitionNode structDefinition) { + private JavaMethodDeclaration generateDecodeStructMethod( + TypedStructDefinitionNode structDefinition, + Context context + ) { var structJavaTypeRef = this.javaGenerator.generateTypeRef(structDefinition.type()); return generateDecodeMethod( @@ -654,7 +682,8 @@ public class JavaTransient0Generator implements Generator { structDefinition.fields().get().stream() .flatMap(field -> generateDecode( this.javaGenerator.generateFieldName(field.name()), - field.type().value() + field.type().value(), + context ).stream()), Stream.of(new JavaReturn(new JavaNewExpression( structJavaTypeRef, @@ -710,22 +739,22 @@ public class JavaTransient0Generator implements Generator { private JavaMethodDeclaration generateDecodeSumMethod( TypedSumDefinitionNode sumDefinition, - TypesInfo typesInfo + Context context ) { var decodeStatements = new ArrayList<JavaBlockStatement>(); var variantTag = JavaIdentifier.of("variantTag"); - decodeStatements.addAll(generateDecode(variantTag, NativeTypes.INT_32)); + decodeStatements.addAll(generateDecode(variantTag, NativeTypes.INT_32, context)); var cases = new ArrayList<JavaSwitchRule>(); - for (var variant : typesInfo.sumVariants(sumDefinition.type())) { + for (var variant : context.typesInfo.sumVariants(sumDefinition.type())) { var variantVariable = JavaIdentifier.of(VALUE_NAME.value() + "$" + variant.tag()); var statements = new ArrayList<JavaBlockStatement>(); - statements.addAll(generateDecode(variantVariable, variant.containerType())); + statements.addAll(generateDecode(variantVariable, variant.containerType(), context)); statements.add(new JavaReturn(new JavaRef(variantVariable))); @@ -850,8 +879,13 @@ public class JavaTransient0Generator implements Generator { private JavaMethodRef generateEncodeMethodRef(Type type, Context context) { return switch (type) { - case ConstructedNativeType _ -> { - throw new UnsupportedOperationException("TODO"); + case ConstructedType constructedType -> { + var constructedTypeIndex = context.constructedTypeIndex(constructedType); + var methodName = generateEncodeConstructedTypeMethodName(constructedTypeIndex); + yield new JavaMethodRef( + generateTransient0TypeRef(context.namespaceName), + methodName + ); } case SimpleType simpleType -> { @@ -871,6 +905,28 @@ public class JavaTransient0Generator implements Generator { }; } + private static JavaIdentifier generateEncodeConstructedTypeMethodName(int constructedTypeIndex) { + return JavaIdentifier.of("encode$constructedType$" + constructedTypeIndex); + } + + private JavaMethodDeclaration generateEncodeConstructedTypeMethod( + ConstructedType constructedType, + int constructedTypeIndex, + Context context + ) { + return new JavaMethodDeclaration( + generateEncodeConstructedTypeMethodName(constructedTypeIndex), + JavaVisibility.PRIVATE, + JavaMemberKind.STATIC, + JavaTypeRef.VOID, + generateEncodeParams(this.javaGenerator.generateTypeRef(constructedType)), + List.of(JavaTypeRef.IO_EXCEPTION), + Optional.of(new JavaBlock( + generateEncode(new JavaRef(VALUE_NAME), constructedType, context) + )) + ); + } + private JavaBlockStatement generateEncode( JavaExpression value, NamespaceName typeNamespaceName, @@ -893,17 +949,21 @@ public class JavaTransient0Generator implements Generator { ); } - private List<JavaBlockStatement> generateDecode(JavaIdentifier target, Type type) { + private List<JavaBlockStatement> generateDecode( + JavaIdentifier target, + Type type, + Context context + ) { return switch (type) { case ConstructedNativeType constructedNativeType -> { if (constructedNativeType.constructor().equals(NativeTypes.BOX)) { - yield generateDecode(target, constructedNativeType.args().getFirst()); + yield generateDecode(target, constructedNativeType.args().getFirst(), context); } else if (constructedNativeType.constructor().equals(NativeTypes.LIST)) { - yield generateDecodeList(target, constructedNativeType.args().getFirst()); + yield generateDecodeList(target, constructedNativeType.args().getFirst(), context); } else if (constructedNativeType.constructor().equals(NativeTypes.OPTION)) { - yield generateDecodeOption(target, constructedNativeType.args().getFirst()); + yield generateDecodeOption(target, constructedNativeType.args().getFirst(), context); } else if (constructedNativeType.constructor().equals(NativeTypes.SHARED)) { - yield generateDecodeShared(target, constructedNativeType.args().getFirst()); + yield generateDecodeShared(target, constructedNativeType.args().getFirst(), context); } else { yield List.of( generateDecode( @@ -911,7 +971,7 @@ public class JavaTransient0Generator implements Generator { constructedNativeType.namespaceName(), constructedNativeType, constructedNativeType.args().stream() - .<JavaExpression>map(typeArg -> generateDecodeMethodRef(typeArg)) + .<JavaExpression>map(typeArg -> generateDecodeMethodRef(typeArg, context)) .toList() ) ); @@ -938,10 +998,15 @@ public class JavaTransient0Generator implements Generator { }; } - private JavaMethodRef generateDecodeMethodRef(Type type) { + private JavaMethodRef generateDecodeMethodRef(Type type, Context context) { return switch (type) { - case ConstructedNativeType _ -> { - throw new UnsupportedOperationException("TODO"); + case ConstructedType constructedType -> { + var constructedTypeIndex = context.constructedTypeIndex(constructedType); + var methodName = generateDecodeConstructedTypeMethodName(constructedTypeIndex); + yield new JavaMethodRef( + generateTransient0TypeRef(context.namespaceName), + methodName + ); } case SimpleType simpleType -> { @@ -961,6 +1026,29 @@ public class JavaTransient0Generator implements Generator { }; } + private static JavaIdentifier generateDecodeConstructedTypeMethodName(int constructedTypeIndex) { + return JavaIdentifier.of("decode$constructedType$" + constructedTypeIndex); + } + + private JavaMethodDeclaration generateDecodeConstructedTypeMethod( + ConstructedType constructedType, + int constructedTypeIndex, + Context context + ) { + return new JavaMethodDeclaration( + generateDecodeConstructedTypeMethodName(constructedTypeIndex), + JavaVisibility.PRIVATE, + JavaMemberKind.STATIC, + this.javaGenerator.generateTypeRef(constructedType), + generateDecodeParams(), + List.of(JavaTypeRef.IO_EXCEPTION), + Optional.of(new JavaBlock(Lists.concat(List.of( + generateDecode(VALUE_NAME, constructedType, context), + List.of(new JavaReturn(new JavaRef(VALUE_NAME))) + )))) + ); + } + private JavaBlockStatement generateDecode( JavaIdentifier target, NamespaceName typeNamespaceName, @@ -1019,7 +1107,8 @@ public class JavaTransient0Generator implements Generator { private List<JavaBlockStatement> generateDecodeList( JavaIdentifier target, - Type elementType + Type elementType, + Context context ) { var size = JavaIdentifier.of(target.value() + "$size"); var index = JavaIdentifier.of(target.value() + "$index"); @@ -1027,7 +1116,7 @@ public class JavaTransient0Generator implements Generator { var statements = new ArrayList<JavaBlockStatement>(); - statements.addAll(generateDecode(size, NativeTypes.INT_64)); + statements.addAll(generateDecode(size, NativeTypes.INT_64, context)); statements.add(generateAssertLessThanIntMax( size, @@ -1049,7 +1138,7 @@ public class JavaTransient0Generator implements Generator { var forBodyStatements = new ArrayList<JavaBlockStatement>(); - forBodyStatements.addAll(generateDecode(element, elementType)); + forBodyStatements.addAll(generateDecode(element, elementType, context)); forBodyStatements.add(new JavaExpressionStatement(new JavaMethodCall( new JavaRef(target), @@ -1115,14 +1204,15 @@ public class JavaTransient0Generator implements Generator { private List<JavaBlockStatement> generateDecodeOption( JavaIdentifier target, - Type elementType + Type elementType, + Context context ) { var isPresent = JavaIdentifier.of(target.value() + "$isPresent"); var element = JavaIdentifier.of(target.value() + "$element"); var statements = new ArrayList<JavaBlockStatement>(); - statements.addAll(generateDecode(isPresent, NativeTypes.BOOL)); + statements.addAll(generateDecode(isPresent, NativeTypes.BOOL, context)); statements.add(new JavaLocalVariableDeclaration( Optional.of(JavaTypeRef.optional(this.javaGenerator.generateReferenceTypeRef(elementType))), @@ -1132,7 +1222,7 @@ public class JavaTransient0Generator implements Generator { var ifTrue = new ArrayList<JavaBlockStatement>(); - ifTrue.addAll(generateDecode(element, elementType)); + ifTrue.addAll(generateDecode(element, elementType, context)); ifTrue.add(new JavaExpressionStatement(new JavaBinaryOperation( JavaBinaryOperator.ASSIGN, @@ -1229,13 +1319,14 @@ public class JavaTransient0Generator implements Generator { private List<JavaBlockStatement> generateDecodeShared( JavaIdentifier target, - Type type + Type type, + Context context ) { var id = JavaIdentifier.of(target.value() + "$id"); var decodedValue = JavaIdentifier.of(target.value() + "$decodedValue"); return Lists.concat(List.of( - generateDecode(id, NativeTypes.INT_64), + generateDecode(id, NativeTypes.INT_64, context), List.of( generateAssertLessThanIntMax( id, @@ -1291,7 +1382,7 @@ public class JavaTransient0Generator implements Generator { )) )), new JavaBlock(Lists.concat(List.of( - generateDecode(decodedValue, type), + generateDecode(decodedValue, type, context), List.of( new JavaExpressionStatement(new JavaMethodCall( new JavaRef(SHARED_VALUES_NAME), @@ -1398,10 +1489,26 @@ public class JavaTransient0Generator implements Generator { } private static class Context { + private final NamespaceName namespaceName; private final TypesInfo typesInfo; + private final Map<ConstructedType, Integer> constructedTypeIndexes = new HashMap<>(); + private final List<ConstructedType> constructedTypes = new ArrayList<>(); - public Context(TypesInfo typesInfo) { + public Context(NamespaceName namespaceName, TypesInfo typesInfo) { + this.namespaceName = namespaceName; this.typesInfo = typesInfo; } + + public int constructedTypeIndex(ConstructedType type) { + var existingIndex = constructedTypeIndexes.get(type); + if (existingIndex != null) { + return existingIndex; + } + + var index = constructedTypes.size(); + constructedTypeIndexes.put(type, index); + constructedTypes.add(type); + return index; + } } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedType.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedType.java index 03d4718..6224331 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedType.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedType.java @@ -1,4 +1,4 @@ package org.zwobble.hobgoblin.compiler.types; -public sealed interface ConstructedType permits ConstructedNativeType { +public sealed interface ConstructedType extends Type permits ConstructedNativeType { } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java index b483209..90dcc9b 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java @@ -1,5 +1,5 @@ package org.zwobble.hobgoblin.compiler.types; -public sealed interface Type extends TypeLevelValue permits ConstructedNativeType, ConstructibleType, EnumType, SimpleNativeType, SimpleType, StructType, SumType, TypeLevelValueType, TypeParam { +public sealed interface Type extends TypeLevelValue permits ConstructedNativeType, ConstructedType, ConstructibleType, EnumType, SimpleNativeType, SimpleType, StructType, SumType, TypeLevelValueType, TypeParam { String name(); } |
