[FIR] Refactor deferred computation of callable copy return types
Rename some classes for clarity and move the implementations to the use sites.
This commit is contained in:
committed by
Space Team
parent
aa1cce78c3
commit
8a90032e93
+48
-53
@@ -5,45 +5,59 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataKey
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataRegistry
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScopeContext
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
|
||||
|
||||
/**
|
||||
* A utility class that, depending on the implementation, calculates the return type of callable copies,
|
||||
* (substitution/intersection overrides, delegated members, and enhanced Java declarations) and returns it.
|
||||
*
|
||||
* See [FirDeclarationAttributes.deferredCallableCopyReturnType].
|
||||
*/
|
||||
abstract class CallableCopyTypeCalculator {
|
||||
/**
|
||||
* Returns the [FirTypeRef] for [FirCallableDeclaration.returnTypeRef] of the [declaration].
|
||||
*
|
||||
* Depending on the implementation, this call might invoke a deferred computation of the return type
|
||||
* (see [FirDeclarationAttributes.deferredCallableCopyReturnType]).
|
||||
*
|
||||
* A return value of `null` signifies that the calculation has failed or that no deferred computation was stored
|
||||
* and the return type could not be resolved ordinarily.
|
||||
*/
|
||||
abstract fun computeReturnType(declaration: FirCallableDeclaration): FirTypeRef?
|
||||
|
||||
fun computeReturnTypeOrNull(declaration: FirCallableDeclaration): ConeKotlinType? {
|
||||
return computeReturnType(declaration)?.coneTypeOrNull
|
||||
}
|
||||
|
||||
/**
|
||||
* Doesn't perform any calculation and returns [FirCallableDeclaration.returnTypeRef].
|
||||
*/
|
||||
object DoNothing : CallableCopyTypeCalculator() {
|
||||
override fun computeReturnType(declaration: FirCallableDeclaration): FirTypeRef {
|
||||
return declaration.returnTypeRef
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractCallableCopyTypeCalculator : CallableCopyTypeCalculator() {
|
||||
/**
|
||||
* If necessary, runs the computation saved in [FirDeclarationAttributes.deferredCallableCopyReturnType] and returns a [FirResolvedTypeRef].
|
||||
*/
|
||||
abstract class DeferredCallableCopyTypeCalculator : CallableCopyTypeCalculator() {
|
||||
override fun computeReturnType(declaration: FirCallableDeclaration): FirResolvedTypeRef? {
|
||||
val callableCopyDeferredTypeCalculation = declaration.attributes.callableCopyDeferredTypeCalculation
|
||||
val callableCopyDeferredTypeCalculation = declaration.attributes.deferredCallableCopyReturnType
|
||||
?: return declaration.getResolvedTypeRef()
|
||||
|
||||
// TODO: drop synchronized in KT-60385
|
||||
synchronized(callableCopyDeferredTypeCalculation) {
|
||||
if (declaration.attributes.callableCopyDeferredTypeCalculation == null) {
|
||||
if (declaration.attributes.deferredCallableCopyReturnType == null) {
|
||||
return declaration.returnTypeRef as FirResolvedTypeRef
|
||||
}
|
||||
|
||||
val returnType = when (callableCopyDeferredTypeCalculation) {
|
||||
is CallableCopySubstitution -> computeSubstitution(callableCopyDeferredTypeCalculation)
|
||||
is CallableCopyIntersection -> computeIntersection(callableCopyDeferredTypeCalculation)
|
||||
} ?: return null
|
||||
val returnType = callableCopyDeferredTypeCalculation.computeReturnType(this) ?: return null
|
||||
val returnTypeRef = declaration.returnTypeRef.resolvedTypeFromPrototype(returnType)
|
||||
|
||||
declaration.replaceReturnTypeRef(returnTypeRef)
|
||||
@@ -52,33 +66,19 @@ abstract class CallableCopyTypeCalculator {
|
||||
declaration.setter?.valueParameters?.firstOrNull()?.replaceReturnTypeRef(returnTypeRef)
|
||||
}
|
||||
|
||||
declaration.attributes.callableCopyDeferredTypeCalculation = null
|
||||
declaration.attributes.deferredCallableCopyReturnType = null
|
||||
|
||||
return returnTypeRef
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeSubstitution(callableCopySubstitutionForTypeUpdater: CallableCopySubstitution): ConeKotlinType? {
|
||||
val (substitutor, baseSymbol) = callableCopySubstitutionForTypeUpdater
|
||||
val baseDeclaration = baseSymbol.fir as FirCallableDeclaration
|
||||
val baseReturnType = computeReturnType(baseDeclaration)?.type ?: return null
|
||||
val coneType = substitutor.substituteOrSelf(baseReturnType)
|
||||
|
||||
return coneType
|
||||
}
|
||||
|
||||
private fun computeIntersection(callableCopyIntersection: CallableCopyIntersection): ConeKotlinType? {
|
||||
val (mostSpecific, session) = callableCopyIntersection
|
||||
return FirTypeIntersectionScopeContext.intersectReturnTypes(mostSpecific, session) {
|
||||
computeReturnType(this)?.type
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun FirCallableDeclaration.getResolvedTypeRef(): FirResolvedTypeRef?
|
||||
}
|
||||
|
||||
|
||||
object Forced : AbstractCallableCopyTypeCalculator() {
|
||||
/**
|
||||
* See [DeferredCallableCopyTypeCalculator].
|
||||
*/
|
||||
object Forced : DeferredCallableCopyTypeCalculator() {
|
||||
override fun FirCallableDeclaration.getResolvedTypeRef(): FirResolvedTypeRef? {
|
||||
return returnTypeRef as? FirResolvedTypeRef
|
||||
}
|
||||
@@ -87,24 +87,19 @@ abstract class CallableCopyTypeCalculator {
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
private object CallableCopyDeferredReturnTypeCalculationKey : FirDeclarationDataKey()
|
||||
private object DeferredCallableCopyReturnTypeKey : FirDeclarationDataKey()
|
||||
|
||||
var FirDeclarationAttributes.callableCopyDeferredTypeCalculation: CallableCopyDeferredReturnTypeCalculation? by FirDeclarationDataRegistry.attributesAccessor(
|
||||
CallableCopyDeferredReturnTypeCalculationKey
|
||||
var FirDeclarationAttributes.deferredCallableCopyReturnType: DeferredCallableCopyReturnType? by FirDeclarationDataRegistry.attributesAccessor(
|
||||
DeferredCallableCopyReturnTypeKey
|
||||
)
|
||||
|
||||
sealed class CallableCopyDeferredReturnTypeCalculation
|
||||
abstract class DeferredCallableCopyReturnType {
|
||||
/**
|
||||
* Performs a deferred computation some declaration's return type.
|
||||
*
|
||||
* [calc] must be used for the return type calculation of overridden members which might recursively trigger the computation of
|
||||
* deferred return types.
|
||||
*/
|
||||
abstract fun computeReturnType(calc: CallableCopyTypeCalculator): ConeKotlinType?
|
||||
}
|
||||
|
||||
data class CallableCopySubstitution internal constructor(
|
||||
val substitutor: ConeSubstitutor,
|
||||
val baseSymbol: FirBasedSymbol<*>
|
||||
) : CallableCopyDeferredReturnTypeCalculation()
|
||||
|
||||
data class CallableCopyIntersection internal constructor(
|
||||
val mostSpecific: Collection<FirCallableSymbol<*>>,
|
||||
val session: FirSession,
|
||||
) : CallableCopyDeferredReturnTypeCalculation() {
|
||||
override fun toString(): String {
|
||||
return "CallableCopyIntersection(mostSpecific=$mostSpecific)"
|
||||
}
|
||||
}
|
||||
+22
-4
@@ -16,7 +16,8 @@ import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSessionKey
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.chain
|
||||
import org.jetbrains.kotlin.fir.scopes.CallableCopySubstitution
|
||||
import org.jetbrains.kotlin.fir.scopes.DeferredCallableCopyReturnType
|
||||
import org.jetbrains.kotlin.fir.scopes.CallableCopyTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
@@ -285,7 +286,7 @@ class FirClassSubstitutionScope(
|
||||
val receiverType: ConeKotlinType?,
|
||||
val returnType: ConeKotlinType?,
|
||||
val substitutor: ConeSubstitutor,
|
||||
val callableCopySubstitution: CallableCopySubstitution?
|
||||
val deferredReturnTypeOfSubstitution: DeferredReturnTypeOfSubstitution?
|
||||
)
|
||||
|
||||
private fun createSubstitutedData(member: FirCallableDeclaration, symbolForOverride: FirBasedSymbol<*>): SubstitutedData {
|
||||
@@ -307,7 +308,7 @@ class FirClassSubstitutionScope(
|
||||
val newDispatchReceiverType = dispatchReceiverTypeForSubstitutedMembers.substitute(substitutor)
|
||||
|
||||
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||
val callableCopySubstitution = runIf(returnType == null) { CallableCopySubstitution(substitutor, member.symbol) }
|
||||
val deferredReturnTypeOfSubstitution = runIf(returnType == null) { DeferredReturnTypeOfSubstitution(substitutor, member.symbol) }
|
||||
val newReturnType = returnType?.substitute(substitutor)
|
||||
return SubstitutedData(
|
||||
newTypeParameters,
|
||||
@@ -315,7 +316,7 @@ class FirClassSubstitutionScope(
|
||||
newReceiverType,
|
||||
newReturnType,
|
||||
substitutor,
|
||||
callableCopySubstitution
|
||||
deferredReturnTypeOfSubstitution
|
||||
)
|
||||
}
|
||||
|
||||
@@ -377,3 +378,20 @@ class FirSubstitutionOverrideStorage(val session: FirSession) : FirSessionCompon
|
||||
}
|
||||
|
||||
private val FirSession.substitutionOverrideStorage: FirSubstitutionOverrideStorage by FirSession.sessionComponentAccessor()
|
||||
|
||||
internal class DeferredReturnTypeOfSubstitution(
|
||||
private val substitutor: ConeSubstitutor,
|
||||
private val baseSymbol: FirBasedSymbol<*>,
|
||||
) : DeferredCallableCopyReturnType() {
|
||||
override fun computeReturnType(calc: CallableCopyTypeCalculator): ConeKotlinType? {
|
||||
val baseDeclaration = baseSymbol.fir as FirCallableDeclaration
|
||||
val baseReturnType = calc.computeReturnTypeOrNull(baseDeclaration) ?: return null
|
||||
val coneType = substitutor.substituteOrSelf(baseReturnType)
|
||||
|
||||
return coneType
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "DeferredReturnTypeOfSubstitution(substitutor=$substitutor, baseSymbol=$baseSymbol)"
|
||||
}
|
||||
}
|
||||
+19
-20
@@ -20,9 +20,8 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.CallableCopyDeferredReturnTypeCalculation
|
||||
import org.jetbrains.kotlin.fir.scopes.CallableCopySubstitution
|
||||
import org.jetbrains.kotlin.fir.scopes.callableCopyDeferredTypeCalculation
|
||||
import org.jetbrains.kotlin.fir.scopes.DeferredCallableCopyReturnType
|
||||
import org.jetbrains.kotlin.fir.scopes.deferredCallableCopyReturnType
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
@@ -50,7 +49,7 @@ object FirFakeOverrideGenerator {
|
||||
newParameterTypes: List<ConeKotlinType?>? = null,
|
||||
newTypeParameters: List<FirTypeParameter>? = null,
|
||||
isExpect: Boolean = baseFunction.isExpect,
|
||||
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null,
|
||||
callableCopySubstitutionForTypeUpdater: DeferredCallableCopyReturnType? = null,
|
||||
): FirNamedFunctionSymbol {
|
||||
createSubstitutionOverrideFunction(
|
||||
symbolForSubstitutionOverride, session, baseFunction, derivedClassLookupTag,
|
||||
@@ -81,7 +80,7 @@ object FirFakeOverrideGenerator {
|
||||
newParameterTypes: List<ConeKotlinType?>?,
|
||||
newTypeParameters: List<FirTypeParameter>?,
|
||||
isExpect: Boolean = baseFunction.isExpect,
|
||||
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?,
|
||||
callableCopySubstitutionForTypeUpdater: DeferredCallableCopyReturnType?,
|
||||
origin: FirDeclarationOrigin.SubstitutionOverride,
|
||||
): FirSimpleFunction {
|
||||
// TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl
|
||||
@@ -120,7 +119,7 @@ object FirFakeOverrideGenerator {
|
||||
newReturnType: ConeKotlinType? = null,
|
||||
newModality: Modality? = null,
|
||||
newVisibility: Visibility? = null,
|
||||
deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation? = null,
|
||||
deferredReturnTypeCalculation: DeferredCallableCopyReturnType? = null,
|
||||
newSource: KtSourceElement? = derivedClassLookupTag?.toSymbol(session)?.source ?: baseFunction.source,
|
||||
): FirSimpleFunction = buildSimpleFunction {
|
||||
source = newSource
|
||||
@@ -155,7 +154,7 @@ object FirFakeOverrideGenerator {
|
||||
newContextReceiverTypes: List<ConeKotlinType?>?,
|
||||
newTypeParameters: List<FirTypeParameterRef>?,
|
||||
isExpect: Boolean,
|
||||
deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation?,
|
||||
deferredReturnTypeCalculation: DeferredCallableCopyReturnType?,
|
||||
newSource: KtSourceElement? = null,
|
||||
): FirConstructor = buildConstructor {
|
||||
// TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl
|
||||
@@ -209,7 +208,7 @@ object FirFakeOverrideGenerator {
|
||||
newReceiverType: ConeKotlinType?,
|
||||
newContextReceiverTypes: List<ConeKotlinType?>?,
|
||||
newReturnType: ConeKotlinType?,
|
||||
deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation?,
|
||||
deferredReturnTypeCalculation: DeferredCallableCopyReturnType?,
|
||||
symbolForOverride: FirFunctionSymbol<*>,
|
||||
copyDefaultValues: Boolean = false,
|
||||
): List<FirTypeParameterRef> {
|
||||
@@ -241,7 +240,7 @@ object FirFakeOverrideGenerator {
|
||||
)
|
||||
val (copiedReturnType, newCallableCopySubstitutionForTypeUpdater) = when (possibleReturnType) {
|
||||
is Maybe.Value -> possibleReturnType.value to null
|
||||
else -> null to CallableCopySubstitution(substitutor, symbol)
|
||||
else -> null to DeferredReturnTypeOfSubstitution(substitutor, symbol)
|
||||
}
|
||||
configureAnnotationsAndSignature(
|
||||
baseFunction,
|
||||
@@ -280,7 +279,7 @@ object FirFakeOverrideGenerator {
|
||||
newReceiverType: ConeKotlinType?,
|
||||
newContextReceiverTypes: List<ConeKotlinType?>?,
|
||||
newReturnType: ConeKotlinType?,
|
||||
deferredTypeCalculation: CallableCopyDeferredReturnTypeCalculation?,
|
||||
deferredTypeCalculation: DeferredCallableCopyReturnType?,
|
||||
origin: FirDeclarationOrigin,
|
||||
copyDefaultValues: Boolean = false,
|
||||
) {
|
||||
@@ -290,12 +289,12 @@ object FirFakeOverrideGenerator {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val deferredTypeCalculation = deferredTypeCalculation
|
||||
?: runIf(baseFunction.returnTypeRef is FirImplicitTypeRef) {
|
||||
CallableCopySubstitution(ConeSubstitutor.Empty, baseFunction.symbol)
|
||||
DeferredReturnTypeOfSubstitution(ConeSubstitutor.Empty, baseFunction.symbol)
|
||||
}
|
||||
|
||||
if (deferredTypeCalculation != null) {
|
||||
returnTypeRef = FirImplicitTypeRefImplWithoutSource
|
||||
attributes.callableCopyDeferredTypeCalculation = deferredTypeCalculation
|
||||
attributes.deferredCallableCopyReturnType = deferredTypeCalculation
|
||||
} else {
|
||||
returnTypeRef = baseFunction.returnTypeRef.withReplacedReturnType(newReturnType)
|
||||
}
|
||||
@@ -366,7 +365,7 @@ object FirFakeOverrideGenerator {
|
||||
newReturnType: ConeKotlinType? = null,
|
||||
newTypeParameters: List<FirTypeParameter>? = null,
|
||||
isExpect: Boolean = baseProperty.isExpect,
|
||||
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null,
|
||||
callableCopySubstitutionForTypeUpdater: DeferredCallableCopyReturnType? = null,
|
||||
): FirPropertySymbol {
|
||||
createCopyForFirProperty(
|
||||
symbolForSubstitutionOverride, baseProperty, derivedClassLookupTag, session, origin,
|
||||
@@ -400,7 +399,7 @@ object FirFakeOverrideGenerator {
|
||||
newReturnType: ConeKotlinType? = null,
|
||||
newModality: Modality? = null,
|
||||
newVisibility: Visibility? = null,
|
||||
deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation? = null,
|
||||
deferredReturnTypeCalculation: DeferredCallableCopyReturnType? = null,
|
||||
newSource: KtSourceElement? = derivedClassLookupTag?.toSymbol(session)?.source ?: baseProperty.source,
|
||||
): FirProperty = buildProperty {
|
||||
source = newSource
|
||||
@@ -547,7 +546,7 @@ object FirFakeOverrideGenerator {
|
||||
newReturnType: ConeKotlinType? = null,
|
||||
newModality: Modality? = null,
|
||||
newVisibility: Visibility? = null,
|
||||
deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation? = null,
|
||||
deferredReturnTypeCalculation: DeferredCallableCopyReturnType? = null,
|
||||
): FirField = buildField {
|
||||
source = baseField.source
|
||||
moduleData = session.nullableModuleData ?: baseField.moduleData
|
||||
@@ -576,7 +575,7 @@ object FirFakeOverrideGenerator {
|
||||
newReceiverType: ConeKotlinType?,
|
||||
newContextReceiverTypes: List<ConeKotlinType?>?,
|
||||
newReturnType: ConeKotlinType?,
|
||||
deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation?,
|
||||
deferredReturnTypeCalculation: DeferredCallableCopyReturnType?,
|
||||
): List<FirTypeParameter> {
|
||||
return when {
|
||||
baseProperty.typeParameters.isEmpty() -> {
|
||||
@@ -594,7 +593,7 @@ object FirFakeOverrideGenerator {
|
||||
)
|
||||
val (copiedReturnType, newCallableCopySubstitutionForTypeUpdater) = when (possibleReturnType) {
|
||||
is Maybe.Value -> possibleReturnType.value to null
|
||||
else -> null to CallableCopySubstitution(substitutor, baseProperty.symbol)
|
||||
else -> null to DeferredReturnTypeOfSubstitution(substitutor, baseProperty.symbol)
|
||||
}
|
||||
configureAnnotationsAndSignature(
|
||||
baseProperty, copiedReceiverType, copiedContextReceiverTypes,
|
||||
@@ -648,7 +647,7 @@ object FirFakeOverrideGenerator {
|
||||
newReceiverType: ConeKotlinType?,
|
||||
newContextReceiverTypes: List<ConeKotlinType?>?,
|
||||
newReturnType: ConeKotlinType?,
|
||||
deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation?,
|
||||
deferredReturnTypeCalculation: DeferredCallableCopyReturnType?,
|
||||
updateReceiver: Boolean = true,
|
||||
) {
|
||||
checkStatusIsResolved(baseVariable)
|
||||
@@ -657,12 +656,12 @@ object FirFakeOverrideGenerator {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val deferredReturnTypeCalculation = deferredReturnTypeCalculation
|
||||
?: runIf(baseVariable.returnTypeRef is FirImplicitTypeRef) {
|
||||
CallableCopySubstitution(ConeSubstitutor.Empty, baseVariable.symbol)
|
||||
DeferredReturnTypeOfSubstitution(ConeSubstitutor.Empty, baseVariable.symbol)
|
||||
}
|
||||
|
||||
if (deferredReturnTypeCalculation != null) {
|
||||
returnTypeRef = FirImplicitTypeRefImplWithoutSource
|
||||
attributes.callableCopyDeferredTypeCalculation = deferredReturnTypeCalculation
|
||||
attributes.deferredCallableCopyReturnType = deferredReturnTypeCalculation
|
||||
} else {
|
||||
returnTypeRef = baseVariable.returnTypeRef.withReplacedReturnType(newReturnType)
|
||||
}
|
||||
|
||||
+29
-15
@@ -427,7 +427,7 @@ class FirTypeIntersectionScopeContext(
|
||||
overrides: Collection<FirCallableSymbol<*>>,
|
||||
containsMultipleNonSubsumed: Boolean,
|
||||
createIntersectionOverrideSymbol: (CallableId, Collection<FirCallableSymbol<*>>, Boolean) -> S,
|
||||
createCopy: (S, F, deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation?, returnType: ConeKotlinType?) -> F
|
||||
createCopy: (S, F, deferredReturnTypeCalculation: DeferredCallableCopyReturnType?, returnType: ConeKotlinType?) -> F
|
||||
): S {
|
||||
val key = mostSpecific.first() as S
|
||||
val keyFir = key.fir
|
||||
@@ -444,32 +444,46 @@ class FirTypeIntersectionScopeContext(
|
||||
return newSymbol
|
||||
}
|
||||
|
||||
private fun deferredReturnTypeCalculationOrNull(mostSpecific: Collection<FirCallableSymbol<*>>): CallableCopyIntersection? {
|
||||
private fun deferredReturnTypeCalculationOrNull(mostSpecific: Collection<FirCallableSymbol<*>>): DeferredReturnTypeOfIntersection? {
|
||||
return runIf(mostSpecific.any { it.fir.returnTypeRef is FirImplicitTypeRef }) {
|
||||
CallableCopyIntersection(mostSpecific, session)
|
||||
DeferredReturnTypeOfIntersection(mostSpecific, session)
|
||||
}
|
||||
}
|
||||
|
||||
private fun intersectReturnTypes(overrides: Collection<FirCallableSymbol<*>>): ConeKotlinType? {
|
||||
return intersectReturnTypes(overrides, session) { returnTypeRef.coneType }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
inline fun intersectReturnTypes(overrides: Collection<FirCallableSymbol<*>>, session: FirSession, getReturnType: FirCallableDeclaration.() -> ConeKotlinType?): ConeKotlinType? {
|
||||
val key = overrides.first()
|
||||
// Remap type parameters to the first declaration's:
|
||||
// (fun <A, B> foo(): B) & (fun <C, D> foo(): D?) -> (fun <A, B> foo(): B & B?)
|
||||
val substituted = overrides.mapNotNull {
|
||||
val returnType = it.fir.getReturnType() ?: return@mapNotNull null
|
||||
if (it == key) return@mapNotNull returnType
|
||||
val substitutor = buildSubstitutorForOverridesCheck(it.fir, key.fir, session) ?: return@mapNotNull null
|
||||
returnType.let(substitutor::substituteOrSelf)
|
||||
}
|
||||
return if (substituted.isNotEmpty()) session.typeContext.intersectTypes(substituted) else null
|
||||
private class DeferredReturnTypeOfIntersection(
|
||||
private val mostSpecific: Collection<FirCallableSymbol<*>>,
|
||||
private val session: FirSession,
|
||||
) : DeferredCallableCopyReturnType() {
|
||||
override fun computeReturnType(calc: CallableCopyTypeCalculator): ConeKotlinType? {
|
||||
return intersectReturnTypes(mostSpecific, session) {
|
||||
calc.computeReturnTypeOrNull(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "CallableCopyIntersection(mostSpecific=$mostSpecific)"
|
||||
}
|
||||
}
|
||||
|
||||
private fun intersectReturnTypes(overrides: Collection<FirCallableSymbol<*>>, session: FirSession, getReturnType: FirCallableDeclaration.() -> ConeKotlinType?): ConeKotlinType? {
|
||||
val key = overrides.first()
|
||||
// Remap type parameters to the first declaration's:
|
||||
// (fun <A, B> foo(): B) & (fun <C, D> foo(): D?) -> (fun <A, B> foo(): B & B?)
|
||||
val substituted = overrides.mapNotNull {
|
||||
val returnType = it.fir.getReturnType() ?: return@mapNotNull null
|
||||
if (it == key) return@mapNotNull returnType
|
||||
val substitutor = buildSubstitutorForOverridesCheck(it.fir, key.fir, session) ?: return@mapNotNull null
|
||||
returnType.let(substitutor::substituteOrSelf)
|
||||
}
|
||||
return if (substituted.isNotEmpty()) session.typeContext.intersectTypes(substituted) else null
|
||||
}
|
||||
|
||||
|
||||
private fun <D : FirCallableSymbol<*>> D.withScope(baseScope: FirTypeScope) = MemberWithBaseScope(this, baseScope)
|
||||
|
||||
typealias FirIntersectionOverrideCache =
|
||||
|
||||
+2
-2
@@ -346,8 +346,8 @@ open class ReturnTypeCalculatorWithJump(
|
||||
return newReturnTypeRef
|
||||
}
|
||||
|
||||
private inner class CallableCopyTypeCalculatorWithJump : CallableCopyTypeCalculator.AbstractCallableCopyTypeCalculator() {
|
||||
override fun FirCallableDeclaration.getResolvedTypeRef(): FirResolvedTypeRef? {
|
||||
private inner class CallableCopyTypeCalculatorWithJump : CallableCopyTypeCalculator.DeferredCallableCopyTypeCalculator() {
|
||||
override fun FirCallableDeclaration.getResolvedTypeRef(): FirResolvedTypeRef {
|
||||
return this@ReturnTypeCalculatorWithJump.computeReturnTypeRef(this)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user