From 77e52091031154fc7d09875eea8b67f2e394eda6 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 9 Aug 2026 21:41:40 +0100 Subject: Allow type constructor in TypedStructDefinitionNode --- .../compiler/ast/typed/TypedStructDefinitionNode.java | 15 +++++++++++++-- .../JavaPreciselyMatchersGenerator.java | 2 +- .../javatransient0/JavaTransient0Generator.java | 6 +++--- .../output/generators/javatypes/JavaTypesGenerator.java | 8 ++++---- .../rusttransient0/RustTransient0Generator.java | 6 +++--- .../hobgoblin/compiler/typechecker/TypeChecker.java | 2 +- .../hobgoblin/compiler/types/TypeOrConstructor.java | 8 ++++++++ .../compiler/typechecker/TypeCheckerNamespaceTests.java | 4 ++-- .../typechecker/TypeCheckerStructDefinitionTests.java | 2 +- 9 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedStructDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedStructDefinitionNode.java index 2c85f6d..c956e2c 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedStructDefinitionNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedStructDefinitionNode.java @@ -3,17 +3,28 @@ package org.zwobble.hobgoblin.compiler.ast.typed; import org.zwobble.hobgoblin.compiler.ast.DocComment; import org.zwobble.hobgoblin.compiler.sources.Source; import org.zwobble.hobgoblin.compiler.types.SimpleStructType; +import org.zwobble.hobgoblin.compiler.types.TypeOrConstructor; import java.util.List; import java.util.Optional; public record TypedStructDefinitionNode( - SimpleStructType type, + TypeOrConstructor typeOrConstructor, Optional> fields, DocComment docComment, Source source ) implements TypedNamespaceStatementNode { + public SimpleStructType typeOrThrow() { + return switch (typeOrConstructor) { + case TypeOrConstructor.Constructor constructor -> + throw new UnsupportedOperationException("TODO"); + + case TypeOrConstructor.Type type -> + type.value(); + }; + } + public String name() { - return this.type.name(); + return this.typeOrConstructor.name(); } } 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 926e53d..dfded67 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 @@ -89,7 +89,7 @@ public class JavaPreciselyMatchersGenerator implements Generator { TypedStructDefinitionNode structDefinition, Context context ) { - var structType = structDefinition.type(); + var structType = structDefinition.typeOrThrow(); var javaStructTypeRef = this.javaGenerator.generateTypeRef(structType); 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 1cc95f5..a8e4972 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 @@ -648,7 +648,7 @@ public class JavaTransient0Generator implements Generator { Context context ) { return generateEncodeMethod( - structDefinition.type(), + structDefinition.typeOrThrow(), new JavaBlock( structDefinition.fields().orElse(List.of()).stream() .flatMap(field -> generateEncode( @@ -669,10 +669,10 @@ public class JavaTransient0Generator implements Generator { TypedStructDefinitionNode structDefinition, Context context ) { - var structJavaTypeRef = this.javaGenerator.generateTypeRef(structDefinition.type()); + var structJavaTypeRef = this.javaGenerator.generateTypeRef(structDefinition.typeOrThrow()); return generateDecodeMethod( - structDefinition.type(), + structDefinition.typeOrThrow(), new JavaBlock( structDefinition.fields().isEmpty() ? List.of(new JavaReturn( diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java index 9ba7397..3dcbd61 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java @@ -123,7 +123,7 @@ public class JavaTypesGenerator implements Generator { TypedStructDefinitionNode structDefinition, Context context ) { - var javaTypeRef = generateTypeRef(structDefinition.type(), context); + var javaTypeRef = generateTypeRef(structDefinition.typeOrThrow(), context); var components = structDefinition.fields().orElse(List.of()).stream() .map(field -> new JavaRecordComponent( @@ -132,11 +132,11 @@ public class JavaTypesGenerator implements Generator { )) .toList(); - var implementsTypes = context.variantOf(structDefinition.type()).stream() + var implementsTypes = context.variantOf(structDefinition.typeOrThrow()).stream() .map(sumType -> this.generateTypeRef(sumType, context)) .toList(); - var builderJavaTypeRef = generateBuilderTypeRef(structDefinition.type()); + var builderJavaTypeRef = generateBuilderTypeRef(structDefinition.typeOrThrow()); var arbitraryValueExpression = new JavaNewExpression( builderJavaTypeRef, @@ -208,7 +208,7 @@ public class JavaTypesGenerator implements Generator { List components, Context context ) { - var structType = structDefinition.type(); + var structType = structDefinition.typeOrThrow(); var builderJavaTypeRef = generateBuilderTypeRef(structType); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java index b2319d6..421366f 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java @@ -443,7 +443,7 @@ public class RustTransient0Generator implements Generator { private RustItem generateEncodeStructFunction(TypedStructDefinitionNode structDefinition) { return generateEncodeFunction( - structDefinition.type(), + structDefinition.typeOrThrow(), structDefinition.fields().orElse(List.of()).stream() .map(field -> generateEncode( new RustPrefixExpression( @@ -460,10 +460,10 @@ public class RustTransient0Generator implements Generator { } private RustItem generateDecodeStructFunction(TypedStructDefinitionNode structDefinition) { - var rustType = this.rustGenerator.generateRustTypeExpression(structDefinition.type()); + var rustType = this.rustGenerator.generateRustTypeExpression(structDefinition.typeOrThrow()); return generateDecodeFunction( - structDefinition.type(), + structDefinition.typeOrThrow(), structDefinition.fields().isEmpty() ? new RustBlockExpression(List.of(), Optional.of(rustType)) : new RustBlockExpression( diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java index 3aac97f..90b95b2 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -239,7 +239,7 @@ public class TypeChecker { } return new TypedStructDefinitionNode( - structType, + TypeOrConstructor.type(structType), typedFieldNodes, untyped.docComment(), untyped.source() diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java index 8844669..3cffbc6 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java @@ -1,6 +1,14 @@ package org.zwobble.hobgoblin.compiler.types; public sealed interface TypeOrConstructor { + static TypeOrConstructor type(T value) { + return new Type<>(value); + } + + static TypeOrConstructor constructor(TypeConstructor value) { + return new Constructor<>(value); + } + record Type(T value) implements TypeOrConstructor { @Override public String name() { diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java index 9545bce..01bf3c4 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java @@ -40,7 +40,7 @@ public class TypeCheckerNamespaceTests { TypedStructDefinitionNode.class, has( "type", - TypedStructDefinitionNode::type, + TypedStructDefinitionNode::typeOrThrow, equalTo(new SimpleStructType(NamespaceName.of("a", "b"), "X")) ) ) @@ -92,7 +92,7 @@ public class TypeCheckerNamespaceTests { TypedStructDefinitionNode.class, has( "type", - TypedStructDefinitionNode::type, + TypedStructDefinitionNode::typeOrThrow, equalTo(new SimpleStructType(NamespaceName.of("a", "b"), "X")) ) ) diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java index 905ff32..9bdf9f8 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java @@ -35,7 +35,7 @@ public class TypeCheckerStructDefinitionTests { TypedStructDefinitionNode.class, has( "type", - TypedStructDefinitionNode::type, + TypedStructDefinitionNode::typeOrThrow, equalTo(new SimpleStructType(NamespaceName.of("a", "b"), "X")) ) )); -- cgit v1.2.3