FIR: Simplify supertypes scopes computation
This commit is contained in:
@@ -36,7 +36,7 @@ class JavaScopeProvider(
|
|||||||
scopeSession: ScopeSession
|
scopeSession: ScopeSession
|
||||||
): FirTypeScope {
|
): FirTypeScope {
|
||||||
val symbol = klass.symbol as FirRegularClassSymbol
|
val symbol = klass.symbol as FirRegularClassSymbol
|
||||||
val enhancementScope = buildJavaEnhancementScope(useSiteSession, symbol, scopeSession, mutableSetOf())
|
val enhancementScope = buildJavaEnhancementScope(useSiteSession, symbol, scopeSession)
|
||||||
if (klass.classKind == ClassKind.ANNOTATION_CLASS) {
|
if (klass.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||||
return buildSyntheticScopeForAnnotations(useSiteSession, symbol, scopeSession, enhancementScope)
|
return buildSyntheticScopeForAnnotations(useSiteSession, symbol, scopeSession, enhancementScope)
|
||||||
}
|
}
|
||||||
@@ -57,14 +57,13 @@ class JavaScopeProvider(
|
|||||||
private fun buildJavaEnhancementScope(
|
private fun buildJavaEnhancementScope(
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
symbol: FirRegularClassSymbol,
|
symbol: FirRegularClassSymbol,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession
|
||||||
visitedSymbols: MutableSet<FirClassLikeSymbol<*>>
|
|
||||||
): JavaClassMembersEnhancementScope {
|
): JavaClassMembersEnhancementScope {
|
||||||
return scopeSession.getOrBuild(symbol, JAVA_ENHANCEMENT) {
|
return scopeSession.getOrBuild(symbol, JAVA_ENHANCEMENT) {
|
||||||
JavaClassMembersEnhancementScope(
|
JavaClassMembersEnhancementScope(
|
||||||
useSiteSession,
|
useSiteSession,
|
||||||
symbol,
|
symbol,
|
||||||
buildUseSiteMemberScopeWithJavaTypes(symbol.fir, useSiteSession, scopeSession, visitedSymbols)
|
buildUseSiteMemberScopeWithJavaTypes(symbol.fir, useSiteSession, scopeSession)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,27 +80,20 @@ class JavaScopeProvider(
|
|||||||
regularClass: FirRegularClass,
|
regularClass: FirRegularClass,
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
visitedSymbols: MutableSet<FirClassLikeSymbol<*>>
|
|
||||||
): JavaClassUseSiteMemberScope {
|
): JavaClassUseSiteMemberScope {
|
||||||
return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) {
|
return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) {
|
||||||
val declaredScope = buildDeclaredMemberScope(regularClass)
|
val declaredScope = buildDeclaredMemberScope(regularClass)
|
||||||
val wrappedDeclaredScope = declaredMemberScopeDecorator(regularClass, declaredScope, useSiteSession, scopeSession)
|
val wrappedDeclaredScope = declaredMemberScopeDecorator(regularClass, declaredScope, useSiteSession, scopeSession)
|
||||||
val superTypeEnhancementScopes =
|
val superTypes =
|
||||||
lookupSuperTypes(regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
|
if (regularClass.isThereLoopInSupertypes(useSiteSession))
|
||||||
.mapNotNull { useSiteSuperType ->
|
listOf(StandardClassIds.Any.toConeKotlinType(emptyArray(), isNullable = false))
|
||||||
if (useSiteSuperType is ConeClassErrorType) return@mapNotNull null
|
else
|
||||||
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
|
lookupSuperTypes(regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
|
||||||
if (symbol is FirRegularClassSymbol && visitedSymbols.add(symbol)) {
|
|
||||||
// We need JavaClassEnhancementScope here to have already enhanced signatures from supertypes
|
val superTypeScopes = superTypes.mapNotNull {
|
||||||
val scope = buildJavaEnhancementScope(useSiteSession, symbol, scopeSession, visitedSymbols)
|
it.scopeForSupertype(useSiteSession, scopeSession, subClass = regularClass, wrappedDeclaredScope, delegateFields = null)
|
||||||
visitedSymbols.remove(symbol)
|
}
|
||||||
useSiteSuperType.wrapSubstitutionScopeIfNeed(
|
|
||||||
useSiteSession, scope, symbol.fir, scopeSession, derivedClass = regularClass
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JavaClassUseSiteMemberScope(
|
JavaClassUseSiteMemberScope(
|
||||||
regularClass, useSiteSession,
|
regularClass, useSiteSession,
|
||||||
FirTypeIntersectionScope.prepareIntersectionScope(
|
FirTypeIntersectionScope.prepareIntersectionScope(
|
||||||
@@ -111,7 +103,7 @@ class JavaScopeProvider(
|
|||||||
if (regularClass is FirJavaClass) regularClass.javaTypeParameterStack
|
if (regularClass is FirJavaClass) regularClass.javaTypeParameterStack
|
||||||
else JavaTypeParameterStack.EMPTY
|
else JavaTypeParameterStack.EMPTY
|
||||||
),
|
),
|
||||||
superTypeEnhancementScopes,
|
superTypeScopes,
|
||||||
regularClass.defaultType(),
|
regularClass.defaultType(),
|
||||||
), wrappedDeclaredScope
|
), wrappedDeclaredScope
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -42,6 +42,39 @@ fun lookupSuperTypes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirClass<*>.isThereLoopInSupertypes(session: FirSession): Boolean {
|
||||||
|
val visitedSymbols: MutableSet<FirClassifierSymbol<*>> = mutableSetOf()
|
||||||
|
val inProcess: MutableSet<FirClassifierSymbol<*>> = mutableSetOf()
|
||||||
|
|
||||||
|
var isThereLoop = false
|
||||||
|
|
||||||
|
fun dfs(current: FirClassifierSymbol<*>) {
|
||||||
|
if (current in visitedSymbols) return
|
||||||
|
if (!inProcess.add(current)) {
|
||||||
|
isThereLoop = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
when (val fir = current.fir) {
|
||||||
|
is FirClass<*> -> {
|
||||||
|
fir.superConeTypes.forEach {
|
||||||
|
it.lookupTag.toSymbol(session)?.let(::dfs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is FirTypeAlias -> {
|
||||||
|
fir.expandedConeType?.lookupTag?.toSymbol(session)?.let(::dfs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitedSymbols.add(current)
|
||||||
|
inProcess.remove(current)
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs(symbol)
|
||||||
|
|
||||||
|
return isThereLoop
|
||||||
|
}
|
||||||
|
|
||||||
fun lookupSuperTypes(
|
fun lookupSuperTypes(
|
||||||
symbol: FirClassifierSymbol<*>,
|
symbol: FirClassifierSymbol<*>,
|
||||||
lookupInterfaces: Boolean,
|
lookupInterfaces: Boolean,
|
||||||
|
|||||||
Reference in New Issue
Block a user