[FIR] Implement replacing Object with type parameters for specials builtins
#KT-42601 Fixed
This commit is contained in:
@@ -26,7 +26,7 @@ FILE: test.kt
|
||||
^ String(value)
|
||||
}
|
||||
)
|
||||
lval otherResult: R|kotlin/String| = R|<local>/map|.R|FakeOverride<kotlin/collections/MutableMap.getOrDefault: R|kotlin/String|>|(String(key), String(value))
|
||||
lval otherResult: R|ft<kotlin/String, kotlin/String?>!| = R|<local>/map|.R|FakeOverride<kotlin/collections/MutableMap.getOrDefault: R|ft<kotlin/String, kotlin/String?>!|>|(String(key), String(value))
|
||||
lval anotherResult: R|kotlin/String?| = R|<local>/map|.R|FakeOverride<kotlin/collections/MutableMap.replace: R|kotlin/String?|>|(String(key), String(value))
|
||||
R|<local>/map|.R|FakeOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| {
|
||||
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
|
||||
|
||||
@@ -19,7 +19,7 @@ FILE: smartSet.kt
|
||||
public final override fun clear(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public final override fun contains(element: R|T|): R|kotlin/Boolean| {
|
||||
public final override operator fun contains(element: R|T|): R|kotlin/Boolean| {
|
||||
^contains Boolean(false)
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -1723,6 +1723,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.ANY, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
|
||||
}
|
||||
|
||||
@TestMetadata("AbstractMutableMap.kt")
|
||||
public void testAbstractMutableMap() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/firProblems/AbstractMutableMap.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("AllCandidates.kt")
|
||||
public void testAllCandidates() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/firProblems/AllCandidates.kt");
|
||||
|
||||
+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