[FIR] Implement replacing Object with type parameters for specials builtins
#KT-42601 Fixed
This commit is contained in:
+69
-3
@@ -5,19 +5,29 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.java.scopes
|
||||
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
|
||||
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||
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.FirFakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptorReplacingKotlinToJava
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.load.java.SpecialGenericSignatures
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class JavaClassMembersEnhancementScope(
|
||||
session: FirSession,
|
||||
owner: FirRegularClassSymbol,
|
||||
private val owner: FirRegularClassSymbol,
|
||||
private val useSiteMemberScope: JavaClassUseSiteMemberScope,
|
||||
) : FirTypeScope() {
|
||||
private val overriddenFunctions = mutableMapOf<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>()
|
||||
@@ -46,10 +56,66 @@ class JavaClassMembersEnhancementScope(
|
||||
return super.processPropertiesByName(name, processor)
|
||||
}
|
||||
|
||||
private fun FirSimpleFunction.changeSignatureIfErasedValueParameter(): FirSimpleFunction {
|
||||
val typeParameters = owner.fir.typeParameters
|
||||
if (typeParameters.isEmpty() || name !in SpecialGenericSignatures.ERASED_VALUE_PARAMETERS_SHORT_NAMES) {
|
||||
return this
|
||||
}
|
||||
val jvmDescriptor = this.computeJvmDescriptorReplacingKotlinToJava()
|
||||
if (SpecialGenericSignatures.ERASED_VALUE_PARAMETERS_SIGNATURES.none { it.endsWith(jvmDescriptor) }) {
|
||||
return this
|
||||
}
|
||||
val superClassIds = listOfNotNull(symbol.callableId.classId) +
|
||||
lookupSuperTypes(owner, lookupInterfaces = true, deep = true, useSiteSession = session).map { it.lookupTag.classId }
|
||||
for (superClassId in superClassIds) {
|
||||
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(superClassId.asSingleFqName().toUnsafe()) ?: superClassId
|
||||
val fqJvmDescriptor = "${javaClassId.asString()}.$jvmDescriptor"
|
||||
if (fqJvmDescriptor in SpecialGenericSignatures.ERASED_VALUE_PARAMETERS_SIGNATURES) {
|
||||
val specialSignatureInfo = SpecialGenericSignatures.getSpecialSignatureInfo(fqJvmDescriptor)
|
||||
if (!specialSignatureInfo.isObjectReplacedWithTypeParameter) {
|
||||
return this
|
||||
}
|
||||
val newParameterTypes = valueParameters.mapIndexed { i, valueParameter ->
|
||||
val classLikeType =
|
||||
valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.lowerBoundIfFlexible().safeAs<ConeClassLikeType>()
|
||||
if (classLikeType?.lookupTag?.classId == StandardClassIds.Any) {
|
||||
val typeParameterIndex = if (name.asString() == "containsValue") 1 else i
|
||||
val typeParameter = typeParameters.getOrNull(typeParameterIndex) ?: typeParameters.first()
|
||||
val type = ConeTypeParameterLookupTag(typeParameter.symbol).constructType(
|
||||
emptyArray(), valueParameter.returnTypeRef.isMarkedNullable == true
|
||||
)
|
||||
if (valueParameter.returnTypeRef.coneType is ConeFlexibleType) {
|
||||
ConeFlexibleType(type, type.withNullability(ConeNullability.NULLABLE))
|
||||
} else {
|
||||
type
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
if (newParameterTypes.none { it != null }) {
|
||||
return this
|
||||
}
|
||||
|
||||
return FirFakeOverrideGenerator.createCopyForFirFunction(
|
||||
FirNamedFunctionSymbol(symbol.callableId),
|
||||
this,
|
||||
session,
|
||||
FirDeclarationOrigin.Enhancement,
|
||||
newParameterTypes = valueParameters.zip(newParameterTypes).map { (valueParameter, newType) ->
|
||||
newType ?: valueParameter.returnTypeRef.coneType
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||
useSiteMemberScope.processFunctionsByName(name) process@{ original ->
|
||||
val enhancedFunctionSymbol = signatureEnhancement.enhancedFunction(original, name)
|
||||
val enhancedFunction = enhancedFunctionSymbol.fir as? FirSimpleFunction
|
||||
val symbol = signatureEnhancement.enhancedFunction(original, name)
|
||||
val enhancedFunction = (symbol.fir as? FirSimpleFunction)?.changeSignatureIfErasedValueParameter()
|
||||
val enhancedFunctionSymbol = enhancedFunction?.symbol ?: symbol
|
||||
|
||||
overriddenFunctions[enhancedFunctionSymbol] =
|
||||
enhancedFunction
|
||||
|
||||
Reference in New Issue
Block a user