Skip to content

Commit 6ff90a2

Browse files
committed
improve constructor detection
1 parent 029de5d commit 6ff90a2

File tree

3 files changed

+80
-12
lines changed

3 files changed

+80
-12
lines changed

jsonb-generator/src/main/java/io/avaje/jsonb/generator/FieldReader.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ final class FieldReader {
1010

1111
private final Map<String, TypeSubTypeMeta> subTypes = new LinkedHashMap<>();
1212

13+
private final Element element;
1314
private final FieldProperty property;
1415
private final String propertyName;
1516
private final boolean serialize;
@@ -34,13 +35,13 @@ final class FieldReader {
3435
}
3536

3637
FieldReader(
37-
Element element,
38-
NamingConvention namingConvention,
39-
TypeSubTypeMeta subType,
40-
List<String> genericTypeParams,
41-
Integer frequency,
42-
boolean jsonCreatorPresent) {
43-
38+
Element element,
39+
NamingConvention namingConvention,
40+
TypeSubTypeMeta subType,
41+
List<String> genericTypeParams,
42+
Integer frequency,
43+
boolean jsonCreatorPresent) {
44+
this.element = element;
4445
num = frequency == 0 ? "" : frequency.toString();
4546
addSubType(subType);
4647
var isMethod = element instanceof ExecutableElement;
@@ -296,4 +297,7 @@ List<String> aliases() {
296297
return aliases;
297298
}
298299

300+
public Element element() {
301+
return element;
302+
}
299303
}

jsonb-generator/src/main/java/io/avaje/jsonb/generator/TypeReader.java

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import javax.lang.model.type.TypeMirror;
55
import javax.lang.model.util.ElementFilter;
66

7+
import static java.util.stream.Collectors.toSet;
8+
79
import java.util.*;
810
import java.util.function.Supplier;
911
import java.util.stream.Collectors;
@@ -304,13 +306,17 @@ private void matchFieldsToSetterOrConstructor() {
304306
}
305307

306308
private void matchFieldToSetter(FieldReader field) {
307-
if (!matchFieldToSetter2(field, false)
309+
if (hasNoSetter(field)) {
310+
logError("Non public field " + baseType + " " + field.fieldName() + " with no matching setter or constructor?");
311+
}
312+
}
313+
314+
private boolean hasNoSetter(FieldReader field) {
315+
return !matchFieldToSetter2(field, false)
308316
&& !matchFieldToSetter2(field, true)
309317
&& !matchFieldToSetterByParam(field)
310318
&& !field.isPublicField()
311-
&& !field.isSubTypeField()) {
312-
logError("Non public field " + baseType + " " + field.fieldName() + " with no matching setter or constructor?");
313-
}
319+
&& !field.isSubTypeField();
314320
}
315321

316322
private boolean matchFieldToSetterByParam(FieldReader field) {
@@ -458,7 +464,29 @@ private MethodReader determineConstructor() {
458464
// fallback to the single public constructor
459465
return allPublic.get(0);
460466
}
461-
// find the largest constructor
467+
468+
// find the right constructor
469+
var contructorFields =
470+
allFields.stream()
471+
.filter(FieldReader::includeFromJson)
472+
.filter(this::hasNoSetter)
473+
.map(f -> f.element().asType().toString())
474+
.map(Util::trimAnnotations)
475+
.collect(toSet());
476+
477+
return allPublic.stream()
478+
.filter(c -> c.getParams().size() == contructorFields.size())
479+
.filter(
480+
c ->
481+
c.getParams().stream()
482+
.map(p -> p.element().asType().toString())
483+
.map(Util::trimAnnotations)
484+
.allMatch(contructorFields::contains))
485+
.findFirst()
486+
.orElseGet(this::largest);
487+
}
488+
489+
private MethodReader largest() {
462490
int argCount = 0;
463491
MethodReader largestConstructor = null;
464492
for (MethodReader ctor : publicConstructors) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package io.avaje.jsonb.generator.models.valid;
2+
3+
import java.util.List;
4+
5+
import io.avaje.jsonb.Json;
6+
7+
@Json
8+
public class MultiConstruct {
9+
10+
private final List<String> body;
11+
private String setter;
12+
13+
public MultiConstruct(String string) {
14+
this(List.of(string));
15+
}
16+
17+
public MultiConstruct(List<String> body) {
18+
this.body = body;
19+
}
20+
21+
public MultiConstruct(List<String> body, int somethin) {
22+
this.body = body;
23+
}
24+
25+
public String getSetter() {
26+
return setter;
27+
}
28+
29+
public void setSetter(String setter) {
30+
this.setter = setter;
31+
}
32+
33+
public List<String> getBody() {
34+
return body;
35+
}
36+
}

0 commit comments

Comments
 (0)