Skip to content

Commit 400f616

Browse files
committed
Make method static creator selection more conservative when generics are involved
1 parent 2d47527 commit 400f616

File tree

1 file changed

+23
-8
lines changed
  • utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/providers

1 file changed

+23
-8
lines changed

utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/providers/Objects.kt

+23-8
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ class ObjectValueProvider(
4747
description: FuzzedDescription,
4848
type: FuzzedType
4949
) = sequence {
50-
val classId = type.classId
51-
findAccessibleCreators(description, classId).forEach { creatorExecutableId ->
52-
yield(createValue(classId, creatorExecutableId, description))
50+
findAccessibleCreators(description, type).forEach { creatorExecutableId ->
51+
yield(createValue(type.classId, creatorExecutableId, description))
5352
}
5453
}
5554

@@ -164,7 +163,8 @@ class AbstractsObjectValueProvider(
164163
}
165164
val jClass = sc.id.jClass
166165
return isAccessible(jClass, description.description.packageName) &&
167-
findAccessibleCreators(description, jClass.id).any()
166+
findAccessibleCreators(description, toFuzzerType(jClass, description.typeCache)).any() &&
167+
jClass.let { toFuzzerType(it, description.typeCache).isDefinitelySubtypeOf(description, type) }
168168
} catch (ignore: Throwable) {
169169
return false
170170
}
@@ -186,12 +186,27 @@ class AbstractsObjectValueProvider(
186186
}
187187
}
188188

189-
private fun findAccessibleCreators(description: FuzzedDescription, classId: ClassId): Sequence<ExecutableId> =
190-
(classId.allConstructors + (classId.jClass.methods
191-
.filter { it.isStatic && it.returnType.id.isSubtypeOf(classId) }
192-
.map { it.executableId })
189+
private fun findAccessibleCreators(
190+
description: FuzzedDescription,
191+
neededType: FuzzedType
192+
): Sequence<ExecutableId> =
193+
(neededType.classId.allConstructors + (neededType.classId.jClass.methods
194+
.filter {
195+
it.isStatic && toFuzzerType(it.genericReturnType, description.typeCache)
196+
.isDefinitelySubtypeOf(description, neededType)
197+
}
198+
.map { it.executableId })
193199
).filter { isAccessible(it.executable, description.description.packageName) }
194200

201+
/**
202+
* NOTE: this function takes conservative when generics are involved.
203+
*
204+
* For example, `false` may be returned when [this] is `List<T>` or `ArrayList<T>` while [other] is `List<String>`.
205+
*/
206+
// TODO should be reworked with accurate generic matching
207+
private fun FuzzedType.isDefinitelySubtypeOf(description: FuzzedDescription, other: FuzzedType): Boolean =
208+
classId.isSubtypeOf(other.classId) && traverseHierarchy(description.typeCache).contains(other)
209+
195210
internal class PublicSetterGetter(
196211
val setter: Method,
197212
val getter: Method,

0 commit comments

Comments
 (0)