FIR DFA: add a utility function for intersecting with original type
This commit is contained in:
+2
-7
@@ -115,13 +115,8 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
|
|||||||
|
|
||||||
for ((realVar, requiredTypeStatement) in conditionStatements) {
|
for ((realVar, requiredTypeStatement) in conditionStatements) {
|
||||||
val fixedRealVar = typeStatements.keys.find { it.identifier == realVar.identifier } ?: realVar
|
val fixedRealVar = typeStatements.keys.find { it.identifier == realVar.identifier } ?: realVar
|
||||||
val resultTypeStatement = typeStatements[fixedRealVar]
|
val originalType = function.getParameterType(fixedRealVar.identifier.symbol, context) ?: continue
|
||||||
|
val resultType = typeStatements[fixedRealVar]?.exactType.intersectWith(typeContext, originalType)
|
||||||
val resultType = mutableListOf<ConeKotlinType>().apply {
|
|
||||||
addIfNotNull(function.getParameterType(fixedRealVar.identifier.symbol, context))
|
|
||||||
if (resultTypeStatement != null) addAll(resultTypeStatement.exactType)
|
|
||||||
}.let { typeContext.intersectTypesOrNull(it) }
|
|
||||||
|
|
||||||
val requiredType = typeContext.intersectTypesOrNull(requiredTypeStatement.exactType.toList())
|
val requiredType = typeContext.intersectTypesOrNull(requiredTypeStatement.exactType.toList())
|
||||||
if (requiredType != null && !requiredType.isSupertypeOf(typeContext, resultType)) return true
|
if (requiredType != null && !requiredType.isSupertypeOf(typeContext, resultType)) return true
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -102,12 +102,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
override fun receiverUpdated(symbol: FirBasedSymbol<*>, types: Set<ConeKotlinType>?) {
|
override fun receiverUpdated(symbol: FirBasedSymbol<*>, types: Set<ConeKotlinType>?) {
|
||||||
val index = receiverStack.getReceiverIndex(symbol) ?: return
|
val index = receiverStack.getReceiverIndex(symbol) ?: return
|
||||||
val originalType = receiverStack.getOriginalType(index)
|
val originalType = receiverStack.getOriginalType(index)
|
||||||
val type = if (types?.isNotEmpty() == true) {
|
receiverStack.replaceReceiverType(index, types.intersectWith(typeContext, originalType))
|
||||||
typeContext.intersectTypes(types.toMutableList().also { it += originalType })
|
|
||||||
} else {
|
|
||||||
originalType
|
|
||||||
}
|
|
||||||
receiverStack.replaceReceiverType(index, type)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val logicSystem: PersistentLogicSystem =
|
override val logicSystem: PersistentLogicSystem =
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeTypeContext
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
@@ -57,14 +58,12 @@ internal inline fun <K, V> PersistentMap<K, V>.put(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@DfaInternals
|
fun Set<ConeKotlinType>?.intersectWith(context: ConeTypeContext, originalType: ConeKotlinType): ConeKotlinType =
|
||||||
fun FirOperation.invert(): FirOperation = when (this) {
|
if (!isNullOrEmpty()) {
|
||||||
FirOperation.EQ -> FirOperation.NOT_EQ
|
context.intersectTypes(toMutableList().also { it += originalType })
|
||||||
FirOperation.NOT_EQ -> FirOperation.EQ
|
} else {
|
||||||
FirOperation.IDENTITY -> FirOperation.NOT_IDENTITY
|
originalType
|
||||||
FirOperation.NOT_IDENTITY -> FirOperation.IDENTITY
|
}
|
||||||
else -> throw IllegalArgumentException("$this can not be inverted")
|
|
||||||
}
|
|
||||||
|
|
||||||
@DfaInternals
|
@DfaInternals
|
||||||
fun FirOperation.isEq(): Boolean {
|
fun FirOperation.isEq(): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user