Analysis API: recreate analysis session when not found by resolve state

This commit is contained in:
Ilya Kirillov
2021-09-23 10:30:40 +02:00
parent 0915dac1f9
commit d63c136854
7 changed files with 15 additions and 13 deletions
@@ -31,7 +31,6 @@ private constructor(
val firResolveState: FirModuleResolveState, val firResolveState: FirModuleResolveState,
internal val firSymbolBuilder: KtSymbolByFirBuilder, internal val firSymbolBuilder: KtSymbolByFirBuilder,
token: ValidityToken, token: ValidityToken,
element: KtElement,
private val mode: AnalysisSessionMode, private val mode: AnalysisSessionMode,
) : KtAnalysisSession(token) { ) : KtAnalysisSession(token) {
@@ -110,7 +109,6 @@ private constructor(
contextResolveState, contextResolveState,
firSymbolBuilder.createReadOnlyCopy(contextResolveState), firSymbolBuilder.createReadOnlyCopy(contextResolveState),
token, token,
originalKtFile,
AnalysisSessionMode.DEPENDENT_COPY AnalysisSessionMode.DEPENDENT_COPY
) )
} }
@@ -118,15 +116,12 @@ private constructor(
val rootModuleSession: FirSession get() = firResolveState.rootModuleSession val rootModuleSession: FirSession get() = firResolveState.rootModuleSession
val firSymbolProvider: FirSymbolProvider get() = rootModuleSession.symbolProvider val firSymbolProvider: FirSymbolProvider get() = rootModuleSession.symbolProvider
val targetPlatform: TargetPlatform get() = rootModuleSession.moduleData.platform val targetPlatform: TargetPlatform get() = rootModuleSession.moduleData.platform
val searchScope: GlobalSearchScope = element.resolveScope//todo
companion object { companion object {
@InvalidWayOfUsingAnalysisSession @InvalidWayOfUsingAnalysisSession
@Deprecated("Please use org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProviderKt.analyze")
internal fun createAnalysisSessionByResolveState( internal fun createAnalysisSessionByResolveState(
firResolveState: FirModuleResolveState, firResolveState: FirModuleResolveState,
token: ValidityToken, token: ValidityToken,
element: KtElement,
): KtFirAnalysisSession { ): KtFirAnalysisSession {
val project = firResolveState.project val project = firResolveState.project
val firSymbolBuilder = KtSymbolByFirBuilder( val firSymbolBuilder = KtSymbolByFirBuilder(
@@ -139,7 +134,6 @@ private constructor(
firResolveState, firResolveState,
firSymbolBuilder, firSymbolBuilder,
token, token,
element,
AnalysisSessionMode.REGULAR, AnalysisSessionMode.REGULAR,
) )
} }
@@ -30,9 +30,10 @@ class KtFirAnalysisSessionProvider(project: Project) : CachingKtAnalysisSessionP
override fun createAnalysisSession( override fun createAnalysisSession(
resolveState: FirModuleResolveState, resolveState: FirModuleResolveState,
validityToken: ValidityToken, validityToken: ValidityToken,
contextElement: KtElement
): KtAnalysisSession { ): KtAnalysisSession {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
return KtFirAnalysisSession.createAnalysisSessionByResolveState(resolveState, validityToken, contextElement) return KtFirAnalysisSession.createAnalysisSessionByResolveState(resolveState, validityToken)
} }
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.api.fir.components package org.jetbrains.kotlin.analysis.api.fir.components
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
@@ -212,7 +213,7 @@ internal class KtFirScopeProvider(
project, project,
builder, builder,
token, token,
analysisSession.searchScope, GlobalSearchScope.allScope(project), // todo
analysisSession.targetPlatform analysisSession.targetPlatform
) )
is FirContainingNamesAwareScope -> KtFirDelegatingScopeImpl(firScope, builder, token) is FirContainingNamesAwareScope -> KtFirDelegatingScopeImpl(firScope, builder, token)
@@ -33,7 +33,6 @@ abstract class CachingKtAnalysisSessionProvider<State : Any>(private val project
protected abstract fun createAnalysisSession( protected abstract fun createAnalysisSession(
resolveState: State, resolveState: State,
validityToken: ValidityToken, validityToken: ValidityToken,
contextElement: KtElement
): KtAnalysisSession ): KtAnalysisSession
@InvalidWayOfUsingAnalysisSession @InvalidWayOfUsingAnalysisSession
@@ -41,7 +40,7 @@ abstract class CachingKtAnalysisSessionProvider<State : Any>(private val project
val resolveState = getResolveState(contextElement) val resolveState = getResolveState(contextElement)
return cache.getAnalysisSession(resolveState to factory.identifier) { return cache.getAnalysisSession(resolveState to factory.identifier) {
val validityToken = factory.create(project) val validityToken = factory.create(project)
createAnalysisSession(resolveState, validityToken, contextElement) createAnalysisSession(resolveState, validityToken)
} }
} }
@@ -49,7 +48,7 @@ abstract class CachingKtAnalysisSessionProvider<State : Any>(private val project
val resolveState = getResolveState(contextSymbol) val resolveState = getResolveState(contextSymbol)
val token = contextSymbol.token val token = contextSymbol.token
return getCachedAnalysisSession(resolveState, token) return getCachedAnalysisSession(resolveState, token)
?: error("analysis session was not found for ${contextSymbol::class}, symbol.isValid=${contextSymbol.isValid()}") ?: createAnalysisSession(resolveState, contextSymbol.token)
} }
private fun getCachedAnalysisSession(resolveState: State, token: ValidityToken): KtAnalysisSession? { private fun getCachedAnalysisSession(resolveState: State, token: ValidityToken): KtAnalysisSession? {
@@ -29,6 +29,8 @@ public class AlwaysAccessibleValidityToken(project: Project) : ValidityToken() {
override fun getInaccessibilityReason(): String { override fun getInaccessibilityReason(): String {
error("Getting inaccessibility reason for validity token when it is accessible") error("Getting inaccessibility reason for validity token when it is accessible")
} }
override val factory: ValidityTokenFactory = AlwaysAccessibleValidityTokenFactory
} }
public object AlwaysAccessibleValidityTokenFactory : ValidityTokenFactory() { public object AlwaysAccessibleValidityTokenFactory : ValidityTokenFactory() {
@@ -52,6 +52,8 @@ public class ReadActionConfinementValidityToken(project: Project) : ValidityToke
@HackToForceAllowRunningAnalyzeOnEDT @HackToForceAllowRunningAnalyzeOnEDT
public val allowOnEdt: ThreadLocal<Boolean> = ThreadLocal.withInitial { false } public val allowOnEdt: ThreadLocal<Boolean> = ThreadLocal.withInitial { false }
} }
public override val factory: ValidityTokenFactory = ReadActionConfinementValidityTokenFactory
} }
public object ReadActionConfinementValidityTokenFactory : ValidityTokenFactory() { public object ReadActionConfinementValidityTokenFactory : ValidityTokenFactory() {
@@ -70,6 +72,7 @@ public object ReadActionConfinementValidityTokenFactory : ValidityTokenFactory()
private val currentAnalysisContextEnteringCount = ThreadLocal.withInitial { 0 } private val currentAnalysisContextEnteringCount = ThreadLocal.withInitial { 0 }
internal fun isInsideAnalysisContext() = currentAnalysisContextEnteringCount.get() > 0 internal fun isInsideAnalysisContext() = currentAnalysisContextEnteringCount.get() > 0
} }
@RequiresOptIn("All frontend related work should not be allowed to be ran from EDT thread. Only use it as a temporary solution") @RequiresOptIn("All frontend related work should not be allowed to be ran from EDT thread. Only use it as a temporary solution")
@@ -14,6 +14,8 @@ public abstract class ValidityToken {
public abstract fun isAccessible(): Boolean public abstract fun isAccessible(): Boolean
public abstract fun getInaccessibilityReason(): String public abstract fun getInaccessibilityReason(): String
public abstract val factory: ValidityTokenFactory
} }
public abstract class ValidityTokenFactory { public abstract class ValidityTokenFactory {