FIR IDE: fix collecting diagnostics multiple times for the same declaration
^KT-45199 fixed
This commit is contained in:
+16
-16
@@ -58,7 +58,7 @@ abstract class AbstractDiagnosticCollector(
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
private var context = PersistentCheckerContext(this, returnTypeCalculator)
|
||||
private var currentAction = DiagnosticCollectorDeclarationAction.CHECK_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
private var currentAction = DiagnosticCollectorDeclarationAction.CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
|
||||
fun initializeComponents(vararg components: AbstractDiagnosticCollectorComponent) {
|
||||
if (componentsInitialized) {
|
||||
@@ -72,9 +72,11 @@ abstract class AbstractDiagnosticCollector(
|
||||
|
||||
private inner class Visitor : FirDefaultVisitor<Unit, Nothing?>() {
|
||||
private fun <T : FirElement> T.runComponents() {
|
||||
components.forEach {
|
||||
beforeCollecting()
|
||||
this.accept(it, context)
|
||||
if (currentAction.checkInCurrentDeclaration) {
|
||||
components.forEach {
|
||||
beforeCollecting()
|
||||
this.accept(it, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,13 +222,11 @@ abstract class AbstractDiagnosticCollector(
|
||||
declaration: FirDeclaration,
|
||||
block: () -> Unit = { declaration.acceptChildren(this, null) }
|
||||
) {
|
||||
if (!currentAction.checkNested) return
|
||||
if (!currentAction.lookupForNestedDeclaration) return
|
||||
|
||||
val action = onDeclarationEnter(declaration)
|
||||
if (action.checkCurrentDeclaration) {
|
||||
declaration.runComponents()
|
||||
}
|
||||
val action = getDeclarationActionOnDeclarationEnter(declaration)
|
||||
withDiagnosticsAction(action) {
|
||||
declaration.runComponents()
|
||||
withDeclaration(declaration) {
|
||||
block()
|
||||
}
|
||||
@@ -258,8 +258,8 @@ abstract class AbstractDiagnosticCollector(
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun onDeclarationEnter(declaration: FirDeclaration): DiagnosticCollectorDeclarationAction =
|
||||
DiagnosticCollectorDeclarationAction.CHECK_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
protected open fun getDeclarationActionOnDeclarationEnter(declaration: FirDeclaration): DiagnosticCollectorDeclarationAction =
|
||||
DiagnosticCollectorDeclarationAction.CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
|
||||
protected open fun onDeclarationExit(declaration: FirDeclaration) {}
|
||||
|
||||
@@ -334,11 +334,11 @@ abstract class AbstractDiagnosticCollector(
|
||||
}
|
||||
}
|
||||
|
||||
enum class DiagnosticCollectorDeclarationAction(val checkCurrentDeclaration: Boolean, val checkNested: Boolean) {
|
||||
CHECK_CURRENT_DECLARATION_AND_CHECK_NESTED(checkCurrentDeclaration = true, checkNested = true),
|
||||
CHECK_CURRENT_DECLARATION_AND_SKIP_NESTED(checkCurrentDeclaration = true, checkNested = false),
|
||||
SKIP_CURRENT_DECLARATION_AND_CHECK_NESTED(checkCurrentDeclaration = false, checkNested = true),
|
||||
SKIP(checkCurrentDeclaration = false, checkNested = false),
|
||||
enum class DiagnosticCollectorDeclarationAction(val checkInCurrentDeclaration: Boolean, val lookupForNestedDeclaration: Boolean) {
|
||||
CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED(checkInCurrentDeclaration = true, lookupForNestedDeclaration = true),
|
||||
CHECK_IN_CURRENT_DECLARATION_AND_DO_NOT_LOOKUP_FOR_NESTED(checkInCurrentDeclaration = true, lookupForNestedDeclaration = false),
|
||||
DO_NOT_CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED(checkInCurrentDeclaration = false, lookupForNestedDeclaration = true),
|
||||
SKIP(checkInCurrentDeclaration = false, lookupForNestedDeclaration = false),
|
||||
}
|
||||
|
||||
fun AbstractDiagnosticCollector.registerAllComponents() {
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement
|
||||
|
||||
internal class FileStructureElementDiagnostics(
|
||||
private val firFile: FirFile,
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ internal class FileStructureElementDiagnosticsCollector private constructor(priv
|
||||
result.addValueFor(diagnostic.psiElement, diagnostic)
|
||||
}
|
||||
|
||||
override fun onDeclarationEnter(
|
||||
override fun getDeclarationActionOnDeclarationEnter(
|
||||
declaration: FirDeclaration,
|
||||
): DiagnosticCollectorDeclarationAction =
|
||||
onDeclarationEnter.invoke(declaration)
|
||||
|
||||
+9
-9
@@ -60,10 +60,10 @@ internal sealed class ReanalyzableStructureElement<KT : KtDeclaration>(firFile:
|
||||
when {
|
||||
firDeclaration == declaration -> {
|
||||
inCurrentDeclaration = true
|
||||
DiagnosticCollectorDeclarationAction.CHECK_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
DiagnosticCollectorDeclarationAction.CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
}
|
||||
inCurrentDeclaration -> DiagnosticCollectorDeclarationAction.CHECK_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
else -> DiagnosticCollectorDeclarationAction.SKIP_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
inCurrentDeclaration -> DiagnosticCollectorDeclarationAction.CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
else -> DiagnosticCollectorDeclarationAction.DO_NOT_CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
}
|
||||
},
|
||||
onDeclarationExit = { firDeclaration ->
|
||||
@@ -176,19 +176,19 @@ internal class NonReanalyzableDeclarationStructureElement(
|
||||
// Some generated declaration contains structures that we need to check. For example the FIR representation of an
|
||||
// enum entry initializer, when present, is a generated anonymous object of kind `ENUM_ENTRY`.
|
||||
firDeclaration.isGeneratedDeclaration ->
|
||||
DiagnosticCollectorDeclarationAction.SKIP_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
firDeclaration is FirFile -> DiagnosticCollectorDeclarationAction.CHECK_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
DiagnosticCollectorDeclarationAction.DO_NOT_CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
firDeclaration is FirFile -> DiagnosticCollectorDeclarationAction.DO_NOT_CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
firDeclaration == fir -> {
|
||||
inCurrentDeclaration = true
|
||||
DiagnosticCollectorDeclarationAction.CHECK_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
DiagnosticCollectorDeclarationAction.CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
}
|
||||
FileElementFactory.isReanalyzableContainer(firDeclaration.ktDeclaration) -> {
|
||||
DiagnosticCollectorDeclarationAction.SKIP
|
||||
}
|
||||
inCurrentDeclaration -> {
|
||||
DiagnosticCollectorDeclarationAction.CHECK_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
DiagnosticCollectorDeclarationAction.CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
}
|
||||
else -> DiagnosticCollectorDeclarationAction.SKIP_CURRENT_DECLARATION_AND_CHECK_NESTED
|
||||
else -> DiagnosticCollectorDeclarationAction.DO_NOT_CHECK_IN_CURRENT_DECLARATION_AND_LOOKUP_FOR_NESTED
|
||||
}
|
||||
},
|
||||
onDeclarationExit = { firDeclaration ->
|
||||
@@ -233,7 +233,7 @@ internal class RootStructureElement(
|
||||
private object DiagnosticRetriever : FileStructureElementDiagnosticRetriever() {
|
||||
override fun retrieve(firFile: FirFile, collector: FileStructureElementDiagnosticsCollector): FileStructureElementDiagnosticList {
|
||||
return collector.collectForStructureElement(firFile) { firDeclaration ->
|
||||
if (firDeclaration is FirFile) DiagnosticCollectorDeclarationAction.CHECK_CURRENT_DECLARATION_AND_SKIP_NESTED
|
||||
if (firDeclaration is FirFile) DiagnosticCollectorDeclarationAction.CHECK_IN_CURRENT_DECLARATION_AND_DO_NOT_LOOKUP_FOR_NESTED
|
||||
else DiagnosticCollectorDeclarationAction.SKIP
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user