[Test] Add handler for comparing pretty kt ir dumps

This commit is contained in:
Dmitriy Novozhilov
2021-01-20 11:40:04 +03:00
committed by TeamCityServer
parent 87ffbd8206
commit aba029237d
13 changed files with 171 additions and 64 deletions
@@ -1,3 +1,13 @@
// FILE: signedToUnsignedConversions_annotation.kt
package kotlin.internal
annotation class ImplicitIntegerCoercion : Annotation {
constructor() /* primary */
}
// FILE: signedToUnsignedConversions_test.kt
@ImplicitIntegerCoercion
const val IMPLICIT_INT: Int
field = 255
@@ -1,7 +0,0 @@
package kotlin.internal
annotation class ImplicitIntegerCoercion : Annotation {
constructor() /* primary */
}
@@ -1,3 +1,22 @@
// MODULE: m1
// FILE: BaseFirBuilder.kt
abstract class BaseFirBuilder<T : Any?> {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
inline fun <T : Any?> withCapturedTypeParameters(block: Function0<T>): T {
return block.invoke()
}
}
// MODULE: m2
// FILE: FirBuilder.kt
open class BaseConverter : BaseFirBuilder<Any> {
constructor() /* primary */ {
super/*BaseFirBuilder*/<Any>()
@@ -55,11 +55,12 @@ data class A {
}
var fn: Function1<A, Int>
field = local fun <anonymous>(<name for destructuring parameter 0>: A): Int {
val y: Int = <name for destructuring parameter 0>.component2()
field = local fun <anonymous>($dstr$_u24__u24$y: A): Int {
val y: Int = $dstr$_u24__u24$y.component2()
return 42.plus(other = y)
}
get
set
@@ -0,0 +1,53 @@
// MODULE: m1
// FILE: genericClassInDifferentModule_m1.kt
abstract class Base<T : Any?> {
constructor(x: T) /* primary */ {
super/*Any*/()
/* <init>() */
}
val x: T
field = x
get
abstract fun <Y : Any?> foo(y: Y): T
abstract var bar: T
abstract get
abstract set
abstract var <Z : Any?> Z.exn: T
abstract get
abstract set
}
// MODULE: m2
// FILE: genericClassInDifferentModule_m2.kt
class Derived1<T : Any?> : Base<T> {
constructor(x: T) /* primary */ {
super/*Base*/<T>(x = x)
/* <init>() */
}
override fun <Y : Any?> foo(y: Y): T {
return <this>.<get-x>()
}
override var bar: T
field = x
override get
override set
override var <Z : Any?> Z.exn: T
override get(): T {
return <this>.<get-x>()
}
override set(value: T) {
}
}
@@ -1,22 +0,0 @@
abstract class Base<T : Any?> {
constructor(x: T) /* primary */ {
super/*Any*/()
/* <init>() */
}
val x: T
field = x
get
abstract fun <Y : Any?> foo(y: Y): T
abstract var bar: T
abstract get
abstract set
abstract var <Z : Any?> Z.exn: T
abstract get
abstract set
}
@@ -1,25 +0,0 @@
class Derived1<T : Any?> : Base<T> {
constructor(x: T) /* primary */ {
super/*Base*/<T>(x = x)
/* <init>() */
}
override fun <Y : Any?> foo(y: Y): T {
return <this>.<get-x>()
}
override var bar: T
field = x
override get
override set
override var <Z : Any?> Z.exn: T
override get(): T {
return <this>.<get-x>()
}
override set(value: T) {
}
}
@@ -0,0 +1,54 @@
/*
* 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.ir.util.FakeOverridesStrategy
import org.jetbrains.kotlin.ir.util.KotlinLikeDumpOptions
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.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.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.moduleStructure
import org.jetbrains.kotlin.test.utils.MultiModuleInfoDumperImpl
import org.jetbrains.kotlin.test.utils.withExtension
class IrPrettyKotlinDumpHandler(testServices: TestServices) : AbstractIrHandler(testServices) {
private val dumper = MultiModuleInfoDumperImpl("// MODULE: %s")
override fun processModule(module: TestModule, info: IrBackendInput) {
if (DUMP_KT_IR !in module.directives || SKIP_KT_DUMP in module.directives) return
val irFiles = info.backendInput.irModuleFragment.files
val builder = dumper.builderForModule(module)
val filteredIrFiles = irFiles.groupWithTestFiles(module).filter {
EXTERNAL_FILE !in it.first.directives
}.map { it.second }
val printFileName = filteredIrFiles.size > 1 || testServices.moduleStructure.modules.size > 1
for (irFile in filteredIrFiles) {
val dump = irFile.dumpKotlinLike(
KotlinLikeDumpOptions(
printFileName = printFileName,
printFilePath = false,
printFakeOverridesStrategy = FakeOverridesStrategy.NONE
)
)
builder.append(dump)
}
}
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
if (dumper.isEmpty()) return
val moduleStructure = testServices.moduleStructure
val extension = computeDumpExtension(moduleStructure.modules.first(), "kt.txt")
val expectedFile = moduleStructure.originalTestDataFiles.first().withExtension(extension)
assertions.assertEqualsToFile(expectedFile, dumper.generateResultingDump())
}
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.test.backend.handlers
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
import org.jetbrains.kotlin.ir.IrVerifier
@@ -26,6 +25,7 @@ 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.FrontendKinds
import org.jetbrains.kotlin.test.model.TestFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.moduleStructure
@@ -35,6 +35,19 @@ import org.jetbrains.kotlin.test.utils.withSuffixAndExtension
import java.io.File
class IrTextDumpHandler(testServices: TestServices) : AbstractIrHandler(testServices) {
companion object {
fun computeDumpExtension(module: TestModule, defaultExtension: String): String {
return if (module.frontendKind == FrontendKinds.ClassicFrontend || FIR_IDENTICAL in module.directives)
defaultExtension else "fir.$defaultExtension"
}
fun List<IrFile>.groupWithTestFiles(module: TestModule): List<Pair<TestFile, IrFile>> = mapNotNull { irFile ->
val name = irFile.fileEntry.name.removePrefix("/")
val testFile = module.files.firstOrNull { it.name == name } ?: return@mapNotNull null
testFile to irFile
}
}
override val directivesContainers: List<DirectivesContainer>
get() = listOf(CodegenTestDirectives, FirDiagnosticsDirectives)
@@ -45,11 +58,7 @@ class IrTextDumpHandler(testServices: TestServices) : AbstractIrHandler(testServ
override fun processModule(module: TestModule, info: IrBackendInput) {
if (DUMP_IR !in module.directives) return
val irFiles = info.backendInput.irModuleFragment.files
val testFileToIrFile = irFiles.mapNotNull { irFile ->
val name = irFile.fileEntry.name.removePrefix("/")
val testFile = module.files.firstOrNull { it.name == name } ?: return@mapNotNull null
testFile to irFile
}
val testFileToIrFile = irFiles.groupWithTestFiles(module)
val builder = baseDumper.builderForModule(module)
for ((testFile, irFile) in testFileToIrFile) {
if (EXTERNAL_FILE in testFile.directives) continue
@@ -112,5 +121,5 @@ class IrTextDumpHandler(testServices: TestServices) : AbstractIrHandler(testServ
}
private val TestModule.dumpExtension: String
get() = if (frontendKind == FrontendKinds.ClassicFrontend || FIR_IDENTICAL in directives) "txt" else "fir.txt"
get() = computeDumpExtension(this, "txt")
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.test.directives
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.handlers.IrPrettyKotlinDumpHandler
import org.jetbrains.kotlin.test.backend.handlers.IrTextDumpHandler
import org.jetbrains.kotlin.test.backend.handlers.NoCompilationErrorsHandler
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
@@ -76,4 +77,12 @@ object CodegenTestDirectives : SimpleDirectivesContainer() {
description = "Indicates that test file is external and should be skipped in ${IrTextDumpHandler::class}",
applicability = File
)
val DUMP_KT_IR by directive(
description = "Dumps generated backend IR in pretty kotlin dump (enables ${IrPrettyKotlinDumpHandler::class})"
)
val SKIP_KT_DUMP by directive(
description = "Skips check pretty kt IR dump (disables ${IrPrettyKotlinDumpHandler::class})"
)
}
@@ -7,10 +7,12 @@ 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.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DUMP_IR
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DUMP_KT_IR
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
@@ -37,6 +39,7 @@ abstract class AbstractIrTextTestBase(
defaultDirectives {
+DUMP_IR
+DUMP_KT_IR
}
useConfigurators(
@@ -59,7 +62,10 @@ abstract class AbstractIrTextTestBase(
::Fir2IrResultsConverter
)
useBackendHandlers(::IrTextDumpHandler)
useBackendHandlers(
::IrTextDumpHandler,
::IrPrettyKotlinDumpHandler
)
}
}