[K/N] Provide original class id for forward-declared declarataion
This commit is contained in:
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.getRefinedMemberScopeIfPossible
|
import org.jetbrains.kotlin.descriptors.impl.getRefinedMemberScopeIfPossible
|
||||||
import org.jetbrains.kotlin.descriptors.impl.getRefinedUnsubstitutedMemberScopeIfPossible
|
import org.jetbrains.kotlin.descriptors.impl.getRefinedUnsubstitutedMemberScopeIfPossible
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getKotlinTypeRefiner
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getKotlinTypeRefiner
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
@@ -226,6 +227,31 @@ private class SimpleTypeImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: a hack to support class descriptor overwriting in case of K/N forward declaration replacement and other such cases
|
||||||
|
class SupposititiousSimpleType(private val realType: SimpleType, val overwrittenClass: ClassId) : SimpleType() {
|
||||||
|
|
||||||
|
private fun maybeWrap(newType: SimpleType): SupposititiousSimpleType {
|
||||||
|
return if (newType === realType) this
|
||||||
|
else SupposititiousSimpleType(newType, overwrittenClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun replaceAnnotations(newAnnotations: Annotations): SimpleType =
|
||||||
|
maybeWrap(realType.replaceAnnotations(newAnnotations))
|
||||||
|
|
||||||
|
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType =
|
||||||
|
maybeWrap(realType.makeNullableAsSpecified(newNullability))
|
||||||
|
|
||||||
|
@TypeRefinement
|
||||||
|
override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): SimpleType =
|
||||||
|
maybeWrap(realType.refine(kotlinTypeRefiner))
|
||||||
|
|
||||||
|
override val constructor: TypeConstructor = realType.constructor
|
||||||
|
override val arguments: List<TypeProjection> = realType.arguments
|
||||||
|
override val isMarkedNullable: Boolean = realType.isMarkedNullable
|
||||||
|
override val memberScope: MemberScope = realType.memberScope
|
||||||
|
override val annotations: Annotations = realType.annotations
|
||||||
|
}
|
||||||
|
|
||||||
abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : DelegatingSimpleType() {
|
abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : DelegatingSimpleType() {
|
||||||
override fun replaceAnnotations(newAnnotations: Annotations) =
|
override fun replaceAnnotations(newAnnotations: Annotations) =
|
||||||
if (newAnnotations !== annotations)
|
if (newAnnotations !== annotations)
|
||||||
|
|||||||
+32
-2
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotations
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotations
|
||||||
@@ -94,8 +96,25 @@ class TypeDeserializer(
|
|||||||
KotlinTypeFactory.simpleType(annotations, constructor, arguments, proto.nullable)
|
KotlinTypeFactory.simpleType(annotations, constructor, arguments, proto.nullable)
|
||||||
}
|
}
|
||||||
|
|
||||||
val abbreviatedTypeProto = proto.abbreviatedType(c.typeTable) ?: return simpleType
|
val computedType = proto.abbreviatedType(c.typeTable)?.let {
|
||||||
return simpleType.withAbbreviation(simpleType(abbreviatedTypeProto))
|
simpleType.withAbbreviation(simpleType(it))
|
||||||
|
} ?: simpleType
|
||||||
|
|
||||||
|
// TODO: move this hack in some platform specific place ASAP
|
||||||
|
if (proto.hasClassName()) {
|
||||||
|
val classId = c.nameResolver.getClassId(proto.className)
|
||||||
|
val originalPackageFqn = classId.packageFqName
|
||||||
|
if (originalPackageFqn in forwardPackagesSet) {
|
||||||
|
// This hack is about keeping original class id written into proto which is required for correct IR linkage
|
||||||
|
val classDescriptor = constructor.declarationDescriptor as ClassDescriptor
|
||||||
|
val realPackageFqn = (classDescriptor.containingDeclaration as PackageFragmentDescriptor).fqName
|
||||||
|
if (originalPackageFqn != realPackageFqn) {
|
||||||
|
return SupposititiousSimpleType(computedType, classId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return computedType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor {
|
private fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor {
|
||||||
@@ -253,4 +272,15 @@ class TypeDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() = debugName + (if (parent == null) "" else ". Child of ${parent.debugName}")
|
override fun toString() = debugName + (if (parent == null) "" else ". Child of ${parent.debugName}")
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val cNames = FqName("cnames")
|
||||||
|
private val cNamesStructs = cNames.child(Name.identifier("structs"))
|
||||||
|
|
||||||
|
private val objCNames = FqName("objcnames")
|
||||||
|
private val objCNamesClasses = objCNames.child(Name.identifier("classes"))
|
||||||
|
private val objCNamesProtocols = objCNames.child(Name.identifier("protocols"))
|
||||||
|
|
||||||
|
private val forwardPackagesSet = setOf(cNamesStructs, objCNamesClasses, objCNamesProtocols)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user