All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.fir.resolve.dfa.SimpleLogicSystem.kt Maven / Gradle / Ivy

/*
 * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.fir.resolve.dfa

import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.HashMultimap
import com.google.common.collect.Multimap

private class SimpleFlow(
    val approvedInfos: MutableApprovedInfos = mutableMapOf(),
    val conditionalInfos: ConditionalInfos = HashMultimap.create()
) : Flow {
    override fun getApprovedInfo(variable: RealDataFlowVariable): FirDataFlowInfo? {
        return approvedInfos[variable]
    }

    override fun getConditionalInfos(variable: DataFlowVariable): Collection {
        return conditionalInfos[variable]
    }

    override fun getVariablesInApprovedInfos(): Collection {
        return approvedInfos.keys
    }

    override fun removeConditionalInfos(variable: DataFlowVariable): Collection {
        return conditionalInfos.removeAll(variable)
    }
}

abstract class SimpleLogicSystem(context: DataFlowInferenceContext) : LogicSystem(context) {
    override val Flow.approvedInfos: MutableApprovedInfos
        get() = (this as SimpleFlow).approvedInfos

    override val Flow.conditionalInfos: ConditionalInfos
        get() = (this as SimpleFlow).conditionalInfos

    override fun createEmptyFlow(): Flow {
        return SimpleFlow()
    }

    override fun forkFlow(flow: Flow): Flow {
        require(flow is SimpleFlow)
        return SimpleFlow(
            flow.approvedInfos.mapValuesTo(mutableMapOf()) { (_, info) -> info.copy() },
            flow.conditionalInfos.copy()
        )
    }

    override fun joinFlow(flows: Collection): Flow {
        @Suppress("UNCHECKED_CAST", "NAME_SHADOWING")
        val flows = flows as Collection
        flows.singleOrNull()?.let { return it }
        val approvedFacts: MutableApprovedInfos = mutableMapOf()
        flows.map { it.approvedInfos.keys }
            .intersectSets()
            .forEach { variable ->
                val infos = flows.map { it.approvedInfos[variable]!! }
                if (infos.isNotEmpty()) {
                    approvedFacts[variable] = or(infos)
                }
            }

        val notApprovedFacts: ConditionalInfos = ArrayListMultimap.create()
        flows.map { it.conditionalInfos.keySet() }
            .intersectSets()
            .forEach { variable ->
                val infos = flows.map { it.conditionalInfos[variable] }.intersectSets()
                if (infos.isNotEmpty()) {
                    notApprovedFacts.putAll(variable, infos)
                }
            }

        val result = SimpleFlow(approvedFacts, notApprovedFacts)
        updateAllReceivers(result)
        return result
    }

    override fun collectInfoForBooleanOperator(
        leftFlow: Flow,
        leftVariable: DataFlowVariable,
        rightFlow: Flow,
        rightVariable: DataFlowVariable
    ): InfoForBooleanOperator {
        require(leftFlow is SimpleFlow && rightFlow is SimpleFlow)
        return InfoForBooleanOperator(
            leftFlow.conditionalInfos[leftVariable],
            rightFlow.conditionalInfos[rightVariable],
            rightFlow.approvedInfos - leftFlow.approvedInfos
        )
    }

    private operator fun ApprovedInfos.minus(other: ApprovedInfos): ApprovedInfos {
        val result: MutableApprovedInfos = mutableMapOf()
        forEach { (variable, info) ->
            require(info is MutableFirDataFlowInfo)
            result[variable] = other[variable]?.let { info - it } ?: info
        }
        return result
    }
}

private fun  Multimap.copy(): Multimap = ArrayListMultimap.create(this)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy