Skip to content

Commit 89ddbe6

Browse files
committed
Better way to get generics
1 parent 6181459 commit 89ddbe6

File tree

1 file changed

+20
-44
lines changed
  • utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/providers

1 file changed

+20
-44
lines changed

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

+20-44
Original file line numberDiff line numberDiff line change
@@ -84,24 +84,8 @@ class MapValueProvider(
8484
idGenerator: IdGenerator<Int>
8585
) : CollectionValueProvider(idGenerator, java.util.Map::class.id) {
8686

87-
private enum class MethodCall { KEYS, VALUES }
88-
89-
private fun findTypeByMethod(description: FuzzedDescription, type: FuzzedType, method: MethodCall): FuzzedType {
90-
val methodName = when (method) {
91-
MethodCall.KEYS -> "keySet"
92-
MethodCall.VALUES -> "values"
93-
}
94-
val m = Map::class.java.getMethod(methodName)
95-
return resolveTypeByMethod(description, type, m)?.let {
96-
assert(it.classId.isSubtypeOf(collectionClassId))
97-
assert(it.generics.size == 1)
98-
it.generics[0]
99-
} ?: FuzzedType(objectClassId)
100-
}
101-
10287
override fun resolveType(description: FuzzedDescription, type: FuzzedType) = sequence {
103-
val keyGeneric = findTypeByMethod(description, type, MethodCall.KEYS)
104-
val valueGeneric = findTypeByMethod(description, type, MethodCall.VALUES)
88+
val (keyGeneric, valueGeneric) = resolveGenericsOfSuperClass<Map<*, *>>(description, type)
10589
when (type.classId) {
10690
java.util.Map::class.id -> {
10791
if (keyGeneric.classId isSubtypeOf Comparable::class) {
@@ -128,19 +112,8 @@ class ListSetValueProvider(
128112
idGenerator: IdGenerator<Int>
129113
) : CollectionValueProvider(idGenerator, java.util.Collection::class.id) {
130114

131-
private val iteratorClassId = java.util.Iterator::class.java.id
132-
133-
private fun findTypeByMethod(description: FuzzedDescription, type: FuzzedType): FuzzedType {
134-
val method = java.util.Collection::class.java.getMethod("iterator")
135-
return resolveTypeByMethod(description, type, method)?.let {
136-
assert(it.classId.isSubtypeOf(iteratorClassId))
137-
assert(it.generics.size == 1)
138-
it.generics[0]
139-
} ?: FuzzedType(objectClassId)
140-
}
141-
142115
override fun resolveType(description: FuzzedDescription, type: FuzzedType) = sequence {
143-
val generic = findTypeByMethod(description, type)
116+
val (generic) = resolveGenericsOfSuperClass<Collection<*>>(description, type)
144117
when (type.classId) {
145118
java.util.Queue::class.id,
146119
java.util.Deque::class.id-> {
@@ -202,20 +175,6 @@ abstract class CollectionValueProvider(
202175
}
203176
}
204177

205-
/**
206-
* Can be used to resolve some types using [type] and some method of this type
207-
*/
208-
protected fun resolveTypeByMethod(description: FuzzedDescription, type: FuzzedType, method: Method): FuzzedType? {
209-
return try {
210-
toFuzzerType(
211-
TypeToken.of(type.jType).resolveType(method.genericReturnType).type,
212-
description.typeCache
213-
)
214-
} catch (t: Throwable) {
215-
null
216-
}
217-
}
218-
219178
/**
220179
* Types should be resolved with type parameters
221180
*/
@@ -267,7 +226,7 @@ class IteratorValueProvider(val idGenerator: IdGenerator<Int>) : JavaValueProvid
267226
}
268227

269228
override fun generate(description: FuzzedDescription, type: FuzzedType): Sequence<Seed<FuzzedType, FuzzedValue>> {
270-
val generic = type.generics.firstOrNull() ?: FuzzedType(objectClassId)
229+
val (generic) = resolveGenericsOfSuperClass<Iterator<*>>(description, type)
271230
return sequenceOf(Seed.Recursive(
272231
construct = Routine.Create(listOf(FuzzedType(iterableClassId, listOf(generic)))) { v ->
273232
val id = idGenerator.createId()
@@ -306,4 +265,21 @@ class IteratorValueProvider(val idGenerator: IdGenerator<Int>) : JavaValueProvid
306265
}
307266
))
308267
}
268+
}
269+
270+
private inline fun <reified T> resolveGenericsOfSuperClass(
271+
description: FuzzedDescription,
272+
type: FuzzedType,
273+
): List<FuzzedType> {
274+
val superClass = T::class.java
275+
return try {
276+
check(superClass.isAssignableFrom(type.classId.jClass)) { "$superClass isn't super class of $type" }
277+
@Suppress("UNCHECKED_CAST")
278+
toFuzzerType(
279+
TypeToken.of(type.jType).getSupertype(superClass as Class<in Any>).type,
280+
description.typeCache
281+
).generics
282+
} catch (e: Throwable) {
283+
superClass.typeParameters.map { toFuzzerType(it, description.typeCache) }
284+
}
309285
}

0 commit comments

Comments
 (0)