[Test] Allow to enable/disable all diagnostics with specific severity

This commit is contained in:
Dmitriy Novozhilov
2021-05-14 13:04:12 +03:00
committed by TeamCityServer
parent 7fc23a1647
commit d44782f49f
4 changed files with 44 additions and 18 deletions
@@ -26,6 +26,11 @@ object DiagnosticsDirectives : SimpleDirectivesContainer() {
'-' means 'exclude'
'+' May be used in case if some diagnostic was disabled by default in test runner
and it should be enabled in specific test
Also you can enable/disable all diagnostics with specific severity using following syntax:
[+-]infos
[+-]warnings
[+-]errors
""".trimIndent()
)
@@ -64,7 +64,7 @@ class ClassicDiagnosticsHandler(testServices: TestServices) : ClassicFrontendAna
val diagnostics = diagnosticsPerFile[ktFile] ?: emptyList()
for (diagnostic in diagnostics) {
if (!diagnostic.isValid) continue
if (!diagnosticsService.shouldRenderDiagnostic(module, diagnostic.factory.name)) continue
if (!diagnosticsService.shouldRenderDiagnostic(module, diagnostic.factory.name, diagnostic.severity)) continue
reporter.reportDiagnostic(diagnostic, module, file, configuration, withNewInferenceModeEnabled)
}
for (errorElement in AnalyzingUtils.getSyntaxErrorRanges(ktFile)) {
@@ -120,7 +120,8 @@ class ClassicDiagnosticsHandler(testServices: TestServices) : ClassicFrontendAna
diagnosedRanges = diagnosedRanges
)
debugAnnotations.mapNotNull { debugAnnotation ->
if (!diagnosticsService.shouldRenderDiagnostic(module, debugAnnotation.diagnostic.factory.name)) return@mapNotNull null
val factory = debugAnnotation.diagnostic.factory
if (!diagnosticsService.shouldRenderDiagnostic(module, factory.name, factory.severity)) return@mapNotNull null
reporter.reportDiagnostic(debugAnnotation.diagnostic, module, file, configuration, withNewInferenceModeEnabled)
}
}
@@ -81,7 +81,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
diagnostics = diagnostics.filter { it.factory.name != FirErrors.NEWER_VERSION_IN_SINCE_KOTLIN.name }
}
val diagnosticsMetadataInfos = diagnostics.mapNotNull { diagnostic ->
if (!diagnosticsService.shouldRenderDiagnostic(module, diagnostic.factory.name)) return@mapNotNull null
if (!diagnosticsService.shouldRenderDiagnostic(module, diagnostic.factory.name, diagnostic.severity)) return@mapNotNull null
// SYNTAX errors will be reported later
if (diagnostic.factory == FirErrors.SYNTAX) return@mapNotNull null
if (!diagnostic.isValid) return@mapNotNull null
@@ -5,24 +5,35 @@
package org.jetbrains.kotlin.test.services
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.util.*
class DiagnosticsService(val testServices: TestServices) : TestService {
private val conditionsPerModule: MutableMap<TestModule, Condition<String>> = mutableMapOf()
fun shouldRenderDiagnostic(module: TestModule, name: String): Boolean {
val condition = conditionsPerModule.getOrPut(module) {
computeDiagnosticConditionForModule(module)
}
return condition(name)
companion object {
private val severityNameMapping = mapOf(
"infos" to Severity.INFO,
"warnings" to Severity.WARNING,
"errors" to Severity.ERROR,
)
}
private fun computeDiagnosticConditionForModule(module: TestModule): Condition<String> {
private val conditionsPerModule: MutableMap<TestModule, Pair<Condition<String>, Condition<Severity>>> = mutableMapOf()
fun shouldRenderDiagnostic(module: TestModule, name: String, severity: Severity): Boolean {
val (nameCondition, severityCondition) = conditionsPerModule.getOrPut(module) {
computeDiagnosticConditionForModule(module)
}
return severityCondition(severity) && nameCondition(name)
}
private fun computeDiagnosticConditionForModule(module: TestModule): Pair<Condition<String>, Condition<Severity>> {
val diagnosticsInDirective = module.directives[DiagnosticsDirectives.DIAGNOSTICS]
val enabledNames = mutableSetOf<String>()
val disabledNames = mutableSetOf<String>()
val enabledSeverities = mutableSetOf<Severity>()
val disabledSeverities = mutableSetOf<Severity>()
for (diagnosticInDirective in diagnosticsInDirective) {
val enabled = when {
diagnosticInDirective.startsWith("+") -> true
@@ -30,17 +41,26 @@ class DiagnosticsService(val testServices: TestServices) : TestService {
else -> error("Incorrect diagnostics directive syntax. See reference:\n${DiagnosticsDirectives.DIAGNOSTICS.description}")
}
val name = diagnosticInDirective.substring(1)
val collection = if (enabled) enabledNames else disabledNames
collection += name
val severity = severityNameMapping[name]
if (severity != null) {
val collection = if (enabled) enabledSeverities else disabledSeverities
collection += severity
} else {
val collection = if (enabled) enabledNames else disabledNames
collection += name
}
}
if (disabledNames.isEmpty()) return Conditions.alwaysTrue()
var condition = !Conditions.oneOf(disabledNames)
if (enabledNames.isNotEmpty()) {
condition = condition or Conditions.oneOf(enabledNames)
return computeCondition(enabledNames, disabledNames) to computeCondition(enabledSeverities, disabledSeverities)
}
private fun <T : Any> computeCondition(enabled: Set<T>, disabled: Set<T>): Condition<T> {
if (disabled.isEmpty()) return Conditions.alwaysTrue()
var condition = !Conditions.oneOf(disabled)
if (enabled.isNotEmpty()) {
condition = condition or Conditions.oneOf(enabled)
}
return condition.cached()
}
}
val TestServices.diagnosticsService: DiagnosticsService by TestServices.testServiceAccessor()