FIR IDE: collect diagnostics context under read lock
This commit is contained in:
+20
-5
@@ -12,17 +12,28 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
|
|||||||
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
|
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.fir.PersistenceContextCollector
|
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.fir.PersistenceContextCollector
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.fir.PersistentCheckerContextFactory
|
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.fir.PersistentCheckerContextFactory
|
||||||
|
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.LockProvider
|
||||||
|
|
||||||
internal abstract class FileStructureElementDiagnosticRetriever {
|
internal abstract class FileStructureElementDiagnosticRetriever {
|
||||||
abstract fun retrieve(firFile: FirFile, collector: FileStructureElementDiagnosticsCollector): FileStructureElementDiagnosticList
|
abstract fun retrieve(
|
||||||
|
firFile: FirFile,
|
||||||
|
collector: FileStructureElementDiagnosticsCollector,
|
||||||
|
lockProvider: LockProvider<FirFile>
|
||||||
|
): FileStructureElementDiagnosticList
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class SingleNonLocalDeclarationDiagnosticRetriever(
|
internal class SingleNonLocalDeclarationDiagnosticRetriever (
|
||||||
private val declaration: FirDeclaration
|
private val declaration: FirDeclaration
|
||||||
) : FileStructureElementDiagnosticRetriever() {
|
) : FileStructureElementDiagnosticRetriever() {
|
||||||
override fun retrieve(firFile: FirFile, collector: FileStructureElementDiagnosticsCollector): FileStructureElementDiagnosticList {
|
override fun retrieve(
|
||||||
|
firFile: FirFile,
|
||||||
|
collector: FileStructureElementDiagnosticsCollector,
|
||||||
|
lockProvider: LockProvider<FirFile>
|
||||||
|
): FileStructureElementDiagnosticList {
|
||||||
val sessionHolder = SessionHolderImpl.createWithEmptyScopeSession(firFile.session)
|
val sessionHolder = SessionHolderImpl.createWithEmptyScopeSession(firFile.session)
|
||||||
val context = PersistenceContextCollector.collectContext(sessionHolder, firFile, declaration)
|
val context = lockProvider.withReadLock(firFile) {
|
||||||
|
PersistenceContextCollector.collectContext(sessionHolder, firFile, declaration)
|
||||||
|
}
|
||||||
return collector.collectForStructureElement(declaration) { components ->
|
return collector.collectForStructureElement(declaration) { components ->
|
||||||
FirIdeDiagnosticVisitor(context, components)
|
FirIdeDiagnosticVisitor(context, components)
|
||||||
}
|
}
|
||||||
@@ -30,7 +41,11 @@ internal class SingleNonLocalDeclarationDiagnosticRetriever(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal object FileDiagnosticRetriever : FileStructureElementDiagnosticRetriever() {
|
internal object FileDiagnosticRetriever : FileStructureElementDiagnosticRetriever() {
|
||||||
override fun retrieve(firFile: FirFile, collector: FileStructureElementDiagnosticsCollector): FileStructureElementDiagnosticList =
|
override fun retrieve(
|
||||||
|
firFile: FirFile,
|
||||||
|
collector: FileStructureElementDiagnosticsCollector,
|
||||||
|
lockProvider: LockProvider<FirFile>
|
||||||
|
): FileStructureElementDiagnosticList =
|
||||||
collector.collectForStructureElement(firFile) { components ->
|
collector.collectForStructureElement(firFile) { components ->
|
||||||
Visitor(firFile, components)
|
Visitor(firFile, components)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -10,18 +10,19 @@ import com.intellij.util.SmartList
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
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.api.DiagnosticCheckerFilter
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement
|
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.LockProvider
|
||||||
|
|
||||||
internal class FileStructureElementDiagnostics(
|
internal class FileStructureElementDiagnostics(
|
||||||
private val firFile: FirFile,
|
private val firFile: FirFile,
|
||||||
|
private val lockProvider: LockProvider<FirFile>,
|
||||||
private val retriever: FileStructureElementDiagnosticRetriever
|
private val retriever: FileStructureElementDiagnosticRetriever
|
||||||
) {
|
) {
|
||||||
private val diagnosticByCommonCheckers: FileStructureElementDiagnosticList by lazy {
|
private val diagnosticByCommonCheckers: FileStructureElementDiagnosticList by lazy {
|
||||||
retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.USUAL_COLLECTOR)
|
retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.USUAL_COLLECTOR, lockProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val diagnosticByExtendedCheckers: FileStructureElementDiagnosticList by lazy {
|
private val diagnosticByExtendedCheckers: FileStructureElementDiagnosticList by lazy {
|
||||||
retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.EXTENDED_COLLECTOR)
|
retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.EXTENDED_COLLECTOR, lockProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun diagnosticsFor(filter: DiagnosticCheckerFilter, element: PsiElement): List<FirPsiDiagnostic<*>> =
|
fun diagnosticsFor(filter: DiagnosticCheckerFilter, element: PsiElement): List<FirPsiDiagnostic<*>> =
|
||||||
|
|||||||
+7
-2
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.LockProvider
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
@@ -21,25 +22,29 @@ internal object FileElementFactory {
|
|||||||
firDeclaration: FirDeclaration,
|
firDeclaration: FirDeclaration,
|
||||||
ktDeclaration: KtDeclaration,
|
ktDeclaration: KtDeclaration,
|
||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
|
firFileLockProvider: LockProvider<FirFile>,
|
||||||
): FileStructureElement = when {
|
): FileStructureElement = when {
|
||||||
ktDeclaration is KtNamedFunction && ktDeclaration.isReanalyzableContainer() -> ReanalyzableFunctionStructureElement(
|
ktDeclaration is KtNamedFunction && ktDeclaration.isReanalyzableContainer() -> ReanalyzableFunctionStructureElement(
|
||||||
firFile,
|
firFile,
|
||||||
ktDeclaration,
|
ktDeclaration,
|
||||||
(firDeclaration as FirSimpleFunction).symbol,
|
(firDeclaration as FirSimpleFunction).symbol,
|
||||||
ktDeclaration.modificationStamp
|
ktDeclaration.modificationStamp,
|
||||||
|
firFileLockProvider,
|
||||||
)
|
)
|
||||||
|
|
||||||
ktDeclaration is KtProperty && ktDeclaration.isReanalyzableContainer() -> ReanalyzablePropertyStructureElement(
|
ktDeclaration is KtProperty && ktDeclaration.isReanalyzableContainer() -> ReanalyzablePropertyStructureElement(
|
||||||
firFile,
|
firFile,
|
||||||
ktDeclaration,
|
ktDeclaration,
|
||||||
(firDeclaration as FirProperty).symbol,
|
(firDeclaration as FirProperty).symbol,
|
||||||
ktDeclaration.modificationStamp
|
ktDeclaration.modificationStamp,
|
||||||
|
firFileLockProvider,
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> NonReanalyzableDeclarationStructureElement(
|
else -> NonReanalyzableDeclarationStructureElement(
|
||||||
firFile,
|
firFile,
|
||||||
firDeclaration,
|
firDeclaration,
|
||||||
ktDeclaration,
|
ktDeclaration,
|
||||||
|
firFileLockProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -115,7 +115,7 @@ internal class FileStructure(
|
|||||||
towerDataContextCollector = collector
|
towerDataContextCollector = collector
|
||||||
)
|
)
|
||||||
return moduleFileCache.firFileLockProvider.withReadLock(firFile) {
|
return moduleFileCache.firFileLockProvider.withReadLock(firFile) {
|
||||||
FileElementFactory.createFileStructureElement(firDeclaration, declaration, firFile)
|
FileElementFactory.createFileStructureElement(firDeclaration, declaration, firFile, moduleFileCache.firFileLockProvider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +133,7 @@ internal class FileStructure(
|
|||||||
RootStructureElement(
|
RootStructureElement(
|
||||||
firFile,
|
firFile,
|
||||||
container,
|
container,
|
||||||
|
moduleFileCache.firFileLockProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is KtDeclaration -> createDeclarationStructure(container)
|
is KtDeclaration -> createDeclarationStructure(container)
|
||||||
|
|||||||
+20
-12
@@ -15,22 +15,24 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.FileDiagnosticRet
|
|||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.FileStructureElementDiagnostics
|
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.FileStructureElementDiagnostics
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.SingleNonLocalDeclarationDiagnosticRetriever
|
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.SingleNonLocalDeclarationDiagnosticRetriever
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
|
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
|
||||||
|
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.LockProvider
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
|
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider
|
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.hasFqName
|
import org.jetbrains.kotlin.idea.fir.low.level.api.util.hasFqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
internal sealed class FileStructureElement(val firFile: FirFile) {
|
internal sealed class FileStructureElement(val firFile: FirFile, protected val lockProvider: LockProvider<FirFile>) {
|
||||||
abstract val psi: KtAnnotated
|
abstract val psi: KtAnnotated
|
||||||
abstract val mappings: Map<KtElement, FirElement>
|
abstract val mappings: Map<KtElement, FirElement>
|
||||||
abstract val diagnostics: FileStructureElementDiagnostics
|
abstract val diagnostics: FileStructureElementDiagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class ReanalyzableStructureElement<KT : KtDeclaration, S: AbstractFirBasedSymbol<*>>(
|
internal sealed class ReanalyzableStructureElement<KT : KtDeclaration, S : AbstractFirBasedSymbol<*>>(
|
||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
protected val firSymbol: S,
|
protected val firSymbol: S,
|
||||||
) : FileStructureElement(firFile) {
|
lockProvider: LockProvider<FirFile>,
|
||||||
|
) : FileStructureElement(firFile, lockProvider) {
|
||||||
abstract override val psi: KtDeclaration
|
abstract override val psi: KtDeclaration
|
||||||
abstract val timestamp: Long
|
abstract val timestamp: Long
|
||||||
|
|
||||||
@@ -48,7 +50,7 @@ internal sealed class ReanalyzableStructureElement<KT : KtDeclaration, S: Abstra
|
|||||||
|
|
||||||
fun isUpToDate(): Boolean = psi.getModificationStamp() == timestamp
|
fun isUpToDate(): Boolean = psi.getModificationStamp() == timestamp
|
||||||
|
|
||||||
override val diagnostics = FileStructureElementDiagnostics(firFile, SingleNonLocalDeclarationDiagnosticRetriever(firSymbol.fir as FirDeclaration))
|
override val diagnostics = FileStructureElementDiagnostics(firFile, lockProvider, SingleNonLocalDeclarationDiagnosticRetriever(firSymbol.fir as FirDeclaration))
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val recorder = FirElementsRecorder()
|
val recorder = FirElementsRecorder()
|
||||||
@@ -59,8 +61,9 @@ internal class ReanalyzableFunctionStructureElement(
|
|||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
override val psi: KtNamedFunction,
|
override val psi: KtNamedFunction,
|
||||||
firSymbol: FirFunctionSymbol<*>,
|
firSymbol: FirFunctionSymbol<*>,
|
||||||
override val timestamp: Long
|
override val timestamp: Long,
|
||||||
) : ReanalyzableStructureElement<KtNamedFunction, FirFunctionSymbol<*>>(firFile, firSymbol) {
|
lockProvider: LockProvider<FirFile>,
|
||||||
|
) : ReanalyzableStructureElement<KtNamedFunction, FirFunctionSymbol<*>>(firFile, firSymbol, lockProvider) {
|
||||||
override val mappings: Map<KtElement, FirElement> =
|
override val mappings: Map<KtElement, FirElement> =
|
||||||
FirElementsRecorder.recordElementsFrom(firSymbol.fir, recorder)
|
FirElementsRecorder.recordElementsFrom(firSymbol.fir, recorder)
|
||||||
|
|
||||||
@@ -89,6 +92,7 @@ internal class ReanalyzableFunctionStructureElement(
|
|||||||
newKtDeclaration,
|
newKtDeclaration,
|
||||||
newFunction.symbol,
|
newFunction.symbol,
|
||||||
newKtDeclaration.modificationStamp,
|
newKtDeclaration.modificationStamp,
|
||||||
|
lockProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,8 +103,9 @@ internal class ReanalyzablePropertyStructureElement(
|
|||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
override val psi: KtProperty,
|
override val psi: KtProperty,
|
||||||
firSymbol: FirPropertySymbol,
|
firSymbol: FirPropertySymbol,
|
||||||
override val timestamp: Long
|
override val timestamp: Long,
|
||||||
) : ReanalyzableStructureElement<KtProperty, FirPropertySymbol>(firFile, firSymbol) {
|
lockProvider: LockProvider<FirFile>,
|
||||||
|
) : ReanalyzableStructureElement<KtProperty, FirPropertySymbol>(firFile, firSymbol, lockProvider) {
|
||||||
override val mappings: Map<KtElement, FirElement> =
|
override val mappings: Map<KtElement, FirElement> =
|
||||||
FirElementsRecorder.recordElementsFrom(firSymbol.fir, recorder)
|
FirElementsRecorder.recordElementsFrom(firSymbol.fir, recorder)
|
||||||
|
|
||||||
@@ -129,6 +134,7 @@ internal class ReanalyzablePropertyStructureElement(
|
|||||||
newKtDeclaration,
|
newKtDeclaration,
|
||||||
newProperty.symbol,
|
newProperty.symbol,
|
||||||
newKtDeclaration.modificationStamp,
|
newKtDeclaration.modificationStamp,
|
||||||
|
lockProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,11 +145,12 @@ internal class NonReanalyzableDeclarationStructureElement(
|
|||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
fir: FirDeclaration,
|
fir: FirDeclaration,
|
||||||
override val psi: KtDeclaration,
|
override val psi: KtDeclaration,
|
||||||
) : FileStructureElement(firFile) {
|
lockProvider: LockProvider<FirFile>,
|
||||||
|
) : FileStructureElement(firFile, lockProvider) {
|
||||||
override val mappings: Map<KtElement, FirElement> =
|
override val mappings: Map<KtElement, FirElement> =
|
||||||
FirElementsRecorder.recordElementsFrom(fir, recorder)
|
FirElementsRecorder.recordElementsFrom(fir, recorder)
|
||||||
|
|
||||||
override val diagnostics = FileStructureElementDiagnostics(firFile, SingleNonLocalDeclarationDiagnosticRetriever(fir))
|
override val diagnostics = FileStructureElementDiagnostics(firFile, lockProvider, SingleNonLocalDeclarationDiagnosticRetriever(fir))
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -169,11 +176,12 @@ internal class NonReanalyzableDeclarationStructureElement(
|
|||||||
internal class RootStructureElement(
|
internal class RootStructureElement(
|
||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
override val psi: KtFile,
|
override val psi: KtFile,
|
||||||
) : FileStructureElement(firFile) {
|
lockProvider: LockProvider<FirFile>,
|
||||||
|
) : FileStructureElement(firFile, lockProvider) {
|
||||||
override val mappings: Map<KtElement, FirElement> =
|
override val mappings: Map<KtElement, FirElement> =
|
||||||
FirElementsRecorder.recordElementsFrom(firFile, recorder)
|
FirElementsRecorder.recordElementsFrom(firFile, recorder)
|
||||||
|
|
||||||
override val diagnostics = FileStructureElementDiagnostics(firFile, FileDiagnosticRetriever)
|
override val diagnostics = FileStructureElementDiagnostics(firFile, lockProvider, FileDiagnosticRetriever)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val recorder = object : FirElementsRecorder() {
|
private val recorder = object : FirElementsRecorder() {
|
||||||
|
|||||||
Reference in New Issue
Block a user