Skip to content

Commit 99555fa

Browse files
committed
Retrieve receiver annotation to stubs from compiled code (KT-19209)
#KT-19209 Fixed
1 parent 8b149db commit 99555fa

File tree

9 files changed

+257
-16
lines changed

9 files changed

+257
-16
lines changed

compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ object KotlinStubVersions {
2828
// Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed
2929
// or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder).
3030
// Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files).
31-
private const val BINARY_STUB_VERSION = 60
31+
private const val BINARY_STUB_VERSION = 61
3232

3333
// Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile)
3434
// Increasing this version will lead to reindexing of all classfiles.

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.decompiler.stubBuilder
1818

1919
import com.intellij.psi.PsiElement
2020
import com.intellij.psi.stubs.StubElement
21+
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
2122
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags.*
2223
import org.jetbrains.kotlin.name.Name
2324
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
@@ -104,11 +105,13 @@ abstract class CallableClsStubBuilder(
104105
}
105106

106107
abstract val receiverType: ProtoBuf.Type?
108+
abstract val receiverAnnotations: List<ClassIdWithTarget>
109+
107110
abstract val returnType: ProtoBuf.Type?
108111

109112
private fun createReceiverTypeReferenceStub() {
110113
receiverType?.let {
111-
typeStubBuilder.createTypeReferenceStub(callableStub, it)
114+
typeStubBuilder.createTypeReferenceStub(callableStub, it, this::receiverAnnotations)
112115
}
113116
}
114117

@@ -134,6 +137,13 @@ private class FunctionClsStubBuilder(
134137
override val receiverType: ProtoBuf.Type?
135138
get() = functionProto.receiverType(c.typeTable)
136139

140+
override val receiverAnnotations: List<ClassIdWithTarget>
141+
get() {
142+
return c.components.annotationLoader
143+
.loadExtensionReceiverParameterAnnotations(protoContainer, functionProto, AnnotatedCallableKind.FUNCTION)
144+
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
145+
}
146+
137147
override val returnType: ProtoBuf.Type?
138148
get() = functionProto.returnType(c.typeTable)
139149

@@ -181,6 +191,13 @@ private class PropertyClsStubBuilder(
181191
override val receiverType: ProtoBuf.Type?
182192
get() = propertyProto.receiverType(c.typeTable)
183193

194+
override val receiverAnnotations: List<ClassIdWithTarget>
195+
get() {
196+
return c.components.annotationLoader
197+
.loadExtensionReceiverParameterAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY_GETTER)
198+
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
199+
}
200+
184201
override val returnType: ProtoBuf.Type?
185202
get() = propertyProto.returnType(c.typeTable)
186203

@@ -229,6 +246,9 @@ private class ConstructorClsStubBuilder(
229246
override val receiverType: ProtoBuf.Type?
230247
get() = null
231248

249+
override val receiverAnnotations: List<ClassIdWithTarget>
250+
get() = emptyList()
251+
232252
override val returnType: ProtoBuf.Type?
233253
get() = null
234254

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,36 +44,37 @@ import java.util.*
4444
private val ANNOTATIONS_NOT_LOADED_FOR_TYPES = setOf(KotlinBuiltIns.FQ_NAMES.parameterName)
4545

4646
class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
47-
48-
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, type: Type) {
49-
if (type.hasAbbreviatedType()) return createTypeReferenceStub(parent, type.abbreviatedType)
47+
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, type: Type, additionalAnnotations: () -> List<ClassIdWithTarget> = { emptyList() }) {
48+
if (type.hasAbbreviatedType()) return createTypeReferenceStub(parent, type.abbreviatedType, additionalAnnotations)
5049
val typeReference = KotlinPlaceHolderStubImpl<KtTypeReference>(parent, KtStubElementTypes.TYPE_REFERENCE)
5150

5251
val annotations = c.components.annotationLoader.loadTypeAnnotations(type, c.nameResolver).filterNot {
5352
val isTopLevelClass = !it.isNestedClass
5453
isTopLevelClass && it.asSingleFqName() in ANNOTATIONS_NOT_LOADED_FOR_TYPES
5554
}
5655

56+
val allAnnotations = additionalAnnotations() + annotations.map { ClassIdWithTarget(it, null) }
57+
5758
when {
5859
type.hasClassName() || type.hasTypeAliasName() ->
59-
createClassReferenceTypeStub(typeReference, type, annotations)
60+
createClassReferenceTypeStub(typeReference, type, allAnnotations)
6061
type.hasTypeParameter() ->
61-
createTypeParameterStub(typeReference, type, c.typeParameters[type.typeParameter], annotations)
62+
createTypeParameterStub(typeReference, type, c.typeParameters[type.typeParameter], allAnnotations)
6263
type.hasTypeParameterName() ->
63-
createTypeParameterStub(typeReference, type, c.nameResolver.getName(type.typeParameterName), annotations)
64+
createTypeParameterStub(typeReference, type, c.nameResolver.getName(type.typeParameterName), allAnnotations)
6465
}
6566
}
6667

6768
private fun nullableTypeParent(parent: KotlinStubBaseImpl<*>, type: Type): KotlinStubBaseImpl<*> =
6869
if (type.nullable) KotlinPlaceHolderStubImpl<KtNullableType>(parent, KtStubElementTypes.NULLABLE_TYPE)
6970
else parent
7071

71-
private fun createTypeParameterStub(parent: KotlinStubBaseImpl<*>, type: Type, name: Name, annotations: List<ClassId>) {
72+
private fun createTypeParameterStub(parent: KotlinStubBaseImpl<*>, type: Type, name: Name, annotations: List<ClassIdWithTarget>) {
7273
createTypeAnnotationStubs(parent, type, annotations)
7374
createStubForTypeName(ClassId.topLevel(FqName.topLevel(name)), nullableTypeParent(parent, type))
7475
}
7576

76-
private fun createClassReferenceTypeStub(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<ClassId>) {
77+
private fun createClassReferenceTypeStub(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<ClassIdWithTarget>) {
7778
if (type.hasFlexibleTypeCapabilitiesId()) {
7879
val id = c.nameResolver.getString(type.flexibleTypeCapabilitiesId)
7980

@@ -92,7 +93,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
9293
&& type.argumentList.none { it.projection == Projection.STAR }
9394
if (shouldBuildAsFunctionType) {
9495
val (extensionAnnotations, notExtensionAnnotations) =
95-
annotations.partition { it.asSingleFqName() == KotlinBuiltIns.FQ_NAMES.extensionFunctionType }
96+
annotations.partition { it.classId.asSingleFqName() == KotlinBuiltIns.FQ_NAMES.extensionFunctionType }
9697

9798
createTypeAnnotationStubs(parent, type, notExtensionAnnotations)
9899

@@ -112,12 +113,12 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
112113
}
113114
}
114115

115-
private fun createTypeAnnotationStubs(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<ClassId>) {
116+
private fun createTypeAnnotationStubs(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<ClassIdWithTarget>) {
116117
val typeModifiers = getTypeModifiersAsWritten(type)
117118
if (annotations.isEmpty() && typeModifiers.isEmpty()) return
118119
val typeModifiersMask = ModifierMaskUtils.computeMask { it in typeModifiers }
119120
val modifiersList = KotlinModifierListStubImpl(parent, typeModifiersMask, KtStubElementTypes.MODIFIER_LIST)
120-
createAnnotationStubs(annotations, modifiersList)
121+
createTargetedAnnotationStubs(annotations, modifiersList)
121122
}
122123

123124
private fun getTypeModifiersAsWritten(type: Type): Set<KtModifierKeywordToken> {

idea/testData/decompiler/stubBuilder/Annotations/Annotations.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,31 @@
2828
enum class En { Entry1, @a @b(E.E2) Entry2, @a @c Entry3 }
2929

3030
fun types(param: @a @b(E.E1) LongRange): @a @b(E.E2) Unit {}
31+
32+
fun @receiver:a Int.foo() {}
33+
val @receiver:a Int.receiverField: String? get() = null
34+
35+
@get: a
36+
val getterField : String? = null
37+
38+
@set: a
39+
var setterField : String? = null
40+
41+
@field: a
42+
val ownField : String? = null
43+
44+
@setparam:a
45+
var setParam: String? = null
46+
47+
@delegate:a
48+
val deleage by lazy { 12 }
49+
50+
class ClassWithConstructor(@param: a val b: Int)
3151
}
3252

3353
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION,
3454
AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER,
35-
AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.TYPE_PARAMETER)
55+
AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.FIELD)
3656
annotation class a
3757

3858
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.CLASS,

idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,27 @@ PsiJetFileStubImpl[package=]
8888
USER_TYPE
8989
REFERENCE_EXPRESSION[referencedName=kotlin]
9090
REFERENCE_EXPRESSION[referencedName=Int]
91+
PROPERTY[fqName=Annotations.deleage, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=deleage]
92+
MODIFIER_LIST[public final]
93+
ANNOTATION_ENTRY[hasValueArguments=false, shortName=a]
94+
ANNOTATION_TARGET[useSiteTarget=PROPERTY_DELEGATE_FIELD]
95+
CONSTRUCTOR_CALLEE
96+
TYPE_REFERENCE
97+
USER_TYPE
98+
REFERENCE_EXPRESSION[referencedName=a]
99+
TYPE_REFERENCE
100+
USER_TYPE
101+
USER_TYPE
102+
REFERENCE_EXPRESSION[referencedName=kotlin]
103+
REFERENCE_EXPRESSION[referencedName=Int]
104+
PROPERTY[fqName=Annotations.getterField, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=getterField]
105+
MODIFIER_LIST[public final]
106+
TYPE_REFERENCE
107+
NULLABLE_TYPE
108+
USER_TYPE
109+
USER_TYPE
110+
REFERENCE_EXPRESSION[referencedName=kotlin]
111+
REFERENCE_EXPRESSION[referencedName=String]
91112
PROPERTY[fqName=Annotations.hasValueArguments, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=hasValueArguments]
92113
MODIFIER_LIST[public final]
93114
ANNOTATION_ENTRY[hasValueArguments=false, shortName=a]
@@ -100,13 +121,63 @@ PsiJetFileStubImpl[package=]
100121
USER_TYPE
101122
REFERENCE_EXPRESSION[referencedName=kotlin]
102123
REFERENCE_EXPRESSION[referencedName=Int]
124+
PROPERTY[fqName=Annotations.ownField, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=ownField]
125+
MODIFIER_LIST[public final]
126+
ANNOTATION_ENTRY[hasValueArguments=false, shortName=a]
127+
ANNOTATION_TARGET[useSiteTarget=FIELD]
128+
CONSTRUCTOR_CALLEE
129+
TYPE_REFERENCE
130+
USER_TYPE
131+
REFERENCE_EXPRESSION[referencedName=a]
132+
TYPE_REFERENCE
133+
NULLABLE_TYPE
134+
USER_TYPE
135+
USER_TYPE
136+
REFERENCE_EXPRESSION[referencedName=kotlin]
137+
REFERENCE_EXPRESSION[referencedName=String]
138+
PROPERTY[fqName=Annotations.setParam, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=true, name=setParam]
139+
MODIFIER_LIST[public final]
140+
TYPE_REFERENCE
141+
NULLABLE_TYPE
142+
USER_TYPE
143+
USER_TYPE
144+
REFERENCE_EXPRESSION[referencedName=kotlin]
145+
REFERENCE_EXPRESSION[referencedName=String]
146+
PROPERTY[fqName=Annotations.setterField, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=true, name=setterField]
147+
MODIFIER_LIST[public final]
148+
TYPE_REFERENCE
149+
NULLABLE_TYPE
150+
USER_TYPE
151+
USER_TYPE
152+
REFERENCE_EXPRESSION[referencedName=kotlin]
153+
REFERENCE_EXPRESSION[referencedName=String]
103154
PROPERTY[fqName=Annotations.withCustomAccessors, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=true, name=withCustomAccessors]
104155
MODIFIER_LIST[public final]
105156
TYPE_REFERENCE
106157
USER_TYPE
107158
USER_TYPE
108159
REFERENCE_EXPRESSION[referencedName=kotlin]
109160
REFERENCE_EXPRESSION[referencedName=Int]
161+
PROPERTY[fqName=Annotations.receiverField, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=true, isTopLevel=false, isVar=false, name=receiverField]
162+
MODIFIER_LIST[public final]
163+
TYPE_REFERENCE
164+
MODIFIER_LIST[]
165+
ANNOTATION_ENTRY[hasValueArguments=false, shortName=a]
166+
ANNOTATION_TARGET[useSiteTarget=RECEIVER]
167+
CONSTRUCTOR_CALLEE
168+
TYPE_REFERENCE
169+
USER_TYPE
170+
REFERENCE_EXPRESSION[referencedName=a]
171+
USER_TYPE
172+
USER_TYPE
173+
REFERENCE_EXPRESSION[referencedName=kotlin]
174+
REFERENCE_EXPRESSION[referencedName=Int]
175+
TYPE_REFERENCE
176+
NULLABLE_TYPE
177+
USER_TYPE
178+
USER_TYPE
179+
REFERENCE_EXPRESSION[referencedName=kotlin]
180+
REFERENCE_EXPRESSION[referencedName=String]
110181
FUN[fqName=Annotations.annotationWithVararg, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=false, name=annotationWithVararg]
111182
MODIFIER_LIST[private final]
112183
VALUE_PARAMETER_LIST
@@ -224,6 +295,51 @@ PsiJetFileStubImpl[package=]
224295
USER_TYPE
225296
REFERENCE_EXPRESSION[referencedName=kotlin]
226297
REFERENCE_EXPRESSION[referencedName=Unit]
298+
FUN[fqName=Annotations.foo, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=true, isTopLevel=false, name=foo]
299+
MODIFIER_LIST[public final]
300+
TYPE_REFERENCE
301+
MODIFIER_LIST[]
302+
ANNOTATION_ENTRY[hasValueArguments=false, shortName=a]
303+
ANNOTATION_TARGET[useSiteTarget=RECEIVER]
304+
CONSTRUCTOR_CALLEE
305+
TYPE_REFERENCE
306+
USER_TYPE
307+
REFERENCE_EXPRESSION[referencedName=a]
308+
USER_TYPE
309+
USER_TYPE
310+
REFERENCE_EXPRESSION[referencedName=kotlin]
311+
REFERENCE_EXPRESSION[referencedName=Int]
312+
VALUE_PARAMETER_LIST
313+
TYPE_REFERENCE
314+
USER_TYPE
315+
USER_TYPE
316+
REFERENCE_EXPRESSION[referencedName=kotlin]
317+
REFERENCE_EXPRESSION[referencedName=Unit]
318+
CLASS[fqName=Annotations.ClassWithConstructor, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=ClassWithConstructor, superNames=[]]
319+
MODIFIER_LIST[public final]
320+
PRIMARY_CONSTRUCTOR
321+
MODIFIER_LIST[public]
322+
VALUE_PARAMETER_LIST
323+
VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=b]
324+
MODIFIER_LIST[]
325+
ANNOTATION_ENTRY[hasValueArguments=false, shortName=a]
326+
CONSTRUCTOR_CALLEE
327+
TYPE_REFERENCE
328+
USER_TYPE
329+
REFERENCE_EXPRESSION[referencedName=a]
330+
TYPE_REFERENCE
331+
USER_TYPE
332+
USER_TYPE
333+
REFERENCE_EXPRESSION[referencedName=kotlin]
334+
REFERENCE_EXPRESSION[referencedName=Int]
335+
CLASS_BODY
336+
PROPERTY[fqName=Annotations.ClassWithConstructor.b, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=b]
337+
MODIFIER_LIST[public final]
338+
TYPE_REFERENCE
339+
USER_TYPE
340+
USER_TYPE
341+
REFERENCE_EXPRESSION[referencedName=kotlin]
342+
REFERENCE_EXPRESSION[referencedName=Int]
227343
CLASS[fqName=Annotations.En, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=En, superNames=[Enum]]
228344
MODIFIER_LIST[enum public final]
229345
PRIMARY_CONSTRUCTOR

idea/testData/decompiler/stubBuilder/AnnotationsOnNullableTypes/AnnotationsOnNullableTypes.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ public class AnnotationsOnNullableTypes {
2020
val lambdaReceiver: (@A C?).() -> C = null!!
2121

2222
val lambdaTypeWithNullableReceiver: @A C?.() -> C = null!!
23+
24+
fun @receiver:A C?.functionWithAnnotatedReceiver() {}
2325
}
2426

25-
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
27+
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER)
2628
annotation class A
2729

2830
interface B<T>

idea/testData/decompiler/stubBuilder/AnnotationsOnNullableTypes/AnnotationsOnNullableTypes.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,25 @@ PsiJetFileStubImpl[package=]
183183
NULLABLE_TYPE
184184
USER_TYPE
185185
REFERENCE_EXPRESSION[referencedName=C]
186+
FUN[fqName=AnnotationsOnNullableTypes.functionWithAnnotatedReceiver, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=true, isTopLevel=false, name=functionWithAnnotatedReceiver]
187+
MODIFIER_LIST[public final]
188+
TYPE_REFERENCE
189+
MODIFIER_LIST[]
190+
ANNOTATION_ENTRY[hasValueArguments=false, shortName=A]
191+
ANNOTATION_TARGET[useSiteTarget=RECEIVER]
192+
CONSTRUCTOR_CALLEE
193+
TYPE_REFERENCE
194+
USER_TYPE
195+
REFERENCE_EXPRESSION[referencedName=A]
196+
NULLABLE_TYPE
197+
USER_TYPE
198+
REFERENCE_EXPRESSION[referencedName=C]
199+
VALUE_PARAMETER_LIST
200+
TYPE_REFERENCE
201+
USER_TYPE
202+
USER_TYPE
203+
REFERENCE_EXPRESSION[referencedName=kotlin]
204+
REFERENCE_EXPRESSION[referencedName=Unit]
186205
FUN[fqName=AnnotationsOnNullableTypes.receiverArgument, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=true, isTopLevel=false, name=receiverArgument]
187206
MODIFIER_LIST[public final]
188207
TYPE_REFERENCE

idea/testData/decompiler/stubBuilder/SuspendLambda/SuspendLambda.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ package test
33
class SuspendLambda {
44
fun <T> (suspend () -> T).createCoroutine(completion: Continuation<T>) {}
55

6+
fun <R, T> (suspend R.() -> T).createCoroutine(receiver: R, completion: Continuation<T>) {}
7+
8+
fun <R, T> (suspend @receiver:A R.() -> T).createCoroutineAnother() {}
9+
610
fun <T> testCoroutine(f: suspend (Int) -> T?) {}
711

812
fun <T> testCoroutineWithAnnotation(f: suspend (Int) -> @A T?) {}
913
}
1014

11-
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
15+
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER)
1216
annotation class A
1317

1418
class Continuation<T> {}

0 commit comments

Comments
 (0)