Skip to content

Commit 3b18316

Browse files
mpiekutowskiSpace Team
authored andcommitted
[Klib] Support reading common annotations in KLIB compilers
^KT-64237
1 parent 5abbc38 commit 3b18316

File tree

2 files changed

+206
-3
lines changed

2 files changed

+206
-3
lines changed

compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedAnnotationDeserializer.kt

Lines changed: 187 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,194 @@
55

66
package org.jetbrains.kotlin.fir.session
77

8+
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
89
import org.jetbrains.kotlin.fir.FirSession
910
import org.jetbrains.kotlin.fir.deserialization.AnnotationDeserializerWithProtocol
11+
import org.jetbrains.kotlin.fir.deserialization.loadAnnotationsFromMetadataIfNotEmpty
12+
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
1013
import org.jetbrains.kotlin.library.metadata.KlibMetadataSerializerProtocol
14+
import org.jetbrains.kotlin.metadata.ProtoBuf
15+
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
16+
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
17+
import org.jetbrains.kotlin.name.ClassId
18+
import org.jetbrains.kotlin.protobuf.MessageLite
19+
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
1120

12-
class KlibBasedAnnotationDeserializer(session: FirSession) :
13-
AnnotationDeserializerWithProtocol(session, KlibMetadataSerializerProtocol)
21+
class KlibBasedAnnotationDeserializer(private val session: FirSession) :
22+
AnnotationDeserializerWithProtocol(session, KlibMetadataSerializerProtocol) {
23+
24+
override fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List<FirAnnotation> =
25+
loadAnnotationsFromMetadataIfNotEmpty(
26+
session,
27+
classProto.flags,
28+
classProto.annotationList,
29+
nameResolver,
30+
) ?: super.loadClassAnnotations(classProto, nameResolver)
31+
32+
override fun loadFunctionAnnotations(
33+
containerSource: DeserializedContainerSource?,
34+
functionProto: ProtoBuf.Function,
35+
nameResolver: NameResolver,
36+
typeTable: TypeTable,
37+
): List<FirAnnotation> =
38+
loadAnnotationsFromMetadataIfNotEmpty(
39+
session,
40+
functionProto.flags,
41+
functionProto.annotationList,
42+
nameResolver,
43+
) ?: super.loadFunctionAnnotations(containerSource, functionProto, nameResolver, typeTable)
44+
45+
override fun loadPropertyAnnotations(
46+
containerSource: DeserializedContainerSource?,
47+
propertyProto: ProtoBuf.Property,
48+
containingClassProto: ProtoBuf.Class?,
49+
nameResolver: NameResolver,
50+
typeTable: TypeTable,
51+
): List<FirAnnotation> =
52+
loadAnnotationsFromMetadataIfNotEmpty(
53+
session,
54+
propertyProto.flags,
55+
propertyProto.annotationList,
56+
nameResolver,
57+
AnnotationUseSiteTarget.PROPERTY,
58+
) ?: super.loadPropertyAnnotations(containerSource, propertyProto, containingClassProto, nameResolver, typeTable)
59+
60+
override fun loadConstructorAnnotations(
61+
containerSource: DeserializedContainerSource?,
62+
constructorProto: ProtoBuf.Constructor,
63+
nameResolver: NameResolver,
64+
typeTable: TypeTable,
65+
): List<FirAnnotation> =
66+
loadAnnotationsFromMetadataIfNotEmpty(
67+
session,
68+
constructorProto.flags,
69+
constructorProto.annotationList,
70+
nameResolver,
71+
) ?: super.loadConstructorAnnotations(containerSource, constructorProto, nameResolver, typeTable)
72+
73+
override fun loadValueParameterAnnotations(
74+
containerSource: DeserializedContainerSource?,
75+
callableProto: MessageLite,
76+
valueParameterProto: ProtoBuf.ValueParameter,
77+
classProto: ProtoBuf.Class?,
78+
nameResolver: NameResolver,
79+
typeTable: TypeTable,
80+
kind: CallableKind,
81+
parameterIndex: Int,
82+
): List<FirAnnotation> =
83+
loadAnnotationsFromMetadataIfNotEmpty(
84+
session,
85+
valueParameterProto.flags,
86+
valueParameterProto.annotationList,
87+
nameResolver,
88+
) ?: super.loadValueParameterAnnotations(
89+
containerSource,
90+
callableProto,
91+
valueParameterProto,
92+
classProto,
93+
nameResolver,
94+
typeTable,
95+
kind,
96+
parameterIndex
97+
)
98+
99+
override fun loadEnumEntryAnnotations(
100+
classId: ClassId,
101+
enumEntryProto: ProtoBuf.EnumEntry,
102+
nameResolver: NameResolver,
103+
): List<FirAnnotation> =
104+
loadAnnotationsFromMetadataIfNotEmpty(
105+
session,
106+
flags = null,
107+
enumEntryProto.annotationList,
108+
nameResolver,
109+
) ?: super.loadEnumEntryAnnotations(classId, enumEntryProto, nameResolver)
110+
111+
override fun loadPropertyGetterAnnotations(
112+
containerSource: DeserializedContainerSource?,
113+
propertyProto: ProtoBuf.Property,
114+
nameResolver: NameResolver,
115+
typeTable: TypeTable,
116+
getterFlags: Int,
117+
): List<FirAnnotation> =
118+
loadAnnotationsFromMetadataIfNotEmpty(
119+
session,
120+
getterFlags,
121+
propertyProto.getterAnnotationList,
122+
nameResolver,
123+
AnnotationUseSiteTarget.PROPERTY_GETTER
124+
) ?: super.loadPropertyGetterAnnotations(containerSource, propertyProto, nameResolver, typeTable, getterFlags)
125+
126+
override fun loadPropertySetterAnnotations(
127+
containerSource: DeserializedContainerSource?,
128+
propertyProto: ProtoBuf.Property,
129+
nameResolver: NameResolver,
130+
typeTable: TypeTable,
131+
setterFlags: Int,
132+
): List<FirAnnotation> =
133+
loadAnnotationsFromMetadataIfNotEmpty(
134+
session,
135+
setterFlags,
136+
propertyProto.setterAnnotationList,
137+
nameResolver,
138+
AnnotationUseSiteTarget.PROPERTY_SETTER
139+
) ?: super.loadPropertySetterAnnotations(containerSource, propertyProto, nameResolver, typeTable, setterFlags)
140+
141+
override fun loadPropertyBackingFieldAnnotations(
142+
containerSource: DeserializedContainerSource?,
143+
propertyProto: ProtoBuf.Property,
144+
nameResolver: NameResolver,
145+
typeTable: TypeTable,
146+
): List<FirAnnotation> =
147+
loadAnnotationsFromMetadataIfNotEmpty(
148+
session,
149+
propertyProto.flags,
150+
propertyProto.backingFieldAnnotationList,
151+
nameResolver,
152+
AnnotationUseSiteTarget.FIELD,
153+
) ?: super.loadPropertyBackingFieldAnnotations(containerSource, propertyProto, nameResolver, typeTable)
154+
155+
override fun loadPropertyDelegatedFieldAnnotations(
156+
containerSource: DeserializedContainerSource?,
157+
propertyProto: ProtoBuf.Property,
158+
nameResolver: NameResolver,
159+
typeTable: TypeTable,
160+
): List<FirAnnotation> =
161+
loadAnnotationsFromMetadataIfNotEmpty(
162+
session,
163+
propertyProto.flags,
164+
propertyProto.delegateFieldAnnotationList,
165+
nameResolver,
166+
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD,
167+
) ?: super.loadPropertyDelegatedFieldAnnotations(containerSource, propertyProto, nameResolver, typeTable)
168+
169+
override fun loadExtensionReceiverParameterAnnotations(
170+
containerSource: DeserializedContainerSource?,
171+
callableProto: MessageLite,
172+
nameResolver: NameResolver,
173+
typeTable: TypeTable,
174+
kind: CallableKind,
175+
): List<FirAnnotation> = when (callableProto) {
176+
is ProtoBuf.Function -> loadAnnotationsFromMetadataIfNotEmpty(
177+
session,
178+
callableProto.flags,
179+
callableProto.extensionReceiverAnnotationList,
180+
nameResolver,
181+
)
182+
is ProtoBuf.Property -> loadAnnotationsFromMetadataIfNotEmpty(
183+
session,
184+
callableProto.flags,
185+
callableProto.extensionReceiverAnnotationList,
186+
nameResolver,
187+
)
188+
else -> null
189+
} ?: super.loadExtensionReceiverParameterAnnotations(containerSource, callableProto, nameResolver, typeTable, kind)
190+
191+
override fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List<FirAnnotation> =
192+
loadAnnotationsFromMetadataIfNotEmpty(session, null, typeProto.annotationList, nameResolver)
193+
?: super.loadTypeAnnotations(typeProto, nameResolver)
194+
195+
override fun loadTypeParameterAnnotations(typeParameterProto: ProtoBuf.TypeParameter, nameResolver: NameResolver): List<FirAnnotation> =
196+
loadAnnotationsFromMetadataIfNotEmpty(session, null, typeParameterProto.annotationList, nameResolver)
197+
?: super.loadTypeParameterAnnotations(typeParameterProto, nameResolver)
198+
}

compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AnnotationDeserializationUtil.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.protobuf.GeneratedMessageLite.ExtendableMessage
2424
import org.jetbrains.kotlin.serialization.deserialization.getClassId
2525
import org.jetbrains.kotlin.serialization.deserialization.getName
2626
import org.jetbrains.kotlin.types.ConstantValueKind
27+
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
2728
import org.jetbrains.kotlin.utils.addToStdlib.runIf
2829

2930
/**
@@ -38,7 +39,24 @@ fun loadAnnotationsFromMetadataGuarded(
3839
languageFeature: LanguageFeature,
3940
useSiteTarget: AnnotationUseSiteTarget? = null,
4041
): List<FirAnnotation>? =
41-
runIf(session.languageVersionSettings.supportsFeature(languageFeature) && annotations.isNotEmpty()) {
42+
runIf(session.languageVersionSettings.supportsFeature(languageFeature)) {
43+
loadAnnotationsFromMetadataIfNotEmpty(session, flags, annotations, nameResolver, useSiteTarget)
44+
}
45+
46+
/**
47+
* Loads annotations from metadata only when the given metadata [annotations] list is not empty.
48+
* Otherwise, returns null instead of an empty list to signal that the fallback annotation loading function should be called.
49+
*
50+
* Implemented for handling migration to the new approach of storing annotations both for klib and JVM backends.
51+
*/
52+
fun loadAnnotationsFromMetadataIfNotEmpty(
53+
session: FirSession,
54+
flags: Int?,
55+
annotations: List<ProtoBuf.Annotation>,
56+
nameResolver: NameResolver,
57+
useSiteTarget: AnnotationUseSiteTarget? = null,
58+
): List<FirAnnotation>? =
59+
annotations.ifNotEmpty {
4260
loadAnnotationsFromMetadata(session, flags, annotations, nameResolver, useSiteTarget)
4361
}
4462

0 commit comments

Comments
 (0)