Deserialize property and field annotations
This commit is contained in:
@@ -140,7 +140,7 @@ public class JvmSerializerExtension extends SerializerExtension {
|
|||||||
fieldType = field.first;
|
fieldType = field.first;
|
||||||
fieldName = field.second;
|
fieldName = field.second;
|
||||||
isStaticInOuter = bindings.get(STATIC_FIELD_IN_OUTER_CLASS, property);
|
isStaticInOuter = bindings.get(STATIC_FIELD_IN_OUTER_CLASS, property);
|
||||||
syntheticMethod = null;
|
syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, property);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fieldType = null;
|
fieldType = null;
|
||||||
|
|||||||
+30
-15
@@ -34,6 +34,9 @@ import org.jetbrains.kotlin.types.JetType
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind.PROPERTY_SYNTHETIC_FUNCTION
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind.PROPERTY_FIELD
|
||||||
|
|
||||||
public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>(
|
public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>(
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
private val kotlinClassFinder: KotlinClassFinder,
|
private val kotlinClassFinder: KotlinClassFinder,
|
||||||
@@ -182,11 +185,14 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
|||||||
val classProto = container.classProto!!
|
val classProto = container.classProto!!
|
||||||
val classKind = Flags.CLASS_KIND[classProto.getFlags()]
|
val classKind = Flags.CLASS_KIND[classProto.getFlags()]
|
||||||
val classId = nameResolver.getClassId(classProto.getFqName())
|
val classId = nameResolver.getClassId(classProto.getFqName())
|
||||||
if (classKind == ProtoBuf.Class.Kind.CLASS_OBJECT && isStaticFieldInOuter(proto)) {
|
|
||||||
|
if (classKind == ProtoBuf.Class.Kind.CLASS_OBJECT && isStaticFieldInOuter(proto)
|
||||||
|
&& annotatedCallableKind != AnnotatedCallableKind.PROPERTY_SYNTHETIC_FUNCTION) {
|
||||||
// Backing fields of properties of a companion object are generated in the outer class
|
// Backing fields of properties of a companion object are generated in the outer class
|
||||||
return kotlinClassFinder.findKotlinClass(classId.getOuterClassId())
|
return kotlinClassFinder.findKotlinClass(classId.getOuterClassId())
|
||||||
}
|
}
|
||||||
else if (classKind == ProtoBuf.Class.Kind.TRAIT && annotatedCallableKind == AnnotatedCallableKind.PROPERTY) {
|
else if (classKind == ProtoBuf.Class.Kind.TRAIT &&
|
||||||
|
(annotatedCallableKind == PROPERTY_SYNTHETIC_FUNCTION || annotatedCallableKind == PROPERTY_FIELD)) {
|
||||||
if (proto.hasExtension(implClassName)) {
|
if (proto.hasExtension(implClassName)) {
|
||||||
val parentPackageFqName = classId.getPackageFqName()
|
val parentPackageFqName = classId.getPackageFqName()
|
||||||
val tImplName = nameResolver.getName(proto.getExtension(implClassName))
|
val tImplName = nameResolver.getName(proto.getExtension(implClassName))
|
||||||
@@ -282,6 +288,25 @@ private fun getCallableSignature(
|
|||||||
kind: AnnotatedCallableKind
|
kind: AnnotatedCallableKind
|
||||||
): MemberSignature? {
|
): MemberSignature? {
|
||||||
val deserializer = SignatureDeserializer(nameResolver)
|
val deserializer = SignatureDeserializer(nameResolver)
|
||||||
|
|
||||||
|
fun getPropertySignature(handleField: Boolean = false, handleSynthetic: Boolean = false): MemberSignature? {
|
||||||
|
if (!proto.hasExtension(propertySignature)) return null
|
||||||
|
|
||||||
|
val propertySignature = proto.getExtension(propertySignature)
|
||||||
|
|
||||||
|
if (handleField && propertySignature.hasField()) {
|
||||||
|
val field = propertySignature.getField()
|
||||||
|
val type = deserializer.typeDescriptor(field.getType())
|
||||||
|
val name = nameResolver.getName(field.getName())
|
||||||
|
return MemberSignature.fromFieldNameAndDesc(name, type)
|
||||||
|
}
|
||||||
|
else if (handleSynthetic && propertySignature.hasSyntheticMethod()) {
|
||||||
|
return deserializer.methodSignature(propertySignature.getSyntheticMethod())
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
when (kind) {
|
when (kind) {
|
||||||
AnnotatedCallableKind.FUNCTION -> if (proto.hasExtension(methodSignature)) {
|
AnnotatedCallableKind.FUNCTION -> if (proto.hasExtension(methodSignature)) {
|
||||||
return deserializer.methodSignature(proto.getExtension(methodSignature))
|
return deserializer.methodSignature(proto.getExtension(methodSignature))
|
||||||
@@ -292,19 +317,9 @@ private fun getCallableSignature(
|
|||||||
AnnotatedCallableKind.PROPERTY_SETTER -> if (proto.hasExtension(propertySignature)) {
|
AnnotatedCallableKind.PROPERTY_SETTER -> if (proto.hasExtension(propertySignature)) {
|
||||||
return deserializer.methodSignature(proto.getExtension(propertySignature).getSetter())
|
return deserializer.methodSignature(proto.getExtension(propertySignature).getSetter())
|
||||||
}
|
}
|
||||||
AnnotatedCallableKind.PROPERTY -> if (proto.hasExtension(propertySignature)) {
|
AnnotatedCallableKind.PROPERTY -> return getPropertySignature(true, true)
|
||||||
val propertySignature = proto.getExtension(propertySignature)
|
AnnotatedCallableKind.PROPERTY_FIELD -> return getPropertySignature(handleField = true)
|
||||||
|
AnnotatedCallableKind.PROPERTY_SYNTHETIC_FUNCTION -> return getPropertySignature(handleSynthetic = true)
|
||||||
if (propertySignature.hasField()) {
|
|
||||||
val field = propertySignature.getField()
|
|
||||||
val type = deserializer.typeDescriptor(field.getType())
|
|
||||||
val name = nameResolver.getName(field.getName())
|
|
||||||
return MemberSignature.fromFieldNameAndDesc(name, type)
|
|
||||||
}
|
|
||||||
else if (propertySignature.hasSyntheticMethod()) {
|
|
||||||
return deserializer.methodSignature(propertySignature.getSyntheticMethod())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -43,6 +43,7 @@ class BuiltInsAnnotationAndConstantLoader(
|
|||||||
nameResolver: NameResolver,
|
nameResolver: NameResolver,
|
||||||
kind: AnnotatedCallableKind
|
kind: AnnotatedCallableKind
|
||||||
): List<AnnotationDescriptor> {
|
): List<AnnotationDescriptor> {
|
||||||
|
if (kind == AnnotatedCallableKind.PROPERTY_FIELD) return emptyList()
|
||||||
val annotations = proto.getExtension(BuiltInsProtoBuf.callableAnnotation).orEmpty()
|
val annotations = proto.getExtension(BuiltInsProtoBuf.callableAnnotation).orEmpty()
|
||||||
return annotations.map { proto -> deserializer.deserializeAnnotation(proto, nameResolver) }
|
return annotations.map { proto -> deserializer.deserializeAnnotation(proto, nameResolver) }
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.serialization.deserialization;
|
|||||||
public enum AnnotatedCallableKind {
|
public enum AnnotatedCallableKind {
|
||||||
FUNCTION,
|
FUNCTION,
|
||||||
PROPERTY,
|
PROPERTY,
|
||||||
|
PROPERTY_SYNTHETIC_FUNCTION,
|
||||||
|
PROPERTY_FIELD,
|
||||||
PROPERTY_GETTER,
|
PROPERTY_GETTER,
|
||||||
PROPERTY_SETTER
|
PROPERTY_SETTER
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-12
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.serialization.deserialization
|
package org.jetbrains.kotlin.serialization.deserialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
@@ -31,7 +32,6 @@ import org.jetbrains.kotlin.serialization.ProtoBuf.Callable.CallableKind.VAL
|
|||||||
import org.jetbrains.kotlin.serialization.ProtoBuf.Callable.CallableKind.VAR
|
import org.jetbrains.kotlin.serialization.ProtoBuf.Callable.CallableKind.VAR
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
import org.jetbrains.kotlin.utils.toReadOnlyList
|
||||||
import org.jetbrains.kotlin.utils.sure
|
|
||||||
|
|
||||||
public class MemberDeserializer(private val c: DeserializationContext) {
|
public class MemberDeserializer(private val c: DeserializationContext) {
|
||||||
public fun loadCallable(proto: Callable): CallableMemberDescriptor {
|
public fun loadCallable(proto: Callable): CallableMemberDescriptor {
|
||||||
@@ -48,7 +48,7 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
|
|
||||||
val property = DeserializedPropertyDescriptor(
|
val property = DeserializedPropertyDescriptor(
|
||||||
c.containingDeclaration, null,
|
c.containingDeclaration, null,
|
||||||
getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY),
|
getPropertyAnnotations(proto),
|
||||||
modality(Flags.MODALITY.get(flags)),
|
modality(Flags.MODALITY.get(flags)),
|
||||||
visibility(Flags.VISIBILITY.get(flags)),
|
visibility(Flags.VISIBILITY.get(flags)),
|
||||||
Flags.CALLABLE_KIND.get(flags) == Callable.CallableKind.VAR,
|
Flags.CALLABLE_KIND.get(flags) == Callable.CallableKind.VAR,
|
||||||
@@ -185,22 +185,36 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getPropertyAnnotations(proto: Callable): Annotations {
|
||||||
|
return DeserializedAnnotationsWithPossibleTargets(c.storageManager) {
|
||||||
|
val annotations = arrayListOf<AnnotationWithTarget>()
|
||||||
|
val container = c.containingDeclaration.asProtoContainer()
|
||||||
|
|
||||||
|
fun loadAnnotations(kind: AnnotatedCallableKind, mapper: (AnnotationDescriptor) -> AnnotationWithTarget) {
|
||||||
|
annotations += c.components.annotationAndConstantLoader.loadCallableAnnotations(
|
||||||
|
container, proto, c.nameResolver, kind
|
||||||
|
).map(mapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAnnotations(AnnotatedCallableKind.PROPERTY_SYNTHETIC_FUNCTION) { AnnotationWithTarget(it, null) }
|
||||||
|
loadAnnotations(AnnotatedCallableKind.PROPERTY_FIELD) { AnnotationWithTarget(it, AnnotationUseSiteTarget.FIELD) }
|
||||||
|
|
||||||
|
annotations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getReceiverParameterAnnotations(
|
private fun getReceiverParameterAnnotations(
|
||||||
proto: Callable,
|
proto: Callable,
|
||||||
kind: AnnotatedCallableKind,
|
kind: AnnotatedCallableKind,
|
||||||
receiverTargetedKind: AnnotatedCallableKind = kind
|
receiverTargetedKind: AnnotatedCallableKind = kind
|
||||||
): Annotations {
|
): Annotations {
|
||||||
return DeserializedAnnotationsWithPossibleTargets(c.storageManager) {
|
return DeserializedAnnotationsWithPossibleTargets(c.storageManager) {
|
||||||
val annotations = arrayListOf<AnnotationWithTarget>()
|
|
||||||
val container = c.containingDeclaration.asProtoContainer()
|
|
||||||
|
|
||||||
if (proto.hasReceiverType()) {
|
if (proto.hasReceiverType()) {
|
||||||
annotations += c.components.annotationAndConstantLoader
|
val container = c.containingDeclaration.asProtoContainer()
|
||||||
|
c.components.annotationAndConstantLoader
|
||||||
.loadExtensionReceiverParameterAnnotations(container, proto, c.nameResolver, receiverTargetedKind)
|
.loadExtensionReceiverParameterAnnotations(container, proto, c.nameResolver, receiverTargetedKind)
|
||||||
.map { AnnotationWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
|
.map { AnnotationWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
|
||||||
}
|
} else emptyList()
|
||||||
|
|
||||||
annotations
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,9 +241,6 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
kind: AnnotatedCallableKind,
|
kind: AnnotatedCallableKind,
|
||||||
valueParameter: Callable.ValueParameter
|
valueParameter: Callable.ValueParameter
|
||||||
): Annotations {
|
): Annotations {
|
||||||
if (!Flags.HAS_ANNOTATIONS.get(valueParameter.getFlags())) {
|
|
||||||
return Annotations.EMPTY
|
|
||||||
}
|
|
||||||
return DeserializedAnnotations(c.storageManager) {
|
return DeserializedAnnotations(c.storageManager) {
|
||||||
c.components.annotationAndConstantLoader.loadValueParameterAnnotations(container, callable, c.nameResolver, kind, valueParameter)
|
c.components.annotationAndConstantLoader.loadValueParameterAnnotations(container, callable, c.nameResolver, kind, valueParameter)
|
||||||
}
|
}
|
||||||
@@ -240,4 +251,9 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
is DeserializedClassDescriptor -> ProtoContainer(classProto, null)
|
is DeserializedClassDescriptor -> ProtoContainer(classProto, null)
|
||||||
else -> error("Only members in classes or package fragments should be serialized: $this")
|
else -> error("Only members in classes or package fragments should be serialized: $this")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
val CONSTRUCTOR_PARAMETER_ANNOTATION_MAPPER =
|
||||||
|
{ a: AnnotationDescriptor -> AnnotationWithTarget(a, AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -37,8 +37,10 @@ public class AnnotationLoaderForKotlinJavaScriptStubBuilder() : AnnotationAndCon
|
|||||||
proto: ProtoBuf.Callable,
|
proto: ProtoBuf.Callable,
|
||||||
nameResolver: NameResolver,
|
nameResolver: NameResolver,
|
||||||
kind: AnnotatedCallableKind
|
kind: AnnotatedCallableKind
|
||||||
): List<ClassId> =
|
): List<ClassId> {
|
||||||
proto.getExtension(JsProtoBuf.callableAnnotation).orEmpty().map { nameResolver.getClassId(it.getId()) }
|
if (kind == AnnotatedCallableKind.PROPERTY_FIELD) return emptyList()
|
||||||
|
return proto.getExtension(JsProtoBuf.callableAnnotation).orEmpty().map { nameResolver.getClassId(it.getId()) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun loadValueParameterAnnotations(
|
override fun loadValueParameterAnnotations(
|
||||||
container: ProtoContainer,
|
container: ProtoContainer,
|
||||||
|
|||||||
+1
@@ -42,6 +42,7 @@ class KotlinJavascriptAnnotationAndConstantLoader(
|
|||||||
nameResolver: NameResolver,
|
nameResolver: NameResolver,
|
||||||
kind: AnnotatedCallableKind
|
kind: AnnotatedCallableKind
|
||||||
): List<AnnotationDescriptor> {
|
): List<AnnotationDescriptor> {
|
||||||
|
if (kind == AnnotatedCallableKind.PROPERTY_FIELD) return emptyList()
|
||||||
val annotations = proto.getExtension(JsProtoBuf.callableAnnotation).orEmpty()
|
val annotations = proto.getExtension(JsProtoBuf.callableAnnotation).orEmpty()
|
||||||
return annotations.map { proto -> deserializer.deserializeAnnotation(proto, nameResolver) }
|
return annotations.map { proto -> deserializer.deserializeAnnotation(proto, nameResolver) }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user