FIR IDE: introduce diagnostics tests bases on FIR diagnostics tests
This commit is contained in:
+2
-2
@@ -354,8 +354,8 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
extractor.provideConfigurationKeys()
|
||||
extractor.configure(keyConfiguration, module.directives)
|
||||
}
|
||||
val kind = configuratorForFlags.extractConfigurationKind(module.directives)
|
||||
val jdkKind = configuratorForFlags.extractJdkKind(module.directives)
|
||||
val kind = JvmEnvironmentConfigurator.extractConfigurationKind(module.directives)
|
||||
val jdkKind = JvmEnvironmentConfigurator.extractJdkKind(module.directives)
|
||||
|
||||
keyConfiguration.languageVersionSettings = module.languageVersionSettings
|
||||
|
||||
|
||||
@@ -29,16 +29,25 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractFirAnalyzerFacade {
|
||||
abstract val scopeSession: ScopeSession
|
||||
abstract fun runCheckers(): Map<FirFile, List<FirDiagnostic<*>>>
|
||||
|
||||
abstract fun runResolution(): List<FirFile>
|
||||
|
||||
abstract fun convertToIr(extensions: GeneratorExtensions): Fir2IrResult
|
||||
}
|
||||
|
||||
class FirAnalyzerFacade(
|
||||
val session: FirSession,
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val ktFiles: Collection<KtFile> = emptyList(), // may be empty if light tree mode enabled
|
||||
val originalFiles: Collection<File> = emptyList(), // may be empty if light tree mode disabled
|
||||
val useLightTree: Boolean = false
|
||||
) {
|
||||
) : AbstractFirAnalyzerFacade() {
|
||||
private var firFiles: List<FirFile>? = null
|
||||
private var _scopeSession: ScopeSession? = null
|
||||
val scopeSession: ScopeSession
|
||||
override val scopeSession: ScopeSession
|
||||
get() = _scopeSession!!
|
||||
|
||||
private var collectedDiagnostics: Map<FirFile, List<FirDiagnostic<*>>>? = null
|
||||
@@ -63,7 +72,7 @@ class FirAnalyzerFacade(
|
||||
}
|
||||
}
|
||||
|
||||
fun runResolution(): List<FirFile> {
|
||||
override fun runResolution(): List<FirFile> {
|
||||
if (firFiles == null) buildRawFir()
|
||||
if (_scopeSession != null) return firFiles!!
|
||||
val resolveProcessor = FirTotalResolveProcessor(session)
|
||||
@@ -73,7 +82,7 @@ class FirAnalyzerFacade(
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
fun runCheckers(): Map<FirFile, List<FirDiagnostic<*>>> {
|
||||
override fun runCheckers(): Map<FirFile, List<FirDiagnostic<*>>> {
|
||||
if (_scopeSession == null) runResolution()
|
||||
if (collectedDiagnostics != null) return collectedDiagnostics!!
|
||||
val collector = FirDiagnosticsCollector.create(session, scopeSession)
|
||||
@@ -87,7 +96,7 @@ class FirAnalyzerFacade(
|
||||
return collectedDiagnostics!!
|
||||
}
|
||||
|
||||
fun convertToIr(extensions: GeneratorExtensions): Fir2IrResult {
|
||||
override fun convertToIr(extensions: GeneratorExtensions): Fir2IrResult {
|
||||
if (_scopeSession == null) runResolution()
|
||||
val signaturer = JvmIdSignatureDescriptor(JvmManglerDesc())
|
||||
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ class FirFrontendFacade(
|
||||
testFile to firFile
|
||||
}.toMap()
|
||||
|
||||
return FirOutputArtifact(session, filesMap, firAnalyzerFacade)
|
||||
return FirOutputArtifactImpl(session, filesMap, firAnalyzerFacade)
|
||||
}
|
||||
|
||||
private fun createSessionForBuiltins(
|
||||
|
||||
+14
-6
@@ -6,19 +6,27 @@
|
||||
package org.jetbrains.kotlin.test.frontend.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.AbstractFirAnalyzerFacade
|
||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
||||
import org.jetbrains.kotlin.test.model.TestFile
|
||||
|
||||
data class FirOutputArtifact(
|
||||
val session: FirSession,
|
||||
val allFirFiles: Map<TestFile, FirFile>,
|
||||
val firAnalyzerFacade: FirAnalyzerFacade
|
||||
) : ResultingArtifact.FrontendOutput<FirOutputArtifact>() {
|
||||
abstract class FirOutputArtifact : ResultingArtifact.FrontendOutput<FirOutputArtifact>() {
|
||||
abstract val session: FirSession
|
||||
abstract val firAnalyzerFacade: AbstractFirAnalyzerFacade
|
||||
abstract val allFirFiles: Map<TestFile, FirFile>
|
||||
|
||||
override val kind: FrontendKinds.FIR
|
||||
get() = FrontendKinds.FIR
|
||||
|
||||
val firFiles: Map<TestFile, FirFile> = allFirFiles.filterKeys { !it.isAdditional }
|
||||
|
||||
val firFiles: Map<TestFile, FirFile> by lazy { allFirFiles.filterKeys { !it.isAdditional } }
|
||||
}
|
||||
|
||||
data class FirOutputArtifactImpl(
|
||||
override val session: FirSession,
|
||||
override val allFirFiles: Map<TestFile, FirFile>,
|
||||
override val firAnalyzerFacade: FirAnalyzerFacade
|
||||
) : FirOutputArtifact()
|
||||
+74
-69
@@ -28,75 +28,7 @@ import org.jetbrains.kotlin.test.services.fir.FirOldFrontendMetaConfigurator
|
||||
|
||||
abstract class AbstractFirDiagnosticTest : AbstractKotlinCompilerTest() {
|
||||
override fun TestConfigurationBuilder.configuration() {
|
||||
globalDefaults {
|
||||
frontend = FrontendKinds.FIR
|
||||
targetPlatform = JvmPlatforms.defaultJvmPlatform
|
||||
dependencyKind = DependencyKind.Source
|
||||
}
|
||||
|
||||
enableMetaInfoHandler()
|
||||
|
||||
useConfigurators(
|
||||
::CommonEnvironmentConfigurator,
|
||||
::JvmEnvironmentConfigurator,
|
||||
)
|
||||
|
||||
useAdditionalSourceProviders(
|
||||
::AdditionalDiagnosticsSourceFilesProvider,
|
||||
::CoroutineHelpersSourceFilesProvider,
|
||||
)
|
||||
useFrontendFacades(::FirFrontendFacade)
|
||||
useFrontendHandlers(
|
||||
::FirDiagnosticsHandler,
|
||||
::FirDumpHandler,
|
||||
::FirCfgDumpHandler,
|
||||
::FirCfgConsistencyHandler,
|
||||
::FirNoImplicitTypesHandler,
|
||||
)
|
||||
|
||||
useMetaInfoProcessors(::PsiLightTreeMetaInfoProcessor)
|
||||
|
||||
defaultDirectives {
|
||||
+COMPARE_WITH_LIGHT_TREE
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/testData/diagnostics/*") {
|
||||
useAfterAnalysisCheckers(
|
||||
::FirIdenticalChecker,
|
||||
::FirFailingTestSuppressor,
|
||||
)
|
||||
useMetaTestConfigurators(::FirOldFrontendMetaConfigurator)
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/fir/analysis-tests/testData/*") {
|
||||
defaultDirectives {
|
||||
+FIR_DUMP
|
||||
}
|
||||
}
|
||||
|
||||
forTestsMatching(
|
||||
"compiler/testData/diagnostics/testsWithStdLib/*" or
|
||||
"compiler/fir/analysis-tests/testData/resolveWithStdlib/*" or
|
||||
"compiler/testData/diagnostics/tests/unsignedTypes/*"
|
||||
) {
|
||||
defaultDirectives {
|
||||
+WITH_STDLIB
|
||||
}
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/fir/analysis-tests/testData/resolve/extendedCheckers/*") {
|
||||
defaultDirectives {
|
||||
+WITH_EXTENDED_CHECKERS
|
||||
}
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/testData/diagnostics/tests/testsWithJava15/*") {
|
||||
defaultDirectives {
|
||||
JDK_KIND with TestJdkKind.FULL_JDK_15
|
||||
+WITH_STDLIB
|
||||
+WITH_REFLECT
|
||||
}
|
||||
}
|
||||
baseFirDiagnosticTestConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,3 +42,76 @@ abstract class AbstractFirDiagnosticsWithLightTreeTest : AbstractFirDiagnosticTe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration() {
|
||||
globalDefaults {
|
||||
frontend = FrontendKinds.FIR
|
||||
targetPlatform = JvmPlatforms.defaultJvmPlatform
|
||||
dependencyKind = DependencyKind.Source
|
||||
}
|
||||
|
||||
enableMetaInfoHandler()
|
||||
|
||||
useConfigurators(
|
||||
::CommonEnvironmentConfigurator,
|
||||
::JvmEnvironmentConfigurator,
|
||||
)
|
||||
|
||||
useAdditionalSourceProviders(
|
||||
::AdditionalDiagnosticsSourceFilesProvider,
|
||||
::CoroutineHelpersSourceFilesProvider,
|
||||
)
|
||||
useFrontendFacades(::FirFrontendFacade)
|
||||
useFrontendHandlers(
|
||||
::FirDiagnosticsHandler,
|
||||
::FirDumpHandler,
|
||||
::FirCfgDumpHandler,
|
||||
::FirCfgConsistencyHandler,
|
||||
::FirNoImplicitTypesHandler,
|
||||
)
|
||||
|
||||
useMetaInfoProcessors(::PsiLightTreeMetaInfoProcessor)
|
||||
|
||||
defaultDirectives {
|
||||
+COMPARE_WITH_LIGHT_TREE
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/testData/diagnostics/*") {
|
||||
useAfterAnalysisCheckers(
|
||||
::FirIdenticalChecker,
|
||||
::FirFailingTestSuppressor,
|
||||
)
|
||||
useMetaTestConfigurators(::FirOldFrontendMetaConfigurator)
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/fir/analysis-tests/testData/*") {
|
||||
defaultDirectives {
|
||||
+FIR_DUMP
|
||||
}
|
||||
}
|
||||
|
||||
forTestsMatching(
|
||||
"compiler/testData/diagnostics/testsWithStdLib/*" or
|
||||
"compiler/fir/analysis-tests/testData/resolveWithStdlib/*" or
|
||||
"compiler/testData/diagnostics/tests/unsignedTypes/*"
|
||||
) {
|
||||
defaultDirectives {
|
||||
+WITH_STDLIB
|
||||
}
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/fir/analysis-tests/testData/resolve/extendedCheckers/*") {
|
||||
defaultDirectives {
|
||||
+WITH_EXTENDED_CHECKERS
|
||||
}
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/testData/diagnostics/tests/testsWithJava15/*") {
|
||||
defaultDirectives {
|
||||
JDK_KIND with TestJdkKind.FULL_JDK_15
|
||||
+WITH_STDLIB
|
||||
+WITH_REFLECT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-10
@@ -34,23 +34,27 @@ abstract class AbstractKotlinCompilerTest {
|
||||
val defaultPreprocessors: List<Constructor<SourceFilePreprocessor>> = listOf(
|
||||
::MetaInfosCleanupPreprocessor
|
||||
)
|
||||
|
||||
private fun configureDebugFlags() {
|
||||
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = true
|
||||
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true
|
||||
}
|
||||
|
||||
val defaultConfiguration: TestConfigurationBuilder.() -> Unit = {
|
||||
useAdditionalService<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl)
|
||||
useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl)
|
||||
useSourcePreprocessor(*defaultPreprocessors.toTypedArray())
|
||||
useDirectives(*defaultDirectiveContainers.toTypedArray())
|
||||
configureDebugFlags()
|
||||
}
|
||||
}
|
||||
|
||||
private val configuration: TestConfigurationBuilder.() -> Unit = {
|
||||
assertions = JUnit5Assertions
|
||||
useAdditionalService<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl)
|
||||
useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl)
|
||||
useSourcePreprocessor(*defaultPreprocessors.toTypedArray())
|
||||
useDirectives(*defaultDirectiveContainers.toTypedArray())
|
||||
configureDebugFlags()
|
||||
defaultConfiguration()
|
||||
configure(this)
|
||||
}
|
||||
|
||||
private fun configureDebugFlags() {
|
||||
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = true
|
||||
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true
|
||||
}
|
||||
|
||||
abstract fun TestConfigurationBuilder.configuration()
|
||||
private lateinit var testInfo: KotlinTestInfo
|
||||
|
||||
|
||||
+56
-53
@@ -65,6 +65,61 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
|
||||
private val DEFAULT_JVM_TARGET_FROM_PROPERTY: String? = System.getProperty("kotlin.test.default.jvm.target")
|
||||
|
||||
private const val JAVA_BINARIES_JAR_NAME = "java-binaries"
|
||||
|
||||
fun extractConfigurationKind(registeredDirectives: RegisteredDirectives): ConfigurationKind {
|
||||
val withRuntime = JvmEnvironmentConfigurationDirectives.WITH_RUNTIME in registeredDirectives ||
|
||||
JvmEnvironmentConfigurationDirectives.WITH_STDLIB in registeredDirectives
|
||||
val withReflect = JvmEnvironmentConfigurationDirectives.WITH_REFLECT in registeredDirectives
|
||||
val noRuntime = JvmEnvironmentConfigurationDirectives.NO_RUNTIME in registeredDirectives
|
||||
if (noRuntime && withRuntime) {
|
||||
error("NO_RUNTIME and WITH_RUNTIME can not be used together")
|
||||
}
|
||||
return when {
|
||||
withRuntime && !withReflect -> ConfigurationKind.NO_KOTLIN_REFLECT
|
||||
withRuntime || withReflect -> ConfigurationKind.ALL
|
||||
noRuntime -> ConfigurationKind.JDK_NO_RUNTIME
|
||||
else -> ConfigurationKind.JDK_ONLY
|
||||
}
|
||||
}
|
||||
|
||||
fun extractJdkKind(registeredDirectives: RegisteredDirectives): TestJdkKind {
|
||||
val fullJdkEnabled = JvmEnvironmentConfigurationDirectives.FULL_JDK in registeredDirectives
|
||||
val jdkKinds = registeredDirectives[JvmEnvironmentConfigurationDirectives.JDK_KIND]
|
||||
|
||||
if (fullJdkEnabled) {
|
||||
if (jdkKinds.isNotEmpty()) {
|
||||
error("FULL_JDK and JDK_KIND can not be used together")
|
||||
}
|
||||
return TestJdkKind.FULL_JDK
|
||||
}
|
||||
|
||||
return when (jdkKinds.size) {
|
||||
0 -> TestJdkKind.MOCK_JDK
|
||||
1 -> jdkKinds.single()
|
||||
else -> error("Too many jdk kinds passed: ${jdkKinds.joinToArrayString()}")
|
||||
}
|
||||
}
|
||||
|
||||
fun getLibraryFiles(configurationKind: ConfigurationKind, directives: RegisteredDirectives): List<File> {
|
||||
val files = mutableListOf<File>()
|
||||
if (configurationKind.withRuntime) {
|
||||
files.add(ForTestCompileRuntime.runtimeJarForTests())
|
||||
files.add(ForTestCompileRuntime.scriptRuntimeJarForTests())
|
||||
files.add(ForTestCompileRuntime.kotlinTestJarForTests())
|
||||
} else if (configurationKind.withMockRuntime) {
|
||||
files.add(ForTestCompileRuntime.minimalRuntimeJarForTests())
|
||||
files.add(ForTestCompileRuntime.scriptRuntimeJarForTests())
|
||||
}
|
||||
if (configurationKind.withReflection) {
|
||||
files.add(ForTestCompileRuntime.reflectJarForTests())
|
||||
}
|
||||
files.add(KtTestUtil.getAnnotationsJar())
|
||||
|
||||
if (JvmEnvironmentConfigurationDirectives.STDLIB_JDK8 in directives) {
|
||||
files.add(ForTestCompileRuntime.runtimeJarForTestsWithJdk8())
|
||||
}
|
||||
return files
|
||||
}
|
||||
}
|
||||
|
||||
override val directivesContainers: List<DirectivesContainer>
|
||||
@@ -130,27 +185,8 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
|
||||
configuration.put(TEST_CONFIGURATION_KIND_KEY, it)
|
||||
}
|
||||
|
||||
val javaVersionToCompile = registeredDirectives[COMPILE_JAVA_USING].singleOrNull()
|
||||
val javaBinaryFiles = if (ALL_JAVA_AS_BINARY !in registeredDirectives) {
|
||||
module.javaFiles.filter { INCLUDE_JAVA_AS_BINARY in it.directives }
|
||||
} else module.javaFiles
|
||||
configuration.addJvmClasspathRoots(getLibraryFiles(configurationKind, module.directives))
|
||||
|
||||
val useJava9ToCompileIncludedJavaFiles = javaVersionToCompile == TestJavacVersion.JAVAC_9
|
||||
|
||||
if (configurationKind.withRuntime) {
|
||||
configuration.configureStandardLibs(PathUtil.kotlinPathsForDistDirectory, K2JVMCompilerArguments().also { it.noReflect = true })
|
||||
configuration.addJvmClasspathRoot(ForTestCompileRuntime.kotlinTestJarForTests())
|
||||
} else if (configurationKind.withMockRuntime) {
|
||||
configuration.addJvmClasspathRoot(ForTestCompileRuntime.minimalRuntimeJarForTests())
|
||||
configuration.addJvmClasspathRoot(ForTestCompileRuntime.scriptRuntimeJarForTests())
|
||||
}
|
||||
if (configurationKind.withReflection) {
|
||||
configuration.addJvmClasspathRoot(ForTestCompileRuntime.reflectJarForTests())
|
||||
}
|
||||
|
||||
if (JvmEnvironmentConfigurationDirectives.STDLIB_JDK8 in module.directives) {
|
||||
configuration.addJvmClasspathRoot(ForTestCompileRuntime.runtimeJarForTestsWithJdk8())
|
||||
}
|
||||
|
||||
configuration.addJvmClasspathRoot(KtTestUtil.getAnnotationsJar())
|
||||
|
||||
@@ -309,39 +345,6 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
|
||||
}
|
||||
}
|
||||
|
||||
fun extractJdkKind(registeredDirectives: RegisteredDirectives): TestJdkKind {
|
||||
val fullJdkEnabled = JvmEnvironmentConfigurationDirectives.FULL_JDK in registeredDirectives
|
||||
val jdkKinds = registeredDirectives[JvmEnvironmentConfigurationDirectives.JDK_KIND]
|
||||
|
||||
if (fullJdkEnabled) {
|
||||
if (jdkKinds.isNotEmpty()) {
|
||||
error("FULL_JDK and JDK_KIND can not be used together")
|
||||
}
|
||||
return TestJdkKind.FULL_JDK
|
||||
}
|
||||
|
||||
return when (jdkKinds.size) {
|
||||
0 -> TestJdkKind.MOCK_JDK
|
||||
1 -> jdkKinds.single()
|
||||
else -> error("Too many jdk kinds passed: ${jdkKinds.joinToArrayString()}")
|
||||
}
|
||||
}
|
||||
|
||||
fun extractConfigurationKind(registeredDirectives: RegisteredDirectives): ConfigurationKind {
|
||||
val withRuntime = JvmEnvironmentConfigurationDirectives.WITH_RUNTIME in registeredDirectives ||
|
||||
JvmEnvironmentConfigurationDirectives.WITH_STDLIB in registeredDirectives
|
||||
val withReflect = JvmEnvironmentConfigurationDirectives.WITH_REFLECT in registeredDirectives
|
||||
val noRuntime = JvmEnvironmentConfigurationDirectives.NO_RUNTIME in registeredDirectives
|
||||
if (noRuntime && withRuntime) {
|
||||
error("NO_RUNTIME and WITH_RUNTIME can not be used together")
|
||||
}
|
||||
return when {
|
||||
withRuntime && !withReflect -> ConfigurationKind.NO_KOTLIN_REFLECT
|
||||
withRuntime || withReflect -> ConfigurationKind.ALL
|
||||
noRuntime -> ConfigurationKind.JDK_NO_RUNTIME
|
||||
else -> ConfigurationKind.JDK_ONLY
|
||||
}
|
||||
}
|
||||
|
||||
private fun CompilerConfiguration.registerModuleDependencies(module: TestModule) {
|
||||
val dependencyProvider = testServices.dependencyProvider
|
||||
|
||||
Reference in New Issue
Block a user