diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-06-30 21:23:51 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-06-30 21:23:51 +0100 |
| commit | d0c6cc5511f5b953ca1a4184e6c7b903e4bb7450 (patch) | |
| tree | 5ed9f5bc8227f42fe6076779135f85794132537b /src/main/java/org | |
| parent | e69e58c00f1f7e64dc0bcfb1694564c6f4e8486a (diff) | |
Fully qualify Rust type expressions
Diffstat (limited to 'src/main/java/org')
2 files changed, 58 insertions, 12 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java index 776e401..c4af4e7 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java @@ -14,6 +14,7 @@ import org.zwobble.json5.reader.Json5ObjectReader; import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -39,7 +40,8 @@ public class RustTypesGenerator implements Generator { @Override public void generate(List<TypedNamespaceNode> namespaces, TypesInfo typesInfo) throws IOException { for (var namespace : namespaces) { - var rustModule = generateNamespace(namespace); + var context = new Context(namespace.namespaceName()); + var rustModule = generateNamespace(namespace, context); write(rustModule); } @@ -56,11 +58,11 @@ public class RustTypesGenerator implements Generator { } } - private RustModule generateNamespace(TypedNamespaceNode namespace) { + private RustModule generateNamespace(TypedNamespaceNode namespace, Context context) { var rustModuleName = generateNamespaceName(namespace.namespaceName()); var rustItems = namespace.body().stream() - .flatMap(statement -> generateNamespaceStatement(statement).stream()) + .flatMap(statement -> generateNamespaceStatement(statement, context).stream()) .toList(); return new RustModule(rustModuleName, rustItems); @@ -72,7 +74,10 @@ public class RustTypesGenerator implements Generator { .toList(); } - private List<RustItem> generateNamespaceStatement(TypedNamespaceStatementNode statement) { + private List<RustItem> generateNamespaceStatement( + TypedNamespaceStatementNode statement, + Context context + ) { return switch (statement) { case TypedEnumDefinitionNode enumDefinition -> { yield List.of(); @@ -86,7 +91,10 @@ public class RustTypesGenerator implements Generator { var rustStructName = generateTypeName(structDefinition.name()); var rustFields = structDefinition.fields().stream() - .map(field -> new RustStructField(generateFieldName(field.name()), generateRustTypeExpression(field.type()))) + .map(field -> new RustStructField( + generateFieldName(field.name()), + generateRustTypeExpression(field.type(), context) + )) .toList(); var rustStruct = new RustStructStruct(rustStructName, rustFields, structDefinition.docComment()); @@ -100,17 +108,23 @@ public class RustTypesGenerator implements Generator { }; } - private RustType generateRustTypeExpression(TypedTypeLevelExpressionNode<Type> type) { - return generateRustTypeExpression(type.value()); + private RustType generateRustTypeExpression( + TypedTypeLevelExpressionNode<Type> type, + Context context + ) { + return generateRustTypeExpression(type.value(), context); } - private RustType generateRustTypeExpression(Type type) { + private RustType generateRustTypeExpression(Type type, Context context) { return switch (type) { case ConstructedNativeType constructedNativeType -> { // TODO: avoid cast - var rustType = (RustTypePath) generateRustTypeExpression(constructedNativeType.constructor().genericType()); + var rustType = (RustTypePath) generateRustTypeExpression( + constructedNativeType.constructor().genericType(), + context + ); var rustArgs = constructedNativeType.args().stream() - .map(arg -> generateRustTypeExpression(arg)) + .map(arg -> generateRustTypeExpression(arg, context)) .toList(); yield rustType.withArgs(rustArgs); } @@ -126,8 +140,11 @@ public class RustTypesGenerator implements Generator { } case StructType structType -> { - // TODO: qualify name - yield RustTypePath.of(generateTypeName(structType.name())); + yield generateTypePath( + structType.namespaceName(), + structType.name(), + context + ); } case SumType sumType -> { @@ -144,6 +161,23 @@ public class RustTypesGenerator implements Generator { }; } + private RustType generateTypePath(NamespaceName namespaceName, String typeName, Context context) { + var segments = new ArrayList<RustTypePathSegment>(); + // TODO: use crate as a keyword, not an identifier + segments.add(RustTypePathSegment.of(new RustIdentifier("crate"))); + for (var moduleName : this.namespaceNameToRustCrateModulePath(namespaceName)) { + segments.add(RustTypePathSegment.of(moduleName)); + } + segments.add(RustTypePathSegment.of(generateTypeName(typeName))); + return new RustTypePath(segments); + } + + private List<RustIdentifier> namespaceNameToRustCrateModulePath(NamespaceName namespaceName) { + return namespaceName.parts().stream() + .map(part -> generateModuleName(part)) + .toList(); + } + private RustIdentifier generateFieldName(String fieldName) { return new RustIdentifier(Casing.lowerCamelCaseToSnakeCase(fieldName)); } @@ -155,4 +189,12 @@ public class RustTypesGenerator implements Generator { private RustIdentifier generateModuleName(String part) { return new RustIdentifier(Casing.lowerCamelCaseToSnakeCase(part)); } + + private static class Context { + private final NamespaceName currentNamespaceName; + + private Context(NamespaceName currentNamespaceName) { + this.currentNamespaceName = currentNamespaceName; + } + } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java index 4473aa3..78348c5 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java @@ -35,6 +35,10 @@ public record RustTypePathSegment(org.zwobble.hobgoblin.compiler.output.lang.rus } // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment body + public static RustTypePathSegment of(RustIdentifier name) { + return new RustTypePathSegment(new RustPathIdentSegmentIdentifier(name), Optional.empty()); + } + public RustTypePathSegment withArgs(List<RustType> args) { if (this.args.isPresent()) { throw new IllegalArgumentException("Type path segment already has args"); |
