[FIR] Handle of special getters when there is a kotlin super type

Special getter names (like Collection.size()) can be used only in Java
classes with all-java super-types
Because if there is a kotlin class (not interface) in
 the middle, we 'materialize' special getters to properties.
This commit is contained in:
Andrey Zinovyev
2021-04-30 19:04:45 +03:00
committed by teamcityserver
parent 7066a5b3dc
commit dc9d5cdf35
2 changed files with 25 additions and 2 deletions
@@ -45,6 +45,8 @@ class JavaClassUseSiteMemberScope(
private val typeParameterStack = klass.javaTypeParameterStack
private val specialFunctions = hashMapOf<Name, Collection<FirNamedFunctionSymbol>>()
private val accessorByNameMap = hashMapOf<Name, FirAccessorSymbol>()
private val canUseSpecialGetters: Boolean by lazy { !klass.hasKotlinSuper(session) }
override fun getCallableNames(): Set<Name> {
return declaredMemberScope.getContainingCallableNamesIfPresent() + superTypesScope.getCallableNames()
@@ -136,7 +138,7 @@ class JavaClassUseSiteMemberScope(
private fun FirPropertySymbol.findGetterOverride(
scope: FirScope,
): FirNamedFunctionSymbol? {
val specialGetterName = getBuiltinSpecialPropertyGetterName()
val specialGetterName = if (canUseSpecialGetters) getBuiltinSpecialPropertyGetterName() else null
if (specialGetterName != null) {
return findGetterByName(specialGetterName.asString(), scope)
}
@@ -447,6 +449,28 @@ class JavaClassUseSiteMemberScope(
return result
}
/**
* Checks if class has any kotlin super-types apart from builtins and interfaces
*/
private fun FirRegularClass.hasKotlinSuper(session: FirSession, visited: MutableSet<FirRegularClass> = mutableSetOf()): Boolean =
when {
!visited.add(this) -> false
this is FirJavaClass -> superConeTypes.any { type ->
type.toFir(session)?.hasKotlinSuper(session, visited) == true
}
isInterface || origin == FirDeclarationOrigin.BuiltIns -> false
else -> true
}
private fun ConeClassLikeType.toFir(session: FirSession): FirRegularClass? {
val symbol = this.toSymbol(session)
return if (symbol is FirRegularClassSymbol) {
symbol.fir
} else {
null
}
}
}
private fun FirCallableSymbol<*>.isFromBuiltInClass(session: FirSession) =