[IR] Consider TypeParameter as public declaration and serialize it properly
- Add test case when TypeParameter of generic property is exposed outside its module
This commit is contained in:
-1
@@ -42,7 +42,6 @@ abstract class DeclarationTable(val builtIns: IrBuiltIns, val descriptorTable: D
|
||||
val index = if (value.origin == IrDeclarationOrigin.FAKE_OVERRIDE ||
|
||||
!value.isExported()
|
||||
|| value is IrVariable
|
||||
|| (value is IrTypeParameter && value.parent !is IrClass)
|
||||
|| value is IrValueParameter
|
||||
|| value is IrAnonymousInitializerImpl
|
||||
) {
|
||||
|
||||
+12
-3
@@ -7,10 +7,8 @@ package org.jetbrains.kotlin.backend.common.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.serialization.UniqIdKey
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.backend.common.serialization.resolveFakeOverrideMaybeAbstract
|
||||
import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -136,7 +134,18 @@ abstract class DescriptorReferenceDeserializer(
|
||||
}
|
||||
|
||||
if (isTypeParameter) {
|
||||
return clazz!!.declaredTypeParameters.first { it.name.asString() == name }
|
||||
|
||||
for (m in (listOfNotNull(clazz) + members)) {
|
||||
val typeParameters = when (m) {
|
||||
is PropertyDescriptor -> m.typeParameters
|
||||
is ClassDescriptor -> m.declaredTypeParameters
|
||||
is SimpleFunctionDescriptor -> m.typeParameters
|
||||
is ClassConstructorDescriptor -> m.typeParameters
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
typeParameters.firstOrNull { it.getUniqId() == index }?.let { return it }
|
||||
}
|
||||
}
|
||||
|
||||
if (protoIndex?.let { checkIfSpecialDescriptorId(it) } == true) {
|
||||
|
||||
+24
-18
@@ -27,11 +27,13 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
// TODO: This code still has some uses of descriptors:
|
||||
@@ -823,12 +825,15 @@ abstract class IrModuleDeserializer(
|
||||
val symbol = deserializeIrSymbol(proto.symbol) as IrTypeParameterSymbol
|
||||
val name = deserializeName(proto.name)
|
||||
val variance = deserializeIrTypeVariance(proto.variance)
|
||||
val descriptor = symbol.descriptor
|
||||
|
||||
val parameter = symbolTable.declareGlobalTypeParameter(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||
symbol.descriptor
|
||||
) {
|
||||
IrTypeParameterImpl(start, end, origin, it, name, proto.index, proto.isReified, variance)
|
||||
val parameter = if (descriptor is DeserializedTypeParameterDescriptor && descriptor.containingDeclaration is PropertyDescriptor && symbol.isBound) {
|
||||
// TODO: Get rid of once new properties are implemented
|
||||
IrTypeParameterImpl(start, end, origin, IrTypeParameterSymbolImpl(descriptor), name, proto.index, proto.isReified, variance)
|
||||
} else {
|
||||
symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin, descriptor) {
|
||||
IrTypeParameterImpl(start, end, origin, it, name, proto.index, proto.isReified, variance)
|
||||
}
|
||||
}
|
||||
|
||||
val superTypes = proto.superTypeList.map { deserializeIrType(it) }
|
||||
@@ -966,19 +971,20 @@ abstract class IrModuleDeserializer(
|
||||
val symbol = deserializeIrSymbol(proto.symbol) as IrSimpleFunctionSymbol
|
||||
|
||||
val function = symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||
symbol.descriptor, {
|
||||
IrFunctionImpl(
|
||||
start, end, origin, it,
|
||||
deserializeName(proto.base.name),
|
||||
deserializeVisibility(proto.base.visibility),
|
||||
deserializeModality(proto.modality),
|
||||
deserializeIrType(proto.base.returnType),
|
||||
proto.base.isInline,
|
||||
proto.base.isExternal,
|
||||
proto.isTailrec,
|
||||
proto.isSuspend
|
||||
)
|
||||
})
|
||||
symbol.descriptor
|
||||
) {
|
||||
IrFunctionImpl(
|
||||
start, end, origin, it,
|
||||
deserializeName(proto.base.name),
|
||||
deserializeVisibility(proto.base.visibility),
|
||||
deserializeModality(proto.modality),
|
||||
deserializeIrType(proto.base.returnType),
|
||||
proto.base.isInline,
|
||||
proto.base.isExternal,
|
||||
proto.isTailrec,
|
||||
proto.isSuspend
|
||||
)
|
||||
}
|
||||
|
||||
deserializeIrFunctionBase(proto.base, function as IrFunctionBase, start, end, origin)
|
||||
val overridden = proto.overriddenList.map { deserializeIrSymbol(it) as IrSimpleFunctionSymbol }
|
||||
|
||||
+8
-2
@@ -200,8 +200,14 @@ abstract class KotlinManglerImpl: KotlinMangler {
|
||||
|
||||
val IrTypeParameter.symbolName: String
|
||||
get() {
|
||||
val containingDeclarationPart = parent.fqNameForIrSerialization
|
||||
return "ktypeparam:$containingDeclarationPart$name"
|
||||
|
||||
val parentDeclaration = (parent as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: parent
|
||||
val containingDeclarationPart = when (parentDeclaration) {
|
||||
is IrDeclarationParent -> parentDeclaration.fqNameUnique.asString()
|
||||
is IrProperty -> "${parentDeclaration.parent.fqNameUnique}.${parentDeclaration.name}"
|
||||
else -> error("Unexpected type parameter parent")
|
||||
}
|
||||
return "ktypeparam:$containingDeclarationPart$name@$index"
|
||||
}
|
||||
|
||||
// This is a little extension over what's used in real mangling
|
||||
|
||||
+31
-15
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.util.isAccessor
|
||||
import org.jetbrains.kotlin.ir.util.isGetter
|
||||
import org.jetbrains.kotlin.ir.util.isSetter
|
||||
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
|
||||
@@ -26,6 +27,21 @@ open class DescriptorReferenceSerializer(
|
||||
return DescriptorFactory.isEnumValueOfMethod(descriptor) || DescriptorFactory.isEnumValuesMethod(descriptor)
|
||||
}
|
||||
|
||||
fun extractPackageAndClassFqns(descriptor: DeclarationDescriptor): Pair<String, String>? {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
return when (containingDeclaration) {
|
||||
is ClassDescriptor -> {
|
||||
val classId = containingDeclaration.classId ?: return null
|
||||
Pair(classId.packageFqName.toString(), classId.relativeClassName.toString())
|
||||
}
|
||||
is PackageFragmentDescriptor -> Pair(containingDeclaration.fqName.toString(), "")
|
||||
is PropertyDescriptor -> if (descriptor !is TypeParameterDescriptor) null else {
|
||||
extractPackageAndClassFqns(containingDeclaration)
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
}
|
||||
|
||||
// Not all exported descriptors are deserialized, some a synthesized anew during metadata deserialization.
|
||||
// Those created descriptors can't carry the uniqIdIndex, since it is available only for deserialized descriptors.
|
||||
// So we record the uniq id of some other "discoverable" descriptor for which we know for sure that it will be
|
||||
@@ -40,21 +56,10 @@ open class DescriptorReferenceSerializer(
|
||||
}
|
||||
if (declaration is IrAnonymousInitializer) return null
|
||||
|
||||
if (descriptor is ParameterDescriptor ||
|
||||
(descriptor is VariableDescriptor && descriptor !is PropertyDescriptor)
|
||||
|| (declaration is IrTypeParameter && declaration.parent !is IrClass)
|
||||
) return null
|
||||
if (descriptor is ParameterDescriptor || (descriptor is VariableDescriptor && descriptor !is PropertyDescriptor)) return null
|
||||
|
||||
val containingDeclaration = descriptor.containingDeclaration!!
|
||||
|
||||
val (packageFqName, classFqName) = when (containingDeclaration) {
|
||||
is ClassDescriptor -> {
|
||||
val classId = containingDeclaration.classId ?: return null
|
||||
Pair(classId.packageFqName.toString(), classId.relativeClassName.toString())
|
||||
}
|
||||
is PackageFragmentDescriptor -> Pair(containingDeclaration.fqName.toString(), "")
|
||||
else -> return null
|
||||
}
|
||||
val (packageFqName, classFqName) = extractPackageAndClassFqns(descriptor) ?: return null
|
||||
|
||||
val isAccessor = declaration.isAccessor
|
||||
val isBackingField = declaration is IrField && declaration.correspondingProperty != null
|
||||
@@ -62,7 +67,7 @@ open class DescriptorReferenceSerializer(
|
||||
val isDefaultConstructor = descriptor is ClassConstructorDescriptor && containingDeclaration is ClassDescriptor && (containingDeclaration.kind == ClassKind.OBJECT)
|
||||
val isEnumEntry = descriptor is ClassDescriptor && descriptor.kind == ClassKind.ENUM_ENTRY
|
||||
val isEnumSpecial = isEnumSpecialMember(descriptor)
|
||||
val isTypeParameter = declaration is IrTypeParameter && declaration.parent is IrClass
|
||||
val isTypeParameter = declaration is IrTypeParameter
|
||||
|
||||
// The corresponding descriptor in deserialized metadata has constructors = emptyList() etc.
|
||||
if (containingDeclaration is ClassDescriptor &&
|
||||
@@ -90,13 +95,24 @@ open class DescriptorReferenceSerializer(
|
||||
realDeclaration
|
||||
}
|
||||
|
||||
val nameString = if (isTypeParameter) {
|
||||
val parent = declaration.parent
|
||||
val typeParameterContainer = when (parent) {
|
||||
is IrClass -> parent
|
||||
is IrSimpleFunction -> parent.correspondingPropertySymbol?.owner ?: parent
|
||||
is IrConstructor -> parent
|
||||
else -> error("unknown type parameter container type")
|
||||
}
|
||||
typeParameterContainer.descriptor.name.asString()
|
||||
} else descriptor.name.toString()
|
||||
|
||||
val uniqId = discoverableDescriptorsDeclaration?.let { declarationTable.uniqIdByDeclaration(it) }
|
||||
uniqId?.let { declarationTable.descriptors.put(discoverableDescriptorsDeclaration.descriptor, it) }
|
||||
|
||||
val proto = KotlinIr.DescriptorReference.newBuilder()
|
||||
.setPackageFqName(serializeString(packageFqName))
|
||||
.setClassFqName(serializeString(classFqName))
|
||||
.setName(serializeString(descriptor.name.toString()))
|
||||
.setName(serializeString(nameString))
|
||||
|
||||
if (uniqId != null) proto.setUniqId(protoUniqId(uniqId))
|
||||
|
||||
|
||||
+2
-4
@@ -9,10 +9,7 @@ import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
|
||||
import org.jetbrains.kotlin.backend.common.serialization.tryGetExtension
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||
|
||||
object JsDescriptorUniqIdAware: DescriptorUniqIdAware {
|
||||
override fun DeclarationDescriptor.getUniqId(): Long? = when (this) {
|
||||
@@ -20,6 +17,7 @@ object JsDescriptorUniqIdAware: DescriptorUniqIdAware {
|
||||
is DeserializedSimpleFunctionDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.functionUniqId)
|
||||
is DeserializedPropertyDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.propertyUniqId)
|
||||
is DeserializedClassConstructorDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.constructorUniqId)
|
||||
is DeserializedTypeParameterDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.typeParamUniqId)
|
||||
else -> null
|
||||
}?.index
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// WITH_RUNTIME
|
||||
// MODULE: lib
|
||||
// FILE: common.kt
|
||||
|
||||
class C<T>(var t: T)
|
||||
|
||||
var <T> C<T>.live: T
|
||||
get() {
|
||||
return t
|
||||
}
|
||||
set(value) {
|
||||
t = value
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
import kotlin.reflect.KMutableProperty0
|
||||
|
||||
fun qux(text: KMutableProperty0<String>): String {
|
||||
text.set("OK")
|
||||
return text.get()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val c = C("FAIL")
|
||||
return qux(c::live)
|
||||
}
|
||||
+5
@@ -17993,6 +17993,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/properties/generalAccess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericPropertyMultiModule.kt")
|
||||
public void testGenericPropertyMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/genericPropertyMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaPropertyBoxedGetter.kt")
|
||||
public void testJavaPropertyBoxedGetter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/javaPropertyBoxedGetter.kt");
|
||||
|
||||
+5
@@ -17993,6 +17993,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/properties/generalAccess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericPropertyMultiModule.kt")
|
||||
public void testGenericPropertyMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/genericPropertyMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaPropertyBoxedGetter.kt")
|
||||
public void testJavaPropertyBoxedGetter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/javaPropertyBoxedGetter.kt");
|
||||
|
||||
+5
@@ -17998,6 +17998,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/properties/generalAccess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericPropertyMultiModule.kt")
|
||||
public void testGenericPropertyMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/genericPropertyMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaPropertyBoxedGetter.kt")
|
||||
public void testJavaPropertyBoxedGetter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/javaPropertyBoxedGetter.kt");
|
||||
|
||||
Generated
+5
@@ -14028,6 +14028,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/properties/generalAccess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericPropertyMultiModule.kt")
|
||||
public void testGenericPropertyMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/genericPropertyMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt10715.kt")
|
||||
public void testKt10715() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/kt10715.kt");
|
||||
|
||||
+5
@@ -15183,6 +15183,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/properties/generalAccess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericPropertyMultiModule.kt")
|
||||
public void testGenericPropertyMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/genericPropertyMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt10715.kt")
|
||||
public void testKt10715() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/kt10715.kt");
|
||||
|
||||
Reference in New Issue
Block a user