From dc9d5cdf3582909205947f3d2c3114acafd33710 Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Fri, 30 Apr 2021 19:04:45 +0300 Subject: [PATCH] [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. --- .../scopes/JavaClassUseSiteMemberScope.kt | 26 ++++++++++++++++++- .../implementCollectionThroughKotlin.kt | 1 - 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt index 7556e28d2fb..03d7e8bb5ea 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt @@ -45,6 +45,8 @@ class JavaClassUseSiteMemberScope( private val typeParameterStack = klass.javaTypeParameterStack private val specialFunctions = hashMapOf>() private val accessorByNameMap = hashMapOf() + + private val canUseSpecialGetters: Boolean by lazy { !klass.hasKotlinSuper(session) } override fun getCallableNames(): Set { 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 = 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) = diff --git a/compiler/testData/codegen/box/collections/implementCollectionThroughKotlin.kt b/compiler/testData/codegen/box/collections/implementCollectionThroughKotlin.kt index 7ae5dc78ad3..036eb71f713 100644 --- a/compiler/testData/codegen/box/collections/implementCollectionThroughKotlin.kt +++ b/compiler/testData/codegen/box/collections/implementCollectionThroughKotlin.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // FILE: J.java