summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java237
1 files changed, 187 insertions, 50 deletions
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 6d3177d..52539ce 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
@@ -17,6 +17,7 @@ import org.zwobble.json5.reader.Json5ObjectReader;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
+import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;
@@ -27,6 +28,8 @@ public class JavaTransient0Generator implements Generator {
private static final JavaIdentifier OUTPUT_STREAM_NAME = JavaIdentifier.of("outputStream");
private static final JavaIdentifier INPUT_STREAM_NAME = JavaIdentifier.of("inputStream");
private static final JavaIdentifier SHARED_VALUES_NAME = JavaIdentifier.of("sharedValues");
+ private static final JavaIdentifier ENCODER_ENCODE_METHOD_NAME = JavaIdentifier.of("encode");
+ private static final JavaIdentifier DECODE_DECODE_METHOD_NAME = JavaIdentifier.of("decode");
public static OutputConfig parseGeneratorConfig(
Path projectRoot,
@@ -171,7 +174,7 @@ public class JavaTransient0Generator implements Generator {
private JavaCompilationUnit generateEncoderType() {
return new JavaCompilationUnit(new JavaInterfaceDeclaration(
- encoderRef(),
+ encoderTypeRef(),
JavaInterfaceOpenness.OPEN,
List.of(
new JavaTypeParameter(JavaIdentifier.of("T"))
@@ -179,7 +182,7 @@ public class JavaTransient0Generator implements Generator {
List.of(),
List.of(
new JavaMethodDeclaration(
- JavaIdentifier.of("encode"),
+ ENCODER_ENCODE_METHOD_NAME,
JavaVisibility.PUBLIC,
JavaMemberKind.INSTANCE,
List.of(),
@@ -201,7 +204,7 @@ public class JavaTransient0Generator implements Generator {
);
}
- private JavaTypeRef encoderRef() {
+ private JavaTypeRef encoderTypeRef() {
var packageName = this.namespaceToJavaTransient0PackageName(NamespaceName.of());
return JavaTypeRef.topLevel(
@@ -210,9 +213,13 @@ public class JavaTransient0Generator implements Generator {
);
}
+ private JavaTypeRef encoderTypeRef(JavaTypeRef valueType) {
+ return encoderTypeRef().withArgs(List.of(JavaTypeArg.invariant(valueType)));
+ }
+
private JavaCompilationUnit generateDecoderType() {
return new JavaCompilationUnit(new JavaInterfaceDeclaration(
- decoderRef(),
+ decoderTypeRef(),
JavaInterfaceOpenness.OPEN,
List.of(
new JavaTypeParameter(JavaIdentifier.of("T"))
@@ -220,7 +227,7 @@ public class JavaTransient0Generator implements Generator {
List.of(),
List.of(
new JavaMethodDeclaration(
- JavaIdentifier.of("decode"),
+ DECODE_DECODE_METHOD_NAME,
JavaVisibility.PUBLIC,
JavaMemberKind.INSTANCE,
List.of(),
@@ -241,7 +248,7 @@ public class JavaTransient0Generator implements Generator {
);
}
- private JavaTypeRef decoderRef() {
+ private JavaTypeRef decoderTypeRef() {
var packageName = this.namespaceToJavaTransient0PackageName(NamespaceName.of());
return JavaTypeRef.topLevel(
@@ -250,6 +257,10 @@ public class JavaTransient0Generator implements Generator {
);
}
+ private JavaTypeRef decoderTypeRef(JavaTypeRef valueType) {
+ return decoderTypeRef().withArgs(List.of(JavaTypeArg.invariant(valueType)));
+ }
+
private List<JavaCompilationUnit> generateBuiltins(Context context) {
var packageName = this.namespaceToJavaTransient0PackageName(NamespaceName.of());
var transient0JavaName = generateTransient0ClassName("Builtins");
@@ -378,7 +389,7 @@ public class JavaTransient0Generator implements Generator {
}
private JavaMethodDeclaration generateDecodeIntMethod(
- Type type,
+ SimpleType type,
int bits
) {
var statements = new ArrayList<JavaBlockStatement>();
@@ -654,53 +665,70 @@ public class JavaTransient0Generator implements Generator {
TypedStructDefinitionNode structDefinition,
Context context
) {
- return generateEncodeMethod(
- structDefinition.typeOrThrow(),
- new JavaBlock(
- structDefinition.fields().orElse(List.of()).stream()
- .flatMap(field -> generateEncode(
- new JavaMethodCall(
- new JavaRef(VALUE_NAME),
- this.javaGenerator.generateFieldName(field.name()),
- List.of()
- ),
- field.type().value(),
- context
- ).stream())
- .toList()
- )
+ var fields = structDefinition.fields().orElse(List.of());
+
+ var encodeBody = new JavaBlock(
+ fields.stream()
+ .flatMap(field -> generateEncode(
+ new JavaMethodCall(
+ new JavaRef(VALUE_NAME),
+ this.javaGenerator.generateFieldName(field.name()),
+ List.of()
+ ),
+ field.type().value(),
+ context
+ ).stream())
+ .toList()
);
+
+
+ return switch (structDefinition.typeOrConstructor()) {
+ case TypeOrConstructor.Constructor<SimpleStructType> constructor ->
+ generateEncodeMethod(constructor.value(), encodeBody);
+
+ case TypeOrConstructor.Type<SimpleStructType> type ->
+ generateEncodeMethod(type.value(), encodeBody);
+ };
}
private JavaMethodDeclaration generateDecodeStructMethod(
TypedStructDefinitionNode structDefinition,
Context context
) {
- var structJavaTypeRef = this.javaGenerator.generateTypeRef(structDefinition.typeOrThrow());
-
- return generateDecodeMethod(
- structDefinition.typeOrThrow(),
- new JavaBlock(
- structDefinition.fields().isEmpty()
- ? List.of(new JavaReturn(
- new JavaStaticFieldAccess(structJavaTypeRef, JavaGenerator.INSTANCE_FIELD_NAME)
- ))
- : Stream.concat(
+ Function<JavaTypeRef, JavaBlock> decodeBody = structJavaTypeRef -> new JavaBlock(
+ structDefinition.fields().isEmpty()
+ ? List.of(new JavaReturn(
+ new JavaStaticFieldAccess(structJavaTypeRef, JavaGenerator.INSTANCE_FIELD_NAME)
+ ))
+ : Stream.concat(
+ structDefinition.fields().get().stream()
+ .flatMap(field -> generateDecode(
+ this.javaGenerator.generateFieldName(field.name()),
+ field.type().value(),
+ context
+ ).stream()),
+ Stream.of(new JavaReturn(new JavaNewExpression(
+ structJavaTypeRef,
structDefinition.fields().get().stream()
- .flatMap(field -> generateDecode(
- this.javaGenerator.generateFieldName(field.name()),
- field.type().value(),
- context
- ).stream()),
- Stream.of(new JavaReturn(new JavaNewExpression(
- structJavaTypeRef,
- structDefinition.fields().get().stream()
- .<JavaExpression>map(field -> new JavaRef(this.javaGenerator.generateFieldName(field.name())))
- .toList()
- )))
- ).toList()
- )
+ .<JavaExpression>map(field -> new JavaRef(this.javaGenerator.generateFieldName(field.name())))
+ .toList()
+ )))
+ ).toList()
);
+
+ return switch (structDefinition.typeOrConstructor()) {
+ case TypeOrConstructor.Constructor<SimpleStructType> constructor ->
+ generateDecodeMethod(
+ constructor.value(),
+ decodeBody
+ );
+
+ case TypeOrConstructor.Type<SimpleStructType> type ->
+ generateDecodeMethod(
+ type.value(),
+ decodeBody.apply(this.javaGenerator.generateTypeRef(type.value()))
+ );
+ };
}
private JavaMethodDeclaration generateEncodeSumMethod(
@@ -816,12 +844,57 @@ public class JavaTransient0Generator implements Generator {
);
}
+ private JavaMethodDeclaration generateEncodeMethod(
+ TypeConstructor<?> constructor,
+ JavaBlock body
+ ) {
+ var javaTypeParams = constructor.params().stream()
+ .map(typeParam -> new JavaTypeParameter(this.javaGenerator.generateTypeName(typeParam.name())))
+ .toList();
+
+ var javaTypeArgs = javaTypeParams.stream()
+ .map(javaTypeParam -> JavaTypeArg.invariant(JavaTypeRef.local(javaTypeParam.name())))
+ .toList();
+
+ var javaTypeRef = this.javaGenerator.generateTypeRef(constructor.genericType())
+ .withArgs(javaTypeArgs);
+
+ var typeArgEncoderParams = IntStream.range(0, constructor.params().size())
+ .mapToObj(typeParamIndex -> {
+ var typeParam = constructor.params().get(typeParamIndex);
+ var javaTypeParam = javaTypeParams.get(typeParamIndex);
+ return new JavaParam(
+ encoderTypeRef(JavaTypeRef.local(javaTypeParam.name())),
+ generateEncoderVariableName(typeParam)
+ );
+ })
+ .toList();
+
+ return new JavaMethodDeclaration(
+ encodeMethodName(constructor.genericType()),
+ JavaVisibility.PUBLIC,
+ JavaMemberKind.STATIC,
+ javaTypeParams,
+ JavaTypeRef.VOID,
+ Lists.concat(List.of(
+ generateEncodeParams(javaTypeRef),
+ typeArgEncoderParams
+ )),
+ List.of(JavaTypeRef.IO_EXCEPTION),
+ body
+ );
+ }
+
+ private JavaIdentifier generateEncoderVariableName(TypeParam typeParam) {
+ return JavaIdentifier.of("encoder$" + this.javaGenerator.generateTypeName(typeParam.name()).value());
+ }
+
private JavaTypeRef generateEncoderSharedValuesTypeRef() {
return JavaTypeRef.map(this.taggedSharedValueRef(), JavaTypeRef.LONG_BOXED);
}
private JavaMethodDeclaration generateDecodeMethod(
- Type type,
+ SimpleType type,
JavaBlock body
) {
var javaTypeRef = this.javaGenerator.generateTypeRef(type);
@@ -838,6 +911,51 @@ public class JavaTransient0Generator implements Generator {
);
}
+ private JavaMethodDeclaration generateDecodeMethod(
+ TypeConstructor<?> constructor,
+ Function<JavaTypeRef, JavaBlock> generateBody
+ ) {
+ var javaTypeParams = constructor.params().stream()
+ .map(typeParam -> new JavaTypeParameter(this.javaGenerator.generateTypeName(typeParam.name())))
+ .toList();
+
+ var javaTypeArgs = javaTypeParams.stream()
+ .map(javaTypeParam -> JavaTypeArg.invariant(JavaTypeRef.local(javaTypeParam.name())))
+ .toList();
+
+ var javaTypeRef = this.javaGenerator.generateTypeRef(constructor.genericType())
+ .withArgs(javaTypeArgs);
+
+ var typeArgDecoderParams = IntStream.range(0, constructor.params().size())
+ .mapToObj(typeParamIndex -> {
+ var typeParam = constructor.params().get(typeParamIndex);
+ var javaTypeParam = javaTypeParams.get(typeParamIndex);
+ return new JavaParam(
+ decoderTypeRef(JavaTypeRef.local(javaTypeParam.name())),
+ generateDecoderVariableName(typeParam)
+ );
+ })
+ .toList();
+
+ return new JavaMethodDeclaration(
+ decodeMethodName(constructor.genericType()),
+ JavaVisibility.PUBLIC,
+ JavaMemberKind.STATIC,
+ javaTypeParams,
+ javaTypeRef,
+ Lists.concat(List.of(
+ generateDecodeParams(),
+ typeArgDecoderParams
+ )),
+ List.of(JavaTypeRef.IO_EXCEPTION),
+ generateBody.apply(javaTypeRef)
+ );
+ }
+
+ private JavaIdentifier generateDecoderVariableName(TypeParam typeParam) {
+ return JavaIdentifier.of("decoder$" + this.javaGenerator.generateTypeName(typeParam.name()).value());
+ }
+
private static JavaTypeRef generateDecoderSharedValuesType() {
return JavaTypeRef.list(JavaTypeRef.OBJECT);
}
@@ -880,8 +998,16 @@ public class JavaTransient0Generator implements Generator {
throw new UnsupportedOperationException("TODO");
}
- case TypeParam _ -> {
- throw new UnsupportedOperationException("TODO");
+ case TypeParam typeParam -> {
+ yield List.of(new JavaExpressionStatement(new JavaMethodCall(
+ new JavaRef(generateEncoderVariableName(typeParam)),
+ ENCODER_ENCODE_METHOD_NAME,
+ List.of(
+ value,
+ new JavaRef(OUTPUT_STREAM_NAME),
+ new JavaRef(SHARED_VALUES_NAME)
+ )
+ )));
}
};
}
@@ -1003,8 +1129,19 @@ public class JavaTransient0Generator implements Generator {
throw new UnsupportedOperationException("TODO");
}
- case TypeParam _ -> {
- throw new UnsupportedOperationException("TODO");
+ case TypeParam typeParam -> {
+ yield List.of(new JavaLocalVariableDeclaration(
+ Optional.empty(),
+ target,
+ Optional.of(new JavaMethodCall(
+ new JavaRef(generateDecoderVariableName(typeParam)),
+ DECODE_DECODE_METHOD_NAME,
+ List.of(
+ new JavaRef(INPUT_STREAM_NAME),
+ new JavaRef(SHARED_VALUES_NAME)
+ )
+ ))
+ ));
}
};
}