mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-05 08:31:31 +00:00
[Test] Migrate AbstractFir2IrTextTest to new infrastructure
This commit is contained in:
committed by
TeamCityServer
parent
aba029237d
commit
bdcb8aecab
File diff suppressed because it is too large
Load Diff
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.fir
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
||||
import org.jetbrains.kotlin.ir.AbstractIrTextTestCase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractFir2IrTextTest : AbstractIrTextTestCase() {
|
||||
|
||||
private fun prepareProjectExtensions(project: Project) {
|
||||
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
||||
}
|
||||
|
||||
override fun doTest(wholeFile: File, testFiles: List<TestFile>) {
|
||||
buildFragmentAndTestIt(wholeFile, testFiles)
|
||||
}
|
||||
|
||||
override fun doTest(filePath: String) {
|
||||
val oldFrontendTextPath = filePath.replace(".kt", ".txt")
|
||||
val firTextPath = filePath.replace(".kt", ".fir.txt")
|
||||
val oldFrontendTextFile = File(oldFrontendTextPath)
|
||||
val firTextFile = File(firTextPath)
|
||||
if (oldFrontendTextFile.exists() && firTextFile.exists()) {
|
||||
compareAndMergeFirFileAndOldFrontendFile(oldFrontendTextFile, firTextFile, compareWithTrimming = true)
|
||||
}
|
||||
super.doTest(filePath)
|
||||
}
|
||||
|
||||
override fun getExpectedTextFileName(testFile: TestFile, name: String): String {
|
||||
// NB: replace with if (true) to make test against old FE results
|
||||
if ("// FIR_IDENTICAL" in testFile.content.split("\n")) {
|
||||
return super.getExpectedTextFileName(testFile, name)
|
||||
}
|
||||
return name.replace(".txt", ".fir.txt").replace(".kt", ".fir.txt")
|
||||
}
|
||||
|
||||
override fun generateIrModule(ignoreErrors: Boolean): IrModuleFragment {
|
||||
val psiFiles = myFiles.psiFiles
|
||||
|
||||
val project = psiFiles.first().project
|
||||
prepareProjectExtensions(project)
|
||||
|
||||
val scope = GlobalSearchScope.filesScope(project, psiFiles.map { it.virtualFile })
|
||||
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
|
||||
val session = createSession(myEnvironment, scope)
|
||||
val firAnalyzerFacade = FirAnalyzerFacade(session, myEnvironment.configuration.languageVersionSettings, psiFiles)
|
||||
return firAnalyzerFacade.convertToIr(JvmGeneratorExtensions(generateFacades = false)).irModuleFragment
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.directives.FirDiagnosticsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.FIR_IDENTICAL
|
||||
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 FirIrDumpIdenticalChecker(testServices: TestServices) : AfterAnalysisChecker(testServices) {
|
||||
override val directives: List<DirectivesContainer>
|
||||
get() = listOf(FirDiagnosticsDirectives)
|
||||
|
||||
private val simpleDumpChecker = object : FirIdenticalCheckerHelper(testServices) {
|
||||
override fun getClassicFileToCompare(testDataFile: File): File? {
|
||||
return testDataFile.withExtension(IrTextDumpHandler.DUMP_EXTENSION).takeIf { it.exists() }
|
||||
}
|
||||
|
||||
override fun getFirFileToCompare(testDataFile: File): File? {
|
||||
return testDataFile.withExtension("fir.${IrTextDumpHandler.DUMP_EXTENSION}").takeIf { it.exists() }
|
||||
}
|
||||
}
|
||||
|
||||
private val prettyDumpChecker = object : FirIdenticalCheckerHelper(testServices) {
|
||||
override fun getClassicFileToCompare(testDataFile: File): File? {
|
||||
return testDataFile.withExtension(IrPrettyKotlinDumpHandler.DUMP_EXTENSION).takeIf { it.exists() }
|
||||
}
|
||||
|
||||
override fun getFirFileToCompare(testDataFile: File): File? {
|
||||
return testDataFile.withExtension("fir.${IrPrettyKotlinDumpHandler.DUMP_EXTENSION}").takeIf { it.exists() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun check(failedAssertions: List<AssertionError>) {
|
||||
if (failedAssertions.isNotEmpty()) return
|
||||
val testDataFile = testServices.moduleStructure.originalTestDataFiles.first()
|
||||
if (FIR_IDENTICAL in testServices.moduleStructure.allDirectives) {
|
||||
simpleDumpChecker.deleteFirFile(testDataFile)
|
||||
prettyDumpChecker.deleteFirFile(testDataFile)
|
||||
return
|
||||
}
|
||||
if (
|
||||
simpleDumpChecker.firAndClassicContentsAreEquals(testDataFile) &&
|
||||
prettyDumpChecker.firAndClassicContentsAreEquals(testDataFile, trimLines = true)
|
||||
) {
|
||||
simpleDumpChecker.deleteFirFile(testDataFile)
|
||||
prettyDumpChecker.deleteFirFile(testDataFile)
|
||||
simpleDumpChecker.addDirectiveToClassicFileAndAssert(testDataFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,12 @@ import org.jetbrains.kotlin.ir.util.dumpKotlinLike
|
||||
import org.jetbrains.kotlin.test.backend.handlers.IrTextDumpHandler.Companion.computeDumpExtension
|
||||
import org.jetbrains.kotlin.test.backend.handlers.IrTextDumpHandler.Companion.groupWithTestFiles
|
||||
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DUMP_KT_IR
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.EXTERNAL_FILE
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.SKIP_KT_DUMP
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.moduleStructure
|
||||
@@ -21,8 +24,15 @@ import org.jetbrains.kotlin.test.utils.MultiModuleInfoDumperImpl
|
||||
import org.jetbrains.kotlin.test.utils.withExtension
|
||||
|
||||
class IrPrettyKotlinDumpHandler(testServices: TestServices) : AbstractIrHandler(testServices) {
|
||||
companion object {
|
||||
const val DUMP_EXTENSION = "kt.txt"
|
||||
}
|
||||
|
||||
private val dumper = MultiModuleInfoDumperImpl("// MODULE: %s")
|
||||
|
||||
override val directivesContainers: List<DirectivesContainer>
|
||||
get() = listOf(CodegenTestDirectives, FirDiagnosticsDirectives)
|
||||
|
||||
override fun processModule(module: TestModule, info: IrBackendInput) {
|
||||
if (DUMP_KT_IR !in module.directives || SKIP_KT_DUMP in module.directives) return
|
||||
|
||||
@@ -47,7 +57,7 @@ class IrPrettyKotlinDumpHandler(testServices: TestServices) : AbstractIrHandler(
|
||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
|
||||
if (dumper.isEmpty()) return
|
||||
val moduleStructure = testServices.moduleStructure
|
||||
val extension = computeDumpExtension(moduleStructure.modules.first(), "kt.txt")
|
||||
val extension = computeDumpExtension(moduleStructure.modules.first(), DUMP_EXTENSION)
|
||||
val expectedFile = moduleStructure.originalTestDataFiles.first().withExtension(extension)
|
||||
assertions.assertEqualsToFile(expectedFile, dumper.generateResultingDump())
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ import java.io.File
|
||||
|
||||
class IrTextDumpHandler(testServices: TestServices) : AbstractIrHandler(testServices) {
|
||||
companion object {
|
||||
const val DUMP_EXTENSION = "txt"
|
||||
|
||||
fun computeDumpExtension(module: TestModule, defaultExtension: String): String {
|
||||
return if (module.frontendKind == FrontendKinds.ClassicFrontend || FIR_IDENTICAL in module.directives)
|
||||
defaultExtension else "fir.$defaultExtension"
|
||||
@@ -74,6 +76,9 @@ class IrTextDumpHandler(testServices: TestServices) : AbstractIrHandler(testServ
|
||||
}
|
||||
|
||||
private fun compareDumpsOfExternalClasses(module: TestModule, info: IrBackendInput) {
|
||||
// FIR doesn't support searching descriptors
|
||||
if (module.frontendKind == FrontendKinds.FIR) return
|
||||
|
||||
val externalClassFqns = module.directives[DUMP_EXTERNAL_CLASS]
|
||||
if (externalClassFqns.isEmpty()) return
|
||||
|
||||
@@ -121,5 +126,5 @@ class IrTextDumpHandler(testServices: TestServices) : AbstractIrHandler(testServ
|
||||
}
|
||||
|
||||
private val TestModule.dumpExtension: String
|
||||
get() = computeDumpExtension(this, "txt")
|
||||
get() = computeDumpExtension(this, DUMP_EXTENSION)
|
||||
}
|
||||
|
||||
@@ -5,49 +5,43 @@
|
||||
|
||||
package org.jetbrains.kotlin.test.frontend.fir.handlers
|
||||
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||
import org.jetbrains.kotlin.test.model.AfterAnalysisChecker
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
import org.jetbrains.kotlin.test.services.moduleStructure
|
||||
import org.jetbrains.kotlin.test.utils.FirIdenticalCheckerHelper
|
||||
import org.jetbrains.kotlin.test.utils.firTestDataFile
|
||||
import org.jetbrains.kotlin.test.utils.isFirTestData
|
||||
import org.jetbrains.kotlin.test.utils.originalTestDataFile
|
||||
import java.io.File
|
||||
|
||||
class FirIdenticalChecker(testServices: TestServices) : AfterAnalysisChecker(testServices) {
|
||||
private val helper = object : FirIdenticalCheckerHelper(testServices) {
|
||||
override fun getClassicFileToCompare(testDataFile: File): File {
|
||||
return if (testDataFile.isFirTestData) testDataFile.originalTestDataFile else testDataFile
|
||||
}
|
||||
|
||||
override fun getFirFileToCompare(testDataFile: File): File {
|
||||
return if (testDataFile.isFirTestData) testDataFile else testDataFile.firTestDataFile
|
||||
}
|
||||
}
|
||||
|
||||
override fun check(failedAssertions: List<AssertionError>) {
|
||||
if (failedAssertions.isNotEmpty()) return
|
||||
val file = testServices.moduleStructure.originalTestDataFiles.first()
|
||||
if (file.isFirTestData) {
|
||||
addDirectiveToClassicFile(file)
|
||||
val testDataFile = testServices.moduleStructure.originalTestDataFiles.first()
|
||||
if (testDataFile.isFirTestData) {
|
||||
val firFile = helper.getFirFileToCompare(testDataFile)
|
||||
val classicFile = helper.getClassicFileToCompare(testDataFile)
|
||||
if (helper.contentsAreEquals(classicFile, firFile)) {
|
||||
helper.deleteFirFile(testDataFile)
|
||||
helper.addDirectiveToClassicFileAndAssert(testDataFile)
|
||||
}
|
||||
} else {
|
||||
removeFirFileIfExist(file)
|
||||
removeFirFileIfExist(testDataFile)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addDirectiveToClassicFile(firFile: File) {
|
||||
val classicFile = firFile.originalTestDataFile
|
||||
val classicFileContent = classicFile.readText()
|
||||
val firFileContent = firFile.readText()
|
||||
if (classicFileContent == firFileContent) {
|
||||
classicFile.writer().use {
|
||||
it.appendLine("// ${FirDiagnosticsDirectives.FIR_IDENTICAL.name}")
|
||||
it.append(classicFileContent)
|
||||
}
|
||||
firFile.delete()
|
||||
testServices.assertions.fail {
|
||||
"""
|
||||
Dumps via FIR & via old FE are the same.
|
||||
Deleted .fir.txt dump, added // FIR_IDENTICAL to test source
|
||||
Please re-run the test now
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeFirFileIfExist(classicFile: File) {
|
||||
val firFile = classicFile.firTestDataFile
|
||||
private fun removeFirFileIfExist(testDataFile: File) {
|
||||
val firFile = helper.getFirFileToCompare(testDataFile)
|
||||
firFile.delete()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.test.runners.ir
|
||||
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import org.jetbrains.kotlin.test.backend.handlers.IrPrettyKotlinDumpHandler
|
||||
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
||||
import org.jetbrains.kotlin.test.backend.handlers.*
|
||||
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DUMP_IR
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DUMP_KT_IR
|
||||
@@ -70,3 +70,12 @@ abstract class AbstractIrTextTestBase(
|
||||
}
|
||||
|
||||
open class AbstractIrTextTest : AbstractIrTextTestBase(FrontendKinds.ClassicFrontend)
|
||||
|
||||
open class AbstractFir2IrTextTest : AbstractIrTextTestBase(FrontendKinds.FIR) {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
with(builder) {
|
||||
useAfterAnalysisCheckers(::FirIrDumpIdenticalChecker)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.utils
|
||||
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
import java.io.File
|
||||
|
||||
abstract class FirIdenticalCheckerHelper(private val testServices: TestServices) {
|
||||
abstract fun getClassicFileToCompare(testDataFile: File): File?
|
||||
abstract fun getFirFileToCompare(testDataFile: File): File?
|
||||
|
||||
fun firAndClassicContentsAreEquals(testDataFile: File, trimLines: Boolean = false): Boolean {
|
||||
val classicFile = getClassicFileToCompare(testDataFile) ?: return true
|
||||
val firFile = getFirFileToCompare(testDataFile) ?: return true
|
||||
return contentsAreEquals(classicFile, firFile, trimLines)
|
||||
}
|
||||
|
||||
fun contentsAreEquals(classicFile: File, firFile: File, trimLines: Boolean = false): Boolean {
|
||||
val classicFileContent = classicFile.readContent(trimLines)
|
||||
val firFileContent = firFile.readContent(trimLines)
|
||||
return classicFileContent == firFileContent
|
||||
}
|
||||
|
||||
private fun File.readContent(trimLines: Boolean): String {
|
||||
return if (trimLines) {
|
||||
this.readLines().map { it.trimEnd() }.joinToString("\n").trimEnd()
|
||||
} else {
|
||||
this.readText()
|
||||
}
|
||||
}
|
||||
|
||||
fun addDirectiveToClassicFileAndAssert(testDataFile: File) {
|
||||
val classicFileContent = testDataFile.readText()
|
||||
testDataFile.writer().use {
|
||||
it.appendLine("// ${FirDiagnosticsDirectives.FIR_IDENTICAL.name}")
|
||||
it.append(classicFileContent)
|
||||
}
|
||||
testServices.assertions.fail {
|
||||
"""
|
||||
Dumps via FIR & via old FE are the same.
|
||||
Deleted .fir.txt dump, added // FIR_IDENTICAL to test source
|
||||
Please re-run the test now
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteFirFile(testDataFile: File) {
|
||||
getFirFileToCompare(testDataFile)?.takeIf { it.exists() }?.delete()
|
||||
}
|
||||
}
|
||||
@@ -597,16 +597,6 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
testGroup(
|
||||
"compiler/fir/fir2ir/tests-gen", "compiler/testData",
|
||||
testRunnerMethodName = "runTestWithCustomIgnoreDirective",
|
||||
additionalRunnerArguments = listOf("\"// IGNORE_BACKEND_FIR: \"")
|
||||
) {
|
||||
testClass<AbstractFir2IrTextTest> {
|
||||
model("ir/irText")
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("compiler/visualizer/tests-gen", "compiler/fir/raw-fir/psi2fir/testData") {
|
||||
testClass<AbstractPsiVisualizer>("PsiVisualizerForRawFirDataGenerated") {
|
||||
model("rawBuilder", testMethod = "doFirBuilderDataTest")
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.test.runners.*
|
||||
import org.jetbrains.kotlin.test.runners.codegen.AbstractBlackBoxCodegenTest
|
||||
import org.jetbrains.kotlin.test.runners.codegen.AbstractFirBlackBoxCodegenTest
|
||||
import org.jetbrains.kotlin.test.runners.codegen.AbstractIrBlackBoxCodegenTest
|
||||
import org.jetbrains.kotlin.test.runners.ir.AbstractFir2IrTextTest
|
||||
import org.jetbrains.kotlin.test.runners.ir.AbstractIrTextTest
|
||||
import org.junit.jupiter.api.parallel.Execution
|
||||
import org.junit.jupiter.api.parallel.ExecutionMode
|
||||
@@ -99,6 +100,11 @@ fun generateJUnit5CompilerTests(args: Array<String>) {
|
||||
model("resolve", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testGroup(testsRoot = "compiler/fir/analysis-tests/tests-gen", testDataRoot = "compiler/testData") {
|
||||
testClass<AbstractFir2IrTextTest> {
|
||||
model("ir/irText")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user