[Test] Add Fir Identical checkers for signature dump handler
This commit is contained in:
committed by
Space Team
parent
e3dc0f0fa3
commit
d1e7b9b4cf
@@ -1,23 +0,0 @@
|
||||
// CHECK:
|
||||
// Mangled name: A
|
||||
// Public signature: /A|null[0]
|
||||
class A : Java1 {
|
||||
// CHECK:
|
||||
// Mangled name: A#<init>(){}
|
||||
// Public signature: /A.<init>|-5645683436151566731[0]
|
||||
// Public signature debug description: <init>(){}
|
||||
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
|
||||
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
|
||||
-44
@@ -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<DirectivesContainer>
|
||||
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<WrappedException>) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
-2
@@ -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<Constructor<AfterAnalysisChecker>>
|
||||
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 {
|
||||
|
||||
+10
-1
@@ -40,7 +40,16 @@ class IrSourceRangesDumpHandler(
|
||||
get() = listOf(CodegenTestDirectives, FirDiagnosticsDirectives)
|
||||
|
||||
override val additionalAfterAnalysisCheckers: List<Constructor<AfterAnalysisChecker>>
|
||||
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<File, StringBuilder> = mutableMapOf()
|
||||
|
||||
+73
@@ -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<DirectivesContainer>
|
||||
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<WrappedException>) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
+34
-5
@@ -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 {
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user