@@ -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