[LL FIR] do not fail on cycle in module dependencies
This commit is contained in:
+1
-6
@@ -41,12 +41,7 @@ internal class LLFirLibrarySessionFactory(
|
||||
ConcurrentHashMap<KtBinaryModule, LLFirLibrarySession>()
|
||||
}
|
||||
|
||||
fun getLibrarySessionsForModule(module: KtModule): List<LLFirLibraryLikeSession> = buildList {
|
||||
LLFirBuiltinsSessionFactory.getInstance(project).getBuiltinsSession(module.platform).let(::add)
|
||||
return module.allDirectDependenciesOfType<KtBinaryModule>().mapTo(this) { getLibrarySession(it) }
|
||||
}
|
||||
|
||||
private fun getLibrarySession(ktBinaryModule: KtBinaryModule): LLFirLibrarySession {
|
||||
fun getLibrarySession(ktBinaryModule: KtBinaryModule): LLFirLibrarySession {
|
||||
return librarySessionByModule.getOrPut(ktBinaryModule) { createModuleLibrariesSession(ktBinaryModule) }
|
||||
}
|
||||
|
||||
|
||||
+38
-14
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
@@ -78,21 +79,15 @@ internal class LLFirModuleWithDependenciesSymbolProvider(
|
||||
providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
||||
}
|
||||
|
||||
internal class LLFirDependentModuleProviders(
|
||||
internal abstract class LLFirDependentModuleProviders(
|
||||
session: FirSession,
|
||||
private val providers: List<FirSymbolProvider>
|
||||
) : FirDependenciesSymbolProvider(session) {
|
||||
|
||||
val dependenciesAsSessions: List<LLFirSession>
|
||||
get() = buildList {
|
||||
providers.mapTo(this) { it.session as LLFirSession }
|
||||
}
|
||||
|
||||
constructor(session: FirSession, createSubProviders: MutableList<FirSymbolProvider>.() -> Unit)
|
||||
: this(session, buildList { createSubProviders() })
|
||||
abstract val dependentProviders: List<FirSymbolProvider>
|
||||
abstract val dependentSessions: List<LLFirSession>
|
||||
|
||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||
providers.firstNotNullOfOrNull { provider ->
|
||||
dependentProviders.firstNotNullOfOrNull { provider ->
|
||||
when (provider) {
|
||||
is LLFirModuleWithDependenciesSymbolProvider -> provider.getClassLikeSymbolByFqNameWithoutDependencies(classId)
|
||||
else -> provider.getClassLikeSymbolByClassId(classId)
|
||||
@@ -102,10 +97,11 @@ internal class LLFirDependentModuleProviders(
|
||||
|
||||
@FirSymbolProviderInternals
|
||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||
providers.forEach { provider ->
|
||||
dependentProviders.forEach { provider ->
|
||||
when (provider) {
|
||||
is LLFirModuleWithDependenciesSymbolProvider ->
|
||||
provider.getTopLevelCallableSymbolsToWithoutDependencies(destination, packageFqName, name)
|
||||
|
||||
else -> provider.getTopLevelCallableSymbolsTo(destination, packageFqName, name)
|
||||
}
|
||||
}
|
||||
@@ -113,10 +109,11 @@ internal class LLFirDependentModuleProviders(
|
||||
|
||||
@FirSymbolProviderInternals
|
||||
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
|
||||
providers.forEach { provider ->
|
||||
dependentProviders.forEach { provider ->
|
||||
when (provider) {
|
||||
is LLFirModuleWithDependenciesSymbolProvider ->
|
||||
provider.getTopLevelFunctionSymbolsToWithoutDependencies(destination, packageFqName, name)
|
||||
|
||||
else -> provider.getTopLevelFunctionSymbolsTo(destination, packageFqName, name)
|
||||
}
|
||||
}
|
||||
@@ -124,20 +121,47 @@ internal class LLFirDependentModuleProviders(
|
||||
|
||||
@FirSymbolProviderInternals
|
||||
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
|
||||
providers.forEach { provider ->
|
||||
dependentProviders.forEach { provider ->
|
||||
when (provider) {
|
||||
is LLFirModuleWithDependenciesSymbolProvider ->
|
||||
provider.getTopLevelPropertySymbolsToWithoutDependencies(destination, packageFqName, name)
|
||||
|
||||
else -> provider.getTopLevelPropertySymbolsTo(destination, packageFqName, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? =
|
||||
providers.firstNotNullOfOrNull { provider ->
|
||||
dependentProviders.firstNotNullOfOrNull { provider ->
|
||||
when (provider) {
|
||||
is LLFirModuleWithDependenciesSymbolProvider -> provider.getPackageWithoutDependencies(fqName)
|
||||
else -> provider.getPackage(fqName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class LLFirDependentModuleProvidersBySessions(
|
||||
session: FirSession,
|
||||
override val dependentSessions: List<LLFirSession>
|
||||
) : LLFirDependentModuleProviders(session) {
|
||||
|
||||
override val dependentProviders: List<FirSymbolProvider> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
dependentSessions.map { it.symbolProvider }
|
||||
}
|
||||
|
||||
constructor(session: FirSession, createSessions: MutableList<LLFirSession>.() -> Unit)
|
||||
: this(session, buildList { createSessions() })
|
||||
}
|
||||
|
||||
|
||||
internal class LLFirDependentModuleProvidersByProviders(
|
||||
session: FirSession,
|
||||
override val dependentProviders: List<FirSymbolProvider>,
|
||||
) : LLFirDependentModuleProviders(session) {
|
||||
|
||||
override val dependentSessions: List<LLFirSession>
|
||||
get() = dependentProviders.map { it.session as LLFirSession }
|
||||
|
||||
constructor(session: FirSession, createProviders: MutableList<FirSymbolProvider>.() -> Unit)
|
||||
: this(session, buildList { createProviders() })
|
||||
}
|
||||
|
||||
+24
-17
@@ -55,6 +55,8 @@ internal object LLFirSessionFactory {
|
||||
): LLFirSourcesSession {
|
||||
sessionsCache[module]?.let { return it as LLFirSourcesSession }
|
||||
val platform = module.platform
|
||||
val builtinsSession = LLFirBuiltinsSessionFactory.getInstance(project).getBuiltinsSession(platform)
|
||||
|
||||
val languageVersionSettings = object : LanguageVersionSettings by module.languageVersionSettings {
|
||||
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State =
|
||||
if (feature == LanguageFeature.EnableDfaWarningsInK2) LanguageFeature.State.ENABLED
|
||||
@@ -71,12 +73,11 @@ internal object LLFirSessionFactory {
|
||||
val components = LLFirModuleResolveComponents(module, globalResolveComponents, scopeProvider)
|
||||
|
||||
val contentScope = module.contentScope
|
||||
val dependentModules = module.directRegularDependenciesOfType<KtSourceModule>()
|
||||
val session = LLFirSourcesSession(
|
||||
module,
|
||||
project,
|
||||
components,
|
||||
LLFirBuiltinsSessionFactory.getInstance(project).getBuiltinsSession(platform).builtinTypes
|
||||
builtinsSession.builtinTypes
|
||||
)
|
||||
sessionsCache[module] = session
|
||||
components.session = session
|
||||
@@ -109,21 +110,27 @@ internal object LLFirSessionFactory {
|
||||
register(FirSwitchableExtensionDeclarationsSymbolProvider::class, it)
|
||||
}
|
||||
|
||||
val dependencyProvider = LLFirDependentModuleProviders(this) {
|
||||
librariesSessionFactory.getLibrarySessionsForModule(module).mapTo(this) { it.symbolProvider }
|
||||
dependentModules
|
||||
.mapTo(this) { dependentSourceModule ->
|
||||
val dependentSourceSession = createSourcesSession(
|
||||
project,
|
||||
dependentSourceModule,
|
||||
globalResolveComponents,
|
||||
sessionInvalidator,
|
||||
sessionsCache,
|
||||
librariesSessionFactory = librariesSessionFactory,
|
||||
configureSession = configureSession,
|
||||
)
|
||||
dependentSourceSession.symbolProvider
|
||||
val dependencyProvider = LLFirDependentModuleProvidersBySessions(this) {
|
||||
module.directRegularDependencies.mapNotNullTo(this) { dependency ->
|
||||
when (dependency) {
|
||||
is KtBuiltinsModule -> null // build in is already added
|
||||
is KtBinaryModule -> LLFirLibrarySessionFactory.getInstance(project).getLibrarySession(dependency)
|
||||
is KtSourceModule -> {
|
||||
createSourcesSession(
|
||||
project,
|
||||
dependency,
|
||||
globalResolveComponents,
|
||||
sessionInvalidator,
|
||||
sessionsCache,
|
||||
librariesSessionFactory = librariesSessionFactory,
|
||||
configureSession = configureSession,
|
||||
)
|
||||
}
|
||||
is KtNotUnderContentRootModule -> error("Module $module cannot depend on ${dependency::class}: $dependency")
|
||||
is KtLibrarySourceModule -> error("Module $module cannot depend on ${dependency::class}: $dependency")
|
||||
}
|
||||
}
|
||||
add(builtinsSession)
|
||||
}
|
||||
|
||||
val javaSymbolProvider = createJavaSymbolProvider(this, moduleData, project, contentScope)
|
||||
@@ -205,7 +212,7 @@ internal object LLFirSessionFactory {
|
||||
register(FirRegisteredPluginAnnotations::class, LLFirIdeRegisteredPluginAnnotations(this@session, annotationsResolver))
|
||||
register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider())
|
||||
|
||||
val dependencyProvider = LLFirDependentModuleProviders(this) {
|
||||
val dependencyProvider = LLFirDependentModuleProvidersByProviders(this) {
|
||||
// <all libraries scope> - <current library scope>
|
||||
val librariesSearchScope =
|
||||
ProjectScope.getLibrariesScope(project).intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope))
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ class LLFirSessionProvider internal constructor(
|
||||
) : FirSessionProvider() {
|
||||
|
||||
private val moduleToSession = moduleToResolvableSession + moduleToResolvableSession.values.flatMap { module ->
|
||||
(module.dependenciesSymbolProvider as LLFirDependentModuleProviders).dependenciesAsSessions
|
||||
(module.dependenciesSymbolProvider as LLFirDependentModuleProviders).dependentSessions
|
||||
}.associateBy { it.ktModule }
|
||||
|
||||
override fun getSession(moduleData: FirModuleData): LLFirSession {
|
||||
|
||||
Reference in New Issue
Block a user