diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt index aca8868a00a..1044169a0da 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt @@ -44,66 +44,7 @@ import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed */ abstract class IrBasedDeclarationDescriptor(val owner: T) : DeclarationDescriptor { - override val annotations: Annotations by lazy { - val ownerAnnotations = (owner as? IrAnnotationContainer)?.annotations ?: return@lazy Annotations.EMPTY - Annotations.create(ownerAnnotations.memoryOptimizedMap { it.toAnnotationDescriptor() }) - } - - private fun IrConstructorCall.toAnnotationDescriptor(): AnnotationDescriptor { - val annotationClass = symbol.owner.parentAsClass - - @OptIn(ObsoleteDescriptorBasedAPI::class) - if (annotationClass.symbol.descriptor == ErrorUtils.errorClass) { - // This should be possible only in case of KAPT3 where IR generated by psi2ir can have annotations with unresolved types. - // Apparently annotations with unresolved types is a useful feature for KAPT3 in the "correct error types mode", see kt32596.kt. - // This is a hack which should preferably be removed as soon as KAPT3 is no longer used. - return AnnotationDescriptorImpl(type.toKotlinType(), emptyMap(), source) - } - - assert(annotationClass.isAnnotationClass) { - "Expected call to constructor of annotation class but was: ${this.dump()}" - } - return AnnotationDescriptorImpl( - annotationClass.defaultType.toIrBasedKotlinType(), - symbol.owner.valueParameters.memoryOptimizedMap { it.name to getValueArgument(it.index) } - .filter { it.second != null } - .associate { it.first to it.second!!.toConstantValue() }, - source - ) - } - - private fun IrElement.toConstantValue(): ConstantValue<*> { - return when (this) { - is IrConst<*> -> when (kind) { - IrConstKind.Null -> NullValue() - IrConstKind.Boolean -> BooleanValue(value as Boolean) - IrConstKind.Char -> CharValue(value as Char) - IrConstKind.Byte -> ByteValue(value as Byte) - IrConstKind.Short -> ShortValue(value as Short) - IrConstKind.Int -> IntValue(value as Int) - IrConstKind.Long -> LongValue(value as Long) - IrConstKind.String -> StringValue(value as String) - IrConstKind.Float -> FloatValue(value as Float) - IrConstKind.Double -> DoubleValue(value as Double) - } - - is IrVararg -> { - val elements = elements.memoryOptimizedMap { if (it is IrSpreadElement) error("$it is not expected") else it.toConstantValue() } - ArrayValue(elements) { moduleDescriptor -> - // TODO: substitute. - moduleDescriptor.builtIns.array.defaultType - } - } - - is IrGetEnumValue -> EnumValue(symbol.owner.parentAsClass.toIrBasedDescriptor().classId!!, symbol.owner.name) - - is IrClassReference -> KClassValue((classType.classifierOrFail.owner as IrClass).toIrBasedDescriptor().classId!!, /*TODO*/0) - - is IrConstructorCall -> AnnotationValue(this.toAnnotationDescriptor()) - - else -> error("$this is not expected: ${this.dump()}") - } - } + override val annotations: Annotations by lazy(owner::toAnnotations) @OptIn(ObsoleteDescriptorBasedAPI::class) protected fun IrType.toIrBasedKotlinType(): KotlinType = toIrBasedKotlinType(owner.module.builtIns) @@ -922,19 +863,27 @@ open class IrBasedPropertyDescriptor(owner: IrProperty) : override val isDelegated get() = owner.isDelegated - override fun getBackingField(): FieldDescriptor? { - TODO("not implemented") - } + override fun getBackingField(): FieldDescriptor? = + owner.backingField?.toIrBackingFieldDescriptor(isDelegate = false, correspondingProperty = this) - override fun getDelegateField(): FieldDescriptor? { - TODO("not implemented") - } + override fun getDelegateField(): FieldDescriptor? = + owner.backingField?.toIrBackingFieldDescriptor(isDelegate = true, correspondingProperty = this) override fun getInType(): KotlinType? = setter?.valueParameters?.get(0)?.type override fun getUserData(key: CallableDescriptor.UserDataKey?): V? = null } +private fun IrField.toIrBackingFieldDescriptor( + isDelegate: Boolean, + correspondingProperty: PropertyDescriptor, +): IrBasedBackingFieldDescriptor? = + if (isDelegate == (origin == IrDeclarationOrigin.PROPERTY_DELEGATE)) { + IrBasedBackingFieldDescriptor(this, correspondingProperty) + } else { + null + } + fun IrProperty.toIrBasedDescriptor() = IrBasedPropertyDescriptor(this) abstract class IrBasedPropertyAccessorDescriptor(owner: IrSimpleFunction) : IrBasedSimpleFunctionDescriptor(owner), @@ -959,6 +908,15 @@ open class IrBasedPropertyGetterDescriptor(owner: IrSimpleFunction) : IrBasedPro visitor!!.visitPropertyGetterDescriptor(this, data) } +class IrBasedBackingFieldDescriptor(val owner: IrField, override val correspondingProperty: PropertyDescriptor) : FieldDescriptor { + + override val annotations: Annotations by lazy(owner::toAnnotations) + + override fun equals(other: Any?): Boolean = other is IrBasedBackingFieldDescriptor && owner == other.owner + + override fun hashCode(): Int = owner.hashCode() +} + open class IrBasedPropertySetterDescriptor(owner: IrSimpleFunction) : IrBasedPropertyAccessorDescriptor(owner), PropertySetterDescriptor { override fun getOverriddenDescriptors() = super.getOverriddenDescriptors().memoryOptimizedMap { it as PropertySetterDescriptor } @@ -1119,8 +1077,11 @@ open class IrBasedFieldDescriptor(owner: IrField) : PropertyDescriptor, IrBasedD override val isDelegated get() = false // Following functions are used in error reporting when rendering annotations on properties - override fun getBackingField(): FieldDescriptor? = null // TODO - override fun getDelegateField(): FieldDescriptor? = null // TODO + override fun getBackingField(): FieldDescriptor? = + owner.toIrBackingFieldDescriptor(isDelegate = false, correspondingProperty = this) + + override fun getDelegateField(): FieldDescriptor? = + owner.toIrBackingFieldDescriptor(isDelegate = true, correspondingProperty = this) override fun getInType(): KotlinType? = setter?.valueParameters?.get(0)?.type @@ -1269,3 +1230,64 @@ private fun IrScriptSymbol.toIrBasedDescriptorIfPossible(): ScriptDescriptor = d // see comment above to IrScriptSymbol.toIrBasedDescriptorIfPossible() @OptIn(ObsoleteDescriptorBasedAPI::class) private fun IrScript.toIrBasedDescriptor() = descriptor + +private fun IrElement.toConstantValue(): ConstantValue<*> { + return when (this) { + is IrConst<*> -> when (kind) { + IrConstKind.Null -> NullValue() + IrConstKind.Boolean -> BooleanValue(value as Boolean) + IrConstKind.Char -> CharValue(value as Char) + IrConstKind.Byte -> ByteValue(value as Byte) + IrConstKind.Short -> ShortValue(value as Short) + IrConstKind.Int -> IntValue(value as Int) + IrConstKind.Long -> LongValue(value as Long) + IrConstKind.String -> StringValue(value as String) + IrConstKind.Float -> FloatValue(value as Float) + IrConstKind.Double -> DoubleValue(value as Double) + } + + is IrVararg -> { + val elements = elements.memoryOptimizedMap { if (it is IrSpreadElement) error("$it is not expected") else it.toConstantValue() } + ArrayValue(elements) { moduleDescriptor -> + // TODO: substitute. + moduleDescriptor.builtIns.array.defaultType + } + } + + is IrGetEnumValue -> EnumValue(symbol.owner.parentAsClass.toIrBasedDescriptor().classId!!, symbol.owner.name) + + is IrClassReference -> KClassValue((classType.classifierOrFail.owner as IrClass).toIrBasedDescriptor().classId!!, /*TODO*/0) + + is IrConstructorCall -> AnnotationValue(this.toAnnotationDescriptor()) + + else -> error("$this is not expected: ${this.dump()}") + } +} + +private fun IrConstructorCall.toAnnotationDescriptor(): AnnotationDescriptor { + val annotationClass = symbol.owner.parentAsClass + + @OptIn(ObsoleteDescriptorBasedAPI::class) + if (annotationClass.symbol.descriptor == ErrorUtils.errorClass) { + // This should be possible only in case of KAPT3 where IR generated by psi2ir can have annotations with unresolved types. + // Apparently annotations with unresolved types is a useful feature for KAPT3 in the "correct error types mode", see kt32596.kt. + // This is a hack which should preferably be removed as soon as KAPT3 is no longer used. + return AnnotationDescriptorImpl(type.toKotlinType(), emptyMap(), source) + } + + assert(annotationClass.isAnnotationClass) { + "Expected call to constructor of annotation class but was: ${this.dump()}" + } + return AnnotationDescriptorImpl( + annotationClass.defaultType.toIrBasedKotlinType(), + symbol.owner.valueParameters.memoryOptimizedMap { it.name to getValueArgument(it.index) } + .filter { it.second != null } + .associate { it.first to it.second!!.toConstantValue() }, + source + ) +} + +private fun IrDeclaration.toAnnotations(): Annotations { + val ownerAnnotations = (this as? IrAnnotationContainer)?.annotations ?: return Annotations.EMPTY + return Annotations.create(ownerAnnotations.memoryOptimizedMap(IrConstructorCall::toAnnotationDescriptor)) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/klibSerializationTests/signatureClash.diag.txt b/compiler/testData/diagnostics/klibSerializationTests/signatureClash.diag.txt index e99ba770625..5cc28ad37f4 100644 --- a/compiler/testData/diagnostics/klibSerializationTests/signatureClash.diag.txt +++ b/compiler/testData/diagnostics/klibSerializationTests/signatureClash.diag.txt @@ -3,20 +3,58 @@ fun foo(): kotlin.String defined in com.example.klib.serialization.diagnostics fun foo(): kotlin.Int defined in com.example.klib.serialization.diagnostics -/main.kt:19:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/foo|foo(){}[0]): +/foo.kt:16:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal|{}myVal[0]): + val myVal: kotlin.String defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics + +/foo.kt:16:1: error: Platform declaration clash: The following declarations have the same IR signature ([ com.example.klib.serialization.diagnostics/myVal|{}myVal[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:myVal type:kotlin.Long visibility:private [static]] ]): + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics + +/foo.kt:16:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal.|(){}[0]): + fun ``(): kotlin.Int defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.Long defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.String defined in com.example.klib.serialization.diagnostics + +/main.kt:21:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/foo|foo(){}[0]): fun foo(): kotlin.Long defined in com.example.klib.serialization.diagnostics fun foo(): kotlin.String defined in com.example.klib.serialization.diagnostics fun foo(): kotlin.Int defined in com.example.klib.serialization.diagnostics -/main.kt:22:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/foo|foo(){}[0]): +/main.kt:24:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/foo|foo(){}[0]): fun foo(): kotlin.Long defined in com.example.klib.serialization.diagnostics fun foo(): kotlin.String defined in com.example.klib.serialization.diagnostics fun foo(): kotlin.Int defined in com.example.klib.serialization.diagnostics -/main.kt:35:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/bar|bar(){}[0]): +/main.kt:26:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal|{}myVal[0]): + val myVal: kotlin.String defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics + +/main.kt:26:1: error: Platform declaration clash: The following declarations have the same IR signature ([ com.example.klib.serialization.diagnostics/myVal|{}myVal[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:myVal type:kotlin.Long visibility:private [static]] ]): + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics + +/main.kt:26:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal.|(){}[0]): + fun ``(): kotlin.Int defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.Long defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.String defined in com.example.klib.serialization.diagnostics + +/main.kt:29:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal|{}myVal[0]): + val myVal: kotlin.String defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics + +/main.kt:31:5: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal.|(){}[0]): + fun ``(): kotlin.Int defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.Long defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.String defined in com.example.klib.serialization.diagnostics + +/main.kt:44:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/bar|bar(){}[0]): fun bar(): kotlin.Long defined in com.example.klib.serialization.diagnostics fun bar(): kotlin.Long defined in com.example.klib.serialization.diagnostics -/main.kt:38:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/bar|bar(){}[0]): +/main.kt:47:1: error: Platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/bar|bar(){}[0]): fun bar(): kotlin.Long defined in com.example.klib.serialization.diagnostics fun bar(): kotlin.Long defined in com.example.klib.serialization.diagnostics diff --git a/compiler/testData/diagnostics/klibSerializationTests/signatureClash.kt b/compiler/testData/diagnostics/klibSerializationTests/signatureClash.kt index 88d9e0041a2..afa1011009c 100644 --- a/compiler/testData/diagnostics/klibSerializationTests/signatureClash.kt +++ b/compiler/testData/diagnostics/klibSerializationTests/signatureClash.kt @@ -13,6 +13,8 @@ package com.example.klib.serialization.diagnostics @Deprecated("", level = DeprecationLevel.HIDDEN) fun foo(): Long = 0L +var myVal: Long = 0L + // FILE: main.kt package com.example.klib.serialization.diagnostics @@ -21,6 +23,13 @@ fun foo(): String = "" fun foo(): Int = 0 +@Deprecated("", level = DeprecationLevel.HIDDEN) +var myVal: Int = 0 + +@Deprecated("", level = DeprecationLevel.HIDDEN) +val myVal: String + get() = "" + @Deprecated("This function moved to the 'lib' module", level = DeprecationLevel.HIDDEN) fun movedToLib() {} diff --git a/native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt b/native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt index 66535ff82be..4584cd85c5b 100644 --- a/native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt +++ b/native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt @@ -7,9 +7,18 @@ class A { fun foo(): Int = 0 } +var myVal: Long = 0L + @Deprecated("This function moved to the 'lib' module", level = DeprecationLevel.HIDDEN) fun movedToLib() {} +@Deprecated("", level = DeprecationLevel.HIDDEN) +var myVal: Int = 0 + +@Deprecated("", level = DeprecationLevel.HIDDEN) +val myVal: String + get() = "" + fun main() { println(A().foo()) movedToLib() diff --git a/native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/output.txt b/native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/output.txt index 00d81c2c03a..d62adbf2840 100644 --- a/native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/output.txt +++ b/native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/output.txt @@ -8,4 +8,50 @@ native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:7: fun foo(): kotlin.Int defined in com.example.klib.serialization.diagnostics.A fun foo(): Int = 0 ^^^^^^^^^^^^^^^^^^ +native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:10:1: error: platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal|{}myVal[0]): + val myVal: kotlin.String defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics +var myVal: Long = 0L +^^^^^^^^^^^^^^^^^^^^ +native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:10:1: error: platform declaration clash: The following declarations have the same IR signature ([ com.example.klib.serialization.diagnostics/myVal|{}myVal[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:myVal type:kotlin.Long visibility:private [static]] ]): + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics +var myVal: Long = 0L +^^^^^^^^^^^^^^^^^^^^ +native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:10:1: error: platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal.|(){}[0]): + fun ``(): kotlin.Int defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.Long defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.String defined in com.example.klib.serialization.diagnostics +var myVal: Long = 0L +^^^^^^^^^^^^^^^^^^^^ +native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:15:1: error: platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal|{}myVal[0]): + val myVal: kotlin.String defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics +@Deprecated("", level = DeprecationLevel.HIDDEN) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:15:1: error: platform declaration clash: The following declarations have the same IR signature ([ com.example.klib.serialization.diagnostics/myVal|{}myVal[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:myVal type:kotlin.Long visibility:private [static]] ]): + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics +@Deprecated("", level = DeprecationLevel.HIDDEN) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:15:1: error: platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal.|(){}[0]): + fun ``(): kotlin.Int defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.Long defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.String defined in com.example.klib.serialization.diagnostics +@Deprecated("", level = DeprecationLevel.HIDDEN) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:18:1: error: platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal|{}myVal[0]): + val myVal: kotlin.String defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Int defined in com.example.klib.serialization.diagnostics + var myVal: kotlin.Long defined in com.example.klib.serialization.diagnostics +@Deprecated("", level = DeprecationLevel.HIDDEN) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +native/native.tests/testData/compilerOutput/SignatureClashDiagnostics/main.kt:20:5: error: platform declaration clash: The following declarations have the same IR signature (com.example.klib.serialization.diagnostics/myVal.|(){}[0]): + fun ``(): kotlin.Int defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.Long defined in com.example.klib.serialization.diagnostics + fun ``(): kotlin.String defined in com.example.klib.serialization.diagnostics + get() = "" + ^^^^^^^^^^ COMPILATION_ERROR