[klib] Implement diagnostics for clashing KLIB signatures
Now, we detect clashing signatures during serialization to KLIB and
report a compiler error if two or more declarations have the same
`IdSignature`
For example, for the following code:
```kotlin
@Deprecated("", level = DeprecationLevel.HIDDEN)
fun foo(): String = ""
fun foo(): Int = 0
```
the compiler will produce this diagnostic:
```
e: main.kt:1:1 Platform declaration clash: The following declarations
have the same KLIB signature (/foo|foo(){}[0]):
fun foo(): String defined in root package
fun foo(): Int defined in root package
e: main.kt:4:1 Platform declaration clash: The following declarations
have the same KLIB signature (/foo|foo(){}[0]):
fun foo(): String defined in root package
fun foo(): Int defined in root package
```
Note that we report this diagnostic during serialization and not earlier
(e.g., in fir2ir) for more robustness, so ensure that we check
exactly the signatures that will be written to a KLIB.
If we later introduce some annotation for customizing a declaration's
signature (e.g., for preserving binary compatibility), this
diagnostic will continue to work as expected.
^KT-63670 Fixed
This commit is contained in:
committed by
Space Team
parent
e0cb145c6b
commit
eda30ff704
+14
-13
@@ -11,12 +11,14 @@ import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies.DECLA
|
||||
import org.jetbrains.kotlin.diagnostics.error0
|
||||
import org.jetbrains.kotlin.diagnostics.error1
|
||||
import org.jetbrains.kotlin.diagnostics.error2
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.*
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.NAME
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.utils.join
|
||||
|
||||
object JvmBackendErrors {
|
||||
val CONFLICTING_JVM_DECLARATIONS by error1<PsiElement, ConflictingJvmDeclarationsData>(DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
@@ -48,17 +50,16 @@ object JvmBackendErrors {
|
||||
object KtDefaultJvmErrorMessages : BaseDiagnosticRendererFactory() {
|
||||
|
||||
@JvmField
|
||||
val CONFLICTING_JVM_DECLARATIONS_DATA = Renderer<ConflictingJvmDeclarationsData> {
|
||||
val renderedDescriptors = it.signatureDescriptors.sortedWith(MemberComparator.INSTANCE)
|
||||
val renderingContext = RenderingContext.Impl(renderedDescriptors)
|
||||
"""
|
||||
The following declarations have the same JVM signature (${it.signature.name}${it.signature.desc}):
|
||||
|
||||
""".trimIndent() +
|
||||
join(renderedDescriptors.map { descriptor ->
|
||||
" " + Renderers.WITHOUT_MODIFIERS.render(descriptor, renderingContext)
|
||||
}, "\n")
|
||||
}
|
||||
val CONFLICTING_JVM_DECLARATIONS_DATA = CommonRenderers.renderConflictingSignatureData(
|
||||
signatureKind = "JVM",
|
||||
sortUsing = MemberComparator.INSTANCE,
|
||||
declarationRenderer = Renderers.WITHOUT_MODIFIERS,
|
||||
renderSignature = {
|
||||
append(it.signature.name)
|
||||
append(it.signature.desc)
|
||||
},
|
||||
declarations = ConflictingJvmDeclarationsData::signatureDescriptors,
|
||||
)
|
||||
|
||||
override val MAP = KtDiagnosticFactoryToRendererMap("KT").also { map ->
|
||||
map.put(JvmBackendErrors.CONFLICTING_JVM_DECLARATIONS, "Platform declaration clash: {0}", CONFLICTING_JVM_DECLARATIONS_DATA)
|
||||
|
||||
Reference in New Issue
Block a user