From 34257d6199fcd2fd6a3b37280ce78d5d2cebc084 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 12 Jan 2025 14:10:44 -0500 Subject: [PATCH] Merge pull request #543 from SentryMan/genericIssue Fix JsonB generic generation errors --- .../io/avaje/http/generator/core/Append.java | 13 ++++++ .../avaje/http/generator/core/JsonBUtil.java | 8 ++-- .../io/avaje/http/generator/core/UType.java | 17 ++++++- .../http/generator/core/JsonBUtilTest.java | 46 +++++++++++++++++++ .../myapp/web/test/GenericController.java | 27 +++++++++++ 5 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 http-generator-core/src/test/java/io/avaje/http/generator/core/JsonBUtilTest.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/GenericController.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Append.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Append.java index 90f89beca..0210f5ec9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Append.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Append.java @@ -8,7 +8,10 @@ */ public class Append { + private static final boolean DEBUG = Boolean.getBoolean("append.debug"); + private final Writer writer; + private final StringBuilder stringBuilder = new StringBuilder(); public Append(Writer writer) { this.writer = writer; @@ -17,6 +20,9 @@ public Append(Writer writer) { public Append append(String content) { try { writer.append(content); + if (DEBUG) { + stringBuilder.append(content); + } return this; } catch (IOException e) { throw new RuntimeException(e); @@ -35,6 +41,9 @@ public void close() { public Append eol() { try { writer.append("\n"); + if (DEBUG) { + stringBuilder.append("\n"); + } return this; } catch (IOException e) { throw new RuntimeException(e); @@ -48,4 +57,8 @@ public Append append(String format, Object... args) { return append(String.format(format, args)); } + @Override + public String toString() { + return stringBuilder.toString(); + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 212600c96..2a33c04a9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -86,12 +86,14 @@ public static void writeJsonbType(UType type, Append writer) { static void writeType(UType type, Append writer) { if (type.isGeneric()) { final var params = - type.importTypes().stream() - .skip(1) + type.params().stream() .map(Util::shortName) + .map(s -> "?".equals(s) ? "Object" : s) .collect(Collectors.joining(".class, ")); - writer.append("Types.newParameterizedType(%s.class, %s.class))", Util.shortName(type.mainType()), params); + writer.append( + "Types.newParameterizedType(%s.class, %s.class))", + Util.shortName(type.mainType()), params); } else { writer.append("%s.class)", Util.shortName(type.mainType())); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index 24738fdb3..460a3bcc2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -1,6 +1,9 @@ package io.avaje.http.generator.core; import javax.lang.model.type.TypeMirror; + +import static java.util.stream.Collectors.toList; + import java.util.*; public interface UType { @@ -69,6 +72,13 @@ default UType paramRaw() { return null; } + /** + * Return the first generic parameter. + */ + default List params() { + return List.of(); + } + /** * Return the raw type. */ @@ -275,7 +285,7 @@ public String shortType() { @Override public String shortName() { - return shortName.replace(".", "$"); + return shortName.replace(".", "$").replace("?", "Object"); } @Override @@ -293,6 +303,11 @@ public String param1() { return allTypes.size() < 3 ? null : allTypes.get(2); } + @Override + public List params() { + return allTypes.stream().skip(1).collect(toList()); + } + @Override public UType paramRaw() { return rawParamType; diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/JsonBUtilTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/JsonBUtilTest.java new file mode 100644 index 000000000..838e20313 --- /dev/null +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/JsonBUtilTest.java @@ -0,0 +1,46 @@ +package io.avaje.http.generator.core; + +import org.junit.jupiter.api.Test; + +import java.io.StringWriter; + +import static org.assertj.core.api.Assertions.assertThat; + +class JsonBUtilTest { + + @Test + void writeType() { + UType uType = UType.parse("my.pack.Foo"); + var sw = new StringWriter(); + JsonBUtil.writeType(uType, new Append(sw)); + + assertThat(sw.toString()).isEqualTo("Foo.class)"); + } + + @Test + void writeType_generic() { + UType uType = UType.parse("my.pack.Some"); + var sw = new StringWriter(); + JsonBUtil.writeType(uType, new Append(sw)); + + assertThat(sw.toString()).isEqualTo("Types.newParameterizedType(Some.class, String.class))"); + } + + @Test + void writeType_genericWithWildcard() { + UType uType = UType.parse("my.pack.Some"); + var sw = new StringWriter(); + JsonBUtil.writeType(uType, new Append(sw)); + + assertThat(sw.toString()).isEqualTo("Types.newParameterizedType(Some.class, String.class, Object.class))"); + } + + @Test + void writeType_genericWithMultiple() { + UType uType = UType.parse("my.pack.Some"); + var sw = new StringWriter(); + JsonBUtil.writeType(uType, new Append(sw)); + + assertThat(sw.toString()).isEqualTo("Types.newParameterizedType(Some.class, String.class, Foo.class))"); + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/GenericController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/GenericController.java new file mode 100644 index 000000000..08f8c7669 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/GenericController.java @@ -0,0 +1,27 @@ +package org.example.myapp.web.test; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.jsonb.Json; + +@Path("/jsonbGeneric") +@Controller +public class GenericController { + + @Json + public static class Data {} + + @Json + public static class Data2 {} + + @Get("single") + Data getData() { + return null; + } + + @Get("double") + Data2 getData2() { + return null; + } +}