[FIR] Properly collect overriddens for method enhancement
If some java class has multiple supertypes then we need to collect overriddens from all those types directly, even if superTypeScope (which is FirTypeIntersectionScope in this case) returns only one symbol from one of this types (not intersection one) This is needed to proper enhancement in cases when some type occurs multiple times in supertypes graph with different nullability of arguments: class ConcurrentHashMap<K, V> : AbstractMap<K!, V!>, MutableMap<K, V> If we try to find method `get(key: K): V` supertype scope returns `AbstractMap.get(key: K!): V!` (because it actually overrides `MutableMap(key: K): V?`), but we need to get both symbols to properly enhance types for `ConcurrentHashMap.remove`
This commit is contained in:
-3
@@ -384,9 +384,6 @@ class FirSignatureEnhancement(
|
||||
ownerParameter: FirJavaValueParameter,
|
||||
index: Int
|
||||
): FirResolvedTypeRef {
|
||||
if (ownerParameter.returnTypeRef is FirResolvedTypeRef) {
|
||||
return ownerParameter.returnTypeRef as FirResolvedTypeRef
|
||||
}
|
||||
return ownerFunction.enhanceValueParameter(
|
||||
overriddenMembers,
|
||||
ownerParameter,
|
||||
|
||||
+19
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -26,7 +27,7 @@ class JavaClassMembersEnhancementScope(
|
||||
|
||||
private val overrideBindCache = mutableMapOf<Name, Map<FirCallableSymbol<*>?, List<FirCallableDeclaration>>>()
|
||||
private val signatureEnhancement = FirSignatureEnhancement(owner.fir, session) {
|
||||
overriddenMembers(name)
|
||||
overriddenMembersForEnhancement(name)
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
@@ -64,6 +65,23 @@ class JavaClassMembersEnhancementScope(
|
||||
return super.processFunctionsByName(name, processor)
|
||||
}
|
||||
|
||||
private fun FirCallableDeclaration.overriddenMembersForEnhancement(name: Name): List<FirCallableDeclaration> {
|
||||
val directlyOverriddensFromScopeFir = overriddenMembers(name)
|
||||
val superTypesScope = useSiteMemberScope.superTypesScope as? FirTypeIntersectionScope ?: return directlyOverriddensFromScopeFir
|
||||
|
||||
val directlyOverriddensFromScope = directlyOverriddensFromScopeFir.map { it.symbol }
|
||||
val result = mutableSetOf<FirCallableSymbol<*>>()
|
||||
for (intersectedOverriddenSymbol in directlyOverriddensFromScope) {
|
||||
val newOverriddens = superTypesScope.getDirectOverriddenSymbols(intersectedOverriddenSymbol).map { it.member }
|
||||
if (newOverriddens.isNotEmpty()) {
|
||||
result += newOverriddens
|
||||
} else {
|
||||
result += intersectedOverriddenSymbol
|
||||
}
|
||||
}
|
||||
return result.map { it.fir }
|
||||
}
|
||||
|
||||
private fun FirCallableDeclaration.overriddenMembers(name: Name): List<FirCallableDeclaration> {
|
||||
val backMap = overrideBindCache.getOrPut(name) {
|
||||
val result = mutableMapOf<FirCallableSymbol<*>?, MutableList<FirCallableDeclaration>>()
|
||||
|
||||
Reference in New Issue
Block a user