[Test] Replace three fixed phases of tests with step system

Now each test is just a sequence of any number of different steps. There
  are two kinds of steps:
1. Run some facade
2. Run handlers of specific artifact kind

Through the test each module passed to each step (if it is compatible
  by kinds of artifacts)
This commit is contained in:
Dmitriy Novozhilov
2021-07-20 16:54:37 +03:00
committed by teamcityserver
parent ba48f80e53
commit a66f3d26fd
37 changed files with 900 additions and 559 deletions
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.model.ResultingArtifact
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
@@ -382,6 +383,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
"test${testDataFile.nameWithoutExtension.replaceFirstChar(Char::uppercaseChar)}",
emptySet()
)
startingArtifactFactory = { ResultingArtifact.Source() }
}.build(testDataFile.path)
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.test
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.model.AfterAnalysisChecker
import org.jetbrains.kotlin.test.model.ResultingArtifact
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.MetaTestConfigurator
import org.jetbrains.kotlin.test.services.ModuleStructureExtractor
import org.jetbrains.kotlin.test.services.PreAnalysisHandler
@@ -33,16 +35,11 @@ abstract class TestConfiguration {
abstract val afterAnalysisCheckers: List<AfterAnalysisChecker>
abstract val startingArtifactFactory: (TestModule) -> ResultingArtifact<*>
abstract val steps: List<TestStep<*, *>>
abstract val metaInfoHandlerEnabled: Boolean
abstract fun <I : ResultingArtifact<I>, O : ResultingArtifact<O>> getFacade(
inputKind: TestArtifactKind<I>,
outputKind: TestArtifactKind<O>
): AbstractTestFacade<I, O>
abstract fun <A : ResultingArtifact<A>> getHandlers(artifactKind: TestArtifactKind<A>): List<AnalysisHandler<A>>
abstract fun getAllHandlers(): List<AnalysisHandler<*>>
}
// ---------------------------- Utils ----------------------------
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -7,13 +7,22 @@ package org.jetbrains.kotlin.test
import com.intellij.openapi.util.Disposer
import com.intellij.testFramework.TestDataFile
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.model.AnalysisHandler
import org.jetbrains.kotlin.test.model.ResultingArtifact
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.IOException
class TestRunner(private val testConfiguration: TestConfiguration) {
private val failedAssertions = mutableListOf<WrappedException>()
companion object {
fun AnalysisHandler<*>.shouldRun(thereWasAnException: Boolean): Boolean {
return !(doNotRunIfThereWerePreviousFailures && thereWasAnException)
}
}
private val allFailedExceptions = mutableListOf<WrappedException>()
private val allRanHandlers = mutableSetOf<AnalysisHandler<*>>()
fun runTest(@TestDataFile testDataFileName: String, beforeDispose: (TestConfiguration) -> Unit = {}) {
try {
@@ -68,27 +77,15 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
preprocessor.preprocessModuleStructure(moduleStructure)
}
var failedException: WrappedException? = null
try {
for (module in modules) {
val shouldProcessNextModules = processModule(services, module, dependencyProvider, moduleStructure)
if (!shouldProcessNextModules) break
}
} catch (e: WrappedException) {
failedException = e
} catch (e: Exception) {
throw IllegalStateException("Unexpected exception type. Only WrappedException are expected here", e)
for (module in modules) {
val shouldProcessNextModules = processModule(module, dependencyProvider)
if (!shouldProcessNextModules) break
}
for (handler in testConfiguration.getAllHandlers()) {
val wrapperFactory = when (handler) {
is FrontendOutputHandler -> WrappedException::FromFrontendHandler
is BackendInputHandler -> WrappedException::FromBackendHandler
is BinaryArtifactHandler -> WrappedException::FromBinaryHandler
else -> WrappedException::FromUnknownHandler
}
for (handler in allRanHandlers) {
val wrapperFactory: (Throwable) -> WrappedException = { WrappedException.FromHandler(it, handler) }
withAssertionCatching(wrapperFactory) {
val thereWasAnException = failedException != null || failedAssertions.isNotEmpty()
val thereWasAnException = allFailedExceptions.isNotEmpty()
if (handler.shouldRun(thereWasAnException)) {
handler.processAfterAllModules(thereWasAnException)
}
@@ -99,100 +96,56 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
globalMetadataInfoHandler.compareAllMetaDataInfos()
}
}
if (failedException != null) {
failedAssertions.add(0, failedException)
}
testConfiguration.afterAnalysisCheckers.forEach {
withAssertionCatching(WrappedException::FromAfterAnalysisChecker) {
it.check(failedAssertions)
it.check(allFailedExceptions)
}
}
val filteredFailedAssertions = filterFailedExceptions(failedAssertions)
val filteredFailedAssertions = filterFailedExceptions(allFailedExceptions)
filteredFailedAssertions.firstIsInstanceOrNull<WrappedException.FromFacade>()?.let {
throw it
}
services.assertions.assertAll(filteredFailedAssertions)
}
private fun filterFailedExceptions(failedExceptions: List<WrappedException>): List<Throwable> {
return testConfiguration.afterAnalysisCheckers
.fold(failedExceptions) { assertions, checker ->
checker.suppressIfNeeded(assertions)
}
.sorted()
.map { it.cause }
}
/*
* If there was failure from handler with `failureDisablesNextSteps=true` then `processModule`
* returns false which indicates that other modules should not be processed
* Returns false if next modules should be not processed
*/
private fun processModule(
services: TestServices,
module: TestModule,
dependencyProvider: DependencyProviderImpl,
moduleStructure: TestModuleStructure
dependencyProvider: DependencyProviderImpl
): Boolean {
val sourcesArtifact = ResultingArtifact.Source()
var inputArtifact = testConfiguration.startingArtifactFactory.invoke(module)
val frontendKind = module.frontendKind
if (!frontendKind.shouldRunAnalysis) return true
for (step in testConfiguration.steps) {
if (!step.shouldProcessModule(module, inputArtifact)) continue
val frontendArtifacts: ResultingArtifact.FrontendOutput<*> = withExceptionWrapping(WrappedException.FromFacade::Frontend) {
testConfiguration.getFacade(SourcesKind, frontendKind)
.transform(module, sourcesArtifact)?.also { dependencyProvider.registerArtifact(module, it) }
?: return true
}
val frontendHandlers: List<AnalysisHandler<*>> = testConfiguration.getHandlers(frontendKind)
for (frontendHandler in frontendHandlers) {
val thereWasAnException = withAssertionCatching(WrappedException::FromFrontendHandler) {
if (frontendHandler.shouldRun(failedAssertions.isNotEmpty())) {
frontendHandler.hackyProcess(module, frontendArtifacts)
when (val result = step.hackyProcessModule(module, inputArtifact, allFailedExceptions.isNotEmpty())) {
is TestStep.StepResult.Artifact<*> -> {
require(step is TestStep.FacadeStep<*, *>)
if (step.inputArtifactKind != step.outputArtifactKind) {
dependencyProvider.registerArtifact(module, result.outputArtifact)
}
inputArtifact = result.outputArtifact
}
}
if (thereWasAnException && frontendHandler.failureDisablesNextSteps) return false
}
val backendKind = services.backendKindExtractor.backendKind(module.targetBackend)
if (!backendKind.shouldRunAnalysis) return true
val backendInputInfo = withExceptionWrapping(WrappedException.FromFacade::Converter) {
testConfiguration.getFacade(frontendKind, backendKind)
.hackyTransform(module, frontendArtifacts)?.also { dependencyProvider.registerArtifact(module, it) } ?: return true
}
val backendHandlers: List<AnalysisHandler<*>> = testConfiguration.getHandlers(backendKind)
for (backendHandler in backendHandlers) {
val thereWasAnException = withAssertionCatching(WrappedException::FromBackendHandler) {
if (backendHandler.shouldRun(failedAssertions.isNotEmpty())) {
backendHandler.hackyProcess(module, backendInputInfo)
is TestStep.StepResult.ErrorFromFacade -> {
allFailedExceptions += result.exception
return false
}
}
if (thereWasAnException && backendHandler.failureDisablesNextSteps) return false
}
for (artifactKind in moduleStructure.getTargetArtifactKinds(module)) {
if (!artifactKind.shouldRunAnalysis) continue
val binaryArtifact = withExceptionWrapping(WrappedException.FromFacade::Backend) {
testConfiguration.getFacade(backendKind, artifactKind)
.hackyTransform(module, backendInputInfo)?.also {
dependencyProvider.registerArtifact(module, it)
} ?: return true
}
val binaryHandlers: List<AnalysisHandler<*>> = testConfiguration.getHandlers(artifactKind)
for (binaryHandler in binaryHandlers) {
val thereWasAnException = withAssertionCatching(WrappedException::FromBinaryHandler) {
if (binaryHandler.shouldRun(failedAssertions.isNotEmpty())) {
binaryHandler.hackyProcess(module, binaryArtifact)
is TestStep.StepResult.HandlersResult -> {
val (exceptionsFromHandlers, shouldRunNextSteps) = result
require(step is TestStep.HandlersStep<*>)
allRanHandlers += step.handlers
allFailedExceptions += exceptionsFromHandlers
if (!shouldRunNextSteps) {
return false
}
}
if (thereWasAnException && binaryHandler.failureDisablesNextSteps) return false
is TestStep.StepResult.NoArtifactFromFacade -> return false
}
}
return true
}
@@ -204,57 +157,38 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
block()
false
} catch (e: Throwable) {
failedAssertions += exceptionWrapper(e)
allFailedExceptions += exceptionWrapper(e)
true
}
}
private inline fun <R> withExceptionWrapping(exceptionWrapper: (Throwable) -> WrappedException, block: () -> R): R {
return try {
block()
} catch (e: Throwable) {
throw exceptionWrapper(e)
}
private fun filterFailedExceptions(failedExceptions: List<WrappedException>): List<Throwable> {
return testConfiguration.afterAnalysisCheckers
.fold(failedExceptions) { assertions, checker ->
checker.suppressIfNeeded(assertions)
}
.sorted()
.map { it.cause }
}
private fun AnalysisHandler<*>.shouldRun(thereWasAnException: Boolean): Boolean {
return !(doNotRunIfThereWerePreviousFailures && thereWasAnException)
// -------------------------------------- hacks --------------------------------------
private fun TestStep<*, *>.hackyProcessModule(
module: TestModule,
inputArtifact: ResultingArtifact<*>,
thereWereExceptionsOnPreviousSteps: Boolean
): TestStep.StepResult<*> {
@Suppress("UNCHECKED_CAST")
return (this as TestStep<ResultingArtifact.Source, *>)
.processModule(module, inputArtifact as ResultingArtifact<ResultingArtifact.Source>, thereWereExceptionsOnPreviousSteps)
}
private fun <I : ResultingArtifact<I>> TestStep<I, *>.processModule(
module: TestModule,
artifact: ResultingArtifact<I>,
thereWereExceptionsOnPreviousSteps: Boolean
): TestStep.StepResult<*> {
@Suppress("UNCHECKED_CAST")
return processModule(module, artifact as I, thereWereExceptionsOnPreviousSteps)
}
}
// ----------------------------------------------------------------------------------------------------------------
/*
* Those `hackyProcess` methods are needed to hack kotlin type system. In common test case
* we have artifact of type ResultingArtifact<*> and handler of type AnalysisHandler<*> and actually
* at runtime types under `*` are same (that achieved by grouping handlers and facades by
* frontend/backend/artifact kind). But there is no way to tell that to compiler, so I unsafely cast types with `*`
* to types with Empty artifacts to make it compile. Since unsafe cast has no effort at runtime, it's safe to use it
*/
private fun AnalysisHandler<*>.hackyProcess(module: TestModule, artifact: ResultingArtifact<*>) {
@Suppress("UNCHECKED_CAST")
(this as AnalysisHandler<ResultingArtifact.Source>)
.processModule(module, artifact as ResultingArtifact<ResultingArtifact.Source>)
}
private fun <A : ResultingArtifact<A>> AnalysisHandler<A>.processModule(module: TestModule, artifact: ResultingArtifact<A>) {
@Suppress("UNCHECKED_CAST")
processModule(module, artifact as A)
}
private fun AbstractTestFacade<*, *>.hackyTransform(
module: TestModule,
artifact: ResultingArtifact<*>
): ResultingArtifact<*>? {
@Suppress("UNCHECKED_CAST")
return (this as AbstractTestFacade<ResultingArtifact.Source, ResultingArtifact.Source>)
.transform(module, artifact as ResultingArtifact<ResultingArtifact.Source>)
}
private fun <I : ResultingArtifact<I>, O : ResultingArtifact<O>> AbstractTestFacade<I, O>.transform(
module: TestModule,
inputArtifact: ResultingArtifact<I>
): O? {
@Suppress("UNCHECKED_CAST")
return transform(module, inputArtifact as I)
}
@@ -0,0 +1,84 @@
/*
* 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
import org.jetbrains.kotlin.test.TestRunner.Companion.shouldRun
import org.jetbrains.kotlin.test.model.*
sealed class TestStep<I : ResultingArtifact<I>, out O : ResultingArtifact<out O>> {
abstract val inputArtifactKind: TestArtifactKind<I>
open fun shouldProcessModule(module: TestModule, inputArtifact: ResultingArtifact<*>): Boolean {
return inputArtifact.kind == inputArtifactKind
}
abstract fun processModule(module: TestModule, inputArtifact: I, thereWereExceptionsOnPreviousSteps: Boolean): StepResult<O>
class FacadeStep<I : ResultingArtifact<I>, O : ResultingArtifact<O>>(val facade: AbstractTestFacade<I, O>) : TestStep<I, O>() {
override val inputArtifactKind: TestArtifactKind<I>
get() = facade.inputKind
val outputArtifactKind: TestArtifactKind<O>
get() = facade.outputKind
override fun shouldProcessModule(module: TestModule, inputArtifact: ResultingArtifact<*>): Boolean {
return super.shouldProcessModule(module, inputArtifact) && facade.shouldRunAnalysis(module)
}
override fun processModule(module: TestModule, inputArtifact: I, thereWereExceptionsOnPreviousSteps: Boolean): StepResult<O> {
val outputArtifact = try {
facade.transform(module, inputArtifact) ?: return StepResult.NoArtifactFromFacade
} catch (e: Throwable) {
// TODO: remove inheritors of WrappedException.FromFacade
return StepResult.ErrorFromFacade(WrappedException.FromFacade(e, facade))
}
return StepResult.Artifact(outputArtifact)
}
}
class HandlersStep<I : ResultingArtifact<I>>(
override val inputArtifactKind: TestArtifactKind<I>,
val handlers: List<AnalysisHandler<I>>
) : TestStep<I, Nothing>() {
init {
require(handlers.all { it.artifactKind == inputArtifactKind })
}
override fun processModule(
module: TestModule,
inputArtifact: I,
thereWereExceptionsOnPreviousSteps: Boolean
): StepResult.HandlersResult {
val exceptions = mutableListOf<WrappedException>()
for (outputHandler in handlers) {
if (outputHandler.shouldRun(thereWasAnException = thereWereExceptionsOnPreviousSteps || exceptions.isNotEmpty())) {
try {
outputHandler.processModule(module, inputArtifact)
} catch (e: Throwable) {
exceptions += WrappedException.FromHandler(e, outputHandler)
if (outputHandler.failureDisablesNextSteps) {
return StepResult.HandlersResult(exceptions, shouldRunNextSteps = false)
}
}
}
}
return StepResult.HandlersResult(exceptions, shouldRunNextSteps = true)
}
}
sealed class StepResult<out O : ResultingArtifact<out O>> {
class Artifact<out O : ResultingArtifact<out O>>(val outputArtifact: O, ) : StepResult<O>()
class ErrorFromFacade<O : ResultingArtifact<O>>(val exception: WrappedException) : StepResult<O>()
data class HandlersResult(
val exceptionsFromHandlers: Collection<WrappedException>,
val shouldRunNextSteps: Boolean
) : StepResult<Nothing>()
object NoArtifactFromFacade : StepResult<Nothing>()
}
}
@@ -0,0 +1,41 @@
/*
* 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
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.TestServices
sealed class TestStepBuilder<I : ResultingArtifact<I>, out O : ResultingArtifact<out O>> {
@TestInfrastructureInternals
abstract fun createTestStep(testServices: TestServices): TestStep<I, O>
}
class FacadeStepBuilder<I : ResultingArtifact<I>, O : ResultingArtifact<O>>(
val facade: Constructor<AbstractTestFacade<I, O>>
) : TestStepBuilder<I, O>() {
@TestInfrastructureInternals
override fun createTestStep(testServices: TestServices): TestStep.FacadeStep<I, O> {
return TestStep.FacadeStep(facade.invoke(testServices))
}
}
class HandlersStepBuilder<I : ResultingArtifact<I>>(val artifactKind: TestArtifactKind<I>) : TestStepBuilder<I, Nothing>() {
private val handlers: MutableList<Constructor<AnalysisHandler<I>>> = mutableListOf()
fun useHandlers(vararg constructor: Constructor<AnalysisHandler<I>>) {
handlers += constructor
}
fun useHandlers(constructors: List<Constructor<AnalysisHandler<I>>>) {
handlers += constructors
}
@TestInfrastructureInternals
override fun createTestStep(testServices: TestServices): TestStep.HandlersStep<I> {
return TestStep.HandlersStep(artifactKind, handlers.map { it.invoke(testServices) })
}
}
@@ -5,26 +5,22 @@
package org.jetbrains.kotlin.test
import org.jetbrains.kotlin.test.model.AbstractTestFacade
import org.jetbrains.kotlin.test.model.AnalysisHandler
sealed class WrappedException(
cause: Throwable,
val priority: Int,
val additionalPriority: Int
) : Exception(cause), Comparable<WrappedException> {
sealed class FromFacade(cause: Throwable, additionalPriority: Int) : WrappedException(cause, 0, additionalPriority) {
class Frontend(cause: Throwable) : FromFacade(cause, 1)
class Converter(cause: Throwable) : FromFacade(cause, 2)
class Backend(cause: Throwable) : FromFacade(cause, 3)
class FromFacade(cause: Throwable, val facade: AbstractTestFacade<*, *>) : WrappedException(cause, 0, 1) {
override val message: String
get() = "Exception was thrown"
}
class FromMetaInfoHandler(cause: Throwable) : WrappedException(cause, 1, 1)
class FromFrontendHandler(cause: Throwable) : WrappedException(cause, 1, 1)
class FromBackendHandler(cause: Throwable) : WrappedException(cause, 1, 2)
class FromBinaryHandler(cause: Throwable) : WrappedException(cause, 1, 3)
class FromUnknownHandler(cause: Throwable) : WrappedException(cause, 1, 4)
class FromHandler(cause: Throwable, val handler: AnalysisHandler<*>) : WrappedException(cause, 1, 2)
class FromAfterAnalysisChecker(cause: Throwable) : WrappedException(cause, 2, 1)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.test.model
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.services.ServiceRegistrationData
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.backendKindExtractor
interface ServicesAndDirectivesContainer {
val additionalServices: List<ServiceRegistrationData>
@@ -22,6 +23,7 @@ abstract class AbstractTestFacade<I : ResultingArtifact<I>, O : ResultingArtifac
abstract val outputKind: TestArtifactKind<O>
abstract fun transform(module: TestModule, inputArtifact: I): O?
abstract fun shouldRunAnalysis(module: TestModule): Boolean
}
abstract class FrontendFacade<R : ResultingArtifact.FrontendOutput<R>>(
@@ -31,6 +33,10 @@ abstract class FrontendFacade<R : ResultingArtifact.FrontendOutput<R>>(
final override val inputKind: TestArtifactKind<ResultingArtifact.Source>
get() = SourcesKind
override fun shouldRunAnalysis(module: TestModule): Boolean {
return module.frontendKind == outputKind
}
abstract fun analyze(module: TestModule): R
final override fun transform(module: TestModule, inputArtifact: ResultingArtifact.Source): R {
@@ -43,10 +49,18 @@ abstract class Frontend2BackendConverter<R : ResultingArtifact.FrontendOutput<R>
val testServices: TestServices,
final override val inputKind: FrontendKind<R>,
final override val outputKind: BackendKind<I>
) : AbstractTestFacade<R, I>()
) : AbstractTestFacade<R, I>() {
override fun shouldRunAnalysis(module: TestModule): Boolean {
return testServices.backendKindExtractor.backendKind(module.targetBackend) == outputKind
}
}
abstract class BackendFacade<I : ResultingArtifact.BackendInput<I>, A : ResultingArtifact.Binary<A>>(
val testServices: TestServices,
final override val inputKind: BackendKind<I>,
final override val outputKind: BinaryKind<A>
) : AbstractTestFacade<I, A>()
) : AbstractTestFacade<I, A>() {
override fun shouldRunAnalysis(module: TestModule): Boolean {
return testServices.backendKindExtractor.backendKind(module.targetBackend) == inputKind && module.binaryKind == outputKind
}
}
@@ -0,0 +1,121 @@
/*
* 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.builders
import org.jetbrains.kotlin.test.HandlersStepBuilder
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.CompilerStepsNames.CLASSIC_FRONTEND_HANDLERS_STEP_NAME
import org.jetbrains.kotlin.test.builders.CompilerStepsNames.FIR_HANDLERS_STEP_NAME
import org.jetbrains.kotlin.test.builders.CompilerStepsNames.JVM_ARTIFACTS_HANDLERS_STEP_NAME
import org.jetbrains.kotlin.test.builders.CompilerStepsNames.RAW_IR_HANDLERS_STEP_NAME
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.model.ArtifactKinds
import org.jetbrains.kotlin.test.model.BackendKinds
import org.jetbrains.kotlin.test.model.BinaryArtifacts
import org.jetbrains.kotlin.test.model.FrontendKinds
object CompilerStepsNames {
const val FRONTEND_STEP_NAME = "frontend"
const val CLASSIC_FRONTEND_HANDLERS_STEP_NAME = "classic frontend handlers"
const val FIR_HANDLERS_STEP_NAME = "FIR frontend handlers"
const val CONVERTER_STEP_NAME = "converter"
const val RAW_IR_HANDLERS_STEP_NAME = "raw IR handlers"
const val JVM_BACKEND_STEP_NAME = "jvm backend"
const val JVM_ARTIFACTS_HANDLERS_STEP_NAME = "jvm artifacts handlers"
}
// --------------------- default compiler steps ---------------------
fun TestConfigurationBuilder.classicFrontendStep() {
facadeStep(::ClassicFrontendFacade)
}
fun TestConfigurationBuilder.firFrontendStep() {
facadeStep(::FirFrontendFacade)
}
fun TestConfigurationBuilder.psi2ClassicBackendStep() {
facadeStep(::ClassicFrontend2ClassicBackendConverter)
}
fun TestConfigurationBuilder.psi2IrStep() {
facadeStep(::ClassicFrontend2IrConverter)
}
fun TestConfigurationBuilder.fir2IrStep() {
facadeStep(::Fir2IrResultsConverter)
}
fun TestConfigurationBuilder.classicJvmBackendStep() {
facadeStep(::ClassicJvmBackendFacade)
}
fun TestConfigurationBuilder.jvmIrBackendStep() {
facadeStep(::JvmIrBackendFacade)
}
// --------------------- default handlers steps ---------------------
// use those ones to define new step
inline fun TestConfigurationBuilder.classicFrontendHandlersStep(
init: HandlersStepBuilder<ClassicFrontendOutputArtifact>.() -> Unit = {}
) {
namedHandlersStep(CLASSIC_FRONTEND_HANDLERS_STEP_NAME, FrontendKinds.ClassicFrontend, init)
}
inline fun TestConfigurationBuilder.firHandlersStep(
init: HandlersStepBuilder<FirOutputArtifact>.() -> Unit = {}
) {
namedHandlersStep(FIR_HANDLERS_STEP_NAME, FrontendKinds.FIR, init)
}
inline fun TestConfigurationBuilder.irHandlersStep(
init: HandlersStepBuilder<IrBackendInput>.() -> Unit = {}
) {
namedHandlersStep(RAW_IR_HANDLERS_STEP_NAME, BackendKinds.IrBackend, init)
}
inline fun TestConfigurationBuilder.jvmArtifactsHandlersStep(
init: HandlersStepBuilder<BinaryArtifacts.Jvm>.() -> Unit = {}
) {
namedHandlersStep(JVM_ARTIFACTS_HANDLERS_STEP_NAME, ArtifactKinds.Jvm, init)
}
// and those ones to configure already defined step
inline fun TestConfigurationBuilder.configureClassicFrontendHandlersStep(
init: HandlersStepBuilder<ClassicFrontendOutputArtifact>.() -> Unit = {}
) {
configureNamedHandlersStep(CLASSIC_FRONTEND_HANDLERS_STEP_NAME, FrontendKinds.ClassicFrontend, init)
}
inline fun TestConfigurationBuilder.configureFirHandlersStep(
init: HandlersStepBuilder<FirOutputArtifact>.() -> Unit = {}
) {
configureNamedHandlersStep(FIR_HANDLERS_STEP_NAME, FrontendKinds.FIR, init)
}
inline fun TestConfigurationBuilder.configureIrHandlersStep(
init: HandlersStepBuilder<IrBackendInput>.() -> Unit = {}
) {
configureNamedHandlersStep(RAW_IR_HANDLERS_STEP_NAME, BackendKinds.IrBackend, init)
}
inline fun TestConfigurationBuilder.configureJvmArtifactsHandlersStep(
init: HandlersStepBuilder<BinaryArtifacts.Jvm>.() -> Unit = {}
) {
configureNamedHandlersStep(JVM_ARTIFACTS_HANDLERS_STEP_NAME, ArtifactKinds.Jvm, init)
}
@@ -6,9 +6,8 @@
package org.jetbrains.kotlin.test.builders
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestConfiguration
import org.jetbrains.kotlin.test.TestInfrastructureInternals
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.impl.TestConfigurationImpl
import org.jetbrains.kotlin.test.model.*
@@ -16,14 +15,16 @@ import org.jetbrains.kotlin.test.services.*
import kotlin.io.path.Path
@DefaultsDsl
@OptIn(TestInfrastructureInternals::class)
@OptIn(TestInfrastructureInternals::class, PrivateForInline::class)
class TestConfigurationBuilder {
val defaultsProviderBuilder: DefaultsProviderBuilder = DefaultsProviderBuilder()
lateinit var assertions: AssertionsService
private val facades: MutableList<Constructor<AbstractTestFacade<*, *>>> = mutableListOf()
@PrivateForInline
val steps: MutableList<TestStepBuilder<*, *>> = mutableListOf()
private val handlers: MutableList<Constructor<AnalysisHandler<*>>> = mutableListOf()
@PrivateForInline
val namedSteps: MutableMap<String, TestStepBuilder<*, *>> = mutableMapOf()
private val sourcePreprocessors: MutableList<Constructor<SourceFilePreprocessor>> = mutableListOf()
private val additionalMetaInfoProcessors: MutableList<Constructor<AdditionalMetaInfoProcessor>> = mutableListOf()
@@ -50,6 +51,8 @@ class TestConfigurationBuilder {
lateinit var testInfo: KotlinTestInfo
lateinit var startingArtifactFactory: (TestModule) -> ResultingArtifact<*>
inline fun <reified T : TestService> useAdditionalService(noinline serviceConstructor: (TestServices) -> T) {
useAdditionalService(service(serviceConstructor))
}
@@ -89,32 +92,47 @@ class TestConfigurationBuilder {
defaultsProviderBuilder.apply(init)
}
fun unregisterAllFacades() {
facades.clear()
fun <I : ResultingArtifact<I>, O : ResultingArtifact<O>> facadeStep(
facade: Constructor<AbstractTestFacade<I, O>>,
): FacadeStepBuilder<I, O> {
return FacadeStepBuilder(facade).also {
steps += it
}
}
fun useFrontendFacades(vararg constructor: Constructor<FrontendFacade<*>>) {
facades += constructor
inline fun <I : ResultingArtifact<I>> handlersStep(
artifactKind: TestArtifactKind<I>,
init: HandlersStepBuilder<I>.() -> Unit
): HandlersStepBuilder<I> {
return HandlersStepBuilder(artifactKind).also {
it.init()
steps += it
}
}
fun useBackendFacades(vararg constructor: Constructor<BackendFacade<*, *>>) {
facades += constructor
inline fun <I : ResultingArtifact<I>> namedHandlersStep(
name: String,
artifactKind: TestArtifactKind<I>,
init: HandlersStepBuilder<I>.() -> Unit
): HandlersStepBuilder<I> {
val step = handlersStep(artifactKind, init)
val previouslyContainedStep = namedSteps.put(name, step)
if (previouslyContainedStep != null) {
error { "Step with name \"$name\" already registered" }
}
return step
}
fun useFrontend2BackendConverters(vararg constructor: Constructor<Frontend2BackendConverter<*, *>>) {
facades += constructor
}
fun useFrontendHandlers(vararg constructor: Constructor<FrontendOutputHandler<*>>) {
handlers += constructor
}
fun useBackendHandlers(vararg constructor: Constructor<BackendInputHandler<*>>) {
handlers += constructor
}
fun useArtifactsHandlers(vararg constructor: Constructor<BinaryArtifactHandler<*>>) {
handlers += constructor
inline fun <I : ResultingArtifact<I>> configureNamedHandlersStep(
name: String,
artifactKind: TestArtifactKind<I>,
init: HandlersStepBuilder<I>.() -> Unit
) {
val step = namedSteps[name] ?: error { "Step \"$name\" not found" }
require(step is HandlersStepBuilder<*>) { "Step '$name' is not a handlers step" }
require(step.artifactKind == artifactKind) { "Step kind: ${step.artifactKind}, passed kind is $artifactKind" }
@Suppress("UNCHECKED_CAST")
(step as HandlersStepBuilder<I>).apply(init)
}
fun useSourcePreprocessor(vararg preprocessors: Constructor<SourceFilePreprocessor>, needToPrepend: Boolean = false) {
@@ -145,6 +163,11 @@ class TestConfigurationBuilder {
additionalSourceProviders += providers
}
@TestInfrastructureInternals
fun resetModuleStructureTransformers() {
moduleStructureTransformers.clear()
}
@TestInfrastructureInternals
fun useModuleStructureTransformers(vararg transformers: ModuleStructureTransformer) {
moduleStructureTransformers += transformers
@@ -193,8 +216,7 @@ class TestConfigurationBuilder {
testInfo,
defaultsProviderBuilder.build(),
assertions,
facades,
handlers,
steps,
sourcePreprocessors,
additionalMetaInfoProcessors,
environmentConfigurators,
@@ -208,6 +230,7 @@ class TestConfigurationBuilder {
metaInfoHandlerEnabled,
directives,
defaultRegisteredDirectivesBuilder.build(),
startingArtifactFactory,
additionalServices
)
}
@@ -1,7 +0,0 @@
/*
* Copyright 2010-2020 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.builders
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.test.WrappedException
import org.jetbrains.kotlin.test.model.AfterAnalysisChecker
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.moduleStructure
@@ -15,7 +16,13 @@ class FirFailingTestSuppressor(testServices: TestServices) : AfterAnalysisChecke
val testFile = testServices.moduleStructure.originalTestDataFiles.first()
val failFile = testFile.parentFile.resolve("${testFile.nameWithoutExtension}.fail")
val exceptionFromFir =
failedAssertions.firstOrNull { it is WrappedException.FromFacade.Frontend || it is WrappedException.FromFrontendHandler }
failedAssertions.firstOrNull {
when (it) {
is WrappedException.FromFacade -> it.facade is FirFrontendFacade
is WrappedException.FromHandler -> it.handler.artifactKind == FrontendKinds.FIR
else -> false
}
}
return when {
failFile.exists() && exceptionFromFir != null -> emptyList()
failFile.exists() && exceptionFromFir == null -> {
@@ -1,18 +1,19 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.impl
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestConfiguration
import org.jetbrains.kotlin.test.TestInfrastructureInternals
import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.directives.model.ComposedDirectivesContainer
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.model.AfterAnalysisChecker
import org.jetbrains.kotlin.test.model.ResultingArtifact
import org.jetbrains.kotlin.test.model.ServicesAndDirectivesContainer
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.impl.ModuleStructureExtractorImpl
import org.jetbrains.kotlin.test.utils.TestDisposable
@@ -24,9 +25,7 @@ class TestConfigurationImpl(
defaultsProvider: DefaultsProvider,
assertions: AssertionsService,
facades: List<Constructor<AbstractTestFacade<*, *>>>,
analysisHandlers: List<Constructor<AnalysisHandler<*>>>,
steps: List<TestStepBuilder<*, *>>,
sourcePreprocessors: List<Constructor<SourceFilePreprocessor>>,
additionalMetaInfoProcessors: List<Constructor<AdditionalMetaInfoProcessor>>,
@@ -45,6 +44,7 @@ class TestConfigurationImpl(
directives: List<DirectivesContainer>,
override val defaultRegisteredDirectives: RegisteredDirectives,
override val startingArtifactFactory: (TestModule) -> ResultingArtifact<*>,
additionalServices: List<ServiceRegistrationData>
) : TestConfiguration() {
override val rootDisposable: Disposable = TestDisposable()
@@ -67,35 +67,28 @@ class TestConfigurationImpl(
}
private val environmentConfigurators: List<EnvironmentConfigurator> =
environmentConfigurators.map { it.invoke(testServices) }.also { configurators ->
configurators.flatMapTo(allDirectives) { it.directiveContainers }
for (configurator in configurators) {
configurator.additionalServices.forEach { testServices.register(it) }
}
}
environmentConfigurators
.map { it.invoke(testServices) }
.also { it.registerDirectivesAndServices() }
override val preAnalysisHandlers: List<PreAnalysisHandler> =
preAnalysisHandlers.map { it.invoke(testServices) }
override val moduleStructureExtractor: ModuleStructureExtractor = ModuleStructureExtractorImpl(
testServices,
additionalSourceProviders.map { it.invoke(testServices) }.also {
it.flatMapTo(allDirectives) { provider -> provider.directiveContainers }
},
additionalSourceProviders
.map { it.invoke(testServices) }
.also { it.registerDirectivesAndServices() },
moduleStructureTransformers,
this.environmentConfigurators
)
override val metaTestConfigurators: List<MetaTestConfigurator> = metaTestConfigurators.map {
it.invoke(testServices).also { configurator ->
allDirectives += configurator.directiveContainers
}
override val metaTestConfigurators: List<MetaTestConfigurator> = metaTestConfigurators.map { constructor ->
constructor.invoke(testServices).also { it.registerDirectivesAndServices() }
}
override val afterAnalysisCheckers: List<AfterAnalysisChecker> = afterAnalysisCheckers.map {
it.invoke(testServices).also { checker ->
allDirectives += checker.directiveContainers
}
override val afterAnalysisCheckers: List<AfterAnalysisChecker> = afterAnalysisCheckers.map { constructor ->
constructor.invoke(testServices).also { it.registerDirectivesAndServices() }
}
init {
@@ -120,61 +113,23 @@ class TestConfigurationImpl(
}
}
private val facades: Map<TestArtifactKind<*>, Map<TestArtifactKind<*>, AbstractTestFacade<*, *>>> =
facades
.map { it.invoke(testServices) }
.groupBy { it.inputKind }
.mapValues { (frontendKind, converters) ->
converters.groupBy { it.outputKind }.mapValues {
it.value.singleOrNull() ?: manyFacadesError("converters", "$frontendKind -> ${it.key}")
}
}
private val analysisHandlers: Map<TestArtifactKind<*>, List<AnalysisHandler<*>>> =
analysisHandlers.map { it.invoke(testServices).also(this::registerDirectivesAndServices) }
.groupBy { it.artifactKind }
.withDefault { emptyList() }
private fun manyFacadesError(name: String, kinds: String): Nothing {
error("Too many $name passed for $kinds configuration")
}
private fun registerDirectivesAndServices(handler: AnalysisHandler<*>) {
allDirectives += handler.directiveContainers
testServices.register(handler.additionalServices)
}
init {
testServices.apply {
this@TestConfigurationImpl.facades.values.forEach {
it.values.forEach { facade ->
register(facade.additionalServices)
allDirectives += facade.directiveContainers
}
override val steps: List<TestStep<*, *>> = steps
.map { it.createTestStep(testServices) }
.onEach { step ->
when (step) {
is TestStep.FacadeStep<*, *> -> step.facade.registerDirectivesAndServices()
is TestStep.HandlersStep<*> -> step.handlers.registerDirectivesAndServices()
}
}
// ---------------------------------- utils ----------------------------------
private fun ServicesAndDirectivesContainer.registerDirectivesAndServices() {
allDirectives += directiveContainers
testServices.register(additionalServices)
}
override fun <I : ResultingArtifact<I>, O : ResultingArtifact<O>> getFacade(
inputKind: TestArtifactKind<I>,
outputKind: TestArtifactKind<O>
): AbstractTestFacade<I, O> {
@Suppress("UNCHECKED_CAST")
return facades[inputKind]?.get(outputKind) as AbstractTestFacade<I, O>?
?: facadeNotFoundError(inputKind, outputKind)
}
private fun facadeNotFoundError(from: Any, to: Any): Nothing {
error("Facade for converting '$from' to '$to' not found")
}
override fun <A : ResultingArtifact<A>> getHandlers(artifactKind: TestArtifactKind<A>): List<AnalysisHandler<A>> {
@Suppress("UNCHECKED_CAST")
return analysisHandlers.getValue(artifactKind) as List<AnalysisHandler<A>>
}
override fun getAllHandlers(): List<AnalysisHandler<*>> {
return analysisHandlers.values.flatten()
private fun List<ServicesAndDirectivesContainer>.registerDirectivesAndServices() {
this.forEach { it.registerDirectivesAndServices() }
}
}
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.config.ExplicitApiMode
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.classicFrontendStep
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.CHECK_COMPILE_TIME_VALUES
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.DIAGNOSTICS
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.REPORT_JVM_DIAGNOSTICS_ON_FRONTEND
@@ -24,10 +26,10 @@ import org.jetbrains.kotlin.test.frontend.classic.handlers.*
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.ScriptingEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
abstract class AbstractDiagnosticTest : AbstractKotlinCompilerTest() {
companion object {
@@ -70,12 +72,15 @@ abstract class AbstractDiagnosticTest : AbstractKotlinCompilerTest() {
::CoroutineHelpersSourceFilesProvider,
)
useFrontendFacades(::ClassicFrontendFacade)
useFrontendHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
::ConstantValuesHandler
)
classicFrontendStep()
classicFrontendHandlersStep {
useHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
::ConstantValuesHandler
)
}
useAfterAnalysisCheckers(::FirTestDataConsistencyHandler)
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.classicFrontendStep
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
@@ -40,10 +42,12 @@ abstract class AbstractDiagnosticsNativeTest : AbstractKotlinCompilerTest() {
::CoroutineHelpersSourceFilesProvider,
)
useFrontendFacades(::ClassicFrontendFacade)
useFrontendHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
)
classicFrontendStep()
classicFrontendHandlersStep {
useHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
)
}
}
}
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.classicFrontendStep
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
@@ -45,11 +47,13 @@ abstract class AbstractDiagnosticsTestWithJsStdLib : AbstractKotlinCompilerTest(
::CoroutineHelpersSourceFilesProvider,
)
useFrontendFacades(::ClassicFrontendFacade)
useFrontendHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
::DynamicCallsDumpHandler,
)
classicFrontendStep()
classicFrontendHandlersStep {
useHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
::DynamicCallsDumpHandler,
)
}
}
}
@@ -6,27 +6,35 @@
package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.handlers.JvmBackendDiagnosticsHandler
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.classicFrontendStep
import org.jetbrains.kotlin.test.builders.jvmArtifactsHandlersStep
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
import org.jetbrains.kotlin.test.frontend.classic.handlers.DeclarationsDumpHandler
import org.jetbrains.kotlin.test.frontend.classic.handlers.OldNewInferenceMetaInfoProcessor
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
abstract class AbstractDiagnosticsTestWithJvmBackend : AbstractKotlinCompilerTest() {
abstract class AbstractDiagnosticsTestWithJvmBackend<I : ResultingArtifact.BackendInput<I>> : AbstractKotlinCompilerTest() {
abstract val targetBackend: TargetBackend
abstract val converter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, I>>
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() {
globalDefaults {
@@ -53,35 +61,43 @@ abstract class AbstractDiagnosticsTestWithJvmBackend : AbstractKotlinCompilerTes
::CoroutineHelpersSourceFilesProvider,
)
useFrontendFacades(::ClassicFrontendFacade)
classicFrontendStep()
classicFrontendHandlersStep {
useHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
)
}
useFrontendHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
)
facadeStep(converter)
facadeStep(backendFacade)
useFrontend2BackendConverters(
::ClassicFrontend2ClassicBackendConverter,
::ClassicFrontend2IrConverter
)
useBackendFacades(
::ClassicJvmBackendFacade,
::JvmIrBackendFacade
)
useArtifactsHandlers(
::JvmBackendDiagnosticsHandler
)
jvmArtifactsHandlersStep {
useHandlers(
::JvmBackendDiagnosticsHandler
)
}
}
}
abstract class AbstractDiagnosticsTestWithOldJvmBackend : AbstractDiagnosticsTestWithJvmBackend() {
abstract class AbstractDiagnosticsTestWithOldJvmBackend : AbstractDiagnosticsTestWithJvmBackend<ClassicBackendInput>() {
override val targetBackend: TargetBackend
get() = TargetBackend.JVM_OLD
override val converter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, ClassicBackendInput>>
get() = ::ClassicFrontend2ClassicBackendConverter
override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Jvm>>
get() = ::ClassicJvmBackendFacade
}
abstract class AbstractDiagnosticsTestWithJvmIrBackend : AbstractDiagnosticsTestWithJvmBackend() {
abstract class AbstractDiagnosticsTestWithJvmIrBackend : AbstractDiagnosticsTestWithJvmBackend<IrBackendInput>() {
override val targetBackend: TargetBackend
get() = TargetBackend.JVM_IR
override val converter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2IrConverter
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade
}
@@ -6,10 +6,11 @@
package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.COMPARE_WITH_LIGHT_TREE
import org.jetbrains.kotlin.test.builders.firHandlersStep
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.FIR_DUMP
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.USE_LIGHT_TREE
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS
@@ -18,8 +19,10 @@ import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirective
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_STDLIB
import org.jetbrains.kotlin.test.frontend.fir.FirFailingTestSuppressor
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.handlers.*
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendFacade
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
@@ -44,9 +47,11 @@ abstract class AbstractFirDiagnosticsWithLightTreeTest : AbstractFirDiagnosticTe
}
}
// `baseDir` is used in Kotlin plugin from IJ infra
fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(baseDir: String = ".") {
fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(
baseDir: String = ".",
frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>> = ::FirFrontendFacade
) {
globalDefaults {
frontend = FrontendKinds.FIR
targetPlatform = JvmPlatforms.defaultJvmPlatform
@@ -64,14 +69,17 @@ fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(baseDir: String
::AdditionalDiagnosticsSourceFilesProvider.bind(baseDir),
::CoroutineHelpersSourceFilesProvider.bind(baseDir),
)
useFrontendFacades(::FirFrontendFacade)
useFrontendHandlers(
::FirDiagnosticsHandler,
::FirDumpHandler,
::FirCfgDumpHandler,
::FirCfgConsistencyHandler,
::FirNoImplicitTypesHandler,
)
facadeStep(frontendFacade)
firHandlersStep {
useHandlers(
::FirDiagnosticsHandler,
::FirDumpHandler,
::FirCfgDumpHandler,
::FirCfgConsistencyHandler,
::FirNoImplicitTypesHandler,
)
}
useMetaInfoProcessors(::PsiLightTreeMetaInfoProcessor)
@@ -6,10 +6,12 @@
package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestJavacVersion
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.classicFrontendStep
import org.jetbrains.kotlin.test.builders.configureClassicFrontendHandlersStep
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.REPORT_JVM_DIAGNOSTICS_ON_FRONTEND
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.SKIP_TXT
import org.jetbrains.kotlin.test.directives.ForeignAnnotationsDirectives.ANNOTATIONS_PATH
@@ -60,11 +62,13 @@ abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest()
::CoroutineHelpersSourceFilesProvider,
)
useFrontendFacades(::ClassicFrontendFacade)
useFrontendHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
)
classicFrontendStep()
classicFrontendHandlersStep {
useHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
)
}
forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/tests/*") {
defaultDirectives {
@@ -88,7 +92,9 @@ abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest()
}
forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/*") {
useFrontendHandlers(::JspecifyDiagnosticComplianceHandler)
configureClassicFrontendHandlersStep {
useHandlers(::JspecifyDiagnosticComplianceHandler)
}
useSourcePreprocessor(::JspecifyMarksCleanupPreprocessor)
}
}
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.testRunner
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
import org.jetbrains.kotlin.test.model.ResultingArtifact
import org.jetbrains.kotlin.test.preprocessors.MetaInfosCleanupPreprocessor
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl
@@ -46,6 +47,7 @@ abstract class AbstractKotlinCompilerTest {
useSourcePreprocessor(*defaultPreprocessors.toTypedArray())
useDirectives(*defaultDirectiveContainers.toTypedArray())
configureDebugFlags()
startingArtifactFactory = { ResultingArtifact.Source() }
}
}
@@ -7,22 +7,23 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.model.*
open class AbstractBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact>(
open class AbstractBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact, ClassicBackendInput>(
FrontendKinds.ClassicFrontend,
TargetBackend.JVM
) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>>
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, ClassicBackendInput>>
get() = ::ClassicFrontend2ClassicBackendConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Jvm>>
get() = ::ClassicJvmBackendFacade
}
@@ -8,56 +8,64 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.handlers.BytecodeListingHandler
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.configureJvmArtifactsHandlersStep
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.frontend.classic.*
import org.jetbrains.kotlin.test.model.*
abstract class AbstractBytecodeListingTestBase<R : ResultingArtifact.FrontendOutput<R>>(
abstract class AbstractBytecodeListingTestBase<R : ResultingArtifact.FrontendOutput<R>, I : ResultingArtifact.BackendInput<I>>(
targetBackend: TargetBackend,
val targetFrontend: FrontendKind<*>
val targetFrontend: FrontendKind<R>
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
abstract val frontendFacade: Constructor<FrontendFacade<R>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>>
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
commonHandlersForCodegenTest()
defaultDirectives {
+CodegenTestDirectives.CHECK_BYTECODE_LISTING
}
useArtifactsHandlers(::BytecodeListingHandler)
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
commonHandlersForCodegenTest()
configureJvmArtifactsHandlersStep {
useHandlers(::BytecodeListingHandler)
}
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
}
}
open class AbstractBytecodeListingTest : AbstractBytecodeListingTestBase<ClassicFrontendOutputArtifact>(
open class AbstractBytecodeListingTest : AbstractBytecodeListingTestBase<ClassicFrontendOutputArtifact, ClassicBackendInput>(
TargetBackend.JVM, FrontendKinds.ClassicFrontend
) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>>
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, ClassicBackendInput>>
get() = ::ClassicFrontend2ClassicBackendConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Jvm>>
get() = ::ClassicJvmBackendFacade
}
open class AbstractIrBytecodeListingTest : AbstractBytecodeListingTestBase<ClassicFrontendOutputArtifact>(
open class AbstractIrBytecodeListingTest : AbstractBytecodeListingTestBase<ClassicFrontendOutputArtifact, IrBackendInput>(
TargetBackend.JVM_IR, FrontendKinds.ClassicFrontend
) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>>
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2IrConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade
}
@@ -8,10 +8,13 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.handlers.BytecodeTextHandler
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.configureJvmArtifactsHandlersStep
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_PSI_CLASS_FILES_READING
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_REFLECT
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_STDLIB
@@ -25,69 +28,71 @@ import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
abstract class AbstractBytecodeTextTestBase<R : ResultingArtifact.FrontendOutput<R>>(
abstract class AbstractBytecodeTextTestBase<R : ResultingArtifact.FrontendOutput<R>, I : ResultingArtifact.BackendInput<I>>(
targetBackend: TargetBackend,
val targetFrontend: FrontendKind<*>
val targetFrontend: FrontendKind<R>
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
abstract val frontendFacade: Constructor<FrontendFacade<R>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>>
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
defaultDirectives {
+WITH_STDLIB
+WITH_REFLECT
}
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
commonHandlersForCodegenTest()
useArtifactsHandlers(::BytecodeTextHandler)
configureJvmArtifactsHandlersStep {
useHandlers(::BytecodeTextHandler)
}
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
}
}
open class AbstractBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact>(
open class AbstractBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact, ClassicBackendInput>(
targetBackend = TargetBackend.JVM,
targetFrontend = FrontendKinds.ClassicFrontend
) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>>
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, ClassicBackendInput>>
get() = ::ClassicFrontend2ClassicBackendConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Jvm>>
get() = ::ClassicJvmBackendFacade
}
open class AbstractIrBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact>(
open class AbstractIrBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact, IrBackendInput>(
targetBackend = TargetBackend.JVM_IR,
targetFrontend = FrontendKinds.ClassicFrontend
) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>>
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2IrConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade
}
open class AbstractFirBytecodeTextTest : AbstractBytecodeTextTestBase<FirOutputArtifact>(
open class AbstractFirBytecodeTextTest : AbstractBytecodeTextTestBase<FirOutputArtifact, IrBackendInput>(
targetBackend = TargetBackend.JVM_IR,
targetFrontend = FrontendKinds.FIR
) {
override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>>
get() = ::FirFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, *>>
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
get() = ::Fir2IrResultsConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade
override fun configure(builder: TestConfigurationBuilder) {
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.configureIrHandlersStep
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND_MULTI_MODULE
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
@@ -45,9 +46,7 @@ abstract class AbstractCompileKotlinAgainstInlineKotlinTestBase<I : ResultingArt
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, I>>
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() = configurationImpl()
protected fun TestConfigurationBuilder.configurationImpl() {
override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(
FrontendKinds.ClassicFrontend,
::ClassicFrontendFacade,
@@ -55,7 +54,7 @@ abstract class AbstractCompileKotlinAgainstInlineKotlinTestBase<I : ResultingArt
backendFacade
)
useInlineHandlers()
commonHandlersForBoxTest()
configureCommonHandlersForBoxTest()
useModuleStructureTransformers(
ModuleTransformerForTwoFilesBoxTests()
)
@@ -82,11 +81,15 @@ open class AbstractIrCompileKotlinAgainstInlineKotlinTest :
}
open class AbstractIrSerializeCompileKotlinAgainstInlineKotlinTest : AbstractIrCompileKotlinAgainstInlineKotlinTest() {
override fun TestConfigurationBuilder.configuration() {
// call super
configurationImpl()
useConfigurators(::SerializeSetter)
useBackendHandlers(::CheckInlineBodies)
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
builder.apply {
useConfigurators(::SerializeSetter)
configureIrHandlersStep {
useHandlers(::CheckInlineBodies)
}
}
}
private class SerializeSetter(testServices: TestServices) : EnvironmentConfigurator(testServices) {
@@ -138,4 +141,4 @@ open class AbstractIrSerializeCompileKotlinAgainstInlineKotlinTest : AbstractIrC
}
}
}
}
@@ -9,37 +9,40 @@ import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.TestInfrastructureInternals
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.handlers.*
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.*
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND_MULTI_MODULE
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.services.ModuleTransformerForSwitchingBackend
@OptIn(TestInfrastructureInternals::class)
abstract class AbstractJvmIrAgainstOldBoxTestBase(targetBackend: TargetBackend) : AbstractKotlinCompilerWithTargetBackendTest(
targetBackend
) {
abstract val backendForLib: TargetBackend
abstract val backendForMain: TargetBackend
abstract class AbstractBoxWithDifferentBackendsTest(
targetBackend: TargetBackend,
val backendForLib: TargetBackend,
val backendForMain: TargetBackend
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(
FrontendKinds.ClassicFrontend,
::ClassicFrontendFacade,
::ClassicFrontend2ClassicBackendConverter,
::ClassicJvmBackendFacade
)
commonServicesConfigurationForCodegenTest(FrontendKinds.ClassicFrontend)
commonHandlersForBoxTest()
classicFrontendStep()
classicFrontendHandlersStep {
commonClassicFrontendHandlersForCodegenTest()
}
useFrontend2BackendConverters(::ClassicFrontend2IrConverter)
useBackendFacades(::JvmIrBackendFacade)
psi2ClassicBackendStep()
classicJvmBackendStep()
psi2IrStep()
jvmIrBackendStep()
jvmArtifactsHandlersStep {
commonBackendHandlersForCodegenTest()
boxHandlersForBackendStep()
}
useModuleStructureTransformers(
ModuleTransformerForSwitchingBackend(backendForLib, backendForMain)
@@ -49,17 +52,14 @@ abstract class AbstractJvmIrAgainstOldBoxTestBase(targetBackend: TargetBackend)
}
}
open class AbstractJvmIrAgainstOldBoxTest : AbstractBoxWithDifferentBackendsTest(
TargetBackend.JVM_MULTI_MODULE_IR_AGAINST_OLD,
backendForLib = TargetBackend.JVM,
backendForMain = TargetBackend.JVM_IR,
)
open class AbstractJvmIrAgainstOldBoxTest : AbstractJvmIrAgainstOldBoxTestBase(TargetBackend.JVM_MULTI_MODULE_IR_AGAINST_OLD) {
override val backendForLib: TargetBackend
get() = TargetBackend.JVM
override val backendForMain: TargetBackend
get() = TargetBackend.JVM_IR
}
open class AbstractJvmOldAgainstIrBoxTest : AbstractJvmIrAgainstOldBoxTestBase(TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR) {
override val backendForLib: TargetBackend
get() = TargetBackend.JVM_IR
override val backendForMain: TargetBackend
get() = TargetBackend.JVM
}
open class AbstractJvmOldAgainstIrBoxTest : AbstractBoxWithDifferentBackendsTest(
TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR,
backendForLib = TargetBackend.JVM_IR,
backendForMain = TargetBackend.JVM,
)
@@ -7,9 +7,10 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_FIR_DIAGNOSTICS_DIFF
import org.jetbrains.kotlin.test.builders.configureFirHandlersStep
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_PSI_CLASS_FILES_READING
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
@@ -21,17 +22,17 @@ import org.jetbrains.kotlin.test.frontend.fir.handlers.FirNoImplicitTypesHandler
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirScopeDumpHandler
import org.jetbrains.kotlin.test.model.*
open class AbstractFirBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<FirOutputArtifact>(
open class AbstractFirBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<FirOutputArtifact, IrBackendInput>(
FrontendKinds.FIR,
TargetBackend.JVM_IR
) {
override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>>
get() = ::FirFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, *>>
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
get() = ::Fir2IrResultsConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade
override fun configure(builder: TestConfigurationBuilder) {
@@ -41,18 +42,21 @@ open class AbstractFirBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<F
// See KT-44152
-USE_PSI_CLASS_FILES_READING
}
useFrontendHandlers(
::FirDumpHandler,
::FirScopeDumpHandler,
::FirCfgDumpHandler,
::FirNoImplicitTypesHandler,
)
configureFirHandlersStep {
useHandlers(
::FirDumpHandler,
::FirScopeDumpHandler,
::FirCfgDumpHandler,
::FirNoImplicitTypesHandler,
)
}
useAfterAnalysisCheckers(
::FirMetaInfoDiffSuppressor
)
dumpHandlersForCodegenTest()
configureDumpHandlersForCodegenTest()
}
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
@@ -14,21 +15,21 @@ import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.model.*
open class AbstractIrBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact>(
open class AbstractIrBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact, IrBackendInput>(
FrontendKinds.ClassicFrontend,
TargetBackend.JVM_IR
) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>>
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2IrConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
builder.dumpHandlersForCodegenTest()
builder.configureDumpHandlersForCodegenTest()
}
}
@@ -14,10 +14,13 @@ import org.jetbrains.kotlin.test.backend.handlers.BytecodeListingHandler
import org.jetbrains.kotlin.test.backend.handlers.BytecodeTextHandler
import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_DEXING
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.USE_JAVAC_BASED_ON_JVM_TARGET
import org.jetbrains.kotlin.test.builders.configureClassicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.configureFirHandlersStep
import org.jetbrains.kotlin.test.builders.configureJvmArtifactsHandlersStep
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.DIAGNOSTICS
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_DEXING
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.REPORT_ONLY_EXPLICITLY_DEFINED_DEBUG_INFO
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.USE_JAVAC_BASED_ON_JVM_TARGET
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JDK_KIND
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JVM_TARGET
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_STDLIB
@@ -26,24 +29,38 @@ import org.jetbrains.kotlin.test.frontend.fir.handlers.FirDiagnosticsHandler
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
abstract class AbstractJvmBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendOutput<R>>(
abstract class AbstractJvmBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendOutput<R>, I : ResultingArtifact.BackendInput<I>>(
val targetFrontend: FrontendKind<R>,
targetBackend: TargetBackend
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
abstract val frontendFacade: Constructor<FrontendFacade<R>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>>
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
useFrontendHandlers(
::ClassicDiagnosticsHandler,
::FirDiagnosticsHandler
)
commonHandlersForBoxTest()
useArtifactsHandlers(::BytecodeListingHandler)
useArtifactsHandlers(::BytecodeTextHandler.bind(true))
configureClassicFrontendHandlersStep {
useHandlers(
::ClassicDiagnosticsHandler
)
}
configureFirHandlersStep {
useHandlers(
::FirDiagnosticsHandler
)
}
configureCommonHandlersForBoxTest()
configureJvmArtifactsHandlersStep {
useHandlers(
::BytecodeListingHandler,
::BytecodeTextHandler.bind(true)
)
}
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
defaultDirectives {
@@ -7,55 +7,42 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.TestInfrastructureInternals
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.builders.configureJvmArtifactsHandlersStep
import org.jetbrains.kotlin.test.services.ModuleTransformerForSwitchingBackend
import org.jetbrains.kotlin.test.services.ModuleTransformerForTwoFilesBoxTests
@OptIn(TestInfrastructureInternals::class)
open class AbstractBackendAgainstBackendBoxTestBase(
abstract class AbstractBoxInlineWithDifferentBackendsTest(
targetBackend: TargetBackend,
val backendForLib: TargetBackend,
val backendForMain: TargetBackend
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(
FrontendKinds.ClassicFrontend,
::ClassicFrontendFacade,
::ClassicFrontend2ClassicBackendConverter,
::ClassicJvmBackendFacade
)
useFrontend2BackendConverters(::ClassicFrontend2IrConverter)
useBackendFacades(::JvmIrBackendFacade)
backendForLib: TargetBackend,
backendForMain: TargetBackend
) : AbstractBoxWithDifferentBackendsTest(targetBackend, backendForLib, backendForMain) {
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
builder.apply {
applyDumpSmapDirective()
commonHandlersForBoxTest()
useInlineHandlers()
resetModuleStructureTransformers()
useModuleStructureTransformers(
ModuleTransformerForTwoFilesBoxTests(),
ModuleTransformerForSwitchingBackend(backendForLib, backendForMain)
)
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor.bind(CodegenTestDirectives.IGNORE_BACKEND_MULTI_MODULE))
useModuleStructureTransformers(
ModuleTransformerForTwoFilesBoxTests(),
ModuleTransformerForSwitchingBackend(backendForLib, backendForMain)
)
configureJvmArtifactsHandlersStep {
inlineHandlers()
}
}
}
}
open class AbstractJvmIrAgainstOldBoxInlineTest : AbstractBackendAgainstBackendBoxTestBase(
open class AbstractJvmIrAgainstOldBoxInlineTest : AbstractBoxInlineWithDifferentBackendsTest(
targetBackend = TargetBackend.JVM_MULTI_MODULE_IR_AGAINST_OLD,
backendForLib = TargetBackend.JVM,
backendForMain = TargetBackend.JVM_IR
)
open class AbstractJvmOldAgainstIrBoxInlineTest : AbstractBackendAgainstBackendBoxTestBase(
open class AbstractJvmOldAgainstIrBoxInlineTest : AbstractBoxInlineWithDifferentBackendsTest(
targetBackend = TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR,
backendForLib = TargetBackend.JVM_IR,
backendForMain = TargetBackend.JVM_OLD
@@ -7,10 +7,14 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.HandlersStepBuilder
import org.jetbrains.kotlin.test.backend.handlers.*
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.builders.*
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DUMP_SMAP
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.RUN_DEX_CHECKER
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
@@ -20,12 +24,25 @@ import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFi
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider
fun <R : ResultingArtifact.FrontendOutput<R>> TestConfigurationBuilder.commonConfigurationForCodegenTest(
targetFrontend: FrontendKind<*>,
frontendFacade: Constructor<FrontendFacade<R>>,
frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>>,
backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
fun <F : ResultingArtifact.FrontendOutput<F>, B : ResultingArtifact.BackendInput<B>> TestConfigurationBuilder.commonConfigurationForCodegenTest(
targetFrontend: FrontendKind<F>,
frontendFacade: Constructor<FrontendFacade<F>>,
frontendToBackendConverter: Constructor<Frontend2BackendConverter<F, B>>,
backendFacade: Constructor<BackendFacade<B, BinaryArtifacts.Jvm>>,
) {
commonServicesConfigurationForCodegenTest(targetFrontend)
facadeStep(frontendFacade)
classicFrontendHandlersStep()
firHandlersStep()
commonBackendStepsConfiguration(
frontendToBackendConverter,
irHandlersInit = {},
backendFacade,
jvmHandlersInit = {}
)
}
fun TestConfigurationBuilder.commonServicesConfigurationForCodegenTest(targetFrontend: FrontendKind<*>) {
globalDefaults {
frontend = targetFrontend
targetPlatform = JvmPlatforms.defaultJvmPlatform
@@ -48,45 +65,99 @@ fun <R : ResultingArtifact.FrontendOutput<R>> TestConfigurationBuilder.commonCon
::CodegenHelpersSourceFilesProvider,
::MainFunctionForBlackBoxTestsSourceProvider,
)
useFrontendFacades(frontendFacade)
useFrontend2BackendConverters(frontendToBackendConverter)
useBackendFacades(backendFacade)
}
fun TestConfigurationBuilder.dumpHandlersForCodegenTest() {
useBackendHandlers(::IrTreeVerifierHandler, ::IrTextDumpHandler)
useArtifactsHandlers(::BytecodeListingHandler)
}
fun TestConfigurationBuilder.commonHandlersForBoxTest() {
commonHandlersForCodegenTest()
useArtifactsHandlers(
::JvmBoxRunner
)
}
fun TestConfigurationBuilder.commonHandlersForCodegenTest() {
useFrontendHandlers(
::NoCompilationErrorsHandler,
::NoFirCompilationErrorsHandler,
)
useArtifactsHandlers(
::NoJvmSpecificCompilationErrorsHandler,
::DxCheckerHandler,
)
inline fun <B : ResultingArtifact.BackendInput<B>, F : ResultingArtifact.FrontendOutput<F>> TestConfigurationBuilder.commonBackendStepsConfiguration(
noinline frontendToBackendConverter: Constructor<Frontend2BackendConverter<F, B>>,
irHandlersInit: HandlersStepBuilder<IrBackendInput>.() -> Unit,
noinline backendFacade: Constructor<BackendFacade<B, BinaryArtifacts.Jvm>>,
jvmHandlersInit: HandlersStepBuilder<BinaryArtifacts.Jvm>.() -> Unit,
) {
facadeStep(frontendToBackendConverter)
irHandlersStep(irHandlersInit)
facadeStep(backendFacade)
jvmArtifactsHandlersStep(jvmHandlersInit)
}
fun TestConfigurationBuilder.useInlineHandlers() {
useArtifactsHandlers(
::BytecodeInliningHandler,
::SMAPDumpHandler
)
configureJvmArtifactsHandlersStep {
inlineHandlers()
}
applyDumpSmapDirective()
}
fun TestConfigurationBuilder.applyDumpSmapDirective() {
forTestsMatching("compiler/testData/codegen/boxInline/smap/*") {
defaultDirectives {
+DUMP_SMAP
}
}
}
fun TestConfigurationBuilder.configureDumpHandlersForCodegenTest() {
configureIrHandlersStep {
dumpHandlersForConverterStep()
}
configureJvmArtifactsHandlersStep {
dumpHandlersForBackendStep()
}
}
fun TestConfigurationBuilder.configureCommonHandlersForBoxTest() {
commonHandlersForCodegenTest()
configureJvmArtifactsHandlersStep {
boxHandlersForBackendStep()
}
}
fun TestConfigurationBuilder.commonHandlersForCodegenTest() {
configureClassicFrontendHandlersStep {
commonClassicFrontendHandlersForCodegenTest()
}
configureFirHandlersStep {
commonFirHandlersForCodegenTest()
}
configureJvmArtifactsHandlersStep {
commonBackendHandlersForCodegenTest()
}
}
fun HandlersStepBuilder<IrBackendInput>.dumpHandlersForConverterStep() {
useHandlers(::IrTreeVerifierHandler, ::IrTextDumpHandler)
}
fun HandlersStepBuilder<BinaryArtifacts.Jvm>.dumpHandlersForBackendStep() {
useHandlers(::BytecodeListingHandler)
}
fun HandlersStepBuilder<BinaryArtifacts.Jvm>.boxHandlersForBackendStep() {
useHandlers(::JvmBoxRunner)
}
fun HandlersStepBuilder<ClassicFrontendOutputArtifact>.commonClassicFrontendHandlersForCodegenTest() {
useHandlers(
::NoCompilationErrorsHandler,
)
}
fun HandlersStepBuilder<FirOutputArtifact>.commonFirHandlersForCodegenTest() {
useHandlers(
::NoFirCompilationErrorsHandler,
)
}
fun HandlersStepBuilder<BinaryArtifacts.Jvm>.commonBackendHandlersForCodegenTest() {
useHandlers(
::NoJvmSpecificCompilationErrorsHandler,
::DxCheckerHandler,
)
}
fun HandlersStepBuilder<BinaryArtifacts.Jvm>.inlineHandlers() {
useHandlers(
::BytecodeInliningHandler,
::SMAPDumpHandler
)
}
@@ -6,16 +6,23 @@
package org.jetbrains.kotlin.test.runners.ir
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.handlers.*
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.firHandlersStep
import org.jetbrains.kotlin.test.builders.irHandlersStep
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.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
@@ -24,9 +31,13 @@ import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsS
import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
abstract class AbstractIrTextTestBase(
private val frontend: FrontendKind<*>
) : AbstractKotlinCompilerWithTargetBackendTest(TargetBackend.JVM_IR) {
abstract class AbstractIrTextTestBase<R : ResultingArtifact.FrontendOutput<R>> :
AbstractKotlinCompilerWithTargetBackendTest(TargetBackend.JVM_IR)
{
abstract val frontend: FrontendKind<*>
abstract val frontendFacade: Constructor<FrontendFacade<R>>
abstract val converter: Constructor<Frontend2BackendConverter<R, IrBackendInput>>
override fun TestConfigurationBuilder.configuration() {
globalDefaults {
frontend = this@AbstractIrTextTestBase.frontend
@@ -52,32 +63,48 @@ abstract class AbstractIrTextTestBase(
::CodegenHelpersSourceFilesProvider,
)
useFrontendFacades(
::ClassicFrontendFacade,
::FirFrontendFacade
)
facadeStep(frontendFacade)
classicFrontendHandlersStep {
useHandlers(
::NoCompilationErrorsHandler
)
}
useFrontendHandlers(
::NoCompilationErrorsHandler,
::NoFirCompilationErrorsHandler,
)
firHandlersStep {
useHandlers(
::NoFirCompilationErrorsHandler
)
}
useFrontend2BackendConverters(
::ClassicFrontend2IrConverter,
::Fir2IrResultsConverter
)
facadeStep(converter)
useBackendHandlers(
::IrTextDumpHandler,
::IrTreeVerifierHandler,
::IrPrettyKotlinDumpHandler
)
irHandlersStep {
useHandlers(
::IrTextDumpHandler,
::IrTreeVerifierHandler,
::IrPrettyKotlinDumpHandler
)
}
}
}
open class AbstractIrTextTest : AbstractIrTextTestBase(FrontendKinds.ClassicFrontend)
open class AbstractIrTextTest : AbstractIrTextTestBase<ClassicFrontendOutputArtifact>() {
override val frontend: FrontendKind<*>
get() = FrontendKinds.ClassicFrontend
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade
override val converter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2IrConverter
}
open class AbstractFir2IrTextTest : AbstractIrTextTestBase<FirOutputArtifact>() {
override val frontend: FrontendKind<*>
get() = FrontendKinds.FIR
override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>>
get() = ::FirFrontendFacade
override val converter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
get() = ::Fir2IrResultsConverter
open class AbstractFir2IrTextTest : AbstractIrTextTestBase(FrontendKinds.FIR) {
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
with(builder) {
@@ -12,14 +12,14 @@ import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.handlers.IrInterpreterBackendHandler
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.backend.handlers.NoFirCompilationErrorsHandler
import org.jetbrains.kotlin.test.builders.*
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.model.BinaryKind
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.preprocessors.IrInterpreterImplicitKotlinImports
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
@@ -50,15 +50,19 @@ open class AbstractIrInterpreterAfterFir2IrTest : AbstractKotlinCompilerWithTarg
::JvmEnvironmentConfigurator,
)
firFrontendStep()
fir2IrStep()
irHandlersStep {
useHandlers(::IrInterpreterBackendHandler)
}
useAdditionalSourceProviders(::IrInterpreterHelpersSourceFilesProvider)
useSourcePreprocessor(::IrInterpreterImplicitKotlinImports)
useFrontendFacades(::FirFrontendFacade)
useFrontend2BackendConverters(::Fir2IrResultsConverter)
useBackendFacades(::JvmIrBackendFacade)
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
useBackendHandlers(::IrInterpreterBackendHandler)
enableMetaInfoHandler()
}
}
@@ -68,6 +72,6 @@ class IrInterpreterEnvironmentConfigurator(testServices: TestServices) : Environ
directives: RegisteredDirectives,
languageVersion: LanguageVersion
): Map<AnalysisFlag<*>, Any?> {
return super.provideAdditionalAnalysisFlags(directives, languageVersion) + (AnalysisFlags.builtInsFromSources to true)
return mapOf(AnalysisFlags.builtInsFromSources to true)
}
}
}
@@ -8,8 +8,9 @@ package org.jetbrains.kotlin.visualizer
import org.jetbrains.kotlin.compiler.visualizer.FirVisualizer
import org.jetbrains.kotlin.compiler.visualizer.PsiVisualizer
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestConfiguration
import org.jetbrains.kotlin.test.TestRunner
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.testConfiguration
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
@@ -26,9 +27,14 @@ import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFi
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
abstract class AbstractVisualizerBlackBoxTest {
private val commonConfiguration: TestConfigurationBuilder.() -> Unit = {
private fun <O : ResultingArtifact.FrontendOutput<O>> createConfiguration(
filePath: String,
frontendKind: FrontendKind<O>,
frontendFacade: Constructor<FrontendFacade<O>>
): TestConfiguration = testConfiguration(filePath) {
assertions = JUnit5Assertions
testInfo = KotlinTestInfo("_undefined_", "_testUndefined_", setOf())
startingArtifactFactory = { ResultingArtifact.Source() }
useAdditionalService<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl)
useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl)
@@ -38,6 +44,7 @@ abstract class AbstractVisualizerBlackBoxTest {
globalDefaults {
targetPlatform = JvmPlatforms.defaultJvmPlatform
dependencyKind = DependencyKind.Source
frontend = frontendKind
}
defaultDirectives {
@@ -49,28 +56,20 @@ abstract class AbstractVisualizerBlackBoxTest {
::JvmEnvironmentConfigurator,
)
useFrontendFacades(
::ClassicFrontendFacade,
::FirFrontendFacade
)
useAdditionalSourceProviders(
::AdditionalDiagnosticsSourceFilesProvider,
::CoroutineHelpersSourceFilesProvider,
::CodegenHelpersSourceFilesProvider
)
}
private fun createConfiguration(filePath: String, frontend: FrontendKind<*>) = testConfiguration(filePath) {
commonConfiguration()
globalDefaults { this.frontend = frontend }
facadeStep(frontendFacade)
}
fun runTest(filePath: String) {
lateinit var psiRenderResult: String
lateinit var firRenderResult: String
val psiConfiguration = createConfiguration(filePath, FrontendKinds.ClassicFrontend)
val psiConfiguration = createConfiguration(filePath, FrontendKinds.ClassicFrontend, ::ClassicFrontendFacade)
TestRunner(psiConfiguration).runTest(filePath) { testConfiguration ->
testConfiguration.testServices.moduleStructure.modules.forEach { psiModule ->
val psiArtifact = testConfiguration.testServices.dependencyProvider.getArtifact(psiModule, FrontendKinds.ClassicFrontend)
@@ -79,7 +78,7 @@ abstract class AbstractVisualizerBlackBoxTest {
}
}
val firConfiguration = createConfiguration(filePath, FrontendKinds.FIR)
val firConfiguration = createConfiguration(filePath, FrontendKinds.FIR, ::FirFrontendFacade)
TestRunner(firConfiguration).runTest(filePath) { testConfiguration ->
testConfiguration.testServices.moduleStructure.modules.forEach { firModule ->
val firArtifact = testConfiguration.testServices.dependencyProvider.getArtifact(firModule, FrontendKinds.FIR)
@@ -33,11 +33,12 @@ abstract class AbstractVisualizerTest : AbstractKotlinCompilerTest() {
::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator,
)
useFrontendFacades(
::FirFrontendFacade,
::ClassicFrontendFacade
)
useFrontendHandlers(handler)
// TODO
// useFrontendFacades(
// ::FirFrontendFacade,
// ::ClassicFrontendFacade
// )
// useFrontendHandlers(handler)
defaultDirectives {
+JvmEnvironmentConfigurationDirectives.WITH_STDLIB
@@ -83,10 +83,9 @@ abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() {
configureTest()
defaultConfiguration(this)
unregisterAllFacades()
useAdditionalService(::TestModuleInfoProvider)
usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable))
useFrontendFacades(::LowLevelFirFrontendFacade)
}
open fun TestConfigurationBuilder.configureTest() {}
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.test.runners.baseFirSpecDiagnosticTestConfiguration
abstract class AbstractDiagnosisCompilerTestDataSpecTest : AbstractCompilerBasedTest() {
override fun TestConfigurationBuilder.configureTest() {
baseFirDiagnosticTestConfiguration()
baseFirDiagnosticTestConfiguration(frontendFacade = ::LowLevelFirFrontendFacade)
baseFirSpecDiagnosticTestConfiguration()
addIdeTestIgnoreHandler()
}
}
}
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.test.runners.baseFirDiagnosticTestConfiguration
abstract class AbstractDiagnosisCompilerTestDataTest : AbstractCompilerBasedTest() {
override fun TestConfigurationBuilder.configureTest() {
baseFirDiagnosticTestConfiguration()
baseFirDiagnosticTestConfiguration(frontendFacade = ::LowLevelFirFrontendFacade)
addIdeTestIgnoreHandler()
}
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.test.builders.testConfiguration
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.model.ResultingArtifact
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
@@ -61,6 +62,7 @@ abstract class AbstractLowLevelApiTest : TestWithDisposable() {
usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable))
configureTest(this)
startingArtifactFactory = { ResultingArtifact.Source() }
this.testInfo = this@AbstractLowLevelApiTest.testInfo
}
@@ -136,4 +138,4 @@ fun String.indexOfOrNull(substring: String) =
indexOf(substring).takeIf { it >= 0 }
private fun String.indexOfOrNull(substring: String, startingIndex: Int) =
indexOf(substring, startingIndex).takeIf { it >= 0 }
indexOf(substring, startingIndex).takeIf { it >= 0 }