@@ -34,7 +34,7 @@ import kotlin.reflect.KClass
3434 * Creates a [KArgumentCaptor] for given type.
3535 */
3636inline fun <reified T : Any > argumentCaptor (): KArgumentCaptor <T > {
37- return KArgumentCaptor (ArgumentCaptor .forClass( T :: class .java), T ::class )
37+ return KArgumentCaptor (T ::class )
3838}
3939
4040/* *
@@ -45,8 +45,8 @@ inline fun <reified A : Any, reified B : Any> argumentCaptor(
4545 b : KClass <B > = B : :class
4646): Pair <KArgumentCaptor <A >, KArgumentCaptor<B>> {
4747 return Pair (
48- KArgumentCaptor (ArgumentCaptor .forClass(a.java), a),
49- KArgumentCaptor (ArgumentCaptor .forClass(b.java), b)
48+ KArgumentCaptor (a),
49+ KArgumentCaptor (b)
5050 )
5151}
5252
@@ -59,9 +59,9 @@ inline fun <reified A : Any, reified B : Any, reified C : Any> argumentCaptor(
5959 c : KClass <C > = C : :class
6060): Triple <KArgumentCaptor <A >, KArgumentCaptor<B>, KArgumentCaptor<C>> {
6161 return Triple (
62- KArgumentCaptor (ArgumentCaptor .forClass(a.java), a),
63- KArgumentCaptor (ArgumentCaptor .forClass(b.java), b),
64- KArgumentCaptor (ArgumentCaptor .forClass(c.java), c)
62+ KArgumentCaptor (a),
63+ KArgumentCaptor (b),
64+ KArgumentCaptor (c)
6565 )
6666}
6767
@@ -103,10 +103,10 @@ inline fun <reified A : Any, reified B : Any, reified C : Any, reified D : Any>
103103 d : KClass <D > = D : :class
104104): ArgumentCaptorHolder4 <KArgumentCaptor <A >, KArgumentCaptor<B>, KArgumentCaptor<C>, KArgumentCaptor<D>> {
105105 return ArgumentCaptorHolder4 (
106- KArgumentCaptor (ArgumentCaptor .forClass(a.java), a),
107- KArgumentCaptor (ArgumentCaptor .forClass(b.java), b),
108- KArgumentCaptor (ArgumentCaptor .forClass(c.java), c),
109- KArgumentCaptor (ArgumentCaptor .forClass(d.java), d)
106+ KArgumentCaptor (a),
107+ KArgumentCaptor (b),
108+ KArgumentCaptor (c),
109+ KArgumentCaptor (d)
110110 )
111111}
112112
@@ -121,11 +121,11 @@ inline fun <reified A : Any, reified B : Any, reified C : Any, reified D : Any,
121121 e : KClass <E > = E : :class
122122): ArgumentCaptorHolder5 <KArgumentCaptor <A >, KArgumentCaptor<B>, KArgumentCaptor<C>, KArgumentCaptor<D>, KArgumentCaptor<E>> {
123123 return ArgumentCaptorHolder5 (
124- KArgumentCaptor (ArgumentCaptor .forClass(a.java), a),
125- KArgumentCaptor (ArgumentCaptor .forClass(b.java), b),
126- KArgumentCaptor (ArgumentCaptor .forClass(c.java), c),
127- KArgumentCaptor (ArgumentCaptor .forClass(d.java), d),
128- KArgumentCaptor (ArgumentCaptor .forClass(e.java), e)
124+ KArgumentCaptor (a),
125+ KArgumentCaptor (b),
126+ KArgumentCaptor (c),
127+ KArgumentCaptor (d),
128+ KArgumentCaptor (e)
129129 )
130130}
131131
@@ -140,7 +140,7 @@ inline fun <reified T : Any> argumentCaptor(f: KArgumentCaptor<T>.() -> Unit): K
140140 * Creates a [KArgumentCaptor] for given nullable type.
141141 */
142142inline fun <reified T : Any > nullableArgumentCaptor (): KArgumentCaptor <T ?> {
143- return KArgumentCaptor (ArgumentCaptor .forClass( T :: class .java), T ::class )
143+ return KArgumentCaptor (T ::class )
144144}
145145
146146/* *
@@ -157,48 +157,58 @@ inline fun <reified T : Any> capture(captor: ArgumentCaptor<T>): T {
157157 return captor.capture() ? : createInstance()
158158}
159159
160- class KArgumentCaptor <out T : Any ?>(
161- private val captor : ArgumentCaptor <T >,
160+ class KArgumentCaptor <out T : Any ?> (
162161 private val tClass : KClass <* >
163162) {
163+ private val captor: ArgumentCaptor <Any ?> =
164+ if (tClass.isValue) {
165+ val boxImpl =
166+ tClass.java.declaredMethods
167+ .single { it.name == " box-impl" && it.parameterCount == 1 }
168+ boxImpl.parameters[0 ].type // is the boxed type of the value type
169+ } else {
170+ tClass.java
171+ }.let {
172+ ArgumentCaptor .forClass(it)
173+ }
164174
165175 /* *
166176 * The first captured value of the argument.
167177 * @throws IndexOutOfBoundsException if the value is not available.
168178 */
169179 val firstValue: T
170- get() = captor.firstValue
180+ get() = toKotlinType( captor.firstValue)
171181
172182 /* *
173183 * The second captured value of the argument.
174184 * @throws IndexOutOfBoundsException if the value is not available.
175185 */
176186 val secondValue: T
177- get() = captor.secondValue
187+ get() = toKotlinType( captor.secondValue)
178188
179189 /* *
180190 * The third captured value of the argument.
181191 * @throws IndexOutOfBoundsException if the value is not available.
182192 */
183193 val thirdValue: T
184- get() = captor.thirdValue
194+ get() = toKotlinType( captor.thirdValue)
185195
186196 /* *
187197 * The last captured value of the argument.
188198 * @throws IndexOutOfBoundsException if the value is not available.
189199 */
190200 val lastValue: T
191- get() = captor.lastValue
201+ get() = toKotlinType( captor.lastValue)
192202
193203 /* *
194204 * The *only* captured value of the argument,
195205 * or throws an exception if no value or more than one value was captured.
196206 */
197207 val singleValue: T
198- get() = captor.singleValue
208+ get() = toKotlinType( captor.singleValue)
199209
200210 val allValues: List <T >
201- get() = captor.allValues
211+ get() = captor.allValues.map(::toKotlinType)
202212
203213 @Suppress(" UNCHECKED_CAST" )
204214 fun capture (): T {
@@ -209,14 +219,28 @@ class KArgumentCaptor<out T : Any?>(
209219 // In Java, `captor.capture` returns null and so the method is called with `[null]`
210220 // In Kotlin, we have to create `[null]` explicitly.
211221 // This code-path is applied for non-vararg array arguments as well, but it seems to work fine.
212- return captor.capture() ? : if (tClass.java.isArray) {
222+ return captor.capture() as T ? : if (tClass.java.isArray) {
213223 singleElementArray()
214224 } else {
215225 createInstance(tClass)
216226 } as T
217227 }
218228
219229 private fun singleElementArray (): Any? = Array .newInstance(tClass.java.componentType, 1 )
230+
231+ @Suppress(" UNCHECKED_CAST" )
232+ private fun toKotlinType (rawCapturedValue : Any? ) : T {
233+ return if (tClass.isValue) {
234+ rawCapturedValue
235+ ?.let {
236+ val boxImpl =
237+ tClass.java.declaredMethods.single { it.name == " box-impl" && it.parameterCount == 1 }
238+ boxImpl.invoke(null , it)
239+ } as T
240+ } else {
241+ rawCapturedValue as T
242+ }
243+ }
220244}
221245
222246val <T > ArgumentCaptor <T >.firstValue: T
0 commit comments