[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.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.model.DependencyKind import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds 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.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.* import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator 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)}", "test${testDataFile.nameWithoutExtension.replaceFirstChar(Char::uppercaseChar)}",
emptySet() emptySet()
) )
startingArtifactFactory = { ResultingArtifact.Source() }
}.build(testDataFile.path) }.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. * 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 com.intellij.openapi.Disposable
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives 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.MetaTestConfigurator
import org.jetbrains.kotlin.test.services.ModuleStructureExtractor import org.jetbrains.kotlin.test.services.ModuleStructureExtractor
import org.jetbrains.kotlin.test.services.PreAnalysisHandler import org.jetbrains.kotlin.test.services.PreAnalysisHandler
@@ -33,16 +35,11 @@ abstract class TestConfiguration {
abstract val afterAnalysisCheckers: List<AfterAnalysisChecker> abstract val afterAnalysisCheckers: List<AfterAnalysisChecker>
abstract val startingArtifactFactory: (TestModule) -> ResultingArtifact<*>
abstract val steps: List<TestStep<*, *>>
abstract val metaInfoHandlerEnabled: Boolean 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 ---------------------------- // ---------------------------- 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. * 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.openapi.util.Disposer
import com.intellij.testFramework.TestDataFile 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.test.services.*
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.IOException import java.io.IOException
class TestRunner(private val testConfiguration: TestConfiguration) { 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 = {}) { fun runTest(@TestDataFile testDataFileName: String, beforeDispose: (TestConfiguration) -> Unit = {}) {
try { try {
@@ -68,27 +77,15 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
preprocessor.preprocessModuleStructure(moduleStructure) preprocessor.preprocessModuleStructure(moduleStructure)
} }
var failedException: WrappedException? = null for (module in modules) {
try { val shouldProcessNextModules = processModule(module, dependencyProvider)
for (module in modules) { if (!shouldProcessNextModules) break
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 (handler in testConfiguration.getAllHandlers()) { for (handler in allRanHandlers) {
val wrapperFactory = when (handler) { val wrapperFactory: (Throwable) -> WrappedException = { WrappedException.FromHandler(it, handler) }
is FrontendOutputHandler -> WrappedException::FromFrontendHandler
is BackendInputHandler -> WrappedException::FromBackendHandler
is BinaryArtifactHandler -> WrappedException::FromBinaryHandler
else -> WrappedException::FromUnknownHandler
}
withAssertionCatching(wrapperFactory) { withAssertionCatching(wrapperFactory) {
val thereWasAnException = failedException != null || failedAssertions.isNotEmpty() val thereWasAnException = allFailedExceptions.isNotEmpty()
if (handler.shouldRun(thereWasAnException)) { if (handler.shouldRun(thereWasAnException)) {
handler.processAfterAllModules(thereWasAnException) handler.processAfterAllModules(thereWasAnException)
} }
@@ -99,100 +96,56 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
globalMetadataInfoHandler.compareAllMetaDataInfos() globalMetadataInfoHandler.compareAllMetaDataInfos()
} }
} }
if (failedException != null) {
failedAssertions.add(0, failedException)
}
testConfiguration.afterAnalysisCheckers.forEach { testConfiguration.afterAnalysisCheckers.forEach {
withAssertionCatching(WrappedException::FromAfterAnalysisChecker) { withAssertionCatching(WrappedException::FromAfterAnalysisChecker) {
it.check(failedAssertions) it.check(allFailedExceptions)
} }
} }
val filteredFailedAssertions = filterFailedExceptions(failedAssertions) val filteredFailedAssertions = filterFailedExceptions(allFailedExceptions)
filteredFailedAssertions.firstIsInstanceOrNull<WrappedException.FromFacade>()?.let { filteredFailedAssertions.firstIsInstanceOrNull<WrappedException.FromFacade>()?.let {
throw it throw it
} }
services.assertions.assertAll(filteredFailedAssertions) 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 if next modules should be not processed
* returns false which indicates that other modules should not be processed
*/ */
private fun processModule( private fun processModule(
services: TestServices,
module: TestModule, module: TestModule,
dependencyProvider: DependencyProviderImpl, dependencyProvider: DependencyProviderImpl
moduleStructure: TestModuleStructure
): Boolean { ): Boolean {
val sourcesArtifact = ResultingArtifact.Source() var inputArtifact = testConfiguration.startingArtifactFactory.invoke(module)
val frontendKind = module.frontendKind for (step in testConfiguration.steps) {
if (!frontendKind.shouldRunAnalysis) return true if (!step.shouldProcessModule(module, inputArtifact)) continue
val frontendArtifacts: ResultingArtifact.FrontendOutput<*> = withExceptionWrapping(WrappedException.FromFacade::Frontend) { when (val result = step.hackyProcessModule(module, inputArtifact, allFailedExceptions.isNotEmpty())) {
testConfiguration.getFacade(SourcesKind, frontendKind) is TestStep.StepResult.Artifact<*> -> {
.transform(module, sourcesArtifact)?.also { dependencyProvider.registerArtifact(module, it) } require(step is TestStep.FacadeStep<*, *>)
?: return true if (step.inputArtifactKind != step.outputArtifactKind) {
} dependencyProvider.registerArtifact(module, result.outputArtifact)
val frontendHandlers: List<AnalysisHandler<*>> = testConfiguration.getHandlers(frontendKind) }
for (frontendHandler in frontendHandlers) { inputArtifact = result.outputArtifact
val thereWasAnException = withAssertionCatching(WrappedException::FromFrontendHandler) {
if (frontendHandler.shouldRun(failedAssertions.isNotEmpty())) {
frontendHandler.hackyProcess(module, frontendArtifacts)
} }
} is TestStep.StepResult.ErrorFromFacade -> {
if (thereWasAnException && frontendHandler.failureDisablesNextSteps) return false allFailedExceptions += result.exception
} 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.HandlersResult -> {
if (thereWasAnException && backendHandler.failureDisablesNextSteps) return false val (exceptionsFromHandlers, shouldRunNextSteps) = result
} require(step is TestStep.HandlersStep<*>)
allRanHandlers += step.handlers
for (artifactKind in moduleStructure.getTargetArtifactKinds(module)) { allFailedExceptions += exceptionsFromHandlers
if (!artifactKind.shouldRunAnalysis) continue if (!shouldRunNextSteps) {
val binaryArtifact = withExceptionWrapping(WrappedException.FromFacade::Backend) { return false
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)
} }
} }
if (thereWasAnException && binaryHandler.failureDisablesNextSteps) return false is TestStep.StepResult.NoArtifactFromFacade -> return false
} }
} }
return true return true
} }
@@ -204,57 +157,38 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
block() block()
false false
} catch (e: Throwable) { } catch (e: Throwable) {
failedAssertions += exceptionWrapper(e) allFailedExceptions += exceptionWrapper(e)
true true
} }
} }
private inline fun <R> withExceptionWrapping(exceptionWrapper: (Throwable) -> WrappedException, block: () -> R): R { private fun filterFailedExceptions(failedExceptions: List<WrappedException>): List<Throwable> {
return try { return testConfiguration.afterAnalysisCheckers
block() .fold(failedExceptions) { assertions, checker ->
} catch (e: Throwable) { checker.suppressIfNeeded(assertions)
throw exceptionWrapper(e) }
} .sorted()
.map { it.cause }
} }
private fun AnalysisHandler<*>.shouldRun(thereWasAnException: Boolean): Boolean { // -------------------------------------- hacks --------------------------------------
return !(doNotRunIfThereWerePreviousFailures && thereWasAnException)
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 package org.jetbrains.kotlin.test
import org.jetbrains.kotlin.test.model.AbstractTestFacade
import org.jetbrains.kotlin.test.model.AnalysisHandler
sealed class WrappedException( sealed class WrappedException(
cause: Throwable, cause: Throwable,
val priority: Int, val priority: Int,
val additionalPriority: Int val additionalPriority: Int
) : Exception(cause), Comparable<WrappedException> { ) : Exception(cause), Comparable<WrappedException> {
sealed class FromFacade(cause: Throwable, additionalPriority: Int) : WrappedException(cause, 0, additionalPriority) { class FromFacade(cause: Throwable, val facade: AbstractTestFacade<*, *>) : WrappedException(cause, 0, 1) {
class Frontend(cause: Throwable) : FromFacade(cause, 1)
class Converter(cause: Throwable) : FromFacade(cause, 2)
class Backend(cause: Throwable) : FromFacade(cause, 3)
override val message: String override val message: String
get() = "Exception was thrown" get() = "Exception was thrown"
} }
class FromMetaInfoHandler(cause: Throwable) : WrappedException(cause, 1, 1) class FromMetaInfoHandler(cause: Throwable) : WrappedException(cause, 1, 1)
class FromFrontendHandler(cause: Throwable) : WrappedException(cause, 1, 1) class FromHandler(cause: Throwable, val handler: AnalysisHandler<*>) : WrappedException(cause, 1, 2)
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 FromAfterAnalysisChecker(cause: Throwable) : WrappedException(cause, 2, 1) 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.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.services.ServiceRegistrationData import org.jetbrains.kotlin.test.services.ServiceRegistrationData
import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.backendKindExtractor
interface ServicesAndDirectivesContainer { interface ServicesAndDirectivesContainer {
val additionalServices: List<ServiceRegistrationData> val additionalServices: List<ServiceRegistrationData>
@@ -22,6 +23,7 @@ abstract class AbstractTestFacade<I : ResultingArtifact<I>, O : ResultingArtifac
abstract val outputKind: TestArtifactKind<O> abstract val outputKind: TestArtifactKind<O>
abstract fun transform(module: TestModule, inputArtifact: I): O? abstract fun transform(module: TestModule, inputArtifact: I): O?
abstract fun shouldRunAnalysis(module: TestModule): Boolean
} }
abstract class FrontendFacade<R : ResultingArtifact.FrontendOutput<R>>( 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> final override val inputKind: TestArtifactKind<ResultingArtifact.Source>
get() = SourcesKind get() = SourcesKind
override fun shouldRunAnalysis(module: TestModule): Boolean {
return module.frontendKind == outputKind
}
abstract fun analyze(module: TestModule): R abstract fun analyze(module: TestModule): R
final override fun transform(module: TestModule, inputArtifact: ResultingArtifact.Source): 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, val testServices: TestServices,
final override val inputKind: FrontendKind<R>, final override val inputKind: FrontendKind<R>,
final override val outputKind: BackendKind<I> 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>>( abstract class BackendFacade<I : ResultingArtifact.BackendInput<I>, A : ResultingArtifact.Binary<A>>(
val testServices: TestServices, val testServices: TestServices,
final override val inputKind: BackendKind<I>, final override val inputKind: BackendKind<I>,
final override val outputKind: BinaryKind<A> 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 package org.jetbrains.kotlin.test.builders
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.test.Constructor import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.test.TestConfiguration import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.TestInfrastructureInternals
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.impl.TestConfigurationImpl import org.jetbrains.kotlin.test.impl.TestConfigurationImpl
import org.jetbrains.kotlin.test.model.* import org.jetbrains.kotlin.test.model.*
@@ -16,14 +15,16 @@ import org.jetbrains.kotlin.test.services.*
import kotlin.io.path.Path import kotlin.io.path.Path
@DefaultsDsl @DefaultsDsl
@OptIn(TestInfrastructureInternals::class) @OptIn(TestInfrastructureInternals::class, PrivateForInline::class)
class TestConfigurationBuilder { class TestConfigurationBuilder {
val defaultsProviderBuilder: DefaultsProviderBuilder = DefaultsProviderBuilder() val defaultsProviderBuilder: DefaultsProviderBuilder = DefaultsProviderBuilder()
lateinit var assertions: AssertionsService 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 sourcePreprocessors: MutableList<Constructor<SourceFilePreprocessor>> = mutableListOf()
private val additionalMetaInfoProcessors: MutableList<Constructor<AdditionalMetaInfoProcessor>> = mutableListOf() private val additionalMetaInfoProcessors: MutableList<Constructor<AdditionalMetaInfoProcessor>> = mutableListOf()
@@ -50,6 +51,8 @@ class TestConfigurationBuilder {
lateinit var testInfo: KotlinTestInfo lateinit var testInfo: KotlinTestInfo
lateinit var startingArtifactFactory: (TestModule) -> ResultingArtifact<*>
inline fun <reified T : TestService> useAdditionalService(noinline serviceConstructor: (TestServices) -> T) { inline fun <reified T : TestService> useAdditionalService(noinline serviceConstructor: (TestServices) -> T) {
useAdditionalService(service(serviceConstructor)) useAdditionalService(service(serviceConstructor))
} }
@@ -89,32 +92,47 @@ class TestConfigurationBuilder {
defaultsProviderBuilder.apply(init) defaultsProviderBuilder.apply(init)
} }
fun unregisterAllFacades() { fun <I : ResultingArtifact<I>, O : ResultingArtifact<O>> facadeStep(
facades.clear() facade: Constructor<AbstractTestFacade<I, O>>,
): FacadeStepBuilder<I, O> {
return FacadeStepBuilder(facade).also {
steps += it
}
} }
fun useFrontendFacades(vararg constructor: Constructor<FrontendFacade<*>>) { inline fun <I : ResultingArtifact<I>> handlersStep(
facades += constructor artifactKind: TestArtifactKind<I>,
init: HandlersStepBuilder<I>.() -> Unit
): HandlersStepBuilder<I> {
return HandlersStepBuilder(artifactKind).also {
it.init()
steps += it
}
} }
fun useBackendFacades(vararg constructor: Constructor<BackendFacade<*, *>>) { inline fun <I : ResultingArtifact<I>> namedHandlersStep(
facades += constructor 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<*, *>>) { inline fun <I : ResultingArtifact<I>> configureNamedHandlersStep(
facades += constructor name: String,
} artifactKind: TestArtifactKind<I>,
init: HandlersStepBuilder<I>.() -> Unit
fun useFrontendHandlers(vararg constructor: Constructor<FrontendOutputHandler<*>>) { ) {
handlers += constructor 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" }
fun useBackendHandlers(vararg constructor: Constructor<BackendInputHandler<*>>) { @Suppress("UNCHECKED_CAST")
handlers += constructor (step as HandlersStepBuilder<I>).apply(init)
}
fun useArtifactsHandlers(vararg constructor: Constructor<BinaryArtifactHandler<*>>) {
handlers += constructor
} }
fun useSourcePreprocessor(vararg preprocessors: Constructor<SourceFilePreprocessor>, needToPrepend: Boolean = false) { fun useSourcePreprocessor(vararg preprocessors: Constructor<SourceFilePreprocessor>, needToPrepend: Boolean = false) {
@@ -145,6 +163,11 @@ class TestConfigurationBuilder {
additionalSourceProviders += providers additionalSourceProviders += providers
} }
@TestInfrastructureInternals
fun resetModuleStructureTransformers() {
moduleStructureTransformers.clear()
}
@TestInfrastructureInternals @TestInfrastructureInternals
fun useModuleStructureTransformers(vararg transformers: ModuleStructureTransformer) { fun useModuleStructureTransformers(vararg transformers: ModuleStructureTransformer) {
moduleStructureTransformers += transformers moduleStructureTransformers += transformers
@@ -193,8 +216,7 @@ class TestConfigurationBuilder {
testInfo, testInfo,
defaultsProviderBuilder.build(), defaultsProviderBuilder.build(),
assertions, assertions,
facades, steps,
handlers,
sourcePreprocessors, sourcePreprocessors,
additionalMetaInfoProcessors, additionalMetaInfoProcessors,
environmentConfigurators, environmentConfigurators,
@@ -208,6 +230,7 @@ class TestConfigurationBuilder {
metaInfoHandlerEnabled, metaInfoHandlerEnabled,
directives, directives,
defaultRegisteredDirectivesBuilder.build(), defaultRegisteredDirectivesBuilder.build(),
startingArtifactFactory,
additionalServices 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.WrappedException
import org.jetbrains.kotlin.test.model.AfterAnalysisChecker 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.TestServices
import org.jetbrains.kotlin.test.services.moduleStructure import org.jetbrains.kotlin.test.services.moduleStructure
@@ -15,7 +16,13 @@ class FirFailingTestSuppressor(testServices: TestServices) : AfterAnalysisChecke
val testFile = testServices.moduleStructure.originalTestDataFiles.first() val testFile = testServices.moduleStructure.originalTestDataFiles.first()
val failFile = testFile.parentFile.resolve("${testFile.nameWithoutExtension}.fail") val failFile = testFile.parentFile.resolve("${testFile.nameWithoutExtension}.fail")
val exceptionFromFir = 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 { return when {
failFile.exists() && exceptionFromFir != null -> emptyList() failFile.exists() && exceptionFromFir != null -> emptyList()
failFile.exists() && exceptionFromFir == null -> { 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. * 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 package org.jetbrains.kotlin.test.impl
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.test.Constructor import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.TestConfiguration
import org.jetbrains.kotlin.test.TestInfrastructureInternals
import org.jetbrains.kotlin.test.directives.model.ComposedDirectivesContainer import org.jetbrains.kotlin.test.directives.model.ComposedDirectivesContainer
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives 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.*
import org.jetbrains.kotlin.test.services.impl.ModuleStructureExtractorImpl import org.jetbrains.kotlin.test.services.impl.ModuleStructureExtractorImpl
import org.jetbrains.kotlin.test.utils.TestDisposable import org.jetbrains.kotlin.test.utils.TestDisposable
@@ -24,9 +25,7 @@ class TestConfigurationImpl(
defaultsProvider: DefaultsProvider, defaultsProvider: DefaultsProvider,
assertions: AssertionsService, assertions: AssertionsService,
facades: List<Constructor<AbstractTestFacade<*, *>>>, steps: List<TestStepBuilder<*, *>>,
analysisHandlers: List<Constructor<AnalysisHandler<*>>>,
sourcePreprocessors: List<Constructor<SourceFilePreprocessor>>, sourcePreprocessors: List<Constructor<SourceFilePreprocessor>>,
additionalMetaInfoProcessors: List<Constructor<AdditionalMetaInfoProcessor>>, additionalMetaInfoProcessors: List<Constructor<AdditionalMetaInfoProcessor>>,
@@ -45,6 +44,7 @@ class TestConfigurationImpl(
directives: List<DirectivesContainer>, directives: List<DirectivesContainer>,
override val defaultRegisteredDirectives: RegisteredDirectives, override val defaultRegisteredDirectives: RegisteredDirectives,
override val startingArtifactFactory: (TestModule) -> ResultingArtifact<*>,
additionalServices: List<ServiceRegistrationData> additionalServices: List<ServiceRegistrationData>
) : TestConfiguration() { ) : TestConfiguration() {
override val rootDisposable: Disposable = TestDisposable() override val rootDisposable: Disposable = TestDisposable()
@@ -67,35 +67,28 @@ class TestConfigurationImpl(
} }
private val environmentConfigurators: List<EnvironmentConfigurator> = private val environmentConfigurators: List<EnvironmentConfigurator> =
environmentConfigurators.map { it.invoke(testServices) }.also { configurators -> environmentConfigurators
configurators.flatMapTo(allDirectives) { it.directiveContainers } .map { it.invoke(testServices) }
for (configurator in configurators) { .also { it.registerDirectivesAndServices() }
configurator.additionalServices.forEach { testServices.register(it) }
}
}
override val preAnalysisHandlers: List<PreAnalysisHandler> = override val preAnalysisHandlers: List<PreAnalysisHandler> =
preAnalysisHandlers.map { it.invoke(testServices) } preAnalysisHandlers.map { it.invoke(testServices) }
override val moduleStructureExtractor: ModuleStructureExtractor = ModuleStructureExtractorImpl( override val moduleStructureExtractor: ModuleStructureExtractor = ModuleStructureExtractorImpl(
testServices, testServices,
additionalSourceProviders.map { it.invoke(testServices) }.also { additionalSourceProviders
it.flatMapTo(allDirectives) { provider -> provider.directiveContainers } .map { it.invoke(testServices) }
}, .also { it.registerDirectivesAndServices() },
moduleStructureTransformers, moduleStructureTransformers,
this.environmentConfigurators this.environmentConfigurators
) )
override val metaTestConfigurators: List<MetaTestConfigurator> = metaTestConfigurators.map { override val metaTestConfigurators: List<MetaTestConfigurator> = metaTestConfigurators.map { constructor ->
it.invoke(testServices).also { configurator -> constructor.invoke(testServices).also { it.registerDirectivesAndServices() }
allDirectives += configurator.directiveContainers
}
} }
override val afterAnalysisCheckers: List<AfterAnalysisChecker> = afterAnalysisCheckers.map { override val afterAnalysisCheckers: List<AfterAnalysisChecker> = afterAnalysisCheckers.map { constructor ->
it.invoke(testServices).also { checker -> constructor.invoke(testServices).also { it.registerDirectivesAndServices() }
allDirectives += checker.directiveContainers
}
} }
init { init {
@@ -120,61 +113,23 @@ class TestConfigurationImpl(
} }
} }
private val facades: Map<TestArtifactKind<*>, Map<TestArtifactKind<*>, AbstractTestFacade<*, *>>> = override val steps: List<TestStep<*, *>> = steps
facades .map { it.createTestStep(testServices) }
.map { it.invoke(testServices) } .onEach { step ->
.groupBy { it.inputKind } when (step) {
.mapValues { (frontendKind, converters) -> is TestStep.FacadeStep<*, *> -> step.facade.registerDirectivesAndServices()
converters.groupBy { it.outputKind }.mapValues { is TestStep.HandlersStep<*> -> step.handlers.registerDirectivesAndServices()
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
}
} }
} }
// ---------------------------------- utils ----------------------------------
private fun ServicesAndDirectivesContainer.registerDirectivesAndServices() {
allDirectives += directiveContainers
testServices.register(additionalServices)
} }
override fun <I : ResultingArtifact<I>, O : ResultingArtifact<O>> getFacade( private fun List<ServicesAndDirectivesContainer>.registerDirectivesAndServices() {
inputKind: TestArtifactKind<I>, this.forEach { it.registerDirectivesAndServices() }
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()
} }
} }
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.config.ExplicitApiMode
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.CHECK_COMPILE_TIME_VALUES
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.DIAGNOSTICS import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.DIAGNOSTICS
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.REPORT_JVM_DIAGNOSTICS_ON_FRONTEND 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.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator 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.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.ScriptingEnvironmentConfigurator 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() { abstract class AbstractDiagnosticTest : AbstractKotlinCompilerTest() {
companion object { companion object {
@@ -70,12 +72,15 @@ abstract class AbstractDiagnosticTest : AbstractKotlinCompilerTest() {
::CoroutineHelpersSourceFilesProvider, ::CoroutineHelpersSourceFilesProvider,
) )
useFrontendFacades(::ClassicFrontendFacade) classicFrontendStep()
useFrontendHandlers(
::DeclarationsDumpHandler, classicFrontendHandlersStep {
::ClassicDiagnosticsHandler, useHandlers(
::ConstantValuesHandler ::DeclarationsDumpHandler,
) ::ClassicDiagnosticsHandler,
::ConstantValuesHandler
)
}
useAfterAnalysisCheckers(::FirTestDataConsistencyHandler) useAfterAnalysisCheckers(::FirTestDataConsistencyHandler)
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.konan.NativePlatforms import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
@@ -40,10 +42,12 @@ abstract class AbstractDiagnosticsNativeTest : AbstractKotlinCompilerTest() {
::CoroutineHelpersSourceFilesProvider, ::CoroutineHelpersSourceFilesProvider,
) )
useFrontendFacades(::ClassicFrontendFacade) classicFrontendStep()
useFrontendHandlers( classicFrontendHandlersStep {
::DeclarationsDumpHandler, useHandlers(
::ClassicDiagnosticsHandler, ::DeclarationsDumpHandler,
) ::ClassicDiagnosticsHandler,
)
}
} }
} }
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
@@ -45,11 +47,13 @@ abstract class AbstractDiagnosticsTestWithJsStdLib : AbstractKotlinCompilerTest(
::CoroutineHelpersSourceFilesProvider, ::CoroutineHelpersSourceFilesProvider,
) )
useFrontendFacades(::ClassicFrontendFacade) classicFrontendStep()
useFrontendHandlers( classicFrontendHandlersStep {
::DeclarationsDumpHandler, useHandlers(
::ClassicDiagnosticsHandler, ::DeclarationsDumpHandler,
::DynamicCallsDumpHandler, ::ClassicDiagnosticsHandler,
) ::DynamicCallsDumpHandler,
)
}
} }
} }
@@ -6,27 +6,35 @@
package org.jetbrains.kotlin.test.runners package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend 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.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.handlers.JvmBackendDiagnosticsHandler 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.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade 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.ClassicDiagnosticsHandler
import org.jetbrains.kotlin.test.frontend.classic.handlers.DeclarationsDumpHandler import org.jetbrains.kotlin.test.frontend.classic.handlers.DeclarationsDumpHandler
import org.jetbrains.kotlin.test.frontend.classic.handlers.OldNewInferenceMetaInfoProcessor import org.jetbrains.kotlin.test.frontend.classic.handlers.OldNewInferenceMetaInfoProcessor
import org.jetbrains.kotlin.test.model.DependencyKind import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator 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 targetBackend: TargetBackend
abstract val converter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, I>>
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() { override fun TestConfigurationBuilder.configuration() {
globalDefaults { globalDefaults {
@@ -53,35 +61,43 @@ abstract class AbstractDiagnosticsTestWithJvmBackend : AbstractKotlinCompilerTes
::CoroutineHelpersSourceFilesProvider, ::CoroutineHelpersSourceFilesProvider,
) )
useFrontendFacades(::ClassicFrontendFacade) classicFrontendStep()
classicFrontendHandlersStep {
useHandlers(
::DeclarationsDumpHandler,
::ClassicDiagnosticsHandler,
)
}
useFrontendHandlers( facadeStep(converter)
::DeclarationsDumpHandler, facadeStep(backendFacade)
::ClassicDiagnosticsHandler,
)
useFrontend2BackendConverters( jvmArtifactsHandlersStep {
::ClassicFrontend2ClassicBackendConverter, useHandlers(
::ClassicFrontend2IrConverter ::JvmBackendDiagnosticsHandler
) )
}
useBackendFacades(
::ClassicJvmBackendFacade,
::JvmIrBackendFacade
)
useArtifactsHandlers(
::JvmBackendDiagnosticsHandler
)
} }
} }
abstract class AbstractDiagnosticsTestWithOldJvmBackend : AbstractDiagnosticsTestWithJvmBackend() { abstract class AbstractDiagnosticsTestWithOldJvmBackend : AbstractDiagnosticsTestWithJvmBackend<ClassicBackendInput>() {
override val targetBackend: TargetBackend override val targetBackend: TargetBackend
get() = TargetBackend.JVM_OLD 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 override val targetBackend: TargetBackend
get() = TargetBackend.JVM_IR 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 package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.bind import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.FIR_DUMP
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.USE_LIGHT_TREE import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.USE_LIGHT_TREE
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS 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.directives.JvmEnvironmentConfigurationDirectives.WITH_STDLIB
import org.jetbrains.kotlin.test.frontend.fir.FirFailingTestSuppressor import org.jetbrains.kotlin.test.frontend.fir.FirFailingTestSuppressor
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade 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.frontend.fir.handlers.*
import org.jetbrains.kotlin.test.model.DependencyKind 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.model.FrontendKinds
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider 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 // `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 { globalDefaults {
frontend = FrontendKinds.FIR frontend = FrontendKinds.FIR
targetPlatform = JvmPlatforms.defaultJvmPlatform targetPlatform = JvmPlatforms.defaultJvmPlatform
@@ -64,14 +69,17 @@ fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(baseDir: String
::AdditionalDiagnosticsSourceFilesProvider.bind(baseDir), ::AdditionalDiagnosticsSourceFilesProvider.bind(baseDir),
::CoroutineHelpersSourceFilesProvider.bind(baseDir), ::CoroutineHelpersSourceFilesProvider.bind(baseDir),
) )
useFrontendFacades(::FirFrontendFacade)
useFrontendHandlers( facadeStep(frontendFacade)
::FirDiagnosticsHandler, firHandlersStep {
::FirDumpHandler, useHandlers(
::FirCfgDumpHandler, ::FirDiagnosticsHandler,
::FirCfgConsistencyHandler, ::FirDumpHandler,
::FirNoImplicitTypesHandler, ::FirCfgDumpHandler,
) ::FirCfgConsistencyHandler,
::FirNoImplicitTypesHandler,
)
}
useMetaInfoProcessors(::PsiLightTreeMetaInfoProcessor) useMetaInfoProcessors(::PsiLightTreeMetaInfoProcessor)
@@ -6,10 +6,12 @@
package org.jetbrains.kotlin.test.runners package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestJavacVersion import org.jetbrains.kotlin.test.TestJavacVersion
import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.REPORT_JVM_DIAGNOSTICS_ON_FRONTEND
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.SKIP_TXT import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.SKIP_TXT
import org.jetbrains.kotlin.test.directives.ForeignAnnotationsDirectives.ANNOTATIONS_PATH import org.jetbrains.kotlin.test.directives.ForeignAnnotationsDirectives.ANNOTATIONS_PATH
@@ -60,11 +62,13 @@ abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest()
::CoroutineHelpersSourceFilesProvider, ::CoroutineHelpersSourceFilesProvider,
) )
useFrontendFacades(::ClassicFrontendFacade) classicFrontendStep()
useFrontendHandlers( classicFrontendHandlersStep {
::DeclarationsDumpHandler, useHandlers(
::ClassicDiagnosticsHandler, ::DeclarationsDumpHandler,
) ::ClassicDiagnosticsHandler,
)
}
forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/tests/*") { forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/tests/*") {
defaultDirectives { defaultDirectives {
@@ -88,7 +92,9 @@ abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest()
} }
forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/*") { forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/*") {
useFrontendHandlers(::JspecifyDiagnosticComplianceHandler) configureClassicFrontendHandlersStep {
useHandlers(::JspecifyDiagnosticComplianceHandler)
}
useSourcePreprocessor(::JspecifyMarksCleanupPreprocessor) 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.builders.testRunner
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives 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.preprocessors.MetaInfosCleanupPreprocessor
import org.jetbrains.kotlin.test.services.* import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl
@@ -46,6 +47,7 @@ abstract class AbstractKotlinCompilerTest {
useSourcePreprocessor(*defaultPreprocessors.toTypedArray()) useSourcePreprocessor(*defaultPreprocessors.toTypedArray())
useDirectives(*defaultDirectiveContainers.toTypedArray()) useDirectives(*defaultDirectiveContainers.toTypedArray())
configureDebugFlags() 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.Constructor
import org.jetbrains.kotlin.test.TargetBackend 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.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.model.* import org.jetbrains.kotlin.test.model.*
open class AbstractBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact>( open class AbstractBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact, ClassicBackendInput>(
FrontendKinds.ClassicFrontend, FrontendKinds.ClassicFrontend,
TargetBackend.JVM TargetBackend.JVM
) { ) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>> override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>> override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, ClassicBackendInput>>
get() = ::ClassicFrontend2ClassicBackendConverter get() = ::ClassicFrontend2ClassicBackendConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Jvm>>
get() = ::ClassicJvmBackendFacade get() = ::ClassicJvmBackendFacade
} }
@@ -8,56 +8,64 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.Constructor import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor 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.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.handlers.BytecodeListingHandler 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.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.directives.CodegenTestDirectives
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.frontend.classic.* import org.jetbrains.kotlin.test.frontend.classic.*
import org.jetbrains.kotlin.test.model.* 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, targetBackend: TargetBackend,
val targetFrontend: FrontendKind<*> val targetFrontend: FrontendKind<R>
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) { ) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
abstract val frontendFacade: Constructor<FrontendFacade<R>> abstract val frontendFacade: Constructor<FrontendFacade<R>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>> abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() { override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
commonHandlersForCodegenTest()
defaultDirectives { defaultDirectives {
+CodegenTestDirectives.CHECK_BYTECODE_LISTING +CodegenTestDirectives.CHECK_BYTECODE_LISTING
} }
useArtifactsHandlers(::BytecodeListingHandler)
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
commonHandlersForCodegenTest()
configureJvmArtifactsHandlersStep {
useHandlers(::BytecodeListingHandler)
}
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor) useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
} }
} }
open class AbstractBytecodeListingTest : AbstractBytecodeListingTestBase<ClassicFrontendOutputArtifact>( open class AbstractBytecodeListingTest : AbstractBytecodeListingTestBase<ClassicFrontendOutputArtifact, ClassicBackendInput>(
TargetBackend.JVM, FrontendKinds.ClassicFrontend TargetBackend.JVM, FrontendKinds.ClassicFrontend
) { ) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>> override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>> override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, ClassicBackendInput>>
get() = ::ClassicFrontend2ClassicBackendConverter get() = ::ClassicFrontend2ClassicBackendConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Jvm>>
get() = ::ClassicJvmBackendFacade get() = ::ClassicJvmBackendFacade
} }
open class AbstractIrBytecodeListingTest : AbstractBytecodeListingTestBase<ClassicFrontendOutputArtifact>( open class AbstractIrBytecodeListingTest : AbstractBytecodeListingTestBase<ClassicFrontendOutputArtifact, IrBackendInput>(
TargetBackend.JVM_IR, FrontendKinds.ClassicFrontend TargetBackend.JVM_IR, FrontendKinds.ClassicFrontend
) { ) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>> override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>> override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2IrConverter get() = ::ClassicFrontend2IrConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade get() = ::JvmIrBackendFacade
} }
@@ -8,10 +8,13 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.Constructor import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor 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.classic.ClassicJvmBackendFacade
import org.jetbrains.kotlin.test.backend.handlers.BytecodeTextHandler 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.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.USE_PSI_CLASS_FILES_READING
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_REFLECT import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_REFLECT
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_STDLIB 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.model.*
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest 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, targetBackend: TargetBackend,
val targetFrontend: FrontendKind<*> val targetFrontend: FrontendKind<R>
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) { ) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
abstract val frontendFacade: Constructor<FrontendFacade<R>> abstract val frontendFacade: Constructor<FrontendFacade<R>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>> abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() { override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
defaultDirectives { defaultDirectives {
+WITH_STDLIB +WITH_STDLIB
+WITH_REFLECT +WITH_REFLECT
} }
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
commonHandlersForCodegenTest() commonHandlersForCodegenTest()
useArtifactsHandlers(::BytecodeTextHandler) configureJvmArtifactsHandlersStep {
useHandlers(::BytecodeTextHandler)
}
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor) useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
} }
} }
open class AbstractBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact>( open class AbstractBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact, ClassicBackendInput>(
targetBackend = TargetBackend.JVM, targetBackend = TargetBackend.JVM,
targetFrontend = FrontendKinds.ClassicFrontend targetFrontend = FrontendKinds.ClassicFrontend
) { ) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>> override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>> override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, ClassicBackendInput>>
get() = ::ClassicFrontend2ClassicBackendConverter get() = ::ClassicFrontend2ClassicBackendConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Jvm>>
get() = ::ClassicJvmBackendFacade get() = ::ClassicJvmBackendFacade
} }
open class AbstractIrBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact>( open class AbstractIrBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact, IrBackendInput>(
targetBackend = TargetBackend.JVM_IR, targetBackend = TargetBackend.JVM_IR,
targetFrontend = FrontendKinds.ClassicFrontend targetFrontend = FrontendKinds.ClassicFrontend
) { ) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>> override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>> override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2IrConverter get() = ::ClassicFrontend2IrConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade get() = ::JvmIrBackendFacade
} }
open class AbstractFirBytecodeTextTest : AbstractBytecodeTextTestBase<FirOutputArtifact>( open class AbstractFirBytecodeTextTest : AbstractBytecodeTextTestBase<FirOutputArtifact, IrBackendInput>(
targetBackend = TargetBackend.JVM_IR, targetBackend = TargetBackend.JVM_IR,
targetFrontend = FrontendKinds.FIR targetFrontend = FrontendKinds.FIR
) { ) {
override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>> override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>>
get() = ::FirFrontendFacade get() = ::FirFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, *>> override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
get() = ::Fir2IrResultsConverter get() = ::Fir2IrResultsConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade get() = ::JvmIrBackendFacade
override fun configure(builder: TestConfigurationBuilder) { 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.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.bind import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.directives.CodegenTestDirectives.IGNORE_BACKEND_MULTI_MODULE
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter 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 frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, I>>
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>> abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() = configurationImpl() override fun TestConfigurationBuilder.configuration() {
protected fun TestConfigurationBuilder.configurationImpl() {
commonConfigurationForCodegenTest( commonConfigurationForCodegenTest(
FrontendKinds.ClassicFrontend, FrontendKinds.ClassicFrontend,
::ClassicFrontendFacade, ::ClassicFrontendFacade,
@@ -55,7 +54,7 @@ abstract class AbstractCompileKotlinAgainstInlineKotlinTestBase<I : ResultingArt
backendFacade backendFacade
) )
useInlineHandlers() useInlineHandlers()
commonHandlersForBoxTest() configureCommonHandlersForBoxTest()
useModuleStructureTransformers( useModuleStructureTransformers(
ModuleTransformerForTwoFilesBoxTests() ModuleTransformerForTwoFilesBoxTests()
) )
@@ -82,11 +81,15 @@ open class AbstractIrCompileKotlinAgainstInlineKotlinTest :
} }
open class AbstractIrSerializeCompileKotlinAgainstInlineKotlinTest : AbstractIrCompileKotlinAgainstInlineKotlinTest() { open class AbstractIrSerializeCompileKotlinAgainstInlineKotlinTest : AbstractIrCompileKotlinAgainstInlineKotlinTest() {
override fun TestConfigurationBuilder.configuration() { override fun configure(builder: TestConfigurationBuilder) {
// call super super.configure(builder)
configurationImpl() builder.apply {
useConfigurators(::SerializeSetter) useConfigurators(::SerializeSetter)
useBackendHandlers(::CheckInlineBodies)
configureIrHandlersStep {
useHandlers(::CheckInlineBodies)
}
}
} }
private class SerializeSetter(testServices: TestServices) : EnvironmentConfigurator(testServices) { 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.TestInfrastructureInternals
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade 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.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.bind 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.directives.CodegenTestDirectives.IGNORE_BACKEND_MULTI_MODULE
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter 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.model.FrontendKinds
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.services.ModuleTransformerForSwitchingBackend import org.jetbrains.kotlin.test.services.ModuleTransformerForSwitchingBackend
@OptIn(TestInfrastructureInternals::class) @OptIn(TestInfrastructureInternals::class)
abstract class AbstractJvmIrAgainstOldBoxTestBase(targetBackend: TargetBackend) : AbstractKotlinCompilerWithTargetBackendTest( abstract class AbstractBoxWithDifferentBackendsTest(
targetBackend targetBackend: TargetBackend,
) { val backendForLib: TargetBackend,
abstract val backendForLib: TargetBackend val backendForMain: TargetBackend
abstract val backendForMain: TargetBackend ) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
override fun TestConfigurationBuilder.configuration() { override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest( commonServicesConfigurationForCodegenTest(FrontendKinds.ClassicFrontend)
FrontendKinds.ClassicFrontend,
::ClassicFrontendFacade,
::ClassicFrontend2ClassicBackendConverter,
::ClassicJvmBackendFacade
)
commonHandlersForBoxTest() classicFrontendStep()
classicFrontendHandlersStep {
commonClassicFrontendHandlersForCodegenTest()
}
useFrontend2BackendConverters(::ClassicFrontend2IrConverter) psi2ClassicBackendStep()
useBackendFacades(::JvmIrBackendFacade) classicJvmBackendStep()
psi2IrStep()
jvmIrBackendStep()
jvmArtifactsHandlersStep {
commonBackendHandlersForCodegenTest()
boxHandlersForBackendStep()
}
useModuleStructureTransformers( useModuleStructureTransformers(
ModuleTransformerForSwitchingBackend(backendForLib, backendForMain) 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) { open class AbstractJvmOldAgainstIrBoxTest : AbstractBoxWithDifferentBackendsTest(
override val backendForLib: TargetBackend TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR,
get() = TargetBackend.JVM backendForLib = TargetBackend.JVM_IR,
override val backendForMain: TargetBackend backendForMain = TargetBackend.JVM,
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
}
@@ -7,9 +7,10 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.Constructor import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend 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.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder 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.directives.JvmEnvironmentConfigurationDirectives.USE_PSI_CLASS_FILES_READING
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade 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.frontend.fir.handlers.FirScopeDumpHandler
import org.jetbrains.kotlin.test.model.* import org.jetbrains.kotlin.test.model.*
open class AbstractFirBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<FirOutputArtifact>( open class AbstractFirBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<FirOutputArtifact, IrBackendInput>(
FrontendKinds.FIR, FrontendKinds.FIR,
TargetBackend.JVM_IR TargetBackend.JVM_IR
) { ) {
override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>> override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>>
get() = ::FirFrontendFacade get() = ::FirFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, *>> override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
get() = ::Fir2IrResultsConverter get() = ::Fir2IrResultsConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade get() = ::JvmIrBackendFacade
override fun configure(builder: TestConfigurationBuilder) { override fun configure(builder: TestConfigurationBuilder) {
@@ -41,18 +42,21 @@ open class AbstractFirBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<F
// See KT-44152 // See KT-44152
-USE_PSI_CLASS_FILES_READING -USE_PSI_CLASS_FILES_READING
} }
useFrontendHandlers(
::FirDumpHandler, configureFirHandlersStep {
::FirScopeDumpHandler, useHandlers(
::FirCfgDumpHandler, ::FirDumpHandler,
::FirNoImplicitTypesHandler, ::FirScopeDumpHandler,
) ::FirCfgDumpHandler,
::FirNoImplicitTypesHandler,
)
}
useAfterAnalysisCheckers( useAfterAnalysisCheckers(
::FirMetaInfoDiffSuppressor ::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.Constructor
import org.jetbrains.kotlin.test.TargetBackend 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.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter 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.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.model.* import org.jetbrains.kotlin.test.model.*
open class AbstractIrBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact>( open class AbstractIrBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact, IrBackendInput>(
FrontendKinds.ClassicFrontend, FrontendKinds.ClassicFrontend,
TargetBackend.JVM_IR TargetBackend.JVM_IR
) { ) {
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>> override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade get() = ::ClassicFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>> override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2IrConverter get() = ::ClassicFrontend2IrConverter
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
get() = ::JvmIrBackendFacade get() = ::JvmIrBackendFacade
override fun configure(builder: TestConfigurationBuilder) { override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder) 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.backend.handlers.BytecodeTextHandler
import org.jetbrains.kotlin.test.bind import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_DEXING import org.jetbrains.kotlin.test.builders.configureClassicFrontendHandlersStep
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.USE_JAVAC_BASED_ON_JVM_TARGET 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.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.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.JDK_KIND
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JVM_TARGET import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JVM_TARGET
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_STDLIB 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.model.*
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest 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>, val targetFrontend: FrontendKind<R>,
targetBackend: TargetBackend targetBackend: TargetBackend
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) { ) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
abstract val frontendFacade: Constructor<FrontendFacade<R>> abstract val frontendFacade: Constructor<FrontendFacade<R>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>> abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Jvm>>
override fun TestConfigurationBuilder.configuration() { override fun TestConfigurationBuilder.configuration() {
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade) commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
useFrontendHandlers( configureClassicFrontendHandlersStep {
::ClassicDiagnosticsHandler, useHandlers(
::FirDiagnosticsHandler ::ClassicDiagnosticsHandler
) )
commonHandlersForBoxTest() }
useArtifactsHandlers(::BytecodeListingHandler)
useArtifactsHandlers(::BytecodeTextHandler.bind(true)) configureFirHandlersStep {
useHandlers(
::FirDiagnosticsHandler
)
}
configureCommonHandlersForBoxTest()
configureJvmArtifactsHandlersStep {
useHandlers(
::BytecodeListingHandler,
::BytecodeTextHandler.bind(true)
)
}
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor) useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
defaultDirectives { defaultDirectives {
@@ -7,55 +7,42 @@ package org.jetbrains.kotlin.test.runners.codegen
import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.TestInfrastructureInternals 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.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives import org.jetbrains.kotlin.test.builders.configureJvmArtifactsHandlersStep
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 import org.jetbrains.kotlin.test.services.ModuleTransformerForSwitchingBackend
import org.jetbrains.kotlin.test.services.ModuleTransformerForTwoFilesBoxTests import org.jetbrains.kotlin.test.services.ModuleTransformerForTwoFilesBoxTests
@OptIn(TestInfrastructureInternals::class) @OptIn(TestInfrastructureInternals::class)
open class AbstractBackendAgainstBackendBoxTestBase( abstract class AbstractBoxInlineWithDifferentBackendsTest(
targetBackend: TargetBackend, targetBackend: TargetBackend,
val backendForLib: TargetBackend, backendForLib: TargetBackend,
val backendForMain: TargetBackend backendForMain: TargetBackend
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) { ) : AbstractBoxWithDifferentBackendsTest(targetBackend, backendForLib, backendForMain) {
override fun TestConfigurationBuilder.configuration() { override fun configure(builder: TestConfigurationBuilder) {
commonConfigurationForCodegenTest( super.configure(builder)
FrontendKinds.ClassicFrontend, builder.apply {
::ClassicFrontendFacade, applyDumpSmapDirective()
::ClassicFrontend2ClassicBackendConverter,
::ClassicJvmBackendFacade
)
useFrontend2BackendConverters(::ClassicFrontend2IrConverter)
useBackendFacades(::JvmIrBackendFacade)
commonHandlersForBoxTest() resetModuleStructureTransformers()
useInlineHandlers() useModuleStructureTransformers(
ModuleTransformerForTwoFilesBoxTests(),
ModuleTransformerForSwitchingBackend(backendForLib, backendForMain)
)
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor.bind(CodegenTestDirectives.IGNORE_BACKEND_MULTI_MODULE)) configureJvmArtifactsHandlersStep {
inlineHandlers()
useModuleStructureTransformers( }
ModuleTransformerForTwoFilesBoxTests(), }
ModuleTransformerForSwitchingBackend(backendForLib, backendForMain)
)
} }
} }
open class AbstractJvmIrAgainstOldBoxInlineTest : AbstractBackendAgainstBackendBoxTestBase( open class AbstractJvmIrAgainstOldBoxInlineTest : AbstractBoxInlineWithDifferentBackendsTest(
targetBackend = TargetBackend.JVM_MULTI_MODULE_IR_AGAINST_OLD, targetBackend = TargetBackend.JVM_MULTI_MODULE_IR_AGAINST_OLD,
backendForLib = TargetBackend.JVM, backendForLib = TargetBackend.JVM,
backendForMain = TargetBackend.JVM_IR backendForMain = TargetBackend.JVM_IR
) )
open class AbstractJvmOldAgainstIrBoxInlineTest : AbstractBackendAgainstBackendBoxTestBase( open class AbstractJvmOldAgainstIrBoxInlineTest : AbstractBoxInlineWithDifferentBackendsTest(
targetBackend = TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR, targetBackend = TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR,
backendForLib = TargetBackend.JVM_IR, backendForLib = TargetBackend.JVM_IR,
backendForMain = TargetBackend.JVM_OLD 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.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.HandlersStepBuilder
import org.jetbrains.kotlin.test.backend.handlers.* 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.DUMP_SMAP
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.RUN_DEX_CHECKER 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.model.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator 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.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider
fun <R : ResultingArtifact.FrontendOutput<R>> TestConfigurationBuilder.commonConfigurationForCodegenTest( fun <F : ResultingArtifact.FrontendOutput<F>, B : ResultingArtifact.BackendInput<B>> TestConfigurationBuilder.commonConfigurationForCodegenTest(
targetFrontend: FrontendKind<*>, targetFrontend: FrontendKind<F>,
frontendFacade: Constructor<FrontendFacade<R>>, frontendFacade: Constructor<FrontendFacade<F>>,
frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>>, frontendToBackendConverter: Constructor<Frontend2BackendConverter<F, B>>,
backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>> backendFacade: Constructor<BackendFacade<B, BinaryArtifacts.Jvm>>,
) { ) {
commonServicesConfigurationForCodegenTest(targetFrontend)
facadeStep(frontendFacade)
classicFrontendHandlersStep()
firHandlersStep()
commonBackendStepsConfiguration(
frontendToBackendConverter,
irHandlersInit = {},
backendFacade,
jvmHandlersInit = {}
)
}
fun TestConfigurationBuilder.commonServicesConfigurationForCodegenTest(targetFrontend: FrontendKind<*>) {
globalDefaults { globalDefaults {
frontend = targetFrontend frontend = targetFrontend
targetPlatform = JvmPlatforms.defaultJvmPlatform targetPlatform = JvmPlatforms.defaultJvmPlatform
@@ -48,45 +65,99 @@ fun <R : ResultingArtifact.FrontendOutput<R>> TestConfigurationBuilder.commonCon
::CodegenHelpersSourceFilesProvider, ::CodegenHelpersSourceFilesProvider,
::MainFunctionForBlackBoxTestsSourceProvider, ::MainFunctionForBlackBoxTestsSourceProvider,
) )
useFrontendFacades(frontendFacade)
useFrontend2BackendConverters(frontendToBackendConverter)
useBackendFacades(backendFacade)
} }
fun TestConfigurationBuilder.dumpHandlersForCodegenTest() { inline fun <B : ResultingArtifact.BackendInput<B>, F : ResultingArtifact.FrontendOutput<F>> TestConfigurationBuilder.commonBackendStepsConfiguration(
useBackendHandlers(::IrTreeVerifierHandler, ::IrTextDumpHandler) noinline frontendToBackendConverter: Constructor<Frontend2BackendConverter<F, B>>,
useArtifactsHandlers(::BytecodeListingHandler) irHandlersInit: HandlersStepBuilder<IrBackendInput>.() -> Unit,
} noinline backendFacade: Constructor<BackendFacade<B, BinaryArtifacts.Jvm>>,
jvmHandlersInit: HandlersStepBuilder<BinaryArtifacts.Jvm>.() -> Unit,
fun TestConfigurationBuilder.commonHandlersForBoxTest() { ) {
commonHandlersForCodegenTest() facadeStep(frontendToBackendConverter)
useArtifactsHandlers( irHandlersStep(irHandlersInit)
::JvmBoxRunner facadeStep(backendFacade)
) jvmArtifactsHandlersStep(jvmHandlersInit)
}
fun TestConfigurationBuilder.commonHandlersForCodegenTest() {
useFrontendHandlers(
::NoCompilationErrorsHandler,
::NoFirCompilationErrorsHandler,
)
useArtifactsHandlers(
::NoJvmSpecificCompilationErrorsHandler,
::DxCheckerHandler,
)
} }
fun TestConfigurationBuilder.useInlineHandlers() { fun TestConfigurationBuilder.useInlineHandlers() {
useArtifactsHandlers( configureJvmArtifactsHandlersStep {
::BytecodeInliningHandler, inlineHandlers()
::SMAPDumpHandler }
)
applyDumpSmapDirective()
}
fun TestConfigurationBuilder.applyDumpSmapDirective() {
forTestsMatching("compiler/testData/codegen/boxInline/smap/*") { forTestsMatching("compiler/testData/codegen/boxInline/smap/*") {
defaultDirectives { defaultDirectives {
+DUMP_SMAP +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 package org.jetbrains.kotlin.test.runners.ir
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.handlers.* 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.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_IR
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DUMP_KT_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.ClassicFrontend2IrConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade 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.Fir2IrResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade 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.model.*
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator 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.CodegenHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
abstract class AbstractIrTextTestBase( abstract class AbstractIrTextTestBase<R : ResultingArtifact.FrontendOutput<R>> :
private val frontend: FrontendKind<*> AbstractKotlinCompilerWithTargetBackendTest(TargetBackend.JVM_IR)
) : 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() { override fun TestConfigurationBuilder.configuration() {
globalDefaults { globalDefaults {
frontend = this@AbstractIrTextTestBase.frontend frontend = this@AbstractIrTextTestBase.frontend
@@ -52,32 +63,48 @@ abstract class AbstractIrTextTestBase(
::CodegenHelpersSourceFilesProvider, ::CodegenHelpersSourceFilesProvider,
) )
useFrontendFacades( facadeStep(frontendFacade)
::ClassicFrontendFacade, classicFrontendHandlersStep {
::FirFrontendFacade useHandlers(
) ::NoCompilationErrorsHandler
)
}
useFrontendHandlers( firHandlersStep {
::NoCompilationErrorsHandler, useHandlers(
::NoFirCompilationErrorsHandler, ::NoFirCompilationErrorsHandler
) )
}
useFrontend2BackendConverters( facadeStep(converter)
::ClassicFrontend2IrConverter,
::Fir2IrResultsConverter
)
useBackendHandlers( irHandlersStep {
::IrTextDumpHandler, useHandlers(
::IrTreeVerifierHandler, ::IrTextDumpHandler,
::IrPrettyKotlinDumpHandler ::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) { override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder) super.configure(builder)
with(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.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.handlers.IrInterpreterBackendHandler import org.jetbrains.kotlin.test.backend.handlers.IrInterpreterBackendHandler
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade import org.jetbrains.kotlin.test.backend.handlers.NoFirCompilationErrorsHandler
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.builders.*
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives 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.directives.LanguageSettingsDirectives
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade import org.jetbrains.kotlin.test.model.BinaryKind
import org.jetbrains.kotlin.test.model.* 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.preprocessors.IrInterpreterImplicitKotlinImports
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
@@ -50,15 +50,19 @@ open class AbstractIrInterpreterAfterFir2IrTest : AbstractKotlinCompilerWithTarg
::JvmEnvironmentConfigurator, ::JvmEnvironmentConfigurator,
) )
firFrontendStep()
fir2IrStep()
irHandlersStep {
useHandlers(::IrInterpreterBackendHandler)
}
useAdditionalSourceProviders(::IrInterpreterHelpersSourceFilesProvider) useAdditionalSourceProviders(::IrInterpreterHelpersSourceFilesProvider)
useSourcePreprocessor(::IrInterpreterImplicitKotlinImports) useSourcePreprocessor(::IrInterpreterImplicitKotlinImports)
useFrontendFacades(::FirFrontendFacade)
useFrontend2BackendConverters(::Fir2IrResultsConverter)
useBackendFacades(::JvmIrBackendFacade)
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor) useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
useBackendHandlers(::IrInterpreterBackendHandler)
enableMetaInfoHandler() enableMetaInfoHandler()
} }
} }
@@ -68,6 +72,6 @@ class IrInterpreterEnvironmentConfigurator(testServices: TestServices) : Environ
directives: RegisteredDirectives, directives: RegisteredDirectives,
languageVersion: LanguageVersion languageVersion: LanguageVersion
): Map<AnalysisFlag<*>, Any?> { ): 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.FirVisualizer
import org.jetbrains.kotlin.compiler.visualizer.PsiVisualizer import org.jetbrains.kotlin.compiler.visualizer.PsiVisualizer
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms 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.TestRunner
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.testConfiguration import org.jetbrains.kotlin.test.builders.testConfiguration
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade 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 import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
abstract class AbstractVisualizerBlackBoxTest { 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 assertions = JUnit5Assertions
testInfo = KotlinTestInfo("_undefined_", "_testUndefined_", setOf()) testInfo = KotlinTestInfo("_undefined_", "_testUndefined_", setOf())
startingArtifactFactory = { ResultingArtifact.Source() }
useAdditionalService<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl) useAdditionalService<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl)
useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl) useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl)
@@ -38,6 +44,7 @@ abstract class AbstractVisualizerBlackBoxTest {
globalDefaults { globalDefaults {
targetPlatform = JvmPlatforms.defaultJvmPlatform targetPlatform = JvmPlatforms.defaultJvmPlatform
dependencyKind = DependencyKind.Source dependencyKind = DependencyKind.Source
frontend = frontendKind
} }
defaultDirectives { defaultDirectives {
@@ -49,28 +56,20 @@ abstract class AbstractVisualizerBlackBoxTest {
::JvmEnvironmentConfigurator, ::JvmEnvironmentConfigurator,
) )
useFrontendFacades(
::ClassicFrontendFacade,
::FirFrontendFacade
)
useAdditionalSourceProviders( useAdditionalSourceProviders(
::AdditionalDiagnosticsSourceFilesProvider, ::AdditionalDiagnosticsSourceFilesProvider,
::CoroutineHelpersSourceFilesProvider, ::CoroutineHelpersSourceFilesProvider,
::CodegenHelpersSourceFilesProvider ::CodegenHelpersSourceFilesProvider
) )
}
private fun createConfiguration(filePath: String, frontend: FrontendKind<*>) = testConfiguration(filePath) { facadeStep(frontendFacade)
commonConfiguration()
globalDefaults { this.frontend = frontend }
} }
fun runTest(filePath: String) { fun runTest(filePath: String) {
lateinit var psiRenderResult: String lateinit var psiRenderResult: String
lateinit var firRenderResult: String lateinit var firRenderResult: String
val psiConfiguration = createConfiguration(filePath, FrontendKinds.ClassicFrontend) val psiConfiguration = createConfiguration(filePath, FrontendKinds.ClassicFrontend, ::ClassicFrontendFacade)
TestRunner(psiConfiguration).runTest(filePath) { testConfiguration -> TestRunner(psiConfiguration).runTest(filePath) { testConfiguration ->
testConfiguration.testServices.moduleStructure.modules.forEach { psiModule -> testConfiguration.testServices.moduleStructure.modules.forEach { psiModule ->
val psiArtifact = testConfiguration.testServices.dependencyProvider.getArtifact(psiModule, FrontendKinds.ClassicFrontend) 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 -> TestRunner(firConfiguration).runTest(filePath) { testConfiguration ->
testConfiguration.testServices.moduleStructure.modules.forEach { firModule -> testConfiguration.testServices.moduleStructure.modules.forEach { firModule ->
val firArtifact = testConfiguration.testServices.dependencyProvider.getArtifact(firModule, FrontendKinds.FIR) val firArtifact = testConfiguration.testServices.dependencyProvider.getArtifact(firModule, FrontendKinds.FIR)
@@ -33,11 +33,12 @@ abstract class AbstractVisualizerTest : AbstractKotlinCompilerTest() {
::CommonEnvironmentConfigurator, ::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator, ::JvmEnvironmentConfigurator,
) )
useFrontendFacades( // TODO
::FirFrontendFacade, // useFrontendFacades(
::ClassicFrontendFacade // ::FirFrontendFacade,
) // ::ClassicFrontendFacade
useFrontendHandlers(handler) // )
// useFrontendHandlers(handler)
defaultDirectives { defaultDirectives {
+JvmEnvironmentConfigurationDirectives.WITH_STDLIB +JvmEnvironmentConfigurationDirectives.WITH_STDLIB
@@ -83,10 +83,9 @@ abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() {
configureTest() configureTest()
defaultConfiguration(this) defaultConfiguration(this)
unregisterAllFacades()
useAdditionalService(::TestModuleInfoProvider) useAdditionalService(::TestModuleInfoProvider)
usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable)) usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable))
useFrontendFacades(::LowLevelFirFrontendFacade)
} }
open fun TestConfigurationBuilder.configureTest() {} open fun TestConfigurationBuilder.configureTest() {}
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.test.runners.baseFirSpecDiagnosticTestConfiguration
abstract class AbstractDiagnosisCompilerTestDataSpecTest : AbstractCompilerBasedTest() { abstract class AbstractDiagnosisCompilerTestDataSpecTest : AbstractCompilerBasedTest() {
override fun TestConfigurationBuilder.configureTest() { override fun TestConfigurationBuilder.configureTest() {
baseFirDiagnosticTestConfiguration() baseFirDiagnosticTestConfiguration(frontendFacade = ::LowLevelFirFrontendFacade)
baseFirSpecDiagnosticTestConfiguration() baseFirSpecDiagnosticTestConfiguration()
addIdeTestIgnoreHandler() addIdeTestIgnoreHandler()
} }
} }
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.test.runners.baseFirDiagnosticTestConfiguration
abstract class AbstractDiagnosisCompilerTestDataTest : AbstractCompilerBasedTest() { abstract class AbstractDiagnosisCompilerTestDataTest : AbstractCompilerBasedTest() {
override fun TestConfigurationBuilder.configureTest() { override fun TestConfigurationBuilder.configureTest() {
baseFirDiagnosticTestConfiguration() baseFirDiagnosticTestConfiguration(frontendFacade = ::LowLevelFirFrontendFacade)
addIdeTestIgnoreHandler() addIdeTestIgnoreHandler()
} }
} }
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.test.builders.testConfiguration
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.model.DependencyKind import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds 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.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.* import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
@@ -61,6 +62,7 @@ abstract class AbstractLowLevelApiTest : TestWithDisposable() {
usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable)) usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable))
configureTest(this) configureTest(this)
startingArtifactFactory = { ResultingArtifact.Source() }
this.testInfo = this@AbstractLowLevelApiTest.testInfo this.testInfo = this@AbstractLowLevelApiTest.testInfo
} }
@@ -136,4 +138,4 @@ fun String.indexOfOrNull(substring: String) =
indexOf(substring).takeIf { it >= 0 } indexOf(substring).takeIf { it >= 0 }
private fun String.indexOfOrNull(substring: String, startingIndex: Int) = private fun String.indexOfOrNull(substring: String, startingIndex: Int) =
indexOf(substring, startingIndex).takeIf { it >= 0 } indexOf(substring, startingIndex).takeIf { it >= 0 }