1515 */
1616package org.springframework.core
1717
18+ import org.junit.Assert.assertEquals
19+ import org.junit.Assert.assertFalse
20+ import org.junit.Assert.assertTrue
1821import org.junit.Test
19- import org.junit.Assert.*
2022import java.lang.reflect.Method
23+ import java.lang.reflect.TypeVariable
24+ import kotlin.reflect.full.declaredFunctions
25+ import kotlin.reflect.jvm.javaMethod
2126
2227/* *
2328 * Tests for Kotlin support in [MethodParameter].
2429 *
2530 * @author Raman Gupta
2631 * @author Sebastien Deleuze
2732 * @author Juergen Hoeller
33+ * @author Konrad Kaminski
2834 */
2935class KotlinMethodParameterTests {
3036
@@ -67,6 +73,43 @@ class KotlinMethodParameterTests {
6773 assertTrue(MethodParameter (regularClassConstructor, 1 ).isOptional)
6874 }
6975
76+ @Test
77+ fun `Suspending function return type` () {
78+ assertEquals(Number ::class .java, returnParameterType(" suspendFun" ))
79+ assertEquals(Number ::class .java, returnGenericParameterType(" suspendFun" ))
80+
81+ assertEquals(Producer ::class .java, returnParameterType(" suspendFun2" ))
82+ assertEquals(" org.springframework.core.Producer<? extends java.lang.Number>" , returnGenericParameterTypeName(" suspendFun2" ))
83+
84+ assertEquals(Wrapper ::class .java, returnParameterType(" suspendFun3" ))
85+ assertEquals(" org.springframework.core.Wrapper<java.lang.Number>" , returnGenericParameterTypeName(" suspendFun3" ))
86+
87+ assertEquals(Consumer ::class .java, returnParameterType(" suspendFun4" ))
88+ assertEquals(" org.springframework.core.Consumer<? super java.lang.Number>" , returnGenericParameterTypeName(" suspendFun4" ))
89+
90+ assertEquals(Producer ::class .java, returnParameterType(" suspendFun5" ))
91+ assertTrue(returnGenericParameterType(" suspendFun5" ) is TypeVariable <* >)
92+ assertEquals(" org.springframework.core.Producer<? extends java.lang.Number>" , returnGenericParameterTypeBoundName(" suspendFun5" ))
93+
94+ assertEquals(Wrapper ::class .java, returnParameterType(" suspendFun6" ))
95+ assertTrue(returnGenericParameterType(" suspendFun6" ) is TypeVariable <* >)
96+ assertEquals(" org.springframework.core.Wrapper<java.lang.Number>" , returnGenericParameterTypeBoundName(" suspendFun6" ))
97+
98+ assertEquals(Consumer ::class .java, returnParameterType(" suspendFun7" ))
99+ assertTrue(returnGenericParameterType(" suspendFun7" ) is TypeVariable <* >)
100+ assertEquals(" org.springframework.core.Consumer<? super java.lang.Number>" , returnGenericParameterTypeBoundName(" suspendFun7" ))
101+
102+ assertEquals(Object ::class .java, returnParameterType(" suspendFun8" ))
103+ assertEquals(Object ::class .java, returnGenericParameterType(" suspendFun8" ))
104+ }
105+
106+ private fun returnParameterType (funName : String ) = returnMethodParameter(funName).parameterType
107+ private fun returnGenericParameterType (funName : String ) = returnMethodParameter(funName).genericParameterType
108+ private fun returnGenericParameterTypeName (funName : String ) = returnGenericParameterType(funName).typeName
109+ private fun returnGenericParameterTypeBoundName (funName : String ) = (returnGenericParameterType(funName) as TypeVariable <* >).bounds[0 ].typeName
110+
111+ private fun returnMethodParameter (funName : String ) =
112+ MethodParameter (this ::class .declaredFunctions.first { it.name == funName }.javaMethod!! , - 1 )
70113
71114 @Suppress(" unused_parameter" )
72115 fun nullable (nullable : String? ): Int? = 42
@@ -82,4 +125,33 @@ class KotlinMethodParameterTests {
82125 @Suppress(" unused_parameter" )
83126 class RegularClass (nonNullable : String , nullable : String? )
84127
128+ @Suppress(" unused" , " unused_parameter" )
129+ suspend fun suspendFun (p1 : String ): Number = TODO ()
130+
131+ @Suppress(" unused" , " unused_parameter" )
132+ suspend fun suspendFun2 (p1 : String ): Producer <Number > = TODO ()
133+
134+ @Suppress(" unused" , " unused_parameter" )
135+ suspend fun suspendFun3 (p1 : String ): Wrapper <Number > = TODO ()
136+
137+ @Suppress(" unused" , " unused_parameter" )
138+ suspend fun suspendFun4 (p1 : String ): Consumer <Number > = TODO ()
139+
140+ @Suppress(" unused" , " unused_parameter" )
141+ suspend fun <T : Producer <Number >> suspendFun5 (p1 : String ): T = TODO ()
142+
143+ @Suppress(" unused" , " unused_parameter" )
144+ suspend fun <T : Wrapper <Number >> suspendFun6 (p1 : String ): T = TODO ()
145+
146+ @Suppress(" unused" , " unused_parameter" )
147+ suspend fun <T : Consumer <Number >> suspendFun7 (p1 : String ): T = TODO ()
148+
149+ @Suppress(" unused" , " unused_parameter" )
150+ suspend fun suspendFun8 (p1 : String ): Any? = TODO ()
85151}
152+
153+ interface Producer <out T >
154+
155+ interface Wrapper <T >
156+
157+ interface Consumer <in T >
0 commit comments