FIR IDE: do not resolve symbols by transitive module dependencies
This commit is contained in:
+2
-2
@@ -43,7 +43,7 @@ fun FirSession.registerCommonComponents() {
|
||||
* Resolve components which are same on all platforms
|
||||
*/
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun FirModuleBasedSession.registerResolveComponents() {
|
||||
fun FirSession.registerResolveComponents() {
|
||||
register(FirQualifierResolver::class, FirQualifierResolverImpl(this))
|
||||
register(FirTypeResolver::class, FirTypeResolverImpl(this))
|
||||
register(CheckersComponent::class, CheckersComponent())
|
||||
@@ -53,7 +53,7 @@ fun FirModuleBasedSession.registerResolveComponents() {
|
||||
* Resolve components which have specific implementations on JVM
|
||||
*/
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun FirModuleBasedSession.registerJavaSpecificResolveComponents() {
|
||||
fun FirSession.registerJavaSpecificResolveComponents() {
|
||||
register(FirVisibilityChecker::class, FirJavaVisibilityChecker)
|
||||
register(ConeCallConflictResolverFactory::class, JvmCallConflictResolverFactory)
|
||||
register(FirEffectiveVisibilityResolver::class, FirJvmEffectiveVisibilityResolver(this))
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
|
||||
object FirSessionFactory {
|
||||
class FirSessionConfigurator(private val session: FirModuleBasedSession) {
|
||||
class FirSessionConfigurator(private val session: FirSession) {
|
||||
private val registeredExtensions = mutableListOf<BunchOfRegisteredExtensions>(BunchOfRegisteredExtensions.empty())
|
||||
|
||||
fun registerExtensions(extensions: BunchOfRegisteredExtensions) {
|
||||
|
||||
@@ -30,7 +30,7 @@ abstract class FirSession @PrivateSessionConstructor constructor(val sessionProv
|
||||
|
||||
open val moduleInfo: ModuleInfo? get() = null
|
||||
|
||||
val builtinTypes: BuiltinTypes = BuiltinTypes()
|
||||
open val builtinTypes: BuiltinTypes = BuiltinTypes()
|
||||
|
||||
final override val typeRegistry: TypeRegistry<FirSessionComponent, FirSessionComponent> = Companion
|
||||
|
||||
|
||||
+11
-58
@@ -11,87 +11,40 @@ import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.psi.util.CachedValue
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.LibraryModificationTracker
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener
|
||||
import org.jetbrains.kotlin.idea.caches.trackers.KotlinModuleOutOfCodeBlockModificationTracker
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeDependentModulesSourcesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeLibrariesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionFactory
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProviderStorage
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession
|
||||
import org.jetbrains.kotlin.idea.util.cachedValue
|
||||
import org.jetbrains.kotlin.idea.util.getValue
|
||||
import org.jetbrains.kotlin.idea.util.psiModificationTrackerBasedCachedValue
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
internal class FirIdeResolveStateService(private val project: Project) {
|
||||
internal class FirIdeResolveStateService(project: Project) {
|
||||
private val sessionProviderStorage = FirIdeSessionProviderStorage(project)
|
||||
|
||||
private val stateCache by cachedValue(project, KotlinCodeBlockModificationListener.getInstance(project).kotlinOutOfCodeBlockTracker) {
|
||||
ConcurrentHashMap<IdeaModuleInfo, FirModuleResolveStateImpl>()
|
||||
}
|
||||
|
||||
private val moduleLibraryDependencyStateCache = ConcurrentHashMap<IdeaModuleInfo, CachedValue<FirIdeDependentModulesSourcesSession>>()
|
||||
|
||||
private val librarySessionCache by cachedValue(project, LibraryModificationTracker.getInstance(project)) {
|
||||
ConcurrentHashMap<IdeaModuleInfo, FirIdeLibrariesSession>()
|
||||
}
|
||||
|
||||
private fun createResolveStateFor(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl {
|
||||
require(moduleInfo is ModuleSourceInfo)
|
||||
val firPhaseRunner = FirPhaseRunner()
|
||||
val sessionProvider = FirIdeSessionProvider(project)
|
||||
|
||||
val librariesSession = librarySessionCache.computeIfAbsent(moduleInfo) {
|
||||
FirIdeSessionFactory.createLibrarySession(moduleInfo, sessionProvider, project)
|
||||
}
|
||||
|
||||
val dependentModulesSession = moduleLibraryDependencyStateCache.compute(moduleInfo) { _, cachedIdeaModuleInfo ->
|
||||
if (cachedIdeaModuleInfo?.hasUpToDateValue() == true) cachedIdeaModuleInfo
|
||||
else {
|
||||
CachedValuesManager.getManager(project).createCachedValue {
|
||||
val dependentSession = FirIdeSessionFactory.createDependentModulesSourcesSession(
|
||||
project,
|
||||
moduleInfo,
|
||||
firPhaseRunner,
|
||||
sessionProvider,
|
||||
librariesSession,
|
||||
)
|
||||
CachedValueProvider.Result.create(
|
||||
dependentSession,
|
||||
dependentSession.dependentModules.map { it.createModificationTracker() }
|
||||
.takeUnless { it.isEmpty() }
|
||||
?: listOf(ModificationTracker.NEVER_CHANGED)
|
||||
)
|
||||
}
|
||||
}
|
||||
}?.value ?: error("ModuleLibraryDependencyStateCache should be computed")
|
||||
|
||||
|
||||
val currentModuleSession = FirIdeSessionFactory.createCurrentModuleSourcesSession(
|
||||
project,
|
||||
moduleInfo,
|
||||
firPhaseRunner,
|
||||
dependentModulesSession,
|
||||
sessionProvider,
|
||||
)
|
||||
|
||||
sessionProvider.init(currentModuleSession, dependentModulesSession, librariesSession)
|
||||
|
||||
val sessionProvider = sessionProviderStorage.getSessionProvider(moduleInfo)
|
||||
val firFileBuilder = sessionProvider.rootModuleSession.firFileBuilder
|
||||
return FirModuleResolveStateImpl(
|
||||
moduleInfo,
|
||||
currentModuleSession,
|
||||
dependentModulesSession,
|
||||
librariesSession,
|
||||
sessionProvider,
|
||||
currentModuleSession.firFileBuilder,
|
||||
FirLazyDeclarationResolver(currentModuleSession.firFileBuilder),
|
||||
firFileBuilder,
|
||||
FirLazyDeclarationResolver(firFileBuilder),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl =
|
||||
stateCache.getOrPut(moduleInfo) { createResolveStateFor(moduleInfo) }
|
||||
stateCache.computeIfAbsent(moduleInfo) { createResolveStateFor(moduleInfo) }
|
||||
|
||||
companion object {
|
||||
fun getInstance(project: Project): FirIdeResolveStateService = project.service()
|
||||
|
||||
+10
-15
@@ -20,10 +20,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataC
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureCache
|
||||
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.sessions.FirIdeCurrentModuleSourcesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeDependentModulesSourcesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeLibrariesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
@@ -31,9 +27,9 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
abstract class FirModuleResolveState {
|
||||
abstract val moduleInfo: IdeaModuleInfo
|
||||
abstract val currentModuleSourcesSession: FirSession
|
||||
abstract val dependentModulesSourcesSession: FirSession
|
||||
abstract val librariesSession: FirSession
|
||||
abstract val rootModuleSession: FirSession
|
||||
|
||||
abstract val firTransformerProvider: FirTransformerProvider
|
||||
|
||||
abstract fun getSessionFor(moduleInfo: IdeaModuleInfo): FirSession
|
||||
|
||||
@@ -62,25 +58,24 @@ abstract class FirModuleResolveState {
|
||||
|
||||
internal class FirModuleResolveStateImpl(
|
||||
override val moduleInfo: IdeaModuleInfo,
|
||||
override val currentModuleSourcesSession: FirIdeCurrentModuleSourcesSession,
|
||||
override val dependentModulesSourcesSession: FirIdeDependentModulesSourcesSession,
|
||||
override val librariesSession: FirIdeLibrariesSession,
|
||||
private val sessionProvider: FirIdeSessionProvider,
|
||||
val firFileBuilder: FirFileBuilder,
|
||||
val firLazyDeclarationResolver: FirLazyDeclarationResolver,
|
||||
) : FirModuleResolveState() {
|
||||
override val rootModuleSession: FirIdeSourcesSession get() = sessionProvider.rootModuleSession
|
||||
override val firTransformerProvider: FirTransformerProvider get() = firFileBuilder.firPhaseRunner.transformerProvider
|
||||
val fileStructureCache = FileStructureCache(firFileBuilder, firLazyDeclarationResolver)
|
||||
val elementBuilder = FirElementBuilder()
|
||||
private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, currentModuleSourcesSession.cache)
|
||||
private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, rootModuleSession.cache)
|
||||
|
||||
override fun getSessionFor(moduleInfo: IdeaModuleInfo): FirSession =
|
||||
sessionProvider.getSession(moduleInfo)
|
||||
sessionProvider.getSession(moduleInfo)!!
|
||||
|
||||
override fun getOrBuildFirFor(element: KtElement, toPhase: FirResolvePhase): FirElement =
|
||||
elementBuilder.getOrBuildFirFor(element, currentModuleSourcesSession.cache, fileStructureCache)
|
||||
elementBuilder.getOrBuildFirFor(element, rootModuleSession.cache, fileStructureCache)
|
||||
|
||||
override fun getFirFile(ktFile: KtFile): FirFile =
|
||||
firFileBuilder.buildRawFirFileWithCaching(ktFile, currentModuleSourcesSession.cache)
|
||||
firFileBuilder.buildRawFirFileWithCaching(ktFile, rootModuleSession.cache)
|
||||
|
||||
override fun getDiagnostics(element: KtElement): List<Diagnostic> =
|
||||
diagnosticsCollector.getDiagnosticsFor(element)
|
||||
@@ -107,7 +102,7 @@ internal class FirModuleResolveStateImpl(
|
||||
) {
|
||||
firLazyDeclarationResolver.runLazyResolveWithoutLock(
|
||||
firFunction,
|
||||
currentModuleSourcesSession.cache,
|
||||
rootModuleSession.cache,
|
||||
containerFirFile,
|
||||
firIdeProvider,
|
||||
fromPhase = firFunction.resolvePhase,
|
||||
|
||||
+3
-10
@@ -14,12 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureCache
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FirElementsRecorder
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeCurrentModuleSourcesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeDependentModulesSourcesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeLibrariesSession
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
@@ -27,10 +22,8 @@ internal class FirModuleResolveStateForCompletion(
|
||||
private val originalState: FirModuleResolveStateImpl
|
||||
) : FirModuleResolveState() {
|
||||
override val moduleInfo: IdeaModuleInfo get() = originalState.moduleInfo
|
||||
override val currentModuleSourcesSession: FirIdeCurrentModuleSourcesSession get() = originalState.currentModuleSourcesSession
|
||||
override val dependentModulesSourcesSession: FirIdeDependentModulesSourcesSession get() = originalState.dependentModulesSourcesSession
|
||||
override val librariesSession: FirIdeLibrariesSession get() = originalState.librariesSession
|
||||
|
||||
override val rootModuleSession get() = originalState.rootModuleSession
|
||||
override val firTransformerProvider: FirTransformerProvider get() = originalState.firTransformerProvider
|
||||
private val fileStructureCache = originalState.fileStructureCache
|
||||
|
||||
private val completionMapping = mutableMapOf<KtElement, FirElement>()
|
||||
@@ -42,7 +35,7 @@ internal class FirModuleResolveStateForCompletion(
|
||||
completionMapping[element]?.let { return it }
|
||||
return originalState.elementBuilder.getOrBuildFirFor(
|
||||
element,
|
||||
originalState.currentModuleSourcesSession.cache,
|
||||
originalState.rootModuleSession.cache,
|
||||
fileStructureCache,
|
||||
)
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
internal class FirPhaseRunner {
|
||||
internal class FirPhaseRunner(val transformerProvider: FirTransformerProvider) {
|
||||
private val superTypesBodyResolveLock = ReentrantLock()
|
||||
private val implicitTypesResolveLock = ReentrantLock()
|
||||
|
||||
@@ -28,7 +28,7 @@ internal class FirPhaseRunner {
|
||||
}
|
||||
|
||||
private fun runPhaseWithoutLock(firFile: FirFile, phase: FirResolvePhase) {
|
||||
val phaseProcessor = firFile.session.firTransformerProvider.getTransformerForPhase(phase)
|
||||
val phaseProcessor = transformerProvider.getTransformerForPhase(firFile.session, phase)
|
||||
executeWithoutPCE { phaseProcessor.processFile(firFile) }
|
||||
}
|
||||
}
|
||||
+17
-16
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api
|
||||
|
||||
import com.google.common.collect.MapMaker
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
@@ -13,23 +14,23 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveP
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.createTransformerBasedProcessorByPhase
|
||||
import java.util.*
|
||||
|
||||
class FirTransformerProvider(session: FirSession) : FirSessionComponent {
|
||||
private val scopeSession = ThreadLocal.withInitial { ScopeSession() }
|
||||
private val transformers = ThreadLocal.withInitial {
|
||||
val scopesSession = scopeSession.get()
|
||||
EnumMap<FirResolvePhase, FirTransformerBasedResolveProcessor>(FirResolvePhase::class.java).apply {
|
||||
FirResolvePhase.values().forEach { resolvePhase ->
|
||||
if (resolvePhase != FirResolvePhase.RAW_FIR) {
|
||||
put(resolvePhase, resolvePhase.createTransformerBasedProcessorByPhase(session, scopesSession))
|
||||
class FirTransformerProvider {
|
||||
private val scopeSession = MapMaker().weakKeys().makeMap<FirSession, ScopeSession>()
|
||||
private val transformers = MapMaker().weakKeys().makeMap<FirSession, EnumMap<FirResolvePhase, FirTransformerBasedResolveProcessor>>()
|
||||
|
||||
|
||||
fun getTransformerForPhase(session: FirSession, phase: FirResolvePhase): FirTransformerBasedResolveProcessor =
|
||||
transformers.computeIfAbsent(session) {
|
||||
val scopesSession = getScopeSession(session)
|
||||
EnumMap<FirResolvePhase, FirTransformerBasedResolveProcessor>(FirResolvePhase::class.java).apply {
|
||||
FirResolvePhase.values().forEach { resolvePhase ->
|
||||
if (resolvePhase != FirResolvePhase.RAW_FIR) {
|
||||
put(resolvePhase, resolvePhase.createTransformerBasedProcessorByPhase(session, scopesSession))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.getValue(phase)
|
||||
|
||||
fun getTransformerForPhase(phase: FirResolvePhase): FirTransformerBasedResolveProcessor =
|
||||
transformers.get().getValue(phase)
|
||||
|
||||
fun getScopeSession(): ScopeSession = scopeSession.get()
|
||||
fun getScopeSession(session: FirSession): ScopeSession =
|
||||
scopeSession.getOrPut(session) { ScopeSession() }
|
||||
}
|
||||
|
||||
val FirSession.firTransformerProvider: FirTransformerProvider by FirSession.sessionComponentAccessor()
|
||||
|
||||
+3
-3
@@ -114,7 +114,7 @@ object LowLevelFirApiFacade {
|
||||
symbol = builtFunction.symbol as FirNamedFunctionSymbol
|
||||
resolvePhase = minOf(originalFunction.resolvePhase, FirResolvePhase.DECLARATIONS)
|
||||
source = builtFunction.source
|
||||
session = state.currentModuleSourcesSession
|
||||
session = state.rootModuleSession
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ object LowLevelFirApiFacade {
|
||||
symbol = builtSetter.symbol
|
||||
resolvePhase = minOf(builtSetter.resolvePhase, FirResolvePhase.DECLARATIONS)
|
||||
source = builtSetter.source
|
||||
session = state.currentModuleSourcesSession
|
||||
session = state.rootModuleSession
|
||||
}
|
||||
} else {
|
||||
builtSetter
|
||||
@@ -151,7 +151,7 @@ object LowLevelFirApiFacade {
|
||||
|
||||
resolvePhase = minOf(originalProperty.resolvePhase, FirResolvePhase.DECLARATIONS)
|
||||
source = builtProperty.source
|
||||
session = state.currentModuleSourcesSession
|
||||
session = state.rootModuleSession
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -9,4 +9,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.annotations
|
||||
annotation class ThreadSafe
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class NotThreadSafe
|
||||
annotation class NotThreadSafe
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class Immutable
|
||||
+3
-3
@@ -21,12 +21,12 @@ internal class FirDesignatedBodyResolveTransformerForIDE(
|
||||
private val designation: Iterator<FirElement>,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
implicitTypeOnly: Boolean,
|
||||
phase: FirResolvePhase,
|
||||
private val towerDataContextCollector: FirTowerDataContextCollector? = null
|
||||
) : FirBodyResolveTransformer(
|
||||
session,
|
||||
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
|
||||
implicitTypeOnly = implicitTypeOnly,
|
||||
phase = phase,
|
||||
implicitTypeOnly = phase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
|
||||
scopeSession = scopeSession,
|
||||
returnTypeCalculator = createReturnTypeCalculatorForIDE(session, scopeSession)
|
||||
) {
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.util.lockWithPCECheck
|
||||
@ThreadSafe
|
||||
internal class FirFileBuilder(
|
||||
private val scopeProvider: FirScopeProvider,
|
||||
private val firPhaseRunner: FirPhaseRunner
|
||||
val firPhaseRunner: FirPhaseRunner
|
||||
) {
|
||||
/**
|
||||
* Builds a [FirFile] by given [ktFile] and records it's parenting info if it not present in [cache]
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ internal class FileStructure(
|
||||
val firFile = firFileBuilder.getFirFileResolvedToPhaseWithCaching(
|
||||
container,
|
||||
moduleFileCache,
|
||||
FirResolvePhase.BODY_RESOLVE,
|
||||
FirResolvePhase.IMPORTS,
|
||||
checkPCE = true
|
||||
)
|
||||
FileWithoutDeclarationsFileStructureElement(
|
||||
|
||||
+1
-2
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirDesignated
|
||||
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.ModuleFileCache
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.firTransformerProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
|
||||
@@ -128,7 +127,7 @@ internal class FirLazyDeclarationResolver(
|
||||
if (designation.all { it.resolvePhase >= toPhase }) {
|
||||
return
|
||||
}
|
||||
val scopeSession = containerFirFile.session.firTransformerProvider.getScopeSession()
|
||||
val scopeSession = firFileBuilder.firPhaseRunner.transformerProvider.getScopeSession(containerFirFile.session)
|
||||
val transformer = FirDesignatedBodyResolveTransformerForIDE(
|
||||
designation.iterator(), containerFirFile.session,
|
||||
scopeSession,
|
||||
|
||||
+3
-4
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.ThreadSafeMutableState
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProviderInternals
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
@@ -24,6 +25,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceCheckerForMultipleModules
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceCheckerForSingleModule
|
||||
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.util.collectTransitiveDependenciesWithSelf
|
||||
@@ -46,10 +48,7 @@ internal class FirIdeProvider(
|
||||
override val symbolProvider: FirSymbolProvider = SymbolProvider()
|
||||
|
||||
private val indexHelper = IndexHelper(project, searchScope)
|
||||
private val packageExistenceChecker = PackageExistenceCheckerForMultipleModules(
|
||||
project,
|
||||
moduleInfo.collectTransitiveDependenciesWithSelf().filterIsInstance<ModuleSourceInfo>()
|
||||
)
|
||||
private val packageExistenceChecker = PackageExistenceCheckerForSingleModule(project, moduleInfo)
|
||||
|
||||
private val providerHelper = FirProviderHelper(
|
||||
cache,
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.providers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
internal class FirModuleWithDependenciesSymbolProvider(
|
||||
session: FirSession,
|
||||
private val providers: List<FirSymbolProvider>,
|
||||
private val dependentProviders: List<FirSymbolProvider>,
|
||||
) : FirSymbolProvider(session) {
|
||||
|
||||
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||
providers.firstNotNullResult { it.getClassLikeSymbolByFqName(classId) }
|
||||
?: withDependent(default = null) {
|
||||
dependentProviders.firstNotNullResult { it.getClassLikeSymbolByFqName(classId) }
|
||||
}
|
||||
|
||||
@FirSymbolProviderInternals
|
||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||
providers.flatMapTo(destination) { it.getTopLevelCallableSymbols(packageFqName, name) }
|
||||
withDependent {
|
||||
dependentProviders.flatMapTo(destination) { it.getTopLevelCallableSymbols(packageFqName, name) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? =
|
||||
providers.firstNotNullResult { it.getPackage(fqName) }
|
||||
?: withDependent(default = null) {
|
||||
dependentProviders.firstNotNullResult { it.getPackage(fqName) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val canUseDependent = ThreadLocal.withInitial { true }
|
||||
|
||||
private inline fun <R> withDependent(default: R, action: () -> R): R {
|
||||
if (canUseDependent.get()) {
|
||||
canUseDependent.set(false)
|
||||
try {
|
||||
return action()
|
||||
} finally {
|
||||
canUseDependent.set(true)
|
||||
}
|
||||
}
|
||||
return default
|
||||
}
|
||||
|
||||
private inline fun withDependent(action: () -> Unit) {
|
||||
withDependent(Unit, action)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,13 +7,13 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.public
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeModuleSession
|
||||
|
||||
/**
|
||||
* Returns a [GlobalSearchScope] declarations from which [FirSession] knows about
|
||||
*/
|
||||
val FirSession.searchScope: GlobalSearchScope
|
||||
get() {
|
||||
check(this is FirIdeSession)
|
||||
check(this is FirIdeModuleSession)
|
||||
return scope
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
class FirIdeBuiltinsAndCloneableSession @PrivateSessionConstructor constructor(
|
||||
override val project: Project,
|
||||
builtinTypes: BuiltinTypes,
|
||||
) : FirIdeSession(builtinTypes)
|
||||
+6
-3
@@ -5,8 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
|
||||
/**
|
||||
@@ -15,6 +17,7 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
internal class FirIdeLibrariesSession @PrivateSessionConstructor constructor(
|
||||
moduleInfo: ModuleInfo,
|
||||
sessionProvider: FirIdeSessionProvider,
|
||||
override val scope: GlobalSearchScope
|
||||
) : FirIdeSession(moduleInfo, sessionProvider)
|
||||
override val project: Project,
|
||||
override val scope: GlobalSearchScope,
|
||||
builtinTypes: BuiltinTypes,
|
||||
) : FirIdeModuleSession(moduleInfo, builtinTypes)
|
||||
|
||||
+9
-4
@@ -5,15 +5,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.FirModuleBasedSession
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
internal abstract class FirIdeSession(
|
||||
moduleInfo: ModuleInfo,
|
||||
sessionProvider: FirIdeSessionProvider
|
||||
) : FirModuleBasedSession(moduleInfo, sessionProvider) {
|
||||
abstract class FirIdeSession(override val builtinTypes: BuiltinTypes) : FirSession(sessionProvider = null) {
|
||||
abstract val project: Project
|
||||
}
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
abstract class FirIdeModuleSession(override val moduleInfo: ModuleInfo, builtinTypes: BuiltinTypes) : FirIdeSession(builtinTypes) {
|
||||
abstract val scope: GlobalSearchScope
|
||||
}
|
||||
|
||||
+102
-110
@@ -5,12 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
|
||||
|
||||
import com.intellij.openapi.module.impl.scopes.ModuleWithDependentsScope
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
|
||||
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
@@ -29,133 +29,106 @@ import org.jetbrains.kotlin.fir.session.registerResolveComponents
|
||||
import org.jetbrains.kotlin.idea.caches.project.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.IDEPackagePartProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.FirTransformerProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IdeFirPhaseManager
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IdeSessionComponents
|
||||
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.ModuleFileCacheImpl
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirModuleWithDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.collectTransitiveDependenciesWithSelf
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.ModuleLibrariesSearchScope
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
|
||||
internal object FirIdeSessionFactory {
|
||||
fun createCurrentModuleSourcesSession(
|
||||
fun createSourcesSession(
|
||||
project: Project,
|
||||
moduleInfo: ModuleSourceInfo,
|
||||
builtinsAndCloneableSession: FirIdeBuiltinsAndCloneableSession,
|
||||
firPhaseRunner: FirPhaseRunner,
|
||||
dependentModulesSourcesSession: FirIdeDependentModulesSourcesSession,
|
||||
sessionProvider: FirIdeSessionProvider,
|
||||
): FirIdeCurrentModuleSourcesSession {
|
||||
builtinTypes: BuiltinTypes,
|
||||
sessionsCache: MutableMap<ModuleSourceInfo, FirIdeSourcesSession>,
|
||||
isRootModule: Boolean,
|
||||
): FirIdeSourcesSession {
|
||||
sessionsCache[moduleInfo]?.let { return it }
|
||||
val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner)
|
||||
val searchScope = ModuleProductionSourceScope(moduleInfo.module)
|
||||
return FirIdeCurrentModuleSourcesSession(moduleInfo, sessionProvider, searchScope, firBuilder).apply {
|
||||
val session = FirIdeSourcesSession(moduleInfo, project, searchScope, firBuilder, builtinTypes)
|
||||
sessionsCache[moduleInfo] = session
|
||||
val dependentModules = moduleInfo.dependenciesWithoutSelf()
|
||||
.filterIsInstanceTo<ModuleSourceInfo, MutableList<ModuleSourceInfo>>(mutableListOf())
|
||||
|
||||
return session.apply {
|
||||
val cache = ModuleFileCacheImpl(this)
|
||||
registerCommonSourceSessionComponents(
|
||||
val firPhaseManager = IdeFirPhaseManager(FirLazyDeclarationResolver(firFileBuilder), cache)
|
||||
|
||||
registerCommonComponents()
|
||||
registerResolveComponents()
|
||||
registerIdeComponents()
|
||||
|
||||
val provider = FirIdeProvider(
|
||||
project,
|
||||
this,
|
||||
moduleInfo,
|
||||
scopeProvider,
|
||||
searchScope,
|
||||
firFileBuilder,
|
||||
cache,
|
||||
additionalSymbolProviders = listOf(
|
||||
dependentModulesSourcesSession.firSymbolProvider,
|
||||
searchScope
|
||||
)
|
||||
|
||||
register(FirProvider::class, provider)
|
||||
register(FirIdeProvider::class, provider)
|
||||
|
||||
register(FirPhaseManager::class, firPhaseManager)
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
register(
|
||||
FirSymbolProvider::class,
|
||||
FirModuleWithDependenciesSymbolProvider(
|
||||
this,
|
||||
providers = listOf(
|
||||
provider.symbolProvider,
|
||||
JavaSymbolProvider(this@apply, project, searchScope),
|
||||
),
|
||||
dependentProviders = buildList {
|
||||
add(createLibrarySession(moduleInfo, project, builtinsAndCloneableSession, builtinTypes).firSymbolProvider)
|
||||
dependentModules
|
||||
.mapTo(this) {
|
||||
createSourcesSession(
|
||||
project,
|
||||
it,
|
||||
builtinsAndCloneableSession,
|
||||
firPhaseRunner,
|
||||
builtinTypes,
|
||||
sessionsCache,
|
||||
isRootModule = false
|
||||
).firSymbolProvider
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
registerJavaSpecificComponents()
|
||||
FirSessionFactory.FirSessionConfigurator(this).apply {
|
||||
registerCommonCheckers()
|
||||
if (isRootModule) {
|
||||
registerCommonCheckers()
|
||||
}
|
||||
}.configure()
|
||||
}
|
||||
}
|
||||
|
||||
fun createDependentModulesSourcesSession(
|
||||
project: Project,
|
||||
moduleInfo: ModuleSourceInfo,
|
||||
firPhaseRunner: FirPhaseRunner,
|
||||
sessionProvider: FirIdeSessionProvider,
|
||||
librariesSession: FirIdeLibrariesSession,
|
||||
): FirIdeDependentModulesSourcesSession {
|
||||
val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner)
|
||||
val dependentModules = moduleInfo.collectTransitiveDependenciesWithSelf()
|
||||
.filterIsInstance<ModuleSourceInfo>()
|
||||
.filterNot { it == moduleInfo }
|
||||
val searchScope = if (dependentModules.isNotEmpty()) GlobalSearchScope.union(dependentModules.map { it.contentScope() })
|
||||
else GlobalSearchScope.EMPTY_SCOPE
|
||||
return FirIdeDependentModulesSourcesSession(moduleInfo, dependentModules, sessionProvider, searchScope, firBuilder).apply {
|
||||
val cache = ModuleFileCacheImpl(this)
|
||||
registerCommonSourceSessionComponents(
|
||||
project,
|
||||
moduleInfo,
|
||||
scopeProvider,
|
||||
searchScope,
|
||||
cache,
|
||||
additionalSymbolProviders = listOf(librariesSession.firSymbolProvider)
|
||||
)
|
||||
FirSessionFactory.FirSessionConfigurator(this).configure()
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirIdeSourcesSession.registerCommonSourceSessionComponents(
|
||||
project: Project,
|
||||
moduleInfo: ModuleSourceInfo,
|
||||
scopeProvider: KotlinScopeProvider,
|
||||
searchScope: GlobalSearchScope,
|
||||
cache: ModuleFileCache,
|
||||
additionalSymbolProviders: List<FirSymbolProvider> = emptyList()
|
||||
) {
|
||||
val firPhaseManager = IdeFirPhaseManager(FirLazyDeclarationResolver(firFileBuilder), cache)
|
||||
|
||||
registerCommonComponents()
|
||||
registerResolveComponents()
|
||||
registerIdeComponents()
|
||||
|
||||
val provider = FirIdeProvider(
|
||||
project,
|
||||
this,
|
||||
moduleInfo,
|
||||
scopeProvider,
|
||||
firFileBuilder,
|
||||
cache,
|
||||
searchScope
|
||||
)
|
||||
|
||||
register(FirProvider::class, provider)
|
||||
register(FirIdeProvider::class, provider)
|
||||
|
||||
register(FirPhaseManager::class, firPhaseManager)
|
||||
|
||||
register(
|
||||
FirSymbolProvider::class,
|
||||
FirCompositeSymbolProvider(
|
||||
this,
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
buildList {
|
||||
add(provider.symbolProvider)
|
||||
add(JavaSymbolProvider(this@registerCommonSourceSessionComponents, project, searchScope))
|
||||
addAll(additionalSymbolProviders)
|
||||
}
|
||||
) as FirSymbolProvider
|
||||
)
|
||||
registerJavaSpecificComponents()
|
||||
}
|
||||
|
||||
private fun IdeaModuleInfo.librarySearchScope(): GlobalSearchScope? = when (this) {
|
||||
is LibraryInfo -> contentScope()
|
||||
is SdkInfo -> contentScope()
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun createLibrarySession(
|
||||
moduleInfo: ModuleSourceInfo,
|
||||
sessionProvider: FirIdeSessionProvider,
|
||||
project: Project,
|
||||
builtinsAndCloneableSession: FirIdeBuiltinsAndCloneableSession,
|
||||
builtinTypes: BuiltinTypes,
|
||||
): FirIdeLibrariesSession {
|
||||
val dependencies = moduleInfo.collectTransitiveDependenciesWithSelf()
|
||||
.mapNotNullTo(mutableListOf()) { it.librarySearchScope() }
|
||||
val searchScope = if (dependencies.isEmpty()) GlobalSearchScope.EMPTY_SCOPE else GlobalSearchScope.union(dependencies)
|
||||
checkCanceled()
|
||||
val searchScope = ModuleLibrariesSearchScope(moduleInfo.module)
|
||||
val javaClassFinder = JavaClassFinderImpl().apply {
|
||||
setProjectInstance(project)
|
||||
setScope(searchScope)
|
||||
@@ -163,32 +136,52 @@ internal object FirIdeSessionFactory {
|
||||
val packagePartProvider = IDEPackagePartProvider(searchScope)
|
||||
|
||||
val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope)
|
||||
return FirIdeLibrariesSession(moduleInfo, sessionProvider, searchScope).apply {
|
||||
return FirIdeLibrariesSession(moduleInfo, project, searchScope, builtinTypes).apply {
|
||||
registerCommonComponents()
|
||||
registerJavaSpecificComponents()
|
||||
registerIdeComponents()
|
||||
|
||||
val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, searchScope)
|
||||
val javaSymbolProvider = JavaSymbolProvider(this, project, searchScope)
|
||||
|
||||
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
register(
|
||||
FirSymbolProvider::class,
|
||||
FirCompositeSymbolProvider(
|
||||
this,
|
||||
buildList {
|
||||
add(
|
||||
KotlinDeserializedJvmSymbolsProvider(
|
||||
this@apply,
|
||||
project,
|
||||
packagePartProvider,
|
||||
javaSymbolProvider,
|
||||
kotlinClassFinder,
|
||||
javaClassFinder,
|
||||
kotlinScopeProvider
|
||||
)
|
||||
)
|
||||
add(javaSymbolProvider)
|
||||
addAll((builtinsAndCloneableSession.firSymbolProvider as FirCompositeSymbolProvider).providers)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun createBuiltinsAndCloneableSession(project: Project, builtinTypes: BuiltinTypes): FirIdeBuiltinsAndCloneableSession {
|
||||
return FirIdeBuiltinsAndCloneableSession(project, builtinTypes).apply {
|
||||
registerCommonComponents()
|
||||
|
||||
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
register(IdeSessionComponents::class, IdeSessionComponents.create(this))
|
||||
register(
|
||||
FirSymbolProvider::class,
|
||||
FirCompositeSymbolProvider(
|
||||
this,
|
||||
listOf(
|
||||
KotlinDeserializedJvmSymbolsProvider(
|
||||
this,
|
||||
project,
|
||||
packagePartProvider,
|
||||
javaSymbolProvider,
|
||||
kotlinClassFinder,
|
||||
javaClassFinder,
|
||||
kotlinScopeProvider
|
||||
),
|
||||
FirBuiltinSymbolProvider(this, kotlinScopeProvider),
|
||||
FirCloneableSymbolProvider(this, kotlinScopeProvider),
|
||||
javaSymbolProvider,
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -197,6 +190,5 @@ internal object FirIdeSessionFactory {
|
||||
|
||||
private fun FirIdeSession.registerIdeComponents() {
|
||||
register(IdeSessionComponents::class, IdeSessionComponents.create(this))
|
||||
register(FirTransformerProvider::class, FirTransformerProvider(this))
|
||||
}
|
||||
}
|
||||
+7
-30
@@ -12,38 +12,15 @@ import org.jetbrains.kotlin.fir.FirSessionProvider
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.isLibraryClasses
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.Immutable
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.ThreadSafe
|
||||
|
||||
@ThreadSafe
|
||||
internal class FirIdeSessionProvider(
|
||||
@Immutable
|
||||
class FirIdeSessionProvider internal constructor(
|
||||
override val project: Project,
|
||||
internal val rootModuleSession: FirIdeSourcesSession,
|
||||
val sessions: Map<ModuleSourceInfo, FirIdeSession>
|
||||
) : FirSessionProvider {
|
||||
private lateinit var currentModuleSourcesSession: FirIdeSourcesSession
|
||||
private lateinit var dependentModulesModuleSourcesSession: FirIdeSourcesSession
|
||||
private lateinit var librariesSession: FirIdeLibrariesSession
|
||||
|
||||
|
||||
fun init(
|
||||
currentModuleSourcesSession: FirIdeSourcesSession,
|
||||
dependentModulesModuleSourcesSession: FirIdeSourcesSession,
|
||||
librariesSession: FirIdeLibrariesSession,
|
||||
) {
|
||||
this.currentModuleSourcesSession = currentModuleSourcesSession
|
||||
this.dependentModulesModuleSourcesSession = dependentModulesModuleSourcesSession
|
||||
this.librariesSession = librariesSession
|
||||
}
|
||||
|
||||
|
||||
override fun getSession(moduleInfo: ModuleInfo): FirSession = when {
|
||||
moduleInfo is IdeaModuleInfo && moduleInfo.isLibraryClasses() -> {
|
||||
librariesSession /* TODO check if library is in libraries session scope */
|
||||
}
|
||||
moduleInfo == currentModuleSourcesSession.moduleInfo -> {
|
||||
currentModuleSourcesSession
|
||||
}
|
||||
moduleInfo is ModuleSourceInfo -> {
|
||||
currentModuleSourcesSession /* TODO check if source is in sources session scope */
|
||||
}
|
||||
else -> error("Invalid module info $moduleInfo")
|
||||
}
|
||||
override fun getSession(moduleInfo: ModuleInfo): FirSession? =
|
||||
sessions[moduleInfo]
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.FirTransformerProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
|
||||
|
||||
internal class FirIdeSessionProviderStorage(private val project: Project) {
|
||||
fun getSessionProvider(rootModule: ModuleSourceInfo): FirIdeSessionProvider {
|
||||
val transformerProvider = FirTransformerProvider()
|
||||
val firPhaseRunner = FirPhaseRunner(transformerProvider)
|
||||
val builtinTypes = BuiltinTypes()
|
||||
val builtinsAndCloneableSession = FirIdeSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes)
|
||||
val sessions = mutableMapOf<ModuleSourceInfo, FirIdeSourcesSession>()
|
||||
val session = executeWithoutPCE {
|
||||
FirIdeSessionFactory.createSourcesSession(
|
||||
project,
|
||||
rootModule,
|
||||
builtinsAndCloneableSession,
|
||||
firPhaseRunner,
|
||||
builtinTypes,
|
||||
sessions,
|
||||
isRootModule = true
|
||||
)
|
||||
}
|
||||
|
||||
return FirIdeSessionProvider(project, session, sessions)
|
||||
}
|
||||
}
|
||||
+6
-25
@@ -5,41 +5,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
|
||||
|
||||
/**
|
||||
* [org.jetbrains.kotlin.fir.FirSession] responsible for all Kotlin & Java source modules analysing module transitively depends on
|
||||
*/
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
internal abstract class FirIdeSourcesSession @PrivateSessionConstructor constructor(
|
||||
internal class FirIdeSourcesSession @PrivateSessionConstructor constructor(
|
||||
moduleInfo: ModuleInfo,
|
||||
sessionProvider: FirIdeSessionProvider,
|
||||
override val project: Project,
|
||||
override val scope: GlobalSearchScope,
|
||||
val firFileBuilder: FirFileBuilder,
|
||||
) : FirIdeSession(moduleInfo, sessionProvider) {
|
||||
builtinTypes: BuiltinTypes,
|
||||
) : FirIdeModuleSession(moduleInfo, builtinTypes) {
|
||||
val cache get() = firIdeProvider.cache
|
||||
}
|
||||
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
internal class FirIdeCurrentModuleSourcesSession @PrivateSessionConstructor constructor(
|
||||
moduleInfo: ModuleInfo,
|
||||
sessionProvider: FirIdeSessionProvider,
|
||||
scope: GlobalSearchScope,
|
||||
firFileBuilder: FirFileBuilder,
|
||||
) : FirIdeSourcesSession(moduleInfo, sessionProvider, scope, firFileBuilder) {
|
||||
}
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
internal class FirIdeDependentModulesSourcesSession @PrivateSessionConstructor constructor(
|
||||
moduleInfo: ModuleInfo,
|
||||
val dependentModules: List<ModuleSourceInfo>,
|
||||
sessionProvider: FirIdeSessionProvider,
|
||||
scope: GlobalSearchScope,
|
||||
firFileBuilder: FirFileBuilder,
|
||||
) : FirIdeSourcesSession(moduleInfo, sessionProvider, scope, firFileBuilder)
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.util
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.JdkOrderEntry
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.Comparing
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
|
||||
internal class ModuleLibrariesSearchScope(private val module: Module) : GlobalSearchScope(module.project) {
|
||||
override fun contains(file: VirtualFile): Boolean {
|
||||
val orderEntry = ModuleRootManager.getInstance(module).fileIndex.getOrderEntryForFile(file)
|
||||
return orderEntry is JdkOrderEntry || orderEntry is LibraryOrderEntry
|
||||
}
|
||||
|
||||
override fun compare(file1: VirtualFile, file2: VirtualFile): Int {
|
||||
val fileIndex = ModuleRootManager.getInstance(module).fileIndex
|
||||
return Comparing.compare(fileIndex.getOrderEntryForFile(file2), fileIndex.getOrderEntryForFile(file1))
|
||||
}
|
||||
|
||||
override fun isSearchInModuleContent(aModule: Module): Boolean = false
|
||||
|
||||
override fun isSearchInLibraries(): Boolean = true
|
||||
}
|
||||
+1
-1
@@ -102,7 +102,7 @@ abstract class AbstractFirLazyResolveTest : KotlinLightCodeInsightFixtureTestCas
|
||||
val files = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, contentScope)
|
||||
for (file in files) {
|
||||
val psiFile = psiManager.findFile(file) as KtFile
|
||||
val session = resolveState.currentModuleSourcesSession
|
||||
val session = resolveState.rootModuleSession
|
||||
val firProvider = session.firIdeProvider
|
||||
val firFile = firProvider.cache.getCachedFirFile(psiFile) ?: continue
|
||||
KotlinTestUtils.assertEqualsToFile(File(expectedTxtPath(file)), firFile.render())
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelTypeAliasFqNameIndex
|
||||
@@ -143,4 +143,4 @@ fun FirElement.findPsi(project: Project): PsiElement? =
|
||||
psi ?: FirIdeDeserializedDeclarationSourceProvider.findPsi(this, project)
|
||||
|
||||
fun FirElement.findPsi(session: FirSession): PsiElement? =
|
||||
findPsi(session.sessionProvider!!.project)
|
||||
findPsi((session as FirIdeSession).project)
|
||||
+1
-1
@@ -40,7 +40,7 @@ private constructor(
|
||||
override val callResolver: KtCallResolver = KtFirCallResolver(this, token)
|
||||
override val scopeProvider by threadLocal { KtFirScopeProvider(this, firSymbolBuilder, project, firResolveState, token) }
|
||||
override val symbolProvider: KtSymbolProvider =
|
||||
KtFirSymbolProvider(this, firResolveState.currentModuleSourcesSession.firSymbolProvider, firResolveState, firSymbolBuilder, token)
|
||||
KtFirSymbolProvider(this, firResolveState.rootModuleSession.firSymbolProvider, firResolveState, firSymbolBuilder, token)
|
||||
override val completionCandidateChecker: KtCompletionCandidateChecker by threadLocal { KtFirCompletionCandidateChecker(this, token) }
|
||||
override val symbolDeclarationOverridesProvider: KtSymbolDeclarationOverridesProvider
|
||||
by threadLocal { KtFirSymbolDeclarationOverridesProvider(this, token) }
|
||||
|
||||
+2
-3
@@ -10,7 +10,6 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
@@ -47,11 +46,11 @@ internal class KtSymbolByFirBuilder private constructor(
|
||||
ConeTypeCheckerContext(
|
||||
isErrorTypeEqualsToAnything = true,
|
||||
isStubTypeEqualsToAnything = true,
|
||||
resolveState.currentModuleSourcesSession
|
||||
resolveState.rootModuleSession
|
||||
)
|
||||
}
|
||||
|
||||
private val firProvider get() = resolveState.currentModuleSourcesSession.firSymbolProvider
|
||||
private val firProvider get() = resolveState.rootModuleSession.firSymbolProvider
|
||||
|
||||
constructor(
|
||||
resolveState: FirModuleResolveState,
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ internal class KtFirCallResolver(
|
||||
}
|
||||
|
||||
private fun resolveCall(firCall: FirFunctionCall, callExpression: KtExpression): CallInfo? {
|
||||
val session = firResolveState.currentModuleSourcesSession
|
||||
val session = firResolveState.rootModuleSession
|
||||
val resolvedFunctionSymbol = firCall.calleeReference.toTargetSymbol(session, firSymbolBuilder)
|
||||
val resolvedCalleeSymbol = (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol
|
||||
return when {
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ internal class KtFirCompletionCandidateChecker(
|
||||
): Boolean {
|
||||
val file = firResolveState.getFirFile(originalFile)
|
||||
val explicitReceiverExpression = possibleExplicitReceiver?.getOrBuildFirOfType<FirExpression>(firResolveState)
|
||||
val resolver = SingleCandidateResolver(firResolveState.currentModuleSourcesSession, file)
|
||||
val resolver = SingleCandidateResolver(firResolveState.rootModuleSession, file)
|
||||
val implicitReceivers = getImplicitReceivers(originalFile, file, nameExpression)
|
||||
for (implicitReceiverValue in implicitReceivers) {
|
||||
val resolutionParameters = ResolutionParameters(
|
||||
|
||||
+6
-8
@@ -6,18 +6,14 @@
|
||||
package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.idea.fir.getOrBuildFirOfType
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.firTransformerProvider
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
|
||||
@@ -60,7 +56,8 @@ internal class KtFirScopeProvider(
|
||||
check(classSymbol is KtFirClassOrObjectSymbol)
|
||||
val firScope =
|
||||
classSymbol.firRef.withFir(FirResolvePhase.SUPER_TYPES) { fir ->
|
||||
fir.unsubstitutedScope(fir.session, fir.session.firTransformerProvider.getScopeSession())
|
||||
val firSession = fir.session
|
||||
fir.unsubstitutedScope(firSession, firResolveState.firTransformerProvider.getScopeSession(firSession))
|
||||
}.also(firScopeStorage::register)
|
||||
KtFirMemberScope(classSymbol, firScope, token, builder)
|
||||
}
|
||||
@@ -80,7 +77,7 @@ internal class KtFirScopeProvider(
|
||||
val firPackageScope =
|
||||
FirPackageMemberScope(
|
||||
packageSymbol.fqName,
|
||||
firResolveState.currentModuleSourcesSession/*TODO use correct session here*/
|
||||
firResolveState.rootModuleSession/*TODO use correct session here*/
|
||||
).also(firScopeStorage::register)
|
||||
KtFirPackageScope(firPackageScope, project, builder, token)
|
||||
}
|
||||
@@ -92,8 +89,9 @@ internal class KtFirScopeProvider(
|
||||
|
||||
override fun getTypeScope(type: KtType): KtScope? {
|
||||
check(type is KtFirType) { "KtFirScopeProvider can only work with KtFirType, but ${type::class} was provided" }
|
||||
val firSession = firResolveState.currentModuleSourcesSession
|
||||
val firTypeScope = type.coneType.scope(firSession, firSession.firTransformerProvider.getScopeSession()) ?: return null
|
||||
val firSession = firResolveState.rootModuleSession
|
||||
val firTypeScope = type.coneType.scope(firSession, firResolveState.firTransformerProvider.getScopeSession(firSession))
|
||||
?: return null
|
||||
return convertToKtScope(firTypeScope)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@ internal object FirReferenceResolveHelper {
|
||||
val expression = ref.expression
|
||||
val symbolBuilder = analysisSession.firSymbolBuilder
|
||||
val fir = expression.getOrBuildFir(analysisSession.firResolveState)
|
||||
val session = analysisSession.firResolveState.currentModuleSourcesSession
|
||||
val session = analysisSession.firResolveState.rootModuleSession
|
||||
when (fir) {
|
||||
is FirResolvable -> {
|
||||
val calleeReference =
|
||||
|
||||
Reference in New Issue
Block a user