diff --git a/compiler/testData/ir/irText/fakeOverrides/fakeOverrideOfRaw.fir.sig.kt.txt b/compiler/testData/ir/irText/fakeOverrides/fakeOverrideOfRaw.fir.sig.kt.txt deleted file mode 100644 index 5439c7c9444..00000000000 --- a/compiler/testData/ir/irText/fakeOverrides/fakeOverrideOfRaw.fir.sig.kt.txt +++ /dev/null @@ -1,23 +0,0 @@ -// CHECK: -// Mangled name: A -// Public signature: /A|null[0] -class A : Java1 { - // CHECK: - // Mangled name: A#(){} - // Public signature: /A.|-5645683436151566731[0] - // Public signature debug description: (){} - constructor() /* primary */ - - // CHECK JVM_IR: - // Mangled name: A#bar(){}List? - // Public signature: /A.bar|-6805136188302315839[0] - // Public signature debug description: bar(){}List? - /* fake */ override fun bar(): List? - - // CHECK: - // Mangled name: A#foo(List?){} - // Public signature: /A.foo|-6260703452578085119[0] - // Public signature debug description: foo(List?){} - /* fake */ override fun foo(a: List?): Unit - -} diff --git a/compiler/testData/ir/irText/fakeOverrides/fakeOverrideOfRaw.kt b/compiler/testData/ir/irText/fakeOverrides/fakeOverrideOfRaw.kt index 463787da80f..b91f6f9de47 100644 --- a/compiler/testData/ir/irText/fakeOverrides/fakeOverrideOfRaw.kt +++ b/compiler/testData/ir/irText/fakeOverrides/fakeOverrideOfRaw.kt @@ -1,7 +1,6 @@ // FIR_IDENTICAL // ISSUE: KT-65298 // TARGET_BACKEND: JVM -// SEPARATE_SIGNATURE_DUMP_FOR_K2 // FILE: Java1.java public class Java1 { @@ -11,4 +10,4 @@ public class Java1 { // FILE: 1.kt class A : Java1() { -} \ No newline at end of file +} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/FirIrSourceRangesIdenticalChecker.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/FirIrSourceRangesIdenticalChecker.kt deleted file mode 100644 index 9217746bdc5..00000000000 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/FirIrSourceRangesIdenticalChecker.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.test.backend.handlers - -import org.jetbrains.kotlin.test.WrappedException -import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives -import org.jetbrains.kotlin.test.directives.model.DirectivesContainer -import org.jetbrains.kotlin.test.model.AfterAnalysisChecker -import org.jetbrains.kotlin.test.services.TestServices -import org.jetbrains.kotlin.test.services.moduleStructure -import org.jetbrains.kotlin.test.utils.FirIdenticalCheckerHelper -import org.jetbrains.kotlin.test.utils.withExtension -import java.io.File - -class FirIrSourceRangesIdenticalChecker(testServices: TestServices) : AfterAnalysisChecker(testServices) { - override val directiveContainers: List - get() = listOf(FirDiagnosticsDirectives) - - private val simpleChecker = object : FirIdenticalCheckerHelper(testServices) { - override fun getClassicFileToCompare(testDataFile: File): File? { - return testDataFile.withExtension(IrSourceRangesDumpHandler.DUMP_EXTENSION).takeIf { it.exists() } - } - - override fun getFirFileToCompare(testDataFile: File): File? { - return testDataFile.withExtension("fir.${IrSourceRangesDumpHandler.DUMP_EXTENSION}").takeIf { it.exists() } - } - } - - override fun check(failedAssertions: List) { - if (failedAssertions.isNotEmpty()) return - val testDataFile = testServices.moduleStructure.originalTestDataFiles.first() - if (FirDiagnosticsDirectives.FIR_IDENTICAL in testServices.moduleStructure.allDirectives) { - simpleChecker.deleteFirFile(testDataFile) - return - } - if (simpleChecker.firAndClassicContentsAreEquals(testDataFile)) { - simpleChecker.deleteFirFile(testDataFile) - simpleChecker.addDirectiveToClassicFileAndAssert(testDataFile) - } - } -} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrMangledNameAndSignatureDumpHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrMangledNameAndSignatureDumpHandler.kt index 914b2256b95..97094bb3e7f 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrMangledNameAndSignatureDumpHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrMangledNameAndSignatureDumpHandler.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.test.Constructor import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.backend.codegenSuppressionChecker import org.jetbrains.kotlin.test.backend.ir.IrBackendInput @@ -34,6 +35,7 @@ import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DUMP_SIGNATURE import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.MUTE_SIGNATURE_COMPARISON_K2 import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.SEPARATE_SIGNATURE_DUMP_FOR_K2 import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.FIR_IDENTICAL +import org.jetbrains.kotlin.test.model.AfterAnalysisChecker import org.jetbrains.kotlin.test.model.BackendKind import org.jetbrains.kotlin.test.model.FrontendKinds import org.jetbrains.kotlin.test.model.TestModule @@ -103,11 +105,32 @@ class IrMangledNameAndSignatureDumpHandler( companion object { const val DUMP_EXTENSION = "sig.kt.txt" + + private fun separateSignatureDirectiveNotPresent(testServices: TestServices): Boolean { + return SEPARATE_SIGNATURE_DUMP_FOR_K2 !in testServices.moduleStructure.allDirectives + } + } + + override val additionalAfterAnalysisCheckers: List> + get() = listOf(::IdenticalChecker) + + class IdenticalChecker(testServices: TestServices) : SimpleFirIrIdenticalChecker(testServices) { + override val dumpExtension: String + get() = DUMP_EXTENSION + + override fun markedAsIdentical(): Boolean { + return separateSignatureDirectiveNotPresent(testServices) + } + + override fun processClassicFileIfContentIsIdentical(testDataFile: File) { + simpleChecker.removeDirectiveFromClassicFileAndAssert(testDataFile, SEPARATE_SIGNATURE_DUMP_FOR_K2) + } } private fun computeDumpExtension(): String { - return if (testServices.defaultsProvider.defaultFrontend == FrontendKinds.ClassicFrontend || - SEPARATE_SIGNATURE_DUMP_FOR_K2 !in testServices.moduleStructure.allDirectives + return if ( + testServices.defaultsProvider.defaultFrontend == FrontendKinds.ClassicFrontend || + separateSignatureDirectiveNotPresent(testServices) ) { DUMP_EXTENSION } else { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrSourceRangesDumpHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrSourceRangesDumpHandler.kt index d5174966c25..ec00ed01c76 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrSourceRangesDumpHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrSourceRangesDumpHandler.kt @@ -40,7 +40,16 @@ class IrSourceRangesDumpHandler( get() = listOf(CodegenTestDirectives, FirDiagnosticsDirectives) override val additionalAfterAnalysisCheckers: List> - get() = listOf(::FirIrSourceRangesIdenticalChecker) + get() = listOf(::IdenticalChecker) + + class IdenticalChecker(testServices: TestServices) : SimpleFirIrIdenticalChecker(testServices) { + override val dumpExtension: String + get() = DUMP_EXTENSION + + override fun shouldRun(): Boolean { + return CodegenTestDirectives.DUMP_SOURCE_RANGES_IR in testServices.moduleStructure.allDirectives + } + } private val baseDumper = MultiModuleInfoDumper() private val buildersForSeparateFileDumps: MutableMap = mutableMapOf() diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/SimpleFirIrIdenticalChecker.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/SimpleFirIrIdenticalChecker.kt new file mode 100644 index 00000000000..d5c63a5c42a --- /dev/null +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/SimpleFirIrIdenticalChecker.kt @@ -0,0 +1,73 @@ +/* + * 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.test.backend.handlers + +import org.jetbrains.kotlin.test.WrappedException +import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives +import org.jetbrains.kotlin.test.directives.model.DirectivesContainer +import org.jetbrains.kotlin.test.model.AfterAnalysisChecker +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.moduleStructure +import org.jetbrains.kotlin.test.utils.FirIdenticalCheckerHelper +import org.jetbrains.kotlin.test.utils.withExtension +import java.io.File + +/** + * Use this checker as a base class if you need to check if K1 and K2 dumps are the same + * and add/remove some directive to the testdata file if they actually are + * + * Format of dump filename: + * - K1: `testName.dumpExtension` + * - K2: `testName.fir.dumpExtension` + * + * By default, this checker uses existence of `FIR_IDENTICAL` directive as a marker that dumps are identical + * This behavior can be tweaked by overriding [markedAsIdentical] and [processClassicFileIfContentIsIdentical] functions + * + * For example, [IrMangledNameAndSignatureDumpHandler.IdenticalChecker] uses lack of `SEPARATE_SIGNATURE_DUMP_FOR_K2` directive + * for this purpose + */ +abstract class SimpleFirIrIdenticalChecker(testServices: TestServices) : AfterAnalysisChecker(testServices) { + protected abstract val dumpExtension: String + + override val directiveContainers: List + get() = listOf(FirDiagnosticsDirectives) + + protected val simpleChecker = object : FirIdenticalCheckerHelper(testServices) { + override fun getClassicFileToCompare(testDataFile: File): File? { + return testDataFile.withExtension(dumpExtension).takeIf { it.exists() } + } + + override fun getFirFileToCompare(testDataFile: File): File? { + return testDataFile.withExtension("fir.${dumpExtension}").takeIf { it.exists() } + } + } + + protected open fun shouldRun(): Boolean { + return true + } + + override fun check(failedAssertions: List) { + if (!shouldRun()) return + if (failedAssertions.isNotEmpty()) return + val testDataFile = testServices.moduleStructure.originalTestDataFiles.first() + if (markedAsIdentical()) { + simpleChecker.deleteFirFile(testDataFile) + return + } + if (simpleChecker.firAndClassicContentsAreEquals(testDataFile)) { + simpleChecker.deleteFirFile(testDataFile) + processClassicFileIfContentIsIdentical(testDataFile) + } + } + + protected open fun markedAsIdentical(): Boolean { + return FirDiagnosticsDirectives.FIR_IDENTICAL in testServices.moduleStructure.allDirectives + } + + protected open fun processClassicFileIfContentIsIdentical(testDataFile: File) { + simpleChecker.addDirectiveToClassicFileAndAssert(testDataFile) + } +} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/utils/FirIdenticalCheckerHelper.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/utils/FirIdenticalCheckerHelper.kt index 242b54450e7..dbd945059d2 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/utils/FirIdenticalCheckerHelper.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/utils/FirIdenticalCheckerHelper.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.test.utils import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives +import org.jetbrains.kotlin.test.directives.model.Directive import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions import org.jetbrains.kotlin.utils.addToStdlib.applyIf @@ -13,7 +14,7 @@ import java.io.File abstract class FirIdenticalCheckerHelper(private val testServices: TestServices) { companion object { - private val isTeamCityBuild: Boolean = System.getenv("TEAMCITY_VERSION") != null + val isTeamCityBuild: Boolean = System.getenv("TEAMCITY_VERSION") != null } abstract fun getClassicFileToCompare(testDataFile: File): File? @@ -39,19 +40,47 @@ abstract class FirIdenticalCheckerHelper(private val testServices: TestServices) } } - fun addDirectiveToClassicFileAndAssert(testDataFile: File) { + fun addDirectiveToClassicFileAndAssert(testDataFile: File, directiveToAdd: Directive = FirDiagnosticsDirectives.FIR_IDENTICAL) { if (!isTeamCityBuild) { val classicFileContent = testDataFile.readText() testDataFile.writer().use { - it.appendLine("// ${FirDiagnosticsDirectives.FIR_IDENTICAL.name}") + it.appendLine("// ${directiveToAdd.name}") it.append(classicFileContent) } } + val directiveName = directiveToAdd.name val message = if (isTeamCityBuild) { - "Please remove .fir.txt dump and add // FIR_IDENTICAL to test source" + "Please remove .fir.txt dump and add // $directiveName to test source" } else { - "Deleted .fir.txt dump, added // FIR_IDENTICAL to test source" + "Deleted .fir.txt dump, added // $directiveName to test source" + } + testServices.assertions.fail { + """ + Dumps via FIR & via old FE are the same. + $message + Please re-run the test now + """.trimIndent() + } + } + + fun removeDirectiveFromClassicFileAndAssert(testDataFile: File, directiveToRemove: Directive) { + val directiveName = directiveToRemove.name + if (!isTeamCityBuild) { + val classicFileContent = testDataFile.readLines() + testDataFile.writer().use { + classicFileContent.forEachIndexed { index, line -> + if (line.startsWith("// $directiveName")) return@forEachIndexed + // Don't add empty line at the end, if last line is empty already + if (index == classicFileContent.size - 1 && line.isBlank()) return@forEachIndexed + it.appendLine(line) + } + } + } + val message = if (isTeamCityBuild) { + "Please remove .fir.txt dump and remove // $directiveName from test source" + } else { + "Deleted .fir.txt dump, removed // $directiveName from test source" } testServices.assertions.fail { """