FIR: Simplify supertypes scopes computation

This commit is contained in:
Denis.Zharkov
2021-02-03 20:29:18 +03:00
parent 31b9be2d01
commit 6766c8fe47
2 changed files with 47 additions and 22 deletions
@@ -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,