FIR IDE: Introduce module resolve state for completion

This commit is contained in:
Ilya Kirillov
2020-07-06 18:38:13 +03:00
parent 1d92fbaa7f
commit 9092b33755
5 changed files with 64 additions and 10 deletions
@@ -19,10 +19,10 @@ internal interface FirIdeResolveStateService {
val fallbackModificationTracker: ModificationTracker? val fallbackModificationTracker: ModificationTracker?
fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveState fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl
} }
private class FirModuleData(val state: FirModuleResolveState, val modificationTracker: ModificationTracker?) { private class FirModuleData(val state: FirModuleResolveStateImpl, val modificationTracker: ModificationTracker?) {
val modificationCount: Long = modificationTracker?.modificationCount ?: Long.MIN_VALUE val modificationCount: Long = modificationTracker?.modificationCount ?: Long.MIN_VALUE
fun isOutOfDate(): Boolean { fun isOutOfDate(): Boolean {
@@ -34,7 +34,7 @@ private class FirModuleData(val state: FirModuleResolveState, val modificationTr
internal class FirIdeResolveStateServiceImpl(val project: Project) : FirIdeResolveStateService { internal class FirIdeResolveStateServiceImpl(val project: Project) : FirIdeResolveStateService {
private val stateCache = mutableMapOf<IdeaModuleInfo, FirModuleData>() private val stateCache = mutableMapOf<IdeaModuleInfo, FirModuleData>()
private fun createResolveState(): FirModuleResolveState { private fun createResolveState(): FirModuleResolveStateImpl {
val provider = FirProjectSessionProvider(project) val provider = FirProjectSessionProvider(project)
return FirModuleResolveStateImpl(provider) return FirModuleResolveStateImpl(provider)
} }
@@ -47,7 +47,7 @@ internal class FirIdeResolveStateServiceImpl(val project: Project) : FirIdeResol
} }
// TODO: multi thread protection // TODO: multi thread protection
override fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveState { override fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl {
var moduleData = stateCache.getOrPut(moduleInfo) { var moduleData = stateCache.getOrPut(moduleInfo) {
createModuleData() createModuleData()
} }
@@ -60,7 +60,7 @@ abstract class FirModuleResolveState {
} }
} }
internal abstract operator fun get(psi: KtElement): FirElement? internal abstract fun getCachedMapping(psi: KtElement): FirElement?
internal abstract fun getDiagnostics(psi: KtElement): List<Diagnostic> internal abstract fun getDiagnostics(psi: KtElement): List<Diagnostic>
@@ -73,14 +73,34 @@ abstract class FirModuleResolveState {
internal abstract fun setDiagnosticsForFile(file: KtFile, fir: FirFile, diagnostics: Iterable<FirDiagnostic<*>> = emptyList()) internal abstract fun setDiagnosticsForFile(file: KtFile, fir: FirFile, diagnostics: Iterable<FirDiagnostic<*>> = emptyList())
} }
internal class FirModuleResolveStateImpl(override val sessionProvider: FirProjectSessionProvider) : FirModuleResolveState() { internal abstract class PsiToFirCache {
abstract operator fun get(psi: KtElement): FirElement?
abstract operator fun set(psi: KtElement, fir: FirElement)
abstract fun remove(psi: PsiElement)
}
internal class PsiToFirCacheImpl : PsiToFirCache() {
private val cache = mutableMapOf<KtElement, FirElement>() private val cache = mutableMapOf<KtElement, FirElement>()
override fun get(psi: KtElement): FirElement? = cache[psi]
override fun set(psi: KtElement, fir: FirElement) {
cache[psi] = fir
}
override fun remove(psi: PsiElement) {
cache.remove(psi)
}
}
open class FirModuleResolveStateImpl(override val sessionProvider: FirProjectSessionProvider) : FirModuleResolveState() {
internal open val cache: PsiToFirCache = PsiToFirCacheImpl()
private val diagnosticCache = mutableMapOf<KtElement, MutableList<Diagnostic>>() private val diagnosticCache = mutableMapOf<KtElement, MutableList<Diagnostic>>()
private val diagnosedFiles = mutableMapOf<KtFile, Long>() private val diagnosedFiles = mutableMapOf<KtFile, Long>()
override fun get(psi: KtElement): FirElement? = cache[psi] override fun getCachedMapping(psi: KtElement): FirElement? = cache[psi]
override fun getDiagnostics(psi: KtElement): List<Diagnostic> { override fun getDiagnostics(psi: KtElement): List<Diagnostic> {
return diagnosticCache[psi] ?: emptyList() return diagnosticCache[psi] ?: emptyList()
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.fir.low.level.api
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.psi.KtElement
class FirModuleResolveStateForCompletion(
mainState: FirModuleResolveStateImpl
) : FirModuleResolveStateImpl(mainState.sessionProvider) {
override val cache: PsiToFirCache = PsiToFirCacheForCompletion(mainState.cache)
}
private class PsiToFirCacheForCompletion(private val delegate: PsiToFirCache) : PsiToFirCache() {
private val cache = mutableMapOf<KtElement, FirElement>()
override fun get(psi: KtElement): FirElement? =
cache[psi] ?: delegate[psi]
override fun set(psi: KtElement, fir: FirElement) {
cache[psi] = fir
}
override fun remove(psi: PsiElement) {
cache.remove(psi)
}
}
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.FirUserTypeRef import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
@@ -255,7 +254,7 @@ internal fun KtElement.getOrBuildFir(
is KtPropertyDelegate -> this.expression ?: this is KtPropertyDelegate -> this.expression ?: this
else -> this else -> this
} }
return state[this] ?: run { return state.getCachedMapping(this) ?: run {
containerFir.accept(object : FirVisitorVoid() { containerFir.accept(object : FirVisitorVoid() {
override fun visitElement(element: FirElement) { override fun visitElement(element: FirElement) {
(element.realPsi as? KtElement)?.let { (element.realPsi as? KtElement)?.let {
@@ -288,7 +287,7 @@ internal fun KtElement.getOrBuildFir(
}) })
var current: PsiElement? = psi var current: PsiElement? = psi
while (current is KtElement) { while (current is KtElement) {
val mappedFir = state[current] val mappedFir = state.getCachedMapping(current)
if (mappedFir != null) { if (mappedFir != null) {
if (current != this) { if (current != this) {
state.record(current, mappedFir) state.record(current, mappedFir)
@@ -15,6 +15,10 @@ object LowLevelFirApiFacade {
fun getResolveStateFor(element: KtElement): FirModuleResolveState = fun getResolveStateFor(element: KtElement): FirModuleResolveState =
element.firResolveState() element.firResolveState()
fun getResolveStateForCompletion(element: KtElement, mainState: FirModuleResolveStateImpl): FirModuleResolveStateForCompletion {
return FirModuleResolveStateForCompletion(mainState)
}
fun getSessionFor(element: KtElement, resolveState: FirModuleResolveState): FirSession = fun getSessionFor(element: KtElement, resolveState: FirModuleResolveState): FirSession =
resolveState.getSession(element) resolveState.getSession(element)