diff options
6 files changed, 67 insertions, 10 deletions
diff --git a/hobgoblin/src/output/lang/rust/ast.hob b/hobgoblin/src/output/lang/rust/ast.hob index ab64a91..9a5fb17 100644 --- a/hobgoblin/src/output/lang/rust/ast.hob +++ b/hobgoblin/src/output/lang/rust/ast.hob @@ -36,6 +36,7 @@ struct RustTypePath { struct RustTypePathSegment { field pathIdentSegment: RustPathIdentSegment; + field args: Option[List[RustType]]; } sum RustPathIdentSegment { diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java index 9153d83..6cd67c6 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java @@ -110,6 +110,16 @@ public class RustWriter implements AutoCloseable { private void writeTypePathSegment(RustTypePathSegment segment) throws IOException { writePathIdentSegment(segment.pathIdentSegment()); + + if (segment.args().isPresent()) { + this.writer.write("<"); + writeWithSeparator( + segment.args().get(), + this::writeType, + () -> this.writer.write(", ") + ); + this.writer.write(">"); + } } private void writePathIdentSegment(RustPathIdentSegment pathIdentSegment) throws IOException { diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java index c55b53d..9b44334 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java @@ -3,8 +3,10 @@ package org.zwobble.hobgoblin.compiler.output.lang.rust.ast; // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath imports +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath imports public record RustTypePath(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment> segments) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType { @@ -28,22 +30,38 @@ public record RustTypePath(java.util.List<org.zwobble.hobgoblin.compiler.output. // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath body public static RustTypePath primitive(String name) { return new RustTypePath(List.of( - new RustTypePathSegment(new RustPathIdentSegmentIdentifier(new RustIdentifier(name))) + new RustTypePathSegment( + new RustPathIdentSegmentIdentifier(new RustIdentifier(name)), + Optional.empty() + ) )); } - public static RustType of(String... names) { + public static RustTypePath of(String... names) { var segments = Arrays.stream(names) - .map(name -> new RustTypePathSegment(new RustPathIdentSegmentIdentifier(new RustIdentifier(name)))) + .map(name -> new RustTypePathSegment( + new RustPathIdentSegmentIdentifier(new RustIdentifier(name)), + Optional.empty() + )) .toList(); return new RustTypePath(segments); } public static RustType of(RustIdentifier... names) { var segments = Arrays.stream(names) - .map(name -> new RustTypePathSegment(new RustPathIdentSegmentIdentifier(name))) + .map(name -> new RustTypePathSegment( + new RustPathIdentSegmentIdentifier(name), + Optional.empty() + )) .toList(); return new RustTypePath(segments); } + + public RustType withArgs(List<RustType> args) { + var segments = new ArrayList<>(this.segments); + var lastSegment = segments.removeLast().withArgs(args); + segments.add(lastSegment); + return new RustTypePath(segments); + } // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath body } 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 cbd1c69..4473aa3 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 @@ -5,22 +5,29 @@ package org.zwobble.hobgoblin.compiler.output.lang.rust.ast; // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment imports // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment imports -public record RustTypePathSegment(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment) { +import java.util.List; +import java.util.Optional; + +public record RustTypePathSegment(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment, java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType>> args) { public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder arbitrary() { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.arbitrary().build()); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.arbitrary().build(), java.util.Optional.empty()); } - public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment) { + public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment, java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType>> args) { public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment build() { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment(pathIdentSegment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment(pathIdentSegment, args); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder withPathIdentSegment(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment, args); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder withPathIdentSegment(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment.Builder pathIdentSegment) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment.build()); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment.build(), args); + } + + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder withArgs(java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType>> args) { + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment, args); } // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder body @@ -28,5 +35,12 @@ public record RustTypePathSegment(org.zwobble.hobgoblin.compiler.output.lang.rus } // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment body + public RustTypePathSegment withArgs(List<RustType> args) { + if (this.args.isPresent()) { + throw new IllegalArgumentException("Type path segment already has args"); + } + + return new RustTypePathSegment(this.pathIdentSegment, Optional.of(args)); + } // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment body } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java index eca8685..f52d275 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java @@ -95,6 +95,16 @@ public class RustWriterTests { assertThat(string, equalTo("std::string::String")); } + @Test + public void typeSegmentGenericArgsAreWritten() throws IOException { + var rust = RustTypePath.of("std", "collections", "HashMap") + .withArgs(List.of(RustTypePath.of("i32"), RustTypePath.of("f64"))); + + var string = write(writer -> writer.writeType(rust)); + + assertThat(string, equalTo("std::collections::HashMap<i32, f64>")); + } + private String write(Write write) throws IOException { return write(write, Optional.empty()); } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java index 4a73997..ebefac9 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java @@ -32,6 +32,10 @@ public class RustTypePathSegmentMatcher implements org.zwobble.precisely.Matcher return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("pathIdentSegment", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment::pathIdentSegment, pathIdentSegment))).toList()); } + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher withArgs(org.zwobble.precisely.Matcher<? super java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType>>> args) { + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("args", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment::args, args))).toList()); + } + // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher body // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher body } |
