[FIR] Cleanup FIR modules. Part 2 (dfa package)
This commit is contained in:
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.references.FirReference
|
|||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildBackingFieldReference
|
import org.jetbrains.kotlin.fir.references.builder.buildBackingFieldReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
@@ -64,7 +63,7 @@ class FirCallResolver(
|
|||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
val functionCall = functionCall.transformExplicitReceiver(transformer, ResolutionMode.ContextIndependent)
|
val functionCall = functionCall.transformExplicitReceiver(transformer, ResolutionMode.ContextIndependent)
|
||||||
.also {
|
.also {
|
||||||
dataFlowAnalyzer.enterQualifiedAccessExpression(functionCall)
|
dataFlowAnalyzer.enterQualifiedAccessExpression()
|
||||||
functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-21
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.dfa
|
package org.jetbrains.kotlin.fir.resolve.dfa
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
||||||
import org.jetbrains.kotlin.fir.contracts.description.ConeBooleanConstantReference
|
import org.jetbrains.kotlin.fir.contracts.description.ConeBooleanConstantReference
|
||||||
@@ -17,7 +16,6 @@ import org.jetbrains.kotlin.fir.expressions.*
|
|||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack
|
import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.contracts.buildContractFir
|
import org.jetbrains.kotlin.fir.resolve.dfa.contracts.buildContractFir
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.contracts.createArgumentsMapping
|
import org.jetbrains.kotlin.fir.resolve.dfa.contracts.createArgumentsMapping
|
||||||
@@ -30,6 +28,7 @@ import org.jetbrains.kotlin.fir.visitors.transformSingle
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
class DataFlowAnalyzerContext<FLOW : Flow>(
|
class DataFlowAnalyzerContext<FLOW : Flow>(
|
||||||
val graphBuilder: ControlFlowGraphBuilder,
|
val graphBuilder: ControlFlowGraphBuilder,
|
||||||
@@ -599,9 +598,9 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
graphBuilder.exitCatchClause(catch).mergeIncomingFlow()
|
graphBuilder.exitCatchClause(catch).mergeIncomingFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enterFinallyBlock(tryExpression: FirTryExpression) {
|
fun enterFinallyBlock() {
|
||||||
// TODO
|
// TODO
|
||||||
graphBuilder.enterFinallyBlock(tryExpression).mergeIncomingFlow()
|
graphBuilder.enterFinallyBlock().mergeIncomingFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitFinallyBlock(tryExpression: FirTryExpression) {
|
fun exitFinallyBlock(tryExpression: FirTryExpression) {
|
||||||
@@ -609,9 +608,9 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
graphBuilder.exitFinallyBlock(tryExpression).mergeIncomingFlow()
|
graphBuilder.exitFinallyBlock(tryExpression).mergeIncomingFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitTryExpression(tryExpression: FirTryExpression, callCompleted: Boolean) {
|
fun exitTryExpression(callCompleted: Boolean) {
|
||||||
// TODO
|
// TODO
|
||||||
val (tryExpressionExitNode, unionNode) = graphBuilder.exitTryExpression(tryExpression, callCompleted)
|
val (tryExpressionExitNode, unionNode) = graphBuilder.exitTryExpression(callCompleted)
|
||||||
tryExpressionExitNode.mergeIncomingFlow()
|
tryExpressionExitNode.mergeIncomingFlow()
|
||||||
unionNode?.let { unionFlowFromArguments(it) }
|
unionNode?.let { unionFlowFromArguments(it) }
|
||||||
}
|
}
|
||||||
@@ -619,7 +618,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
// ----------------------------------- Resolvable call -----------------------------------
|
// ----------------------------------- Resolvable call -----------------------------------
|
||||||
|
|
||||||
// Intentionally left empty for potential future needs (call sites are preserved)
|
// Intentionally left empty for potential future needs (call sites are preserved)
|
||||||
fun enterQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) {}
|
fun enterQualifiedAccessExpression() {}
|
||||||
|
|
||||||
fun exitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) {
|
fun exitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) {
|
||||||
graphBuilder.exitQualifiedAccessExpression(qualifiedAccessExpression).mergeIncomingFlow()
|
graphBuilder.exitQualifiedAccessExpression(qualifiedAccessExpression).mergeIncomingFlow()
|
||||||
@@ -663,7 +662,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun exitSafeCall(safeCall: FirSafeCallExpression) {
|
fun exitSafeCall(safeCall: FirSafeCallExpression) {
|
||||||
val node = graphBuilder.exitSafeCall(safeCall).mergeIncomingFlow()
|
val node = graphBuilder.exitSafeCall().mergeIncomingFlow()
|
||||||
val previousFlow = node.previousFlow
|
val previousFlow = node.previousFlow
|
||||||
|
|
||||||
val variable = variableStorage.getOrCreateVariable(previousFlow, safeCall)
|
val variable = variableStorage.getOrCreateVariable(previousFlow, safeCall)
|
||||||
@@ -682,8 +681,8 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
graphBuilder.exitResolvedQualifierNode(resolvedQualifier).mergeIncomingFlow()
|
graphBuilder.exitResolvedQualifierNode(resolvedQualifier).mergeIncomingFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enterCall(functionCall: FirCall) {
|
fun enterCall() {
|
||||||
graphBuilder.enterCall(functionCall)
|
graphBuilder.enterCall()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitFunctionCall(functionCall: FirFunctionCall, callCompleted: Boolean) {
|
fun exitFunctionCall(functionCall: FirFunctionCall, callCompleted: Boolean) {
|
||||||
@@ -838,7 +837,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
|
|
||||||
if (isAssignment) {
|
if (isAssignment) {
|
||||||
if (initializer is FirConstExpression<*> && initializer.kind == FirConstKind.Null) return
|
if (initializer is FirConstExpression<*> && initializer.kind == FirConstKind.Null) return
|
||||||
flow.addTypeStatement(propertyVariable typeEq initializer.typeRef.coneTypeUnsafe<ConeKotlinType>())
|
flow.addTypeStatement(propertyVariable typeEq initializer.typeRef.coneTypeUnsafe())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -894,6 +893,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
node: AbstractBinaryExitNode<*>,
|
node: AbstractBinaryExitNode<*>,
|
||||||
isAnd: Boolean
|
isAnd: Boolean
|
||||||
) {
|
) {
|
||||||
|
@Suppress("UnnecessaryVariable")
|
||||||
val bothEvaluated = isAnd
|
val bothEvaluated = isAnd
|
||||||
val onlyLeftEvaluated = !bothEvaluated
|
val onlyLeftEvaluated = !bothEvaluated
|
||||||
|
|
||||||
@@ -1064,13 +1064,3 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
private val CFGNode<*>.previousFlow: FLOW
|
private val CFGNode<*>.previousFlow: FLOW
|
||||||
get() = firstPreviousNode.flow
|
get() = firstPreviousNode.flow
|
||||||
}
|
}
|
||||||
|
|
||||||
@DfaInternals
|
|
||||||
fun FirElement.extractReturnType(): ConeKotlinType = when (this) {
|
|
||||||
is FirVariable<*> -> returnTypeRef.coneTypeUnsafe()
|
|
||||||
is FirSimpleFunction -> receiverTypeRef?.coneTypeUnsafe()
|
|
||||||
is FirAnonymousFunction -> receiverTypeRef?.coneTypeUnsafe()
|
|
||||||
is FirRegularClass -> defaultType()
|
|
||||||
is FirAnonymousObject -> typeRef.coneTypeUnsafe()
|
|
||||||
else -> null
|
|
||||||
} ?: throw IllegalArgumentException("Unsupported fir: $this")
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
|
|||||||
val allTypes = types.flatMapTo(mutableSetOf()) { it }
|
val allTypes = types.flatMapTo(mutableSetOf()) { it }
|
||||||
val commonTypes = allTypes.toMutableSet()
|
val commonTypes = allTypes.toMutableSet()
|
||||||
types.forEach { commonTypes.retainAll(it) }
|
types.forEach { commonTypes.retainAll(it) }
|
||||||
val differentTypes = types.mapNotNull { (it - commonTypes).takeIf { it.isNotEmpty() } }
|
val differentTypes = types.mapNotNull { typeSet -> (typeSet - commonTypes).takeIf { it.isNotEmpty() } }
|
||||||
if (differentTypes.size == types.size) {
|
if (differentTypes.size == types.size) {
|
||||||
context.commonSuperTypeOrNull(differentTypes.flatten())?.let { commonTypes += it }
|
context.commonSuperTypeOrNull(differentTypes.flatten())?.let { commonTypes += it }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
|||||||
}
|
}
|
||||||
|
|
||||||
private abstract class DiffIterable<T>(private val parentFlow: PersistentFlow, private var currentFlow: PersistentFlow) : Iterable<T> {
|
private abstract class DiffIterable<T>(private val parentFlow: PersistentFlow, private var currentFlow: PersistentFlow) : Iterable<T> {
|
||||||
|
@Suppress("LeakingThis")
|
||||||
private var currentIterator = extractIterator(currentFlow)
|
private var currentIterator = extractIterator(currentFlow)
|
||||||
|
|
||||||
abstract fun extractIterator(flow: PersistentFlow): Iterator<T>
|
abstract fun extractIterator(flow: PersistentFlow): Iterator<T>
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import org.jetbrains.kotlin.fir.FirSourceElement
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
|
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.runIf
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level: Int, private val id: Int) {
|
sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level: Int, private val id: Int) {
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+5
-5
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.isNothing
|
import org.jetbrains.kotlin.fir.types.isNothing
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@RequiresOptIn
|
@RequiresOptIn
|
||||||
@@ -57,7 +58,7 @@ class ControlFlowGraphBuilder {
|
|||||||
private val shouldPassFlowFromInplaceLambda: Stack<Boolean> = stackOf(true)
|
private val shouldPassFlowFromInplaceLambda: Stack<Boolean> = stackOf(true)
|
||||||
|
|
||||||
private enum class Mode {
|
private enum class Mode {
|
||||||
Function, DefaultArguments, TopLevel, Body, ClassInitializer, PropertyInitializer
|
Function, TopLevel, Body, ClassInitializer, PropertyInitializer
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------- Node caches -----------------------------------
|
// ----------------------------------- Node caches -----------------------------------
|
||||||
@@ -773,7 +774,7 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enterFinallyBlock(tryExpression: FirTryExpression): FinallyBlockEnterNode {
|
fun enterFinallyBlock(): FinallyBlockEnterNode {
|
||||||
val enterNode = finallyEnterNodes.pop()
|
val enterNode = finallyEnterNodes.pop()
|
||||||
lastNodes.push(enterNode)
|
lastNodes.push(enterNode)
|
||||||
return enterNode
|
return enterNode
|
||||||
@@ -787,7 +788,6 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun exitTryExpression(
|
fun exitTryExpression(
|
||||||
tryExpression: FirTryExpression,
|
|
||||||
callCompleted: Boolean
|
callCompleted: Boolean
|
||||||
): Pair<TryExpressionExitNode, UnionFunctionCallArgumentsNode?> {
|
): Pair<TryExpressionExitNode, UnionFunctionCallArgumentsNode?> {
|
||||||
levelCounter--
|
levelCounter--
|
||||||
@@ -816,7 +816,7 @@ class ControlFlowGraphBuilder {
|
|||||||
return createResolvedQualifierNode(resolvedQualifier).also(this::addNewSimpleNode)
|
return createResolvedQualifierNode(resolvedQualifier).also(this::addNewSimpleNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enterCall(call: FirCall) {
|
fun enterCall() {
|
||||||
levelCounter++
|
levelCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -979,7 +979,7 @@ class ControlFlowGraphBuilder {
|
|||||||
return enterNode
|
return enterNode
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitSafeCall(safeCall: FirSafeCallExpression): ExitSafeCallNode {
|
fun exitSafeCall(): ExitSafeCallNode {
|
||||||
return exitSafeCallNodes.pop().also {
|
return exitSafeCallNodes.pop().also {
|
||||||
addNewSimpleNode(it)
|
addNewSimpleNode(it)
|
||||||
it.updateDeadStatus()
|
it.updateDeadStatus()
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
// --------------------------------------- Variables ---------------------------------------
|
// --------------------------------------- Variables ---------------------------------------
|
||||||
|
|
||||||
@@ -159,6 +161,8 @@ abstract class TypeStatement : Statement<TypeStatement>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun TypeStatement.plus(other: TypeStatement?): TypeStatement = other?.let { this + other } ?: this
|
||||||
|
|
||||||
class MutableTypeStatement(
|
class MutableTypeStatement(
|
||||||
override val variable: RealVariable,
|
override val variable: RealVariable,
|
||||||
override val exactType: MutableSet<ConeKotlinType> = linkedSetOf(),
|
override val exactType: MutableSet<ConeKotlinType> = linkedSetOf(),
|
||||||
@@ -205,6 +209,16 @@ fun Implication.invertCondition(): Implication = Implication(condition.invert(),
|
|||||||
typealias TypeStatements = Map<RealVariable, TypeStatement>
|
typealias TypeStatements = Map<RealVariable, TypeStatement>
|
||||||
typealias MutableTypeStatements = MutableMap<RealVariable, MutableTypeStatement>
|
typealias MutableTypeStatements = MutableMap<RealVariable, MutableTypeStatement>
|
||||||
|
|
||||||
|
fun MutableTypeStatements.addStatement(variable: RealVariable, statement: TypeStatement) {
|
||||||
|
put(variable, statement.asMutableStatement()) { it.apply { this += statement } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableTypeStatements.mergeTypeStatements(other: TypeStatements) {
|
||||||
|
other.forEach { (variable, info) ->
|
||||||
|
addStatement(variable, info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------- DSL ---------------------------------------
|
// --------------------------------------- DSL ---------------------------------------
|
||||||
|
|
||||||
infix fun DataFlowVariable.eq(constant: Boolean?): OperationStatement {
|
infix fun DataFlowVariable.eq(constant: Boolean?): OperationStatement {
|
||||||
@@ -240,3 +254,23 @@ infix fun RealVariable.typeNotEq(type: ConeKotlinType): TypeStatement =
|
|||||||
} else {
|
} else {
|
||||||
MutableTypeStatement(this)
|
MutableTypeStatement(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------- Utils ---------------------------------------
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
fun DataFlowVariable.isSynthetic(): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (this@isSynthetic is SyntheticVariable)
|
||||||
|
returns(false) implies (this@isSynthetic is RealVariable)
|
||||||
|
}
|
||||||
|
return this is SyntheticVariable
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
fun DataFlowVariable.isReal(): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (this@isReal is RealVariable)
|
||||||
|
returns(false) implies (this@isReal is SyntheticVariable)
|
||||||
|
}
|
||||||
|
return this is RealVariable
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,36 +25,6 @@ import kotlin.contracts.ExperimentalContracts
|
|||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
|
||||||
fun DataFlowVariable.isSynthetic(): Boolean {
|
|
||||||
contract {
|
|
||||||
returns(true) implies (this@isSynthetic is SyntheticVariable)
|
|
||||||
returns(false) implies (this@isSynthetic is RealVariable)
|
|
||||||
}
|
|
||||||
return this is SyntheticVariable
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
|
||||||
fun DataFlowVariable.isReal(): Boolean {
|
|
||||||
contract {
|
|
||||||
returns(true) implies (this@isReal is RealVariable)
|
|
||||||
returns(false) implies (this@isReal is SyntheticVariable)
|
|
||||||
}
|
|
||||||
return this is RealVariable
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun TypeStatement.plus(other: TypeStatement?): TypeStatement = other?.let { this + other } ?: this
|
|
||||||
|
|
||||||
fun MutableTypeStatements.addStatement(variable: RealVariable, statement: TypeStatement) {
|
|
||||||
put(variable, statement.asMutableStatement()) { it.apply { this += statement } }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun MutableTypeStatements.mergeTypeStatements(other: TypeStatements) {
|
|
||||||
other.forEach { (variable, info) ->
|
|
||||||
addStatement(variable, info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
internal inline fun <K, V> MutableMap<K, V>.put(key: K, value: V, remappingFunction: (existing: V) -> V) {
|
internal inline fun <K, V> MutableMap<K, V>.put(key: K, value: V, remappingFunction: (existing: V) -> V) {
|
||||||
contract {
|
contract {
|
||||||
@@ -69,7 +39,11 @@ internal inline fun <K, V> MutableMap<K, V>.put(key: K, value: V, remappingFunct
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
internal inline fun <K, V> PersistentMap<K, V>.put(key: K, valueProducer: () -> V, remappingFunction: (existing: V) -> V): PersistentMap<K, V> {
|
internal inline fun <K, V> PersistentMap<K, V>.put(
|
||||||
|
key: K,
|
||||||
|
valueProducer: () -> V,
|
||||||
|
remappingFunction: (existing: V) -> V
|
||||||
|
): PersistentMap<K, V> {
|
||||||
contract {
|
contract {
|
||||||
callsInPlace(remappingFunction, InvocationKind.AT_MOST_ONCE)
|
callsInPlace(remappingFunction, InvocationKind.AT_MOST_ONCE)
|
||||||
callsInPlace(valueProducer, InvocationKind.AT_MOST_ONCE)
|
callsInPlace(valueProducer, InvocationKind.AT_MOST_ONCE)
|
||||||
@@ -135,10 +109,3 @@ internal val FirResolvable.symbol: AbstractFirBasedSymbol<*>?
|
|||||||
is FirNamedReferenceWithCandidate -> reference.candidateSymbol
|
is FirNamedReferenceWithCandidate -> reference.candidateSymbol
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
//val ConeKotlinType.isNothingOrNullableNothing: Boolean = when (this) {
|
|
||||||
// is ConeFlexibleType -> lowerBound.isNothingOrNullableNothing
|
|
||||||
// else -> false
|
|
||||||
//}
|
|
||||||
|
|
||||||
inline fun <R> runIf(condition: Boolean, block: () -> R): R? = if (condition) block() else null
|
|
||||||
+2
-2
@@ -162,13 +162,13 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = if (result.finallyBlock != null) {
|
result = if (result.finallyBlock != null) {
|
||||||
result.also(dataFlowAnalyzer::enterFinallyBlock)
|
result.also { dataFlowAnalyzer.enterFinallyBlock() }
|
||||||
.transformFinallyBlock(transformer, ResolutionMode.ContextIndependent)
|
.transformFinallyBlock(transformer, ResolutionMode.ContextIndependent)
|
||||||
.also(dataFlowAnalyzer::exitFinallyBlock)
|
.also(dataFlowAnalyzer::exitFinallyBlock)
|
||||||
} else {
|
} else {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
dataFlowAnalyzer.exitTryExpression(result, callCompleted)
|
dataFlowAnalyzer.exitTryExpression(callCompleted)
|
||||||
return result.compose()
|
return result.compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -158,7 +158,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
}
|
}
|
||||||
when (result) {
|
when (result) {
|
||||||
is FirQualifiedAccessExpression -> {
|
is FirQualifiedAccessExpression -> {
|
||||||
dataFlowAnalyzer.enterQualifiedAccessExpression(result)
|
dataFlowAnalyzer.enterQualifiedAccessExpression()
|
||||||
result = components.transformQualifiedAccessUsingSmartcastInfo(result)
|
result = components.transformQualifiedAccessUsingSmartcastInfo(result)
|
||||||
dataFlowAnalyzer.exitQualifiedAccessExpression(result)
|
dataFlowAnalyzer.exitQualifiedAccessExpression(result)
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
storeTypeFromCallee(functionCall)
|
storeTypeFromCallee(functionCall)
|
||||||
}
|
}
|
||||||
if (functionCall.calleeReference !is FirSimpleNamedReference) return functionCall.compose()
|
if (functionCall.calleeReference !is FirSimpleNamedReference) return functionCall.compose()
|
||||||
dataFlowAnalyzer.enterCall(functionCall)
|
dataFlowAnalyzer.enterCall()
|
||||||
functionCall.annotations.forEach { it.accept(this, data) }
|
functionCall.annotations.forEach { it.accept(this, data) }
|
||||||
functionCall.transform<FirFunctionCall, Nothing?>(InvocationKindTransformer, null)
|
functionCall.transform<FirFunctionCall, Nothing?>(InvocationKindTransformer, null)
|
||||||
functionCall.transformTypeArguments(transformer, ResolutionMode.ContextIndependent)
|
functionCall.transformTypeArguments(transformer, ResolutionMode.ContextIndependent)
|
||||||
@@ -700,7 +700,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
dataFlowAnalyzer.enterCall(delegatedConstructorCall)
|
dataFlowAnalyzer.enterCall()
|
||||||
var callCompleted = true
|
var callCompleted = true
|
||||||
var result = delegatedConstructorCall
|
var result = delegatedConstructorCall
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user