[Test] Add ability to specify applicability of diagnostic to module or file

This commit is contained in:
Dmitriy Novozhilov
2021-01-15 14:54:05 +03:00
committed by TeamCityServer
parent 28cff22cd0
commit 6a7cd0c811
117 changed files with 266 additions and 189 deletions
@@ -6,15 +6,19 @@
package org.jetbrains.kotlin.test.directives
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability.Global
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
object CodegenTestDirectives : SimpleDirectivesContainer() {
val IGNORE_BACKEND by enumDirective<TargetBackend>(
description = "Ignore failures of test on target backend"
description = "Ignore failures of test on target backend",
applicability = Global
)
val IGNORE_BACKEND_FIR by enumDirective<TargetBackend>(
description = "Ignore specific backend if test uses FIR"
description = "Ignore specific backend if test uses FIR",
applicability = Global
)
val JAVAC_OPTIONS by stringDirective(
@@ -29,7 +33,8 @@ object CodegenTestDirectives : SimpleDirectivesContainer() {
)
val CHECK_BYTECODE_LISTING by directive(
description = "Dump resulting bytecode to .txt or _ir.txt file"
description = "Dump resulting bytecode to .txt or _ir.txt file",
applicability = Global
)
val RUN_DEX_CHECKER by directive(
@@ -7,6 +7,9 @@ package org.jetbrains.kotlin.test.directives
import org.jetbrains.kotlin.test.backend.handlers.JvmBackendDiagnosticsHandler
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_JAVAC
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability.Any
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability.Global
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
object DiagnosticsDirectives : SimpleDirectivesContainer() {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.test.directives
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability.Global
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
object FirDiagnosticsDirectives : SimpleDirectivesContainer() {
@@ -12,17 +13,20 @@ object FirDiagnosticsDirectives : SimpleDirectivesContainer() {
description = """
Dumps control flow graphs of all declarations to `testName.dot` file
This directive may be applied only to all modules
""".trimIndent()
""".trimIndent(),
applicability = Global
)
val FIR_DUMP by directive(
description = """
Dumps resulting fir to `testName.fir` file
""".trimIndent()
""".trimIndent(),
applicability = Global
)
val FIR_IDENTICAL by directive(
description = "Contents of fir test data file and FE 1.0 are identical"
description = "Contents of fir test data file and FE 1.0 are identical",
applicability = Global
)
val USE_LIGHT_TREE by directive(
@@ -33,7 +37,8 @@ object FirDiagnosticsDirectives : SimpleDirectivesContainer() {
description = """
Enable comparing diagnostics between PSI and light tree modes
For enabling light tree mode use $USE_LIGHT_TREE directive
""".trimIndent()
""".trimIndent(),
applicability = Global
)
val WITH_EXTENDED_CHECKERS by directive(
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.test.builders.LanguageVersionSettingsBuilder
import org.jetbrains.kotlin.test.directives.AdditionalFilesDirectives
import org.jetbrains.kotlin.test.directives.ModuleStructureDirectives
import org.jetbrains.kotlin.test.directives.model.ComposedRegisteredDirectives
import org.jetbrains.kotlin.test.directives.model.Directive
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.model.*
@@ -240,14 +241,38 @@ class ModuleStructureExtractorImpl(
}
private fun finishGlobalDirectives() {
globalDirectives = directivesBuilder.build()
globalDirectives = directivesBuilder.build().also { directives ->
directives.forEach { it.checkDirectiveApplicability(contextIsGlobal = true) }
}
resetModuleCaches()
resetFileCaches()
}
@OptIn(ExperimentalStdlibApi::class)
private fun Directive.checkDirectiveApplicability(
contextIsGlobal: Boolean = false,
contextIsModule: Boolean = false,
contextIsFile: Boolean = false
) {
when {
applicability.forGlobal && contextIsGlobal -> return
applicability.forModule && contextIsModule -> return
applicability.forFile && contextIsFile -> return
}
val context = buildList {
if (contextIsGlobal) add("Global")
if (contextIsModule) add("Module")
if (contextIsFile) add("File")
}.joinToString("|")
error("Directive $this has $applicability applicability but it declared in $context")
}
private fun finishModule() {
finishFile()
val isImplicitModule = currentModuleName == null
val moduleDirectives = moduleDirectivesBuilder.build() + testServices.defaultDirectives + globalDirectives
moduleDirectives.forEach { it.checkDirectiveApplicability(contextIsGlobal = isImplicitModule, contextIsModule = true) }
currentModuleLanguageVersionSettingsBuilder.configureUsingDirectives(moduleDirectives, environmentConfigurators)
val moduleName = currentModuleName ?: defaultModuleName
val testModule = TestModule(
@@ -298,6 +323,9 @@ class ModuleStructureExtractorImpl(
if (filesOfCurrentModule.any { it.name == filename }) {
error("File with name \"$filename\" already defined in module ${currentModuleName ?: actualDefaultFileName}")
}
val directives = fileDirectivesBuilder?.build()?.also { directives ->
directives.forEach { it.checkDirectiveApplicability(contextIsFile = true) }
}
filesOfCurrentModule.add(
TestFile(
relativePath = filename,
@@ -305,7 +333,7 @@ class ModuleStructureExtractorImpl(
originalFile = currentTestDataFile,
startLineNumberInOriginalFile = startLineNumberOfCurrentFile,
isAdditional = false,
directives = fileDirectivesBuilder?.build() ?: RegisteredDirectives.Empty
directives = directives ?: RegisteredDirectives.Empty
)
)
firstFileInModule = false
@@ -333,6 +361,8 @@ class ModuleStructureExtractorImpl(
private fun resetFileCaches() {
if (!firstFileInModule) {
linesOfCurrentFile = mutableListOf()
}
if (firstFileInModule) {
moduleDirectivesBuilder = directivesBuilder
}
currentFileName = null