FIR IDE: fix FirModuleWithDependenciesSymbolProvider recursive calls
This commit is contained in:
+44
-26
@@ -20,21 +20,27 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
|||||||
internal class FirModuleWithDependenciesSymbolProvider(
|
internal class FirModuleWithDependenciesSymbolProvider(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
private val providers: List<FirSymbolProvider>,
|
private val providers: List<FirSymbolProvider>,
|
||||||
private val dependentProviders: List<FirSymbolProvider>,
|
dependentProviders: List<FirSymbolProvider>,
|
||||||
) : FirSymbolProvider(session) {
|
) : FirSymbolProvider(session) {
|
||||||
|
private val dependentProviders = DependentModuleProviders(session, dependentProviders)
|
||||||
|
|
||||||
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? =
|
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||||
|
getClassLikeSymbolByFqNameWithoutDependencies(classId)
|
||||||
|
?: dependentProviders.getClassLikeSymbolByFqName(classId)
|
||||||
|
|
||||||
|
|
||||||
|
fun getClassLikeSymbolByFqNameWithoutDependencies(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||||
providers.firstNotNullResult { it.getClassLikeSymbolByFqName(classId) }
|
providers.firstNotNullResult { it.getClassLikeSymbolByFqName(classId) }
|
||||||
?: withDependent(default = null) {
|
|
||||||
dependentProviders.firstNotNullResult { it.getClassLikeSymbolByFqName(classId) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||||
providers.flatMapTo(destination) { it.getTopLevelCallableSymbols(packageFqName, name) }
|
getTopLevelCallableSymbolsToWithoutDependencies(destination, packageFqName, name)
|
||||||
withDependent {
|
dependentProviders.getTopLevelCallableSymbolsTo(destination, packageFqName, name)
|
||||||
dependentProviders.flatMapTo(destination) { it.getTopLevelCallableSymbols(packageFqName, name) }
|
}
|
||||||
}
|
|
||||||
|
@FirSymbolProviderInternals
|
||||||
|
fun getTopLevelCallableSymbolsToWithoutDependencies(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||||
|
providers.forEach { it.getTopLevelCallableSymbolsTo(destination, packageFqName, name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
@@ -54,28 +60,40 @@ internal class FirModuleWithDependenciesSymbolProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getPackage(fqName: FqName): FqName? =
|
override fun getPackage(fqName: FqName): FqName? =
|
||||||
|
getPackageWithoutDependencies(fqName)
|
||||||
|
?: dependentProviders.getPackage(fqName)
|
||||||
|
|
||||||
|
|
||||||
|
fun getPackageWithoutDependencies(fqName: FqName): FqName? =
|
||||||
providers.firstNotNullResult { it.getPackage(fqName) }
|
providers.firstNotNullResult { it.getPackage(fqName) }
|
||||||
?: withDependent(default = null) {
|
}
|
||||||
dependentProviders.firstNotNullResult { it.getPackage(fqName) }
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
private class DependentModuleProviders(session: FirSession, private val providers: List<FirSymbolProvider>) : FirSymbolProvider(session) {
|
||||||
private val canUseDependent = ThreadLocal.withInitial { true }
|
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||||
|
providers.firstNotNullResult { provider ->
|
||||||
private inline fun <R> withDependent(default: R, action: () -> R): R {
|
when (provider) {
|
||||||
if (canUseDependent.get()) {
|
is FirModuleWithDependenciesSymbolProvider -> provider.getClassLikeSymbolByFqNameWithoutDependencies(classId)
|
||||||
canUseDependent.set(false)
|
else -> provider.getClassLikeSymbolByFqName(classId)
|
||||||
try {
|
|
||||||
return action()
|
|
||||||
} finally {
|
|
||||||
canUseDependent.set(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun withDependent(action: () -> Unit) {
|
|
||||||
withDependent(Unit, action)
|
@FirSymbolProviderInternals
|
||||||
|
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||||
|
providers.forEach { provider ->
|
||||||
|
when (provider) {
|
||||||
|
is FirModuleWithDependenciesSymbolProvider ->
|
||||||
|
provider.getTopLevelCallableSymbolsToWithoutDependencies(destination, packageFqName, name)
|
||||||
|
else -> provider.getTopLevelCallableSymbolsTo(destination, packageFqName, name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
override fun getPackage(fqName: FqName): FqName? =
|
||||||
|
providers.firstNotNullResult { provider ->
|
||||||
|
when (provider) {
|
||||||
|
is FirModuleWithDependenciesSymbolProvider -> provider.getPackageWithoutDependencies(fqName)
|
||||||
|
else -> provider.getPackage(fqName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user