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>>()
|
||||
|
||||
Reference in New Issue
Block a user