diff --git a/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/IrActualizationErrors.kt b/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/IrActualizationErrors.kt index 25874a754dc..471bebb3e42 100644 --- a/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/IrActualizationErrors.kt +++ b/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/IrActualizationErrors.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.ir.IrDiagnosticRenderers import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.types.classFqName +import org.jetbrains.kotlin.ir.util.RenderIrElementVisitorForDiagnosticText import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility @@ -80,14 +80,21 @@ internal object IrActualizationDiagnosticRenderers { } val EXPECT_ACTUAL_ANNOTATION_INCOMPATIBILITY = Renderer { incompatibilityType: ExpectActualAnnotationsIncompatibilityType -> - val expectAnnotationFqName = incompatibilityType.expectAnnotation.type.classFqName ?: "" + val expectAnnotation = ANNOTATION.render(incompatibilityType.expectAnnotation) val reason = when (incompatibilityType) { is ExpectActualAnnotationsIncompatibilityType.MissingOnActual -> "is missing on actual declaration" - is ExpectActualAnnotationsIncompatibilityType.DifferentOnActual -> "has different arguments on actual declaration" + is ExpectActualAnnotationsIncompatibilityType.DifferentOnActual -> { + val actualAnnotation = ANNOTATION.render(incompatibilityType.actualAnnotation) + "has different arguments on actual declaration: `$actualAnnotation`" + } } - "Annotation `$expectAnnotationFqName` $reason" + "Annotation `$expectAnnotation` $reason" } + private val ANNOTATION = Renderer { + "@" + RenderIrElementVisitorForDiagnosticText.renderAsAnnotation(it) + } + @JvmField val MODULE_WITH_PLATFORM = Renderer { module -> val platform = module.platform diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index a81202ce977..49126f69776 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.ifTrue fun IrElement.render(options: DumpIrTreeOptions = DumpIrTreeOptions()) = accept(RenderIrElementVisitor(options), null) -class RenderIrElementVisitor(private val options: DumpIrTreeOptions = DumpIrTreeOptions()) : +open class RenderIrElementVisitor(private val options: DumpIrTreeOptions = DumpIrTreeOptions()) : IrElementVisitor { private val variableNameData = VariableNameData(options.normalizeNames) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElementVisitorForDiagnosticText.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElementVisitorForDiagnosticText.kt new file mode 100644 index 00000000000..8b961a8a221 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElementVisitorForDiagnosticText.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.util + +import org.jetbrains.kotlin.ir.expressions.IrClassReference +import org.jetbrains.kotlin.ir.expressions.IrConstructorCall +import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue +import org.jetbrains.kotlin.ir.types.classOrFail + +/** + * This class can be used to beautifully print IR elements for compiler diagnostics, unlike + * the original [RenderIrElementVisitor] which is used in tests for rendering tree dumps. + */ +class RenderIrElementVisitorForDiagnosticText private constructor() : RenderIrElementVisitor() { + override fun visitClassReference(expression: IrClassReference, data: Nothing?): String { + val className = expression.classType.classOrFail.owner.name + return "$className::class" + } + + override fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?): String { + val className = expression.type.classOrFail.owner.name + val entryName = expression.symbol.owner.name + return "$className.$entryName" + } + + companion object { + fun renderAsAnnotation(annotation: IrConstructorCall): String { + return RenderIrElementVisitorForDiagnosticText().renderAsAnnotation(annotation) + } + } +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/actualAnnotationsNotMatchExpect/annotationArgRendering.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/actualAnnotationsNotMatchExpect/annotationArgRendering.fir.kt index b96046cbf82..d94f9b6682c 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/actualAnnotationsNotMatchExpect/annotationArgRendering.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/actualAnnotationsNotMatchExpect/annotationArgRendering.fir.kt @@ -19,11 +19,11 @@ expect fun kclassArg() // MODULE: m1-jvm()()(m1-common) // FILE: jvm.kt -actual annotation class Ann +actual annotation class Ann -actual fun stringConcat() {} +actual fun stringConcat() {} // Not reported in K1, because supported starting from K2 -actual fun onType(): Any? = null +actual fun onType(): Any? = null -actual fun kclassArg() {} +actual fun kclassArg() {} diff --git a/compiler/testData/diagnostics/tests/multiplatform/actualAnnotationsNotMatchExpect/checkDiagnosticFullText.fir.ir.diag.txt b/compiler/testData/diagnostics/tests/multiplatform/actualAnnotationsNotMatchExpect/checkDiagnosticFullText.fir.ir.diag.txt index e5b043f4e02..ab8d1730c84 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/actualAnnotationsNotMatchExpect/checkDiagnosticFullText.fir.ir.diag.txt +++ b/compiler/testData/diagnostics/tests/multiplatform/actualAnnotationsNotMatchExpect/checkDiagnosticFullText.fir.ir.diag.txt @@ -1,26 +1,26 @@ -/jvm.kt:(94,114): warning: Annotation `Ann` is missing on actual declaration. +/jvm.kt:(94,114): warning: Annotation `@Ann` is missing on actual declaration. All annotations from expect `OnClass` must be present with the same arguments on actual `OnClass`, otherwise they might behave incorrectly. -/jvm.kt:(144,168): warning: Annotation `Ann` is missing on actual declaration. +/jvm.kt:(144,168): warning: Annotation `@Ann` is missing on actual declaration. All annotations from expect `OnMember.onMember` must be present with the same arguments on actual `OnMember.onMember`, otherwise they might behave incorrectly. -/jvm.kt:(196,244): warning: Annotation `Ann` is missing on actual declaration. +/jvm.kt:(196,244): warning: Annotation `@Ann` is missing on actual declaration. All annotations from expect `ViaTypealias` must be present with the same arguments on actual `ViaTypealiasImpl`, otherwise they might behave incorrectly. -/jvm.kt:(301,371): warning: Annotation `Ann` is missing on actual declaration. +/jvm.kt:(301,371): warning: Annotation `@Ann` is missing on actual declaration. All annotations from expect `MemberScopeViaTypealias.foo` must be present with the same arguments on actual `MemberScopeViaTypealiasImpl.foo`, otherwise they might behave incorrectly. -/jvm.kt:(373,427): warning: Annotation `WithArg` has different arguments on actual declaration. +/jvm.kt:(373,427): warning: Annotation `@WithArg(s = 'str')` has different arguments on actual declaration: `@WithArg(s = 'other str')`. All annotations from expect `withDifferentArg` must be present with the same arguments on actual `withDifferentArg`, otherwise they might behave incorrectly. -/jvm.kt:(429,468): warning: Annotation `Ann` is missing on actual declaration. +/jvm.kt:(429,468): warning: Annotation `@Ann` is missing on actual declaration. All annotations from expect `inValueParam` must be present with the same arguments on actual `inValueParam`, otherwise they might behave incorrectly. -/jvm.kt:(470,501): warning: Annotation `Ann` is missing on actual declaration. +/jvm.kt:(470,501): warning: Annotation `@Ann` is missing on actual declaration. All annotations from expect `inTypeParam` must be present with the same arguments on actual `inTypeParam`, otherwise they might behave incorrectly. -/jvm.kt:(503,535): warning: Annotation `Ann` is missing on actual declaration. +/jvm.kt:(503,535): warning: Annotation `@Ann` is missing on actual declaration. All annotations from expect `` must be present with the same arguments on actual ``, otherwise they might behave incorrectly. -/jvm.kt:(537,569): warning: Annotation `Ann` is missing on actual declaration. +/jvm.kt:(537,569): warning: Annotation `@Ann` is missing on actual declaration. All annotations from expect `onType` must be present with the same arguments on actual `onType`, otherwise they might behave incorrectly.