FIR: Make qualifier have only one static scope

It's more correct as that's how it works in FE 1.0
This commit is contained in:
Denis Zharkov
2020-06-25 12:52:39 +03:00
parent a017109d7d
commit f3e4e9b162
3 changed files with 16 additions and 84 deletions
@@ -6,24 +6,20 @@
package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.ScopeSessionKey
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.impl.FirOnlyCallablesScope
import org.jetbrains.kotlin.fir.scopes.impl.FirOnlyClassifiersScope
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import java.util.*
fun FirClassLikeDeclaration<*>.fullyExpandedClass(useSiteSession: FirSession): FirRegularClass? {
@@ -53,7 +49,7 @@ fun createQualifierReceiver(
abstract class QualifierReceiver(final override val explicitReceiver: FirExpression) : AbstractExplicitReceiver<FirResolvedQualifier>() {
abstract fun classifierScope(): FirScope?
abstract fun callableScopes(): List<FirScope>
abstract fun callableScope(): FirScope?
}
class ClassQualifierReceiver(
@@ -64,71 +60,10 @@ class ClassQualifierReceiver(
val scopeSession: ScopeSession
) : QualifierReceiver(explicitReceiver) {
private companion object {
val SUPERTYPE_STATICS_SCOPE_SESSION_KEY = object : ScopeSessionKey<FirClass<*>, List<FirScope>>() {}
}
private fun collectSuperTypeScopesComposedByDepth(
klass: FirClass<*>,
useSiteSession: FirSession,
scopeSession: ScopeSession,
): List<FirScope> {
val result = mutableListOf<FirScope>()
val provider = klass.scopeProvider
val levelScopes = mutableListOf<FirScope>()
var currentDepth = 1
val queue =
ArrayDeque<Pair<ConeClassLikeType, Int>>()
queue.addAll(
lookupSuperTypes(klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession).map { it to 1 },
)
val visitedSymbols = mutableSetOf<FirRegularClassSymbol>()
while (queue.isNotEmpty()) {
val (useSiteSuperType, depth) = queue.poll()
if (depth > currentDepth) {
currentDepth = depth
result += FirCompositeScope(levelScopes.toMutableList())
levelScopes.clear()
}
if (useSiteSuperType is ConeClassErrorType) continue
val superTypeSymbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession) as? FirRegularClassSymbol
?: continue
if (!visitedSymbols.add(superTypeSymbol)) continue
val superTypeScope = provider.getStaticMemberScopeForCallables(
superTypeSymbol.fir, useSiteSession, scopeSession,
)
if (superTypeScope != null) {
levelScopes += superTypeScope
}
queue.addAll(
lookupSuperTypes(
superTypeSymbol.fir, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession,
).map { it to currentDepth + 1 },
)
}
return result
}
private fun getCallableScopes(
useSiteSession: FirSession,
scopeSession: ScopeSession,
): List<FirScope> {
override fun callableScope(): FirScope? {
val klass = classSymbol.fir
val result = mutableListOf<FirScope>()
val provider = klass.scopeProvider
val klassScope = provider.getStaticMemberScopeForCallables(klass, useSiteSession, scopeSession)
if (klassScope != null) {
result += klassScope
if (provider is KotlinScopeProvider) return result
result += scopeSession.getOrBuild(klass, SUPERTYPE_STATICS_SCOPE_SESSION_KEY) {
collectSuperTypeScopesComposedByDepth(klass, useSiteSession, scopeSession)
}
}
return result
}
override fun callableScopes(): List<FirScope> {
return getCallableScopes(useSiteSession, scopeSession)
return provider.getStaticMemberScopeForCallables(klass, useSiteSession, scopeSession)
}
override fun classifierScope(): FirScope? {
@@ -148,7 +83,5 @@ class PackageQualifierReceiver(
return FirOnlyClassifiersScope(scope)
}
override fun callableScopes(): List<FirScope> {
return listOf(FirOnlyCallablesScope(scope))
}
override fun callableScope() = FirOnlyCallablesScope(scope)
}
@@ -155,13 +155,12 @@ class FirTowerResolverSession internal constructor(
info: CallInfo, qualifierReceiver: QualifierReceiver?
) {
if (qualifierReceiver == null) return
for ((depth, qualifierScope) in qualifierReceiver.callableScopes().withIndex()) {
processLevel(
qualifierScope.toScopeTowerLevel(includeInnerConstructors = false),
info.noStubReceiver(), TowerGroup.Qualifier(depth),
useParentGroupForInvokes = true,
)
}
val callableScope = qualifierReceiver.callableScope() ?: return
processLevel(
callableScope.toScopeTowerLevel(includeInnerConstructors = false),
info.noStubReceiver(), TowerGroup.Qualifier,
useParentGroupForInvokes = true,
)
}
private suspend fun processClassifierScope(
@@ -12,7 +12,7 @@ sealed class TowerGroupKind(private val index: Int) : Comparable<TowerGroupKind>
object ClassifierPrioritized : TowerGroupKind(-10)
class Qualifier(depth: Int) : WithDepth(0, depth)
object Qualifier : TowerGroupKind(0)
object Classifier : TowerGroupKind(10)
@@ -59,7 +59,7 @@ private constructor(
val ClassifierPrioritized = kindOf(TowerGroupKind.ClassifierPrioritized)
fun Qualifier(depth: Int) = kindOf(TowerGroupKind.Qualifier(depth))
val Qualifier = kindOf(TowerGroupKind.Qualifier)
val Classifier = kindOf(TowerGroupKind.Classifier)