[Analysis API FIR] fix creating symbol for library declaration

the search scope for symbols is limited to the target module, so we can find only a single declaration
This commit is contained in:
Ilya Kirillov
2022-07-19 09:46:03 +02:00
parent f9126462ac
commit 22b8fd636f
11 changed files with 39 additions and 24 deletions
@@ -45,7 +45,7 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
private fun createBuiltinsAndCloneableSession(platform: TargetPlatform): LLFirBuiltinsAndCloneableSession { private fun createBuiltinsAndCloneableSession(platform: TargetPlatform): LLFirBuiltinsAndCloneableSession {
val builtinsModule = KtBuiltinsModule(platform, platform.getAnalyzerServices(), project) val builtinsModule = KtBuiltinsModule(platform, platform.getAnalyzerServices(), project)
return LLFirBuiltinsAndCloneableSession(project, builtInTypes).apply session@{ return LLFirBuiltinsAndCloneableSession(builtinsModule, project, builtInTypes).apply session@{
val moduleData = LLFirKtModuleBasedModuleData(builtinsModule).apply { val moduleData = LLFirKtModuleBasedModuleData(builtinsModule).apply {
bindSession(this@session) bindSession(this@session)
} }
@@ -56,7 +56,7 @@ internal class LLFirLibrarySessionFactory(
): LLFirLibrarySession { ): LLFirLibrarySession {
val platform = ktLibraryModule.platform val platform = ktLibraryModule.platform
val builtinsSession = LLFirBuiltinsSessionFactory.getInstance(project).getBuiltinsSession(platform) val builtinsSession = LLFirBuiltinsSessionFactory.getInstance(project).getBuiltinsSession(platform)
return LLFirLibrarySession(project, builtinsSession.builtinTypes).apply session@{ return LLFirLibrarySession(ktLibraryModule, project, builtinsSession.builtinTypes).apply session@{
val moduleData = LLFirKtModuleBasedModuleData(ktLibraryModule).apply { bindSession(this@session) } val moduleData = LLFirKtModuleBasedModuleData(ktLibraryModule).apply { bindSession(this@session) }
registerModuleData(moduleData) registerModuleData(moduleData)
registerIdeComponents(project) registerIdeComponents(project)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -82,6 +83,11 @@ internal class LLFirDependentModuleProviders(
private val providers: List<FirSymbolProvider> private val providers: List<FirSymbolProvider>
) : FirDependenciesSymbolProvider(session) { ) : FirDependenciesSymbolProvider(session) {
val dependenciesAsSessions: List<LLFirSession>
get() = buildList {
providers.mapTo(this) { it.session as LLFirSession }
}
constructor(session: FirSession, createSubProviders: MutableList<FirSymbolProvider>.() -> Unit) constructor(session: FirSession, createSubProviders: MutableList<FirSymbolProvider>.() -> Unit)
: this(session, buildList { createSubProviders() }) : this(session, buildList { createSubProviders() })
@@ -6,11 +6,13 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.PrivateSessionConstructor import org.jetbrains.kotlin.fir.PrivateSessionConstructor
@OptIn(PrivateSessionConstructor::class) @OptIn(PrivateSessionConstructor::class)
class LLFirBuiltinsAndCloneableSession @PrivateSessionConstructor constructor( class LLFirBuiltinsAndCloneableSession @PrivateSessionConstructor constructor(
override val ktModule: KtModule,
project: Project, project: Project,
builtinTypes: BuiltinTypes, builtinTypes: BuiltinTypes,
) : LLFirLibraryLikeSession(project, builtinTypes) ) : LLFirLibraryLikeSession(project, builtinTypes)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.PrivateSessionConstructor import org.jetbrains.kotlin.fir.PrivateSessionConstructor
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor
*/ */
@OptIn(PrivateSessionConstructor::class) @OptIn(PrivateSessionConstructor::class)
internal class LLFirLibrarySession @PrivateSessionConstructor constructor( internal class LLFirLibrarySession @PrivateSessionConstructor constructor(
override val ktModule: KtModule,
project: Project, project: Project,
builtinTypes: BuiltinTypes, builtinTypes: BuiltinTypes,
) : LLFirLibraryLikeSession(project, builtinTypes) ) : LLFirLibraryLikeSession(project, builtinTypes)
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
@@ -14,13 +13,13 @@ import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.BuiltinTypes
internal class LLFirLibraryOrLibrarySourceResolvableModuleSession( internal class LLFirLibraryOrLibrarySourceResolvableModuleSession(
override val module: KtModule, override val ktModule: KtModule,
override val project: Project, override val project: Project,
override val moduleComponents: LLFirModuleResolveComponents, override val moduleComponents: LLFirModuleResolveComponents,
builtinTypes: BuiltinTypes, builtinTypes: BuiltinTypes,
) : LLFirResolvableModuleSession(builtinTypes) { ) : LLFirResolvableModuleSession(builtinTypes) {
init { init {
checkIsValidKtModule(module) checkIsValidKtModule(ktModule)
} }
companion object { companion object {
@@ -6,10 +6,8 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firModuleData
import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.PrivateSessionConstructor import org.jetbrains.kotlin.fir.PrivateSessionConstructor
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
@@ -19,14 +17,12 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@OptIn(PrivateSessionConstructor::class) @OptIn(PrivateSessionConstructor::class)
abstract class LLFirSession(override val builtinTypes: BuiltinTypes, kind: Kind) : FirSession(sessionProvider = null, kind) { abstract class LLFirSession(override val builtinTypes: BuiltinTypes, kind: Kind) : FirSession(sessionProvider = null, kind) {
abstract val project: Project abstract val project: Project
abstract val ktModule: KtModule
abstract fun getScopeSession(): ScopeSession abstract fun getScopeSession(): ScopeSession
} }
@OptIn(PrivateSessionConstructor::class) abstract class LLFirModuleSession(builtinTypes: BuiltinTypes, kind: Kind) : LLFirSession(builtinTypes, kind)
abstract class LLFirModuleSession(builtinTypes: BuiltinTypes, kind: Kind) : LLFirSession(builtinTypes, kind) {
abstract val module: KtModule
}
val FirDeclaration.llFirSession: LLFirSession val FirDeclaration.llFirSession: LLFirSession
get() = moduleData.session as LLFirSession get() = moduleData.session as LLFirSession
@@ -9,28 +9,37 @@ import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.Immutable import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.Immutable
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirKtModuleBasedModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirKtModuleBasedModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirDependentModuleProviders
import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSessionProvider import org.jetbrains.kotlin.fir.FirSessionProvider
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
@Immutable @Immutable
class LLFirSessionProvider internal constructor( class LLFirSessionProvider internal constructor(
val project: Project, val project: Project,
internal val rootModuleSession: LLFirResolvableModuleSession, internal val rootModuleSession: LLFirResolvableModuleSession,
private val moduleToSession: Map<KtModule, LLFirResolvableModuleSession> private val moduleToResolvableSession: Map<KtModule, LLFirResolvableModuleSession>
) : FirSessionProvider() { ) : FirSessionProvider() {
private val moduleToSession = moduleToResolvableSession + moduleToResolvableSession.values.flatMap { module ->
(module.dependenciesSymbolProvider as LLFirDependentModuleProviders).dependenciesAsSessions
}.associateBy { it.ktModule }
override fun getSession(moduleData: FirModuleData): LLFirSession { override fun getSession(moduleData: FirModuleData): LLFirSession {
requireIsInstance<LLFirModuleData>(moduleData) requireIsInstance<LLFirModuleData>(moduleData)
return when (moduleData) { return when (moduleData) {
is LLFirKtModuleBasedModuleData -> getSession(moduleData.ktModule) is LLFirKtModuleBasedModuleData -> getResolvableSession(moduleData.ktModule)
} }
} }
fun getSession(module: KtModule): LLFirResolvableModuleSession = fun getSession(module: KtModule): LLFirSession =
moduleToSession.getValue(module) moduleToSession.getValue(module)
fun getResolvableSession(module: KtModule): LLFirResolvableModuleSession =
moduleToResolvableSession.getValue(module)
val allSessions: Collection<LLFirModuleSession> val allSessions: Collection<LLFirModuleSession>
get() = moduleToSession.values get() = moduleToResolvableSession.values
} }
@@ -94,7 +94,7 @@ private class FromModuleViewSessionCache {
val wasSessionInvalidated = sessions.associateWithTo(hashMapOf()) { false } val wasSessionInvalidated = sessions.associateWithTo(hashMapOf()) { false }
val reversedDependencies = sessions.reversedDependencies { session -> val reversedDependencies = sessions.reversedDependencies { session ->
session.firSession.module.directRegularDependencies.mapNotNull { mappings[it] } session.firSession.ktModule.directRegularDependencies.mapNotNull { mappings[it] }
} }
fun markAsInvalidWithDfs(session: FirSessionWithModificationTracker) { fun markAsInvalidWithDfs(session: FirSessionWithModificationTracker) {
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.PrivateSessionConstructor import org.jetbrains.kotlin.fir.PrivateSessionConstructor
internal class LLFirSourcesSession @PrivateSessionConstructor constructor( internal class LLFirSourcesSession @PrivateSessionConstructor constructor(
override val module: KtSourceModule, override val ktModule: KtSourceModule,
override val project: Project, override val project: Project,
override val moduleComponents: LLFirModuleResolveComponents, override val moduleComponents: LLFirModuleResolveComponents,
builtinTypes: BuiltinTypes, builtinTypes: BuiltinTypes,
@@ -11,9 +11,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.*
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibrarySession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCompiledElementSearcher import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCompiledElementSearcher
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
@@ -42,7 +41,7 @@ internal abstract class LLFirResolvableResolveSession(
final override val useSiteFirSession = sessionProvider.rootModuleSession final override val useSiteFirSession = sessionProvider.rootModuleSession
override fun getSessionFor(module: KtModule): FirSession = override fun getSessionFor(module: KtModule): FirSession =
sessionProvider.getSession(module) sessionProvider.getResolvableSession(module)
override fun getScopeSessionFor(firSession: FirSession): ScopeSession { override fun getScopeSessionFor(firSession: FirSession): ScopeSession {
requireIsInstance<LLFirSession>(firSession) requireIsInstance<LLFirSession>(firSession)
@@ -61,7 +60,7 @@ internal abstract class LLFirResolvableResolveSession(
protected fun getModuleComponentsForElement(element: KtElement): LLFirModuleResolveComponents { protected fun getModuleComponentsForElement(element: KtElement): LLFirModuleResolveComponents {
val ktModule = element.getKtModule() val ktModule = element.getKtModule()
return sessionProvider.getSession(ktModule).moduleComponents return sessionProvider.getResolvableSession(ktModule).moduleComponents
} }
override fun resolveToFirSymbol( override fun resolveToFirSymbol(
@@ -80,7 +79,9 @@ internal abstract class LLFirResolvableResolveSession(
"This method will only work on compiled declarations, but this declaration is not compiled: ${ktDeclaration.getElementTextInContext()}" "This method will only work on compiled declarations, but this declaration is not compiled: ${ktDeclaration.getElementTextInContext()}"
} }
val searcher = FirDeclarationForCompiledElementSearcher(useSiteFirSession.symbolProvider) val ktModule = ktDeclaration.getKtModule(project)
val firSession = sessionProvider.getSession(ktModule) as LLFirLibrarySession
val searcher = FirDeclarationForCompiledElementSearcher(firSession.symbolProvider)
val firDeclaration = searcher.findNonLocalDeclaration(ktDeclaration) val firDeclaration = searcher.findNonLocalDeclaration(ktDeclaration)
return firDeclaration.symbol return firDeclaration.symbol
} }
@@ -100,7 +101,7 @@ internal abstract class LLFirResolvableResolveSession(
?: error("Declaration should have non-local container${ktDeclaration.getElementTextInContext()}") ?: error("Declaration should have non-local container${ktDeclaration.getElementTextInContext()}")
if (ktDeclaration == nonLocalNamedDeclaration) { if (ktDeclaration == nonLocalNamedDeclaration) {
val session = sessionProvider.getSession(module) val session = sessionProvider.getResolvableSession(module)
return nonLocalNamedDeclaration.findSourceNonLocalFirDeclaration( return nonLocalNamedDeclaration.findSourceNonLocalFirDeclaration(
firFileBuilder = session.moduleComponents.firFileBuilder, firFileBuilder = session.moduleComponents.firFileBuilder,
provider = session.firProvider, provider = session.firProvider,