Do not load implClassName JVM proto extension
Use JvmPackagePartSource instead for functions/properties in package parts, check containing class kind for properties in interfaces
This commit is contained in:
@@ -21,12 +21,11 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaStaticClassScope
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
fun copyValueParameters(
|
||||
@@ -34,7 +33,7 @@ fun copyValueParameters(
|
||||
oldValueParameters: Collection<ValueParameterDescriptor>,
|
||||
newOwner: CallableDescriptor
|
||||
): List<ValueParameterDescriptor> {
|
||||
assert(newValueParametersTypes.size() == oldValueParameters.size()) {
|
||||
assert(newValueParametersTypes.size == oldValueParameters.size) {
|
||||
"Different value parameters sizes: Enhanced = ${newValueParametersTypes.size}, Old = ${oldValueParameters.size}"
|
||||
}
|
||||
|
||||
@@ -45,14 +44,14 @@ fun copyValueParameters(
|
||||
newOwner,
|
||||
oldParameter,
|
||||
oldParameter.index,
|
||||
oldParameter.getAnnotations(),
|
||||
oldParameter.getName(),
|
||||
oldParameter.annotations,
|
||||
oldParameter.name,
|
||||
newType,
|
||||
oldParameter.declaresDefaultValue(),
|
||||
oldParameter.isCrossinline,
|
||||
oldParameter.isNoinline,
|
||||
if (oldParameter.varargElementType != null) newOwner.module.builtIns.getArrayElementType(newType) else null,
|
||||
oldParameter.getSource()
|
||||
oldParameter.source
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -68,19 +67,5 @@ fun ClassDescriptor.getParentJavaStaticClassScope(): LazyJavaStaticClassScope? {
|
||||
}
|
||||
|
||||
fun DeserializedCallableMemberDescriptor.getImplClassNameForDeserialized(): Name? {
|
||||
val proto = proto
|
||||
return when (proto) {
|
||||
is ProtoBuf.Constructor ->
|
||||
null
|
||||
is ProtoBuf.Function ->
|
||||
if (proto.hasExtension(JvmProtoBuf.methodImplClassName))
|
||||
proto.getExtension(JvmProtoBuf.methodImplClassName)
|
||||
else null
|
||||
is ProtoBuf.Property ->
|
||||
if (proto.hasExtension(JvmProtoBuf.propertyImplClassName))
|
||||
proto.getExtension(JvmProtoBuf.propertyImplClassName)
|
||||
else null
|
||||
else ->
|
||||
error("Unknown message: $proto")
|
||||
}?.let { nameResolver.getName(it) }
|
||||
return (packagePartSource as? JvmPackagePartSource)?.className?.fqNameForClassNameWithoutDollars?.shortName()
|
||||
}
|
||||
|
||||
+34
-50
@@ -21,13 +21,13 @@ import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.*
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.index
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.propertySignature
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -95,26 +95,26 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
val fieldSignature = getPropertySignature(proto, container.nameResolver, container.typeTable, field = true)
|
||||
|
||||
val propertyAnnotations = syntheticFunctionSignature?.let { sig ->
|
||||
findClassAndLoadMemberAnnotations(container, proto, sig)
|
||||
findClassAndLoadMemberAnnotations(container, sig, property = true)
|
||||
}.orEmpty()
|
||||
|
||||
val fieldAnnotations = fieldSignature?.let { sig ->
|
||||
findClassAndLoadMemberAnnotations(container, proto, sig, field = true)
|
||||
findClassAndLoadMemberAnnotations(container, sig, property = true, field = true)
|
||||
}.orEmpty()
|
||||
|
||||
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations)
|
||||
}
|
||||
|
||||
val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, kind) ?: return emptyList()
|
||||
return transformAnnotations(findClassAndLoadMemberAnnotations(container, proto, signature))
|
||||
return transformAnnotations(findClassAndLoadMemberAnnotations(container, signature))
|
||||
}
|
||||
|
||||
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<A> {
|
||||
val signature = MemberSignature.fromFieldNameAndDesc(
|
||||
container.nameResolver.getString(proto.name),
|
||||
ClassMapperLite.mapClass(container.nameResolver.getClassId((container as ProtoContainer.Class).classProto.fqName))
|
||||
ClassMapperLite.mapClass((container as ProtoContainer.Class).classId)
|
||||
)
|
||||
return findClassAndLoadMemberAnnotations(container, proto, signature)
|
||||
return findClassAndLoadMemberAnnotations(container, signature)
|
||||
}
|
||||
|
||||
protected abstract fun loadPropertyAnnotations(propertyAnnotations: List<A>, fieldAnnotations: List<A>): List<T>
|
||||
@@ -122,13 +122,10 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
protected abstract fun transformAnnotations(annotations: List<A>): List<T>
|
||||
|
||||
private fun findClassAndLoadMemberAnnotations(
|
||||
container: ProtoContainer, proto: MessageLite, signature: MemberSignature, field: Boolean = false
|
||||
container: ProtoContainer, signature: MemberSignature, property: Boolean = false, field: Boolean = false
|
||||
): List<A> {
|
||||
val kotlinClass = findClassWithAnnotationsAndInitializers(container, getImplClassName(proto, container.nameResolver), field)
|
||||
if (kotlinClass == null) {
|
||||
errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: ${container.debugFqName()}", null)
|
||||
return listOf()
|
||||
}
|
||||
val kotlinClass = findClassWithAnnotationsAndInitializers(container, getImplClassName(container, property), field)
|
||||
?: return listOf()
|
||||
|
||||
return storage(kotlinClass).memberAnnotations[signature] ?: listOf()
|
||||
}
|
||||
@@ -144,7 +141,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
if (methodSignature != null) {
|
||||
val index = if (proto.hasExtension(index)) proto.getExtension(index) else parameterIndex
|
||||
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, index)
|
||||
return findClassAndLoadMemberAnnotations(container, message, paramSignature)
|
||||
return findClassAndLoadMemberAnnotations(container, paramSignature)
|
||||
}
|
||||
|
||||
return listOf()
|
||||
@@ -158,7 +155,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
val methodSignature = getCallableSignature(message, container.nameResolver, container.typeTable, kind)
|
||||
if (methodSignature != null) {
|
||||
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, 0)
|
||||
return findClassAndLoadMemberAnnotations(container, message, paramSignature)
|
||||
return findClassAndLoadMemberAnnotations(container, paramSignature)
|
||||
}
|
||||
|
||||
return emptyList()
|
||||
@@ -173,54 +170,41 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
}
|
||||
|
||||
override fun loadPropertyConstant(container: ProtoContainer, proto: ProtoBuf.Property, expectedType: KotlinType): C? {
|
||||
val nameResolver = container.nameResolver
|
||||
val signature = getCallableSignature(proto, nameResolver, container.typeTable, AnnotatedCallableKind.PROPERTY) ?: return null
|
||||
val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, AnnotatedCallableKind.PROPERTY)
|
||||
?: return null
|
||||
|
||||
val kotlinClass = findClassWithAnnotationsAndInitializers(container, getImplClassName(proto, nameResolver), field = true)
|
||||
if (kotlinClass == null) {
|
||||
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.debugFqName()}", null)
|
||||
return null
|
||||
}
|
||||
val kotlinClass = findClassWithAnnotationsAndInitializers(container, getImplClassName(container, property = true), field = true)
|
||||
?: return null
|
||||
|
||||
return storage(kotlinClass).propertyConstants[signature]
|
||||
}
|
||||
|
||||
private fun findClassWithAnnotationsAndInitializers(
|
||||
container: ProtoContainer, implClassName: Name?, field: Boolean
|
||||
): KotlinJvmBinaryClass? = when (container) {
|
||||
is ProtoContainer.Package -> {
|
||||
implClassName?.let { kotlinClassFinder.findKotlinClass(ClassId(container.fqName, it)) }
|
||||
container: ProtoContainer, implClassName: ClassId?, field: Boolean
|
||||
): KotlinJvmBinaryClass? {
|
||||
if (implClassName != null) {
|
||||
return kotlinClassFinder.findKotlinClass(implClassName)
|
||||
}
|
||||
is ProtoContainer.Class -> {
|
||||
val classId = container.nameResolver.getClassId(container.classProto.fqName)
|
||||
|
||||
if (implClassName != null) {
|
||||
// TODO: store accurate name for nested traits
|
||||
val implClassId =
|
||||
if (implClassName.asString().endsWith(JvmAbi.DEFAULT_IMPLS_SUFFIX))
|
||||
ClassId(classId.packageFqName, FqName(implClassName.asString().replace(JvmAbi.DEFAULT_IMPLS_SUFFIX, "." + JvmAbi.DEFAULT_IMPLS_CLASS_NAME)), false)
|
||||
else
|
||||
ClassId(classId.packageFqName, implClassName)
|
||||
kotlinClassFinder.findKotlinClass(implClassId)
|
||||
}
|
||||
else if (field && container.isCompanionOfClass) {
|
||||
if (container is ProtoContainer.Class) {
|
||||
if (field && container.isCompanionOfClass) {
|
||||
// Backing fields of properties of a companion object in a class are generated in the outer class
|
||||
kotlinClassFinder.findKotlinClass(classId.outerClassId)
|
||||
}
|
||||
else {
|
||||
kotlinClassFinder.findKotlinClass(classId)
|
||||
return kotlinClassFinder.findKotlinClass(container.classId.outerClassId)
|
||||
}
|
||||
|
||||
return kotlinClassFinder.findKotlinClass(container.classId)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getImplClassName(proto: MessageLite, nameResolver: NameResolver): Name? =
|
||||
when {
|
||||
proto is ProtoBuf.Function && proto.hasExtension(methodImplClassName) ->
|
||||
nameResolver.getName(proto.getExtension(methodImplClassName))
|
||||
proto is ProtoBuf.Property && proto.hasExtension(propertyImplClassName) ->
|
||||
nameResolver.getName(proto.getExtension(propertyImplClassName))
|
||||
else -> null
|
||||
}
|
||||
private fun getImplClassName(container: ProtoContainer, property: Boolean): ClassId? {
|
||||
if (property && container is ProtoContainer.Class && container.isInterface) {
|
||||
return container.classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME))
|
||||
}
|
||||
return ((container as? ProtoContainer.Package)?.packagePartSource as? JvmPackagePartSource)
|
||||
?.className?.fqNameForClassNameWithoutDollars?.let { ClassId.topLevel(it) }
|
||||
}
|
||||
|
||||
private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): Storage<A, C> {
|
||||
val memberAnnotations = HashMap<MemberSignature, MutableList<A>>()
|
||||
|
||||
+2
-1
@@ -248,7 +248,8 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
||||
is DeserializedClassDescriptor -> ProtoContainer.Class(
|
||||
classProto, c.nameResolver, c.typeTable,
|
||||
isCompanionOfClass = DescriptorUtils.isCompanionObject(this) &&
|
||||
containingDeclaration.let { DescriptorUtils.isClass(it) || DescriptorUtils.isEnumClass(it) }
|
||||
containingDeclaration.let { DescriptorUtils.isClass(it) || DescriptorUtils.isEnumClass(it) },
|
||||
isInterface = kind == ClassKind.INTERFACE
|
||||
)
|
||||
else -> null // TODO: support annotations on lambdas and their parameters
|
||||
}
|
||||
|
||||
+6
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.serialization.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.PackagePartSource
|
||||
@@ -28,9 +29,12 @@ sealed class ProtoContainer(
|
||||
val classProto: ProtoBuf.Class,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable,
|
||||
val isCompanionOfClass: Boolean
|
||||
val isCompanionOfClass: Boolean,
|
||||
val isInterface: Boolean
|
||||
) : ProtoContainer(nameResolver, typeTable) {
|
||||
override fun debugFqName(): FqName = nameResolver.getClassId(classProto.fqName).asSingleFqName()
|
||||
val classId: ClassId = nameResolver.getClassId(classProto.fqName)
|
||||
|
||||
override fun debugFqName(): FqName = classId.asSingleFqName()
|
||||
}
|
||||
|
||||
class Package(
|
||||
|
||||
+2
-1
@@ -296,7 +296,8 @@ public class DeserializedClassDescriptor(
|
||||
val annotations = enumEntryProtos[name]?.let { proto ->
|
||||
DeserializedAnnotations(c.storageManager) {
|
||||
c.components.annotationAndConstantLoader.loadEnumEntryAnnotations(
|
||||
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false), proto
|
||||
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false, isInterface = false),
|
||||
proto
|
||||
)
|
||||
}
|
||||
} ?: if (name in oldEnumEntryNames) Annotations.EMPTY
|
||||
|
||||
+4
-3
@@ -68,6 +68,7 @@ private class ClassClsStubBuilder(
|
||||
return classKind == ProtoBuf.Class.Kind.COMPANION_OBJECT &&
|
||||
(outerContext.classKind?.let { it == ProtoBuf.Class.Kind.CLASS || it == ProtoBuf.Class.Kind.ENUM_CLASS } ?: false)
|
||||
}
|
||||
private val isInterface: Boolean get() = classKind == ProtoBuf.Class.Kind.INTERFACE
|
||||
|
||||
private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
|
||||
|
||||
@@ -142,7 +143,7 @@ private class ClassClsStubBuilder(
|
||||
val primaryConstructorProto = classProto.constructorList.find { !Flags.IS_SECONDARY.get(it.flags) } ?: return
|
||||
|
||||
createConstructorStub(classOrObjectStub, primaryConstructorProto, c,
|
||||
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass))
|
||||
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass, isInterface))
|
||||
}
|
||||
|
||||
private fun createDelegationSpecifierList() {
|
||||
@@ -180,7 +181,7 @@ private class ClassClsStubBuilder(
|
||||
private fun createEnumEntryStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
|
||||
if (classKind != ProtoBuf.Class.Kind.ENUM_CLASS) return
|
||||
|
||||
val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false)
|
||||
val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass, isInterface)
|
||||
val enumEntries: List<Pair<Int, List<ClassId>>> =
|
||||
if (classProto.enumEntryList.isNotEmpty())
|
||||
classProto.enumEntryList.map { enumEntryProto ->
|
||||
@@ -211,7 +212,7 @@ private class ClassClsStubBuilder(
|
||||
}
|
||||
|
||||
private fun createCallableMemberStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
|
||||
val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass)
|
||||
val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass, isInterface)
|
||||
|
||||
for (secondaryConstructorProto in classProto.constructorList) {
|
||||
if (Flags.IS_SECONDARY.get(secondaryConstructorProto.flags)) {
|
||||
|
||||
Reference in New Issue
Block a user