Skip to content

Commit 212f6e0

Browse files
mglukhikherokhins
authored andcommitted
Stub creation from cls fixed for suspend function types
(cherry picked from commit f49ef8e)
1 parent a4272ca commit 212f6e0

File tree

4 files changed

+142
-5
lines changed

4 files changed

+142
-5
lines changed

idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/TypeClsStubBuilder.kt

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.psi.*
3333
import org.jetbrains.kotlin.psi.stubs.KotlinUserTypeStub
3434
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
3535
import org.jetbrains.kotlin.psi.stubs.impl.*
36+
import org.jetbrains.kotlin.resolve.DescriptorUtils
3637
import org.jetbrains.kotlin.serialization.Flags
3738
import org.jetbrains.kotlin.serialization.ProtoBuf
3839
import org.jetbrains.kotlin.serialization.ProtoBuf.Type
@@ -100,7 +101,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
100101
createTypeAnnotationStubs(parent, type, notExtensionAnnotations)
101102

102103
val isExtension = extensionAnnotations.isNotEmpty()
103-
createFunctionTypeStub(nullableTypeParent(parent, type), type, isExtension)
104+
createFunctionTypeStub(nullableTypeParent(parent, type), type, isExtension, Flags.SUSPEND_TYPE.get(type.flags))
104105

105106
return
106107
}
@@ -158,7 +159,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
158159
Projection.STAR -> KtProjectionKind.STAR
159160
}
160161

161-
private fun createFunctionTypeStub(parent: StubElement<out PsiElement>, type: Type, isExtensionFunctionType: Boolean) {
162+
private fun createFunctionTypeStub(parent: StubElement<out PsiElement>, type: Type, isExtensionFunctionType: Boolean, isSuspend: Boolean) {
162163
val typeArgumentList = type.argumentList
163164
val functionType = KotlinPlaceHolderStubImpl<KtFunctionType>(parent, KtStubElementTypes.FUNCTION_TYPE)
164165
if (isExtensionFunctionType) {
@@ -171,15 +172,35 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
171172
val parameterList = KotlinPlaceHolderStubImpl<KtParameterList>(functionType, KtStubElementTypes.VALUE_PARAMETER_LIST)
172173
val typeArgumentsWithoutReceiverAndReturnType
173174
= typeArgumentList.subList(if (isExtensionFunctionType) 1 else 0, typeArgumentList.size - 1)
174-
typeArgumentsWithoutReceiverAndReturnType.forEach { argument ->
175+
var suspendParameterType: Type? = null
176+
177+
for ((index, argument) in typeArgumentsWithoutReceiverAndReturnType.withIndex()) {
178+
if (isSuspend && index == typeArgumentsWithoutReceiverAndReturnType.size - 1) {
179+
val parameterType = argument.type(c.typeTable)!!
180+
if (parameterType.hasClassName() && parameterType.argumentCount == 1) {
181+
val classId = c.nameResolver.getClassId(parameterType.className)
182+
val fqName = classId.asSingleFqName()
183+
if (fqName == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME) {
184+
suspendParameterType = parameterType
185+
continue
186+
}
187+
}
188+
}
175189
val parameter = KotlinParameterStubImpl(
176190
parameterList, fqName = null, name = null, isMutable = false, hasValOrVar = false, hasDefaultValue = false
177191
)
192+
178193
createTypeReferenceStub(parameter, argument.type(c.typeTable)!!)
179194
}
180195

181-
val returnType = typeArgumentList.last().type(c.typeTable)!!
182-
createTypeReferenceStub(functionType, returnType)
196+
197+
if (suspendParameterType == null) {
198+
val returnType = typeArgumentList.last().type(c.typeTable)!!
199+
createTypeReferenceStub(functionType, returnType)
200+
}
201+
else {
202+
createTypeReferenceStub(functionType, suspendParameterType.getArgument(0).type)
203+
}
183204
}
184205

185206
fun createValueParameterListStub(
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package test
2+
3+
class SuspendLambda {
4+
fun <T> (suspend () -> T).createCoroutine(completion: Continuation<T>) {}
5+
6+
fun <T> testCoroutine(f: suspend (Int) -> T?) {}
7+
8+
fun <T> testCoroutineWithAnnotation(f: suspend (Int) -> @A T?) {}
9+
}
10+
11+
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
12+
annotation class A
13+
14+
class Continuation<T> {}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
PsiJetFileStubImpl[package=test]
2+
PACKAGE_DIRECTIVE
3+
REFERENCE_EXPRESSION[referencedName=test]
4+
IMPORT_LIST
5+
CLASS[fqName=test.SuspendLambda, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=true, name=SuspendLambda, superNames=[]]
6+
MODIFIER_LIST[public final]
7+
PRIMARY_CONSTRUCTOR
8+
MODIFIER_LIST[public]
9+
VALUE_PARAMETER_LIST
10+
CLASS_BODY
11+
FUN[fqName=test.SuspendLambda.testCoroutine, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=true, isExtension=false, isTopLevel=false, name=testCoroutine]
12+
MODIFIER_LIST[public final]
13+
TYPE_PARAMETER_LIST
14+
TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=T]
15+
VALUE_PARAMETER_LIST
16+
VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=f]
17+
TYPE_REFERENCE
18+
MODIFIER_LIST[suspend]
19+
FUNCTION_TYPE
20+
VALUE_PARAMETER_LIST
21+
VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null]
22+
TYPE_REFERENCE
23+
USER_TYPE
24+
USER_TYPE
25+
REFERENCE_EXPRESSION[referencedName=kotlin]
26+
REFERENCE_EXPRESSION[referencedName=Int]
27+
TYPE_REFERENCE
28+
NULLABLE_TYPE
29+
USER_TYPE
30+
REFERENCE_EXPRESSION[referencedName=T]
31+
TYPE_REFERENCE
32+
USER_TYPE
33+
USER_TYPE
34+
REFERENCE_EXPRESSION[referencedName=kotlin]
35+
REFERENCE_EXPRESSION[referencedName=Unit]
36+
FUN[fqName=test.SuspendLambda.testCoroutineWithAnnotation, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=true, isExtension=false, isTopLevel=false, name=testCoroutineWithAnnotation]
37+
MODIFIER_LIST[public final]
38+
TYPE_PARAMETER_LIST
39+
TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=T]
40+
VALUE_PARAMETER_LIST
41+
VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=f]
42+
TYPE_REFERENCE
43+
MODIFIER_LIST[suspend]
44+
FUNCTION_TYPE
45+
VALUE_PARAMETER_LIST
46+
VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null]
47+
TYPE_REFERENCE
48+
USER_TYPE
49+
USER_TYPE
50+
REFERENCE_EXPRESSION[referencedName=kotlin]
51+
REFERENCE_EXPRESSION[referencedName=Int]
52+
TYPE_REFERENCE
53+
MODIFIER_LIST[]
54+
ANNOTATION_ENTRY[hasValueArguments=false, shortName=A]
55+
CONSTRUCTOR_CALLEE
56+
TYPE_REFERENCE
57+
USER_TYPE
58+
USER_TYPE
59+
REFERENCE_EXPRESSION[referencedName=test]
60+
REFERENCE_EXPRESSION[referencedName=A]
61+
NULLABLE_TYPE
62+
USER_TYPE
63+
REFERENCE_EXPRESSION[referencedName=T]
64+
TYPE_REFERENCE
65+
USER_TYPE
66+
USER_TYPE
67+
REFERENCE_EXPRESSION[referencedName=kotlin]
68+
REFERENCE_EXPRESSION[referencedName=Unit]
69+
FUN[fqName=test.SuspendLambda.createCoroutine, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=true, isExtension=true, isTopLevel=false, name=createCoroutine]
70+
MODIFIER_LIST[public final]
71+
TYPE_PARAMETER_LIST
72+
TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=T]
73+
TYPE_REFERENCE
74+
MODIFIER_LIST[suspend]
75+
FUNCTION_TYPE
76+
VALUE_PARAMETER_LIST
77+
TYPE_REFERENCE
78+
USER_TYPE
79+
REFERENCE_EXPRESSION[referencedName=T]
80+
VALUE_PARAMETER_LIST
81+
VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=completion]
82+
TYPE_REFERENCE
83+
USER_TYPE
84+
USER_TYPE
85+
REFERENCE_EXPRESSION[referencedName=test]
86+
REFERENCE_EXPRESSION[referencedName=Continuation]
87+
TYPE_ARGUMENT_LIST
88+
TYPE_PROJECTION[projectionKind=NONE]
89+
TYPE_REFERENCE
90+
USER_TYPE
91+
REFERENCE_EXPRESSION[referencedName=T]
92+
TYPE_REFERENCE
93+
USER_TYPE
94+
USER_TYPE
95+
REFERENCE_EXPRESSION[referencedName=kotlin]
96+
REFERENCE_EXPRESSION[referencedName=Unit]

idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ public void testSecondaryConstructors() throws Exception {
186186
doTest(fileName);
187187
}
188188

189+
@TestMetadata("SuspendLambda")
190+
public void testSuspendLambda() throws Exception {
191+
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/SuspendLambda/");
192+
doTest(fileName);
193+
}
194+
189195
@TestMetadata("TopLevelMembersAnnotatedKt")
190196
public void testTopLevelMembersAnnotatedKt() throws Exception {
191197
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/TopLevelMembersAnnotatedKt/");

0 commit comments

Comments
 (0)