Skip to content

Commit 5d6344c

Browse files
committed
feat: add support for generic setter based beans
1 parent a5e51f5 commit 5d6344c

File tree

5 files changed

+68
-9
lines changed

5 files changed

+68
-9
lines changed

src/main/java/com/code_intelligence/jazzer/mutation/mutator/aggregate/AggregatesHelper.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,8 @@ static Optional<SerializingMutator<?>> createMutator(
9494
getters.length, setters.length));
9595
for (int i = 0; i < getters.length; i++) {
9696
Preconditions.check(
97-
getters[i]
98-
.getAnnotatedReturnType()
99-
.getType()
100-
.equals(setters[i].getAnnotatedParameterTypes()[0].getType()),
97+
resolveReturnType(getters[i], initialType)
98+
.equals(resolveParameterTypes(setters[i], initialType)[0]),
10199
String.format(
102100
"Parameter of %s does not match return type of %s", setters[i], getters[i]));
103101
}
@@ -107,7 +105,7 @@ static Optional<SerializingMutator<?>> createMutator(
107105
return createMutator(
108106
factory,
109107
newInstance.getDeclaringClass(),
110-
parameterTypes(setters),
108+
parameterTypes(setters, initialType),
111109
asInstantiationFunction(lookup, newInstance, setters),
112110
makeSingleGetter(unreflectMethods(lookup, getters)),
113111
initialType,
@@ -220,9 +218,9 @@ private static <R> Function<Object[], R> asInstantiatorFunction(
220218
}
221219
}
222220

223-
static AnnotatedType[] parameterTypes(Method[] methods) {
221+
static AnnotatedType[] parameterTypes(Method[] methods, AnnotatedType classType) {
224222
return stream(methods)
225-
.map(Method::getAnnotatedParameterTypes)
223+
.map(m -> resolveAnnotatedParameterTypes(m, classType))
226224
.flatMap(Arrays::stream)
227225
.toArray(AnnotatedType[]::new);
228226
}

src/main/java/com/code_intelligence/jazzer/mutation/mutator/aggregate/SetterBasedBeanMutatorFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ clazz, stream(setters).map(BeanSupport::toPropertyName))
5656
getters,
5757
type,
5858
stream(setters)
59-
.map(setter -> setter.getAnnotatedParameterTypes()[0].getType())
59+
.map(setter -> resolveParameterTypes(setter, type)[0])
6060
.toArray(Type[]::new)))
6161
.flatMap(
6262
getters ->

src/main/java/com/code_intelligence/jazzer/mutation/mutator/aggregate/SuperBuilderMutatorFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public Optional<SerializingMutator<?>> tryCreate(
6969
return AggregatesHelper.createMutator(
7070
factory,
7171
clazz,
72-
parameterTypes(builderSetters),
72+
parameterTypes(builderSetters, type),
7373
fromParametersToObject,
7474
fromObjectToParameters,
7575
type,

src/test/java/com/code_intelligence/jazzer/mutation/mutator/StressTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,38 @@ public String toString() {
363363
}
364364
}
365365

366+
public static class GenericImmutableBuilder<T> {
367+
private final T t;
368+
369+
public GenericImmutableBuilder() {
370+
t = null;
371+
}
372+
373+
private GenericImmutableBuilder(T t) {
374+
this.t = t;
375+
}
376+
377+
public T getT() {
378+
return t;
379+
}
380+
381+
public GenericImmutableBuilder<T> setT(T t) {
382+
return new GenericImmutableBuilder<T>(t);
383+
}
384+
385+
@Override
386+
public boolean equals(Object o) {
387+
if (this == o) return true;
388+
if (o == null || getClass() != o.getClass()) return false;
389+
return Objects.equals(t, ((GenericImmutableBuilder<?>) o).t);
390+
}
391+
392+
@Override
393+
public int hashCode() {
394+
return Objects.hash(t);
395+
}
396+
}
397+
366398
public static class ConstructorBasedBean {
367399
private final boolean foo;
368400
private final String bar;
@@ -914,6 +946,12 @@ void singleParam(int parameter) {}
914946
// Low due to int and boolean fields having very few common values during init.
915947
distinctElementsRatio(0.23),
916948
manyDistinctElements()),
949+
arguments(
950+
new TypeHolder<@NotNull GenericImmutableBuilder<@NotNull String>>() {}.annotatedType(),
951+
"[String] -> GenericImmutableBuilder",
952+
false,
953+
manyDistinctElements(),
954+
manyDistinctElements()),
917955
arguments(
918956
new TypeHolder<@NotNull ConstructorBasedBean>() {}.annotatedType(),
919957
"[Boolean, Nullable<String>, Integer] -> ConstructorBasedBean",

src/test/java/com/code_intelligence/jazzer/mutation/mutator/aggregate/SetterBasedBeanMutatorTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,27 @@ void propagateConstraint() {
223223
.isEqualTo(
224224
"[Integer, RecursionBreaking((cycle) -> RecursiveTypeBean)] -> RecursiveTypeBean");
225225
}
226+
227+
public static class Generic<T> {
228+
T t;
229+
230+
public Generic() {}
231+
232+
public void setT(T t) {
233+
this.t = t;
234+
}
235+
236+
public T getT() {
237+
return t;
238+
}
239+
}
240+
241+
@Test
242+
void genericClass() {
243+
SerializingMutator<Generic<String>> mutator =
244+
(SerializingMutator<Generic<String>>)
245+
Mutators.newFactory()
246+
.createOrThrow(new TypeHolder<Generic<String>>() {}.annotatedType());
247+
assertThat(mutator.toString()).isEqualTo("Nullable<[Nullable<String>] -> Generic>");
248+
}
226249
}

0 commit comments

Comments
 (0)