Add multiple renderer sources support to new diagnostics infrastructure

This commit is contained in:
Ilya Chernikov
2021-10-05 16:29:51 +02:00
parent 0de6f8b915
commit da2d3f29da
13 changed files with 1572 additions and 1466 deletions
@@ -10,10 +10,10 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
internal interface KtAbstractFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI>, ValidityTokenOwner {
val firDiagnostic: KtPsiDiagnostic
@@ -25,7 +25,7 @@ internal interface KtAbstractFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithP
get() = withValidityAssertion {
val diagnostic = firDiagnostic as KtDiagnostic
val firDiagnosticRenderer = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic)
val firDiagnosticRenderer = RootDiagnosticRendererFactory(diagnostic)
return firDiagnosticRenderer.render(diagnostic)
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.module
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
import org.jetbrains.kotlin.fir.analysis.checkers.*
@@ -16,10 +17,8 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
import org.jetbrains.kotlin.fir.analysis.collectors.components.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmDeclarationCheckers
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmExpressionCheckers
import org.jetbrains.kotlin.fir.analysis.jvm.diagnostics.FirJvmDefaultErrorMessages
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.platform.SimplePlatform
import org.jetbrains.kotlin.platform.jvm.JvmPlatform
@@ -43,7 +42,6 @@ private object CheckersFactory {
): List<AbstractDiagnosticCollectorComponent> {
val module = session.moduleData.module
val platform = module.platform.componentPlatforms.first()
installPlatformSpecificErrorMessages(platform)
val declarationCheckers = createDeclarationCheckers(useExtendedCheckers, platform)
val expressionCheckers = createExpressionCheckers(useExtendedCheckers, platform)
val typeCheckers = createTypeCheckers(useExtendedCheckers)
@@ -91,14 +89,6 @@ private object CheckersFactory {
}
}
private fun installPlatformSpecificErrorMessages(platform: SimplePlatform) {
when (platform) {
is JvmPlatform -> FirJvmDefaultErrorMessages.installJvmErrorMessages()
else -> {
}
}
}
private fun createTypeCheckers(useExtendedCheckers: Boolean): TypeCheckers? =
if (useExtendedCheckers) null else CommonTypeCheckers
@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeVariableType
import org.jetbrains.kotlin.fir.types.contains
@@ -20,39 +21,39 @@ internal class LLDiagnosticParameterChecker(testServices: TestServices) : FirAna
val diagnostics = info.firAnalyzerFacade.runCheckers().values.flatten()
for (diagnostic in diagnostics) {
checkDiagnosticIsSuitableForFirIde(diagnostic)
checkDiagnosticIsSuitableForFirIde(diagnostic as KtPsiDiagnostic)
}
}
private fun checkDiagnosticIsSuitableForFirIde(diagnostic: FirDiagnostic) {
private fun checkDiagnosticIsSuitableForFirIde(diagnostic: KtPsiDiagnostic) {
val parameters = diagnostic.allParameters()
for (parameter in parameters) {
checkDiagnosticParameter(diagnostic, parameter)
}
}
private fun checkDiagnosticParameter(diagnostic: FirDiagnostic, parameter: Any?) {
private fun checkDiagnosticParameter(diagnostic: KtPsiDiagnostic, parameter: Any?) {
when (parameter) {
is ConeKotlinType -> checkType(parameter, diagnostic)
is ConeKotlinType -> checkType(parameter, diagnostic as KtDiagnostic)
}
}
private fun checkType(parameter: ConeKotlinType, diagnostic: FirDiagnostic) {
private fun checkType(parameter: ConeKotlinType, diagnostic: KtDiagnostic) {
val containsTypeVariableType = parameter.contains { it is ConeTypeVariableType }
if (containsTypeVariableType) {
val rendered = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic).render(diagnostic)
val rendered = RootDiagnosticRendererFactory(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()
private fun KtPsiDiagnostic.allParameters(): List<Any?> = when (this) {
is KtPsiDiagnosticWithParameters1<*> -> listOf(a)
is KtPsiDiagnosticWithParameters2<*, *> -> listOf(a, b)
is KtPsiDiagnosticWithParameters3<*, *, *> -> listOf(a, b, c)
is KtPsiDiagnosticWithParameters4<*, *, *, *> -> listOf(a, b, c, d)
is KtPsiSimpleDiagnostic -> emptyList()
else -> error("Unexpected diagnostic $this")
}