1
1
package org.utbot.fuzzing.providers
2
2
3
+ import com.google.common.reflect.TypeToken
3
4
import org.utbot.framework.plugin.api.*
4
5
import org.utbot.framework.plugin.api.util.*
5
6
import org.utbot.fuzzer.FuzzedType
6
7
import org.utbot.fuzzer.FuzzedValue
7
8
import org.utbot.fuzzer.IdGenerator
8
9
import org.utbot.fuzzer.fuzzed
9
10
import org.utbot.fuzzing.*
11
+ import org.utbot.fuzzing.spring.utils.jType
10
12
import org.utbot.fuzzing.utils.hex
13
+ import java.lang.reflect.Method
11
14
import kotlin.reflect.KClass
12
15
13
16
class EmptyCollectionValueProvider (
@@ -80,9 +83,25 @@ class EmptyCollectionValueProvider(
80
83
class MapValueProvider (
81
84
idGenerator : IdGenerator <Int >
82
85
) : CollectionValueProvider(idGenerator, java.util.Map : :class.id) {
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
+
83
102
override fun resolveType (description : FuzzedDescription , type : FuzzedType ) = sequence {
84
- val keyGeneric = type.generics.getOrNull( 0 ) ? : FuzzedType (objectClassId )
85
- val valueGeneric = type.generics.getOrNull( 1 ) ? : FuzzedType (objectClassId )
103
+ val keyGeneric = findTypeByMethod(description, type, MethodCall . KEYS )
104
+ val valueGeneric = findTypeByMethod(description, type, MethodCall . VALUES )
86
105
when (type.classId) {
87
106
java.util.Map ::class .id -> {
88
107
if (keyGeneric.classId isSubtypeOf Comparable ::class ) {
@@ -108,8 +127,20 @@ class MapValueProvider(
108
127
class ListSetValueProvider (
109
128
idGenerator : IdGenerator <Int >
110
129
) : CollectionValueProvider(idGenerator, java.util.Collection : :class.id) {
130
+
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
+
111
142
override fun resolveType (description : FuzzedDescription , type : FuzzedType ) = sequence {
112
- val generic = type.generics.firstOrNull() ? : FuzzedType (objectClassId )
143
+ val generic = findTypeByMethod(description, type )
113
144
when (type.classId) {
114
145
java.util.Queue ::class .id,
115
146
java.util.Deque ::class .id-> {
@@ -171,6 +202,20 @@ abstract class CollectionValueProvider(
171
202
}
172
203
}
173
204
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
+
174
219
/* *
175
220
* Types should be resolved with type parameters
176
221
*/
0 commit comments