diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticsCollector.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticsCollector.kt index d4a1a37e500..bda622fbcfd 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticsCollector.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticsCollector.kt @@ -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) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/LLFirDiagnosticReporter.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/LLFirDiagnosticReporter.kt index 3a07c0f4c39..73c39385dfa 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/LLFirDiagnosticReporter.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/LLFirDiagnosticReporter.kt @@ -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>() + private val pendingDiagnostics = mutableMapOf>() + val committedDiagnostics = mutableMapOf>() 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 + } + } + } + } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/AbstractDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/AbstractDiagnosticCollectorComponent.kt index 3dc84adc295..25ba5f77029 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/AbstractDiagnosticCollectorComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/AbstractDiagnosticCollectorComponent.kt @@ -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) {} diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/DiagnosticReporter.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/DiagnosticReporter.kt index 2e9cc6ad9b8..43c6ddeaffe 100644 --- a/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/DiagnosticReporter.kt +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/DiagnosticReporter.kt @@ -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( diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/impl/PendingDiagnosticsCollectorWithSuppress.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/impl/PendingDiagnosticsCollectorWithSuppress.kt index 68953603f7b..4ce19c410a9 100644 --- a/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/impl/PendingDiagnosticsCollectorWithSuppress.kt +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/impl/PendingDiagnosticsCollectorWithSuppress.kt @@ -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()