Skip to content

Fix JsonB generic generation errors #543

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -48,4 +57,8 @@ public Append append(String format, Object... args) {
return append(String.format(format, args));
}

@Override
public String toString() {
return stringBuilder.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -69,6 +72,13 @@ default UType paramRaw() {
return null;
}

/**
* Return the first generic parameter.
*/
default List<String> params() {
return List.of();
}

/**
* Return the raw type.
*/
Expand Down Expand Up @@ -275,7 +285,7 @@ public String shortType() {

@Override
public String shortName() {
return shortName.replace(".", "$");
return shortName.replace(".", "$").replace("?", "Object");
}

@Override
Expand All @@ -293,6 +303,11 @@ public String param1() {
return allTypes.size() < 3 ? null : allTypes.get(2);
}

@Override
public List<String> params() {
return allTypes.stream().skip(1).collect(toList());
}

@Override
public UType paramRaw() {
return rawParamType;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<java.lang.String>");
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<java.lang.String, ?>");
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<java.lang.String, my.other.Foo>");
var sw = new StringWriter();
JsonBUtil.writeType(uType, new Append(sw));

assertThat(sw.toString()).isEqualTo("Types.newParameterizedType(Some.class, String.class, Foo.class))");
}
}
Original file line number Diff line number Diff line change
@@ -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<T> {}

@Json
public static class Data2<T, T2> {}

@Get("single")
Data<String> getData() {
return null;
}

@Get("double")
Data2<String, ?> getData2() {
return null;
}
}
Loading