K2 LL API: implement automatic diagnostic suppression

This commit is contained in:
Mikhail Glukhikh
2022-07-21 11:41:03 +02:00
committed by Space
parent 9add6f3d55
commit 07f16ef378
5 changed files with 41 additions and 11 deletions
@@ -27,6 +27,10 @@ internal class FileStructureElementDiagnosticsCollector private constructor(priv
useExtendedCheckers,
)
collector.collectDiagnostics(firDeclaration, reporter)
return FileStructureElementDiagnosticList(reporter.diagnostics)
val source = firDeclaration.source
if (source != null) {
reporter.checkAndCommitReportsOn(source, null)
}
return FileStructureElementDiagnosticList(reporter.committedDiagnostics)
}
}
@@ -6,11 +6,13 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor
import org.jetbrains.kotlin.diagnostics.*
internal class LLFirDiagnosticReporter : DiagnosticReporter() {
val diagnostics = mutableMapOf<PsiElement, MutableList<KtPsiDiagnostic>>()
private val pendingDiagnostics = mutableMapOf<PsiElement, MutableList<KtPsiDiagnostic>>()
val committedDiagnostics = mutableMapOf<PsiElement, MutableList<KtPsiDiagnostic>>()
override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) {
if (diagnostic == null) return
@@ -21,7 +23,31 @@ internal class LLFirDiagnosticReporter : DiagnosticReporter() {
is KtLightDiagnostic -> diagnostic.toPsiDiagnostic()
else -> error("Unknown diagnostic type ${diagnostic::class.simpleName}")
}
diagnostics.addValueFor(psiDiagnostic.psiElement, psiDiagnostic)
pendingDiagnostics.addValueFor(psiDiagnostic.psiElement, psiDiagnostic)
}
override fun checkAndCommitReportsOn(element: AbstractKtSourceElement, context: DiagnosticContext?) {
val commitEverything = context == null
for ((diagnosticElement, pendingList) in pendingDiagnostics) {
val committedList = committedDiagnostics.getOrPut(diagnosticElement) { mutableListOf() }
val iterator = pendingList.iterator()
while (iterator.hasNext()) {
val diagnostic = iterator.next()
when {
context?.isDiagnosticSuppressed(diagnostic as KtDiagnostic) == true -> {
if (diagnostic.element == element ||
diagnostic.element.startOffset >= element.startOffset && diagnostic.element.endOffset <= element.endOffset
) {
iterator.remove()
}
}
diagnostic.element == element || commitEverything -> {
iterator.remove()
committedList += diagnostic
}
}
}
}
}
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.impl.PendingDiagnosticsCollectorWithSuppress
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.visitors.FirVisitor
@@ -21,10 +20,8 @@ abstract class AbstractDiagnosticCollectorComponent(
override fun visitElement(element: FirElement, data: CheckerContext) {}
protected fun checkAndCommitReportsOn(element: FirElement, context: DiagnosticContext?) {
if (reporter is PendingDiagnosticsCollectorWithSuppress) {
val source = element.source ?: return
reporter.checkAndCommitReportsOn(source, context, context == null)
}
val source = element.source ?: return
reporter.checkAndCommitReportsOn(source, context)
}
open fun endOfFile(file: FirFile) {}
@@ -27,6 +27,9 @@ abstract class MutableDiagnosticContext : DiagnosticContext {
abstract class DiagnosticReporter {
abstract fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext)
open fun checkAndCommitReportsOn(element: AbstractKtSourceElement, context: DiagnosticContext?) {
}
}
open class KtDiagnosticReporterWithContext(
@@ -29,11 +29,11 @@ class PendingDiagnosticsCollectorWithSuppress : BaseDiagnosticsCollector() {
}
}
fun checkAndCommitReportsOn(
override fun checkAndCommitReportsOn(
element: AbstractKtSourceElement,
context: DiagnosticContext?,
commitEverything: Boolean
context: DiagnosticContext?
) {
val commitEverything = context == null
for ((path, pendingList) in pendingDiagnosticsByFilePath) {
val committedList = _diagnosticsByFilePath.getOrPut(path) { mutableListOf() }
val iterator = pendingList.iterator()