[klib] Fix exception for clashing signatures from different modules
If we encounter a declaration in the current module whose signature
is the same as that of a declaration in another module which we happen
to also reference from the current module, don't report any errors,
just like we don't do it in Kotlin/JVM. This leaves the user in the KLIB
hell situation, but this is intentional, because otherwise a legitimate
change like moving a declaration to another module and marking
the original one as `@Deprecated("", level = DeprecationLevel.HIDDEN)`
would lead to a error, and we don't want that.
Also, don't try to show the diagnostics on a declaration that doesn't
have an IrFile.
^KT-65063 Fixed
This commit is contained in:
committed by
Space Team
parent
a5c8ecae0b
commit
6900e20096
@@ -9,7 +9,8 @@ import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1
|
||||
import org.jetbrains.kotlin.ir.IrDiagnosticReporter
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.util.file
|
||||
import org.jetbrains.kotlin.ir.util.fileOrNull
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.util.sourceElement
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
|
||||
@@ -53,17 +54,34 @@ abstract class SignatureClashDetector<Signature : Any, Declaration : IrDeclarati
|
||||
}
|
||||
}
|
||||
|
||||
protected inline fun <Data : Any, ConflictingDeclaration : IrDeclaration> reportSignatureClashTo(
|
||||
protected fun <Data : Any, ConflictingDeclaration : IrDeclaration> reportSignatureClashTo(
|
||||
diagnosticReporter: IrDiagnosticReporter,
|
||||
diagnosticFactory: KtDiagnosticFactory1<Data>,
|
||||
declarations: Collection<ConflictingDeclaration>,
|
||||
data: Data,
|
||||
reportOnIfSynthetic: (ConflictingDeclaration) -> IrElement,
|
||||
reportOnIfSynthetic: (ConflictingDeclaration) -> IrElement?,
|
||||
) {
|
||||
declarations.mapTo(LinkedHashSet()) { declaration ->
|
||||
val reportOn = declaration.takeUnless { it.startOffset < 0 } ?: reportOnIfSynthetic(declaration)
|
||||
diagnosticReporter.at(reportOn.sourceElement(), reportOn, declaration.file)
|
||||
}.forEach {
|
||||
val diagnostics = declarations.mapNotNullTo(LinkedHashSet()) { declaration ->
|
||||
// Declarations that come from other modules may not have a file, so we don't show diagnostics on them.
|
||||
val containingFile = declaration.fileOrNull ?: return@mapNotNullTo null
|
||||
val reportOn = declaration.takeUnless { it.startOffset < 0 } ?: reportOnIfSynthetic(declaration) ?: return@mapNotNullTo null
|
||||
diagnosticReporter.at(reportOn.sourceElement(), reportOn, containingFile)
|
||||
}
|
||||
|
||||
assert(diagnostics.isEmpty() == declarations.isEmpty()) {
|
||||
buildString {
|
||||
append("Different declarations with the same signatures were detected, but no diagnostics will be reported ")
|
||||
append("because none of those declarations have any source location info associated with them. ")
|
||||
append("This could happen because the declarations came from an external module, or were generated by a compiler plugin. ")
|
||||
appendLine("The following declarations have conflicting signatures:")
|
||||
for (declaration in declarations) {
|
||||
append(" - ")
|
||||
appendLine(declaration.render())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
diagnostics.forEach {
|
||||
it.report(diagnosticFactory, data)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user