LL API: add checks to the compiler based tests to ensure ConeTypeVariableType are not leaked

This commit is contained in:
Ilya Kirillov
2021-09-28 19:19:51 +02:00
committed by TeamCityServer
parent 7ed4984d11
commit 30b1487afc
2 changed files with 65 additions and 1 deletions
@@ -11,11 +11,11 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilt
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.createResolveStateForNoCaching
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.FirLazyTransformerForIDE
import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.TestConfiguration
import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.firHandlersStep
import org.jetbrains.kotlin.test.builders.testConfiguration
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
@@ -54,6 +54,10 @@ abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() {
useAdditionalService(::TestKtModuleProvider)
usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable))
firHandlersStep {
useHandlers(::LLDiagnosticParameterChecker)
}
}
open fun TestConfigurationBuilder.configureTest() {}
@@ -0,0 +1,60 @@
/*
* 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.analysis.low.level.api.fir.compiler.based
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeVariableType
import org.jetbrains.kotlin.fir.types.contains
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirAnalysisHandler
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
internal class LLDiagnosticParameterChecker(testServices: TestServices) : FirAnalysisHandler(testServices) {
override fun processModule(module: TestModule, info: FirOutputArtifact) {
val diagnostics = info.firAnalyzerFacade.runCheckers().values.flatten()
for (diagnostic in diagnostics) {
checkDiagnosticIsSuitableForFirIde(diagnostic)
}
}
private fun checkDiagnosticIsSuitableForFirIde(diagnostic: FirDiagnostic) {
val parameters = diagnostic.allParameters()
for (parameter in parameters) {
checkDiagnosticParameter(diagnostic, parameter)
}
}
private fun checkDiagnosticParameter(diagnostic: FirDiagnostic, parameter: Any?) {
when (parameter) {
is ConeKotlinType -> checkType(parameter, diagnostic)
}
}
private fun checkType(parameter: ConeKotlinType, diagnostic: FirDiagnostic) {
val containsTypeVariableType = parameter.contains { it is ConeTypeVariableType }
if (containsTypeVariableType) {
val rendered = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic).render(diagnostic)
testServices.assertions.fail {
"ConeTypeVariableType should not be exposed from diagnostic. But it was for ${diagnostic.factoryName} $rendered"
}
}
}
private fun FirDiagnostic.allParameters(): List<Any?> = when (this) {
is FirPsiDiagnosticWithParameters1<*> -> listOf(a)
is FirPsiDiagnosticWithParameters2<*, *> -> listOf(a, b)
is FirPsiDiagnosticWithParameters3<*, *, *> -> listOf(a, b, c)
is FirPsiDiagnosticWithParameters4<*, *, *, *> -> listOf(a, b, c, d)
is FirPsiSimpleDiagnostic -> emptyList()
else -> error("Unexpected diagnostic $this")
}
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
}