FIR: Collect all scopes in FirModuleResolveStateImpl

We need to collect the scopes to later use them in reference shortening

Probably we will need to optimize this behaviour later, since it seems
inefficient
This commit is contained in:
Roman Golyshev
2020-12-21 15:17:58 +03:00
committed by Space
parent 8bc7866f01
commit 11564d7950
6 changed files with 47 additions and 10 deletions
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration 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.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.resolve.FirTowerDataContext
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.InternalForInline import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.InternalForInline
@@ -112,4 +112,7 @@ internal class FirModuleResolveStateForCompletion(
override fun getBuiltFirFileOrNull(ktFile: KtFile): FirFile? { override fun getBuiltFirFileOrNull(ktFile: KtFile): FirFile? {
error("Should not be used in completion") error("Should not be used in completion")
} }
override fun getTowerDataContextForElement(element: KtElement): FirTowerDataContext? =
originalState.getTowerDataContextForElement(element)
} }
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration 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.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.realPsi import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.resolve.FirTowerDataContext
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.DiagnosticsCollector import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.DiagnosticsCollector
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirElementBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirElementBuilder
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.element.builder.getClosestAvailableParentContext
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
@@ -44,7 +45,8 @@ internal class FirModuleResolveStateImpl(
val firLazyDeclarationResolver: FirLazyDeclarationResolver, val firLazyDeclarationResolver: FirLazyDeclarationResolver,
) : FirModuleResolveState() { ) : FirModuleResolveState() {
override val rootModuleSession: FirIdeSourcesSession get() = sessionProvider.rootModuleSession override val rootModuleSession: FirIdeSourcesSession get() = sessionProvider.rootModuleSession
val fileStructureCache = FileStructureCache(firFileBuilder, firLazyDeclarationResolver) private val collector = FirTowerDataContextCollector()
val fileStructureCache = FileStructureCache(firFileBuilder, firLazyDeclarationResolver, collector)
val elementBuilder = FirElementBuilder() val elementBuilder = FirElementBuilder()
private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, rootModuleSession.cache) private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, rootModuleSession.cache)
@@ -103,7 +105,13 @@ internal class FirModuleResolveStateImpl(
) )
if (container.resolvePhase < FirResolvePhase.BODY_RESOLVE) { if (container.resolvePhase < FirResolvePhase.BODY_RESOLVE) {
val cache = (container.session as FirIdeSourcesSession).cache val cache = (container.session as FirIdeSourcesSession).cache
firLazyDeclarationResolver.lazyResolveDeclaration(container, cache, FirResolvePhase.BODY_RESOLVE, checkPCE = false /*TODO*/) firLazyDeclarationResolver.lazyResolveDeclaration(
container,
cache,
FirResolvePhase.BODY_RESOLVE,
checkPCE = false /*TODO*/,
towerDataContextCollector = collector,
)
} }
val firDeclaration = FirElementFinder.findElementIn<FirDeclaration>(container) { firDeclaration -> val firDeclaration = FirElementFinder.findElementIn<FirDeclaration>(container) { firDeclaration ->
when (val realPsi = firDeclaration.realPsi) { when (val realPsi = firDeclaration.realPsi) {
@@ -126,7 +134,13 @@ internal class FirModuleResolveStateImpl(
is FirIdeSourcesSession -> session.cache is FirIdeSourcesSession -> session.cache
else -> return declaration else -> return declaration
} }
firLazyDeclarationResolver.lazyResolveDeclaration(declaration, fileCache, toPhase, checkPCE = true) firLazyDeclarationResolver.lazyResolveDeclaration(
declaration,
fileCache,
toPhase,
checkPCE = true,
towerDataContextCollector = collector,
)
return declaration return declaration
} }
@@ -153,4 +167,8 @@ internal class FirModuleResolveStateImpl(
override fun getFirFile(declaration: FirDeclaration, cache: ModuleFileCache): FirFile? = override fun getFirFile(declaration: FirDeclaration, cache: ModuleFileCache): FirFile? =
cache.getContainerFirFile(declaration) cache.getContainerFirFile(declaration)
override fun getTowerDataContextForElement(element: KtElement): FirTowerDataContext? {
return collector.getClosestAvailableParentContext(element)
}
} }
@@ -10,6 +10,7 @@ import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.FirTowerDataContext
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
@@ -78,4 +79,6 @@ abstract class FirModuleResolveState {
) )
internal abstract fun getFirFile(declaration: FirDeclaration, cache: ModuleFileCache): FirFile? internal abstract fun getFirFile(declaration: FirDeclaration, cache: ModuleFileCache): FirFile?
abstract fun getTowerDataContextForElement(element: KtElement): FirTowerDataContext?
} }
@@ -24,3 +24,11 @@ class FirTowerDataContextCollector {
fun getContext(psi: KtElement): FirTowerDataContext? = state[psi] fun getContext(psi: KtElement): FirTowerDataContext? = state[psi]
} }
fun FirTowerDataContextCollector.getClosestAvailableParentContext(element: KtElement): FirTowerDataContext? {
var current: KtElement = element
while (true) {
getContext(current)?.let { return it }
current = current.parent as? KtElement ?: return null
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
@@ -24,7 +25,8 @@ internal class FileStructure(
private val firFile: FirFile, private val firFile: FirFile,
private val firLazyDeclarationResolver: FirLazyDeclarationResolver, private val firLazyDeclarationResolver: FirLazyDeclarationResolver,
private val firFileBuilder: FirFileBuilder, private val firFileBuilder: FirFileBuilder,
private val moduleFileCache: ModuleFileCache private val moduleFileCache: ModuleFileCache,
private val collector: FirTowerDataContextCollector
) { ) {
private val firIdeProvider = firFile.session.firIdeProvider private val firIdeProvider = firFile.session.firIdeProvider
@@ -74,7 +76,8 @@ internal class FileStructure(
firDeclaration, firDeclaration,
moduleFileCache, moduleFileCache,
FirResolvePhase.BODY_RESOLVE, FirResolvePhase.BODY_RESOLVE,
checkPCE = true checkPCE = true,
towerDataContextCollector = collector
) )
return moduleFileCache.firFileLockProvider.withReadLock(firFile) { return moduleFileCache.firFileLockProvider.withReadLock(firFile) {
FileElementFactory.createFileStructureElement(firDeclaration, declaration, firFile) FileElementFactory.createFileStructureElement(firDeclaration, declaration, firFile)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
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
@@ -12,16 +13,17 @@ import org.jetbrains.kotlin.psi.KtFile
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
/** /**
* Belongs to a [org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState] * Belongs to a [org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState]
*/ */
internal class FileStructureCache( internal class FileStructureCache(
private val fileBuilder: FirFileBuilder, private val fileBuilder: FirFileBuilder,
private val firLazyDeclarationResolver: FirLazyDeclarationResolver, private val firLazyDeclarationResolver: FirLazyDeclarationResolver,
private val collector: FirTowerDataContextCollector,
) { ) {
private val cache = ConcurrentHashMap<KtFile, FileStructure>() private val cache = ConcurrentHashMap<KtFile, FileStructure>()
fun getFileStructure(ktFile: KtFile, moduleFileCache: ModuleFileCache): FileStructure = cache.computeIfAbsent(ktFile) { fun getFileStructure(ktFile: KtFile, moduleFileCache: ModuleFileCache): FileStructure = cache.computeIfAbsent(ktFile) {
val firFile = fileBuilder.buildRawFirFileWithCaching(ktFile, moduleFileCache, lazyBodiesMode = false) val firFile = fileBuilder.buildRawFirFileWithCaching(ktFile, moduleFileCache, lazyBodiesMode = false)
FileStructure(ktFile, firFile, firLazyDeclarationResolver, fileBuilder, moduleFileCache) FileStructure(ktFile, firFile, firLazyDeclarationResolver, fileBuilder, moduleFileCache, collector)
} }
} }