FIR DFA: remove RealVariableAndType
This commit is contained in:
@@ -76,26 +76,6 @@ class RealVariable(
|
||||
}
|
||||
}
|
||||
|
||||
class RealVariableAndType(val variable: RealVariable, val originalType: ConeKotlinType?) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as RealVariableAndType
|
||||
|
||||
if (variable != other.variable) return false
|
||||
if (originalType != other.originalType) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = variable.hashCode()
|
||||
result = 31 * result + originalType.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class SyntheticVariable(val fir: FirElement, variableIndexForDebug: Int) : DataFlowVariable(variableIndexForDebug) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
||||
@@ -5,17 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.dfa
|
||||
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
|
||||
abstract class Flow {
|
||||
abstract fun getTypeStatement(variable: RealVariable): TypeStatement?
|
||||
abstract fun getImplications(variable: DataFlowVariable): Collection<Implication>
|
||||
abstract fun getVariablesInTypeStatements(): Collection<RealVariable>
|
||||
abstract fun removeOperations(variable: DataFlowVariable): Collection<Implication>
|
||||
|
||||
abstract val directAliasMap: Map<RealVariable, RealVariableAndType>
|
||||
abstract val backwardsAliasMap: Map<RealVariable, List<RealVariable>>
|
||||
abstract val assignmentIndex: Map<RealVariable, Int>
|
||||
}
|
||||
|
||||
fun Flow.unwrapVariable(variable: RealVariable): RealVariable {
|
||||
return directAliasMap[variable]?.variable ?: variable
|
||||
abstract fun unwrapVariable(variable: RealVariable): RealVariable
|
||||
abstract fun getType(variable: RealVariable): Set<ConeKotlinType>?
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
|
||||
shouldRemoveSynthetics: Boolean,
|
||||
): FLOW
|
||||
|
||||
abstract fun addLocalVariableAlias(flow: FLOW, alias: RealVariable, underlyingVariable: RealVariableAndType)
|
||||
abstract fun addLocalVariableAlias(flow: FLOW, alias: RealVariable, underlyingVariable: RealVariable)
|
||||
abstract fun removeLocalVariableAlias(flow: FLOW, alias: RealVariable)
|
||||
|
||||
abstract fun recordNewAssignment(flow: FLOW, variable: RealVariable, index: Int)
|
||||
@@ -126,7 +126,7 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
|
||||
op: (Collection<Set<ConeKotlinType>>) -> MutableSet<ConeKotlinType>
|
||||
): MutableTypeStatement {
|
||||
require(statements.isNotEmpty())
|
||||
statements.singleOrNull()?.let { return it as MutableTypeStatement }
|
||||
statements.singleOrNull()?.let { return it.asMutableStatement() }
|
||||
val variable = statements.first().variable
|
||||
assert(statements.all { it.variable == variable })
|
||||
val exactType = op.invoke(statements.map { it.exactType })
|
||||
|
||||
+22
-42
@@ -9,7 +9,6 @@ import com.google.common.collect.ArrayListMultimap
|
||||
import kotlinx.collections.immutable.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeInferenceContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
|
||||
@@ -51,10 +50,10 @@ class PersistentFlow : Flow {
|
||||
* directAliasMap: { x -> a, y -> a}
|
||||
* backwardsAliasMap: { a -> [x, y] }
|
||||
*/
|
||||
override var directAliasMap: PersistentMap<RealVariable, RealVariableAndType>
|
||||
override var backwardsAliasMap: PersistentMap<RealVariable, PersistentList<RealVariable>>
|
||||
var directAliasMap: PersistentMap<RealVariable, RealVariable>
|
||||
var backwardsAliasMap: PersistentMap<RealVariable, PersistentList<RealVariable>>
|
||||
|
||||
override var assignmentIndex: PersistentMap<RealVariable, Int>
|
||||
var assignmentIndex: PersistentMap<RealVariable, Int>
|
||||
|
||||
constructor(previousFlow: PersistentFlow) {
|
||||
this.previousFlow = previousFlow
|
||||
@@ -78,24 +77,22 @@ class PersistentFlow : Flow {
|
||||
assignmentIndex = persistentMapOf()
|
||||
}
|
||||
|
||||
override fun getTypeStatement(variable: RealVariable): TypeStatement? {
|
||||
return approvedTypeStatements[variable]
|
||||
override fun unwrapVariable(variable: RealVariable): RealVariable {
|
||||
return directAliasMap[variable] ?: variable
|
||||
}
|
||||
|
||||
override fun getImplications(variable: DataFlowVariable): Collection<Implication> {
|
||||
return logicStatements[variable] ?: emptyList()
|
||||
}
|
||||
|
||||
override fun getVariablesInTypeStatements(): Collection<RealVariable> {
|
||||
return approvedTypeStatements.keys
|
||||
}
|
||||
|
||||
override fun removeOperations(variable: DataFlowVariable): Collection<Implication> {
|
||||
return getImplications(variable).also {
|
||||
if (it.isNotEmpty()) {
|
||||
logicStatements -= variable
|
||||
}
|
||||
fun getTypeStatement(variable: RealVariable): TypeStatement {
|
||||
val result = MutableTypeStatement(variable)
|
||||
approvedTypeStatements[variable]?.let { result += it }
|
||||
val variableUnderAlias = directAliasMap[variable]
|
||||
if (variableUnderAlias != null) {
|
||||
approvedTypeStatements[variableUnderAlias]?.let { result += it }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getType(variable: RealVariable): Set<ConeKotlinType> {
|
||||
return getTypeStatement(variable).exactType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +107,7 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
||||
|
||||
override fun joinFlow(flows: Collection<PersistentFlow>): PersistentFlow {
|
||||
// One input flow executes - one set of statements is true, others might be false.
|
||||
return foldFlow(flows) { variable -> or(flows.map { it.getApprovedTypeStatements(variable) }).takeIf { it.isNotEmpty } }
|
||||
return foldFlow(flows) { variable -> or(flows.map { it.getTypeStatement(variable) }).takeIf { it.isNotEmpty } }
|
||||
}
|
||||
|
||||
override fun unionFlow(flows: Collection<PersistentFlow>): PersistentFlow {
|
||||
@@ -120,7 +117,7 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
||||
// happened last (and the flows that don't reassign may or may not have executed after that).
|
||||
return foldFlow(flows) { variable ->
|
||||
or(flows.groupBy { it.assignmentIndex[variable] ?: -1 }.values.map { flowSubset ->
|
||||
and(flowSubset.map { it.getApprovedTypeStatements(variable) })
|
||||
and(flowSubset.map { it.getTypeStatement(variable) })
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -166,16 +163,16 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
||||
return commonFlow
|
||||
}
|
||||
|
||||
private fun computeCommonAliases(flows: Collection<PersistentFlow>): Map<RealVariable, RealVariableAndType> =
|
||||
private fun computeCommonAliases(flows: Collection<PersistentFlow>): Map<RealVariable, RealVariable> =
|
||||
flows.first().directAliasMap.filterTo(mutableMapOf()) { (variable, alias) ->
|
||||
flows.all { it.directAliasMap[variable] == alias }
|
||||
}
|
||||
|
||||
override fun addLocalVariableAlias(flow: PersistentFlow, alias: RealVariable, underlyingVariable: RealVariableAndType) {
|
||||
override fun addLocalVariableAlias(flow: PersistentFlow, alias: RealVariable, underlyingVariable: RealVariable) {
|
||||
removeLocalVariableAlias(flow, alias)
|
||||
flow.directAliasMap = flow.directAliasMap.put(alias, underlyingVariable)
|
||||
flow.backwardsAliasMap = flow.backwardsAliasMap.put(
|
||||
underlyingVariable.variable,
|
||||
underlyingVariable,
|
||||
{ persistentListOf(alias) },
|
||||
{ variables -> variables + alias }
|
||||
)
|
||||
@@ -221,7 +218,7 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
||||
processApprovedStatements(isDiff = true)
|
||||
}
|
||||
|
||||
val original = flow.directAliasMap[alias]?.variable
|
||||
val original = flow.directAliasMap[alias]
|
||||
if (original != null) {
|
||||
flow.directAliasMap = flow.directAliasMap.remove(alias)
|
||||
val updatedBackwardsAliasList = flow.backwardsAliasMap.getValue(original).remove(alias)
|
||||
@@ -252,23 +249,6 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
||||
return statement as T
|
||||
}
|
||||
|
||||
|
||||
@OptIn(DfaInternals::class)
|
||||
private fun PersistentFlow.getApprovedTypeStatements(variable: RealVariable): MutableTypeStatement {
|
||||
var flow = this
|
||||
val result = MutableTypeStatement(variable)
|
||||
val variableUnderAlias = directAliasMap[variable]
|
||||
if (variableUnderAlias == null) {
|
||||
flow.approvedTypeStatements[variable]?.let {
|
||||
result += it
|
||||
}
|
||||
} else {
|
||||
result.exactType.addIfNotNull(variableUnderAlias.originalType)
|
||||
flow.approvedTypeStatements[variableUnderAlias.variable]?.let { result += it }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun addTypeStatement(flow: PersistentFlow, statement: TypeStatement) {
|
||||
if (statement.isEmpty) return
|
||||
with(flow) {
|
||||
|
||||
+1
-2
@@ -56,8 +56,7 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
||||
fir: FirElement,
|
||||
stability: PropertyStability
|
||||
): RealVariable {
|
||||
val variable = getOrCreateRealVariableWithoutUnwrappingAlias(flow, symbol, fir, stability)
|
||||
return flow.directAliasMap[variable]?.variable ?: variable
|
||||
return flow.unwrapVariable(getOrCreateRealVariableWithoutUnwrappingAlias(flow, symbol, fir, stability))
|
||||
}
|
||||
|
||||
private fun FirElement.unwrapElement(): FirElement = when (this) {
|
||||
|
||||
Reference in New Issue
Block a user