FIR DFA: add a utility function for intersecting with original type

This commit is contained in:
pyos
2022-11-11 18:57:11 +01:00
committed by teamcity
parent 5b08c300f4
commit 2e9cccd809
3 changed files with 10 additions and 21 deletions
@@ -115,13 +115,8 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
for ((realVar, requiredTypeStatement) in conditionStatements) {
val fixedRealVar = typeStatements.keys.find { it.identifier == realVar.identifier } ?: realVar
val resultTypeStatement = typeStatements[fixedRealVar]
val resultType = mutableListOf<ConeKotlinType>().apply {
addIfNotNull(function.getParameterType(fixedRealVar.identifier.symbol, context))
if (resultTypeStatement != null) addAll(resultTypeStatement.exactType)
}.let { typeContext.intersectTypesOrNull(it) }
val originalType = function.getParameterType(fixedRealVar.identifier.symbol, context) ?: continue
val resultType = typeStatements[fixedRealVar]?.exactType.intersectWith(typeContext, originalType)
val requiredType = typeContext.intersectTypesOrNull(requiredTypeStatement.exactType.toList())
if (requiredType != null && !requiredType.isSupertypeOf(typeContext, resultType)) return true
}
@@ -102,12 +102,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
override fun receiverUpdated(symbol: FirBasedSymbol<*>, types: Set<ConeKotlinType>?) {
val index = receiverStack.getReceiverIndex(symbol) ?: return
val originalType = receiverStack.getOriginalType(index)
val type = if (types?.isNotEmpty() == true) {
typeContext.intersectTypes(types.toMutableList().also { it += originalType })
} else {
originalType
}
receiverStack.replaceReceiverType(index, type)
receiverStack.replaceReceiverType(index, types.intersectWith(typeContext, originalType))
}
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.FirSyntheticPropertySymbol
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.name.StandardClassIds
import kotlin.contracts.ExperimentalContracts
@@ -57,14 +58,12 @@ internal inline fun <K, V> PersistentMap<K, V>.put(
}
}
@DfaInternals
fun FirOperation.invert(): FirOperation = when (this) {
FirOperation.EQ -> FirOperation.NOT_EQ
FirOperation.NOT_EQ -> FirOperation.EQ
FirOperation.IDENTITY -> FirOperation.NOT_IDENTITY
FirOperation.NOT_IDENTITY -> FirOperation.IDENTITY
else -> throw IllegalArgumentException("$this can not be inverted")
}
fun Set<ConeKotlinType>?.intersectWith(context: ConeTypeContext, originalType: ConeKotlinType): ConeKotlinType =
if (!isNullOrEmpty()) {
context.intersectTypes(toMutableList().also { it += originalType })
} else {
originalType
}
@DfaInternals
fun FirOperation.isEq(): Boolean {