@@ -84,24 +84,8 @@ class MapValueProvider(
84
84
idGenerator : IdGenerator <Int >
85
85
) : CollectionValueProvider(idGenerator, java.util.Map : :class.id) {
86
86
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
-
102
87
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)
105
89
when (type.classId) {
106
90
java.util.Map ::class .id -> {
107
91
if (keyGeneric.classId isSubtypeOf Comparable ::class ) {
@@ -128,19 +112,8 @@ class ListSetValueProvider(
128
112
idGenerator : IdGenerator <Int >
129
113
) : CollectionValueProvider(idGenerator, java.util.Collection : :class.id) {
130
114
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
-
142
115
override fun resolveType (description : FuzzedDescription , type : FuzzedType ) = sequence {
143
- val generic = findTypeByMethod (description, type)
116
+ val ( generic) = resolveGenericsOfSuperClass< Collection < * >> (description, type)
144
117
when (type.classId) {
145
118
java.util.Queue ::class .id,
146
119
java.util.Deque ::class .id-> {
@@ -202,20 +175,6 @@ abstract class CollectionValueProvider(
202
175
}
203
176
}
204
177
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
-
219
178
/* *
220
179
* Types should be resolved with type parameters
221
180
*/
@@ -267,7 +226,7 @@ class IteratorValueProvider(val idGenerator: IdGenerator<Int>) : JavaValueProvid
267
226
}
268
227
269
228
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 )
271
230
return sequenceOf(Seed .Recursive (
272
231
construct = Routine .Create (listOf (FuzzedType (iterableClassId, listOf (generic)))) { v ->
273
232
val id = idGenerator.createId()
@@ -306,4 +265,21 @@ class IteratorValueProvider(val idGenerator: IdGenerator<Int>) : JavaValueProvid
306
265
}
307
266
))
308
267
}
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
+ }
309
285
}
0 commit comments