[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
@@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
import org.jetbrains.kotlin.KtPsiSourceFile
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols
|
||||
@@ -37,7 +38,6 @@ import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.collectExportedNames
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
@@ -529,7 +529,11 @@ class GenerateIrRuntime {
|
||||
|
||||
|
||||
private fun doSerializeIrModule(module: IrModuleFragment): SerializedIrModule {
|
||||
val serializedIr = JsIrModuleSerializer(
|
||||
return JsIrModuleSerializer(
|
||||
KtDiagnosticReporterWithImplicitIrBasedContext(
|
||||
DiagnosticReporterFactory.createPendingReporter(),
|
||||
configuration.languageVersionSettings,
|
||||
),
|
||||
IrMessageLogger.None,
|
||||
module.irBuiltins,
|
||||
CompatibilityMode.CURRENT,
|
||||
@@ -537,7 +541,6 @@ class GenerateIrRuntime {
|
||||
emptyList(),
|
||||
configuration.languageVersionSettings,
|
||||
).serializedIrModule(module)
|
||||
return serializedIr
|
||||
}
|
||||
|
||||
private fun doWriteIrModuleToStorage(serializedIrModule: SerializedIrModule, writer: KotlinLibraryOnlyIrWriter) {
|
||||
|
||||
@@ -211,6 +211,15 @@ fun main(args: Array<String>) {
|
||||
model("debug/localVariables")
|
||||
}
|
||||
|
||||
testClass<AbstractFirPsiJsDiagnosticWithBackendTest>(suiteTestClassName = "FirPsiJsKlibDiagnosticsTestGenerated") {
|
||||
model(
|
||||
relativeRootPath = "diagnostics/klibSerializationTests",
|
||||
pattern = "^([^_](.+))\\.kt$",
|
||||
excludedPattern = excludedFirTestdataPattern,
|
||||
targetBackend = TargetBackend.JS_IR
|
||||
)
|
||||
}
|
||||
|
||||
testClass<AbstractFirPsiJsDiagnosticTest>(suiteTestClassName = "FirPsiJsOldFrontendDiagnosticsTestGenerated") {
|
||||
model(
|
||||
relativeRootPath = "diagnostics/testsWithJsStdLib",
|
||||
|
||||
+3
-1
@@ -164,5 +164,7 @@ fun <
|
||||
irHandlersStep()
|
||||
|
||||
facadeStep(backendFacade)
|
||||
klibArtifactsHandlersStep()
|
||||
klibArtifactsHandlersStep {
|
||||
useHandlers(::JsBackendDiagnosticsHandler)
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.js.test.fir;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateJsTestsKt}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/diagnostics/klibSerializationTests")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class FirPsiJsKlibDiagnosticsTestGenerated extends AbstractFirPsiJsDiagnosticWithBackendTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInKlibSerializationTests() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/klibSerializationTests"), Pattern.compile("^([^_](.+))\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("signatureClash.kt")
|
||||
public void testSignatureClash() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/klibSerializationTests/signatureClash.kt");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user