FIR DFA: remove RealVariableAndType
This commit is contained in:
+26
-20
@@ -1286,32 +1286,35 @@ digraph boundSmartcastsInBranches_kt {
|
||||
506 [label="Exit when branch result"];
|
||||
507 [label="Exit when"];
|
||||
}
|
||||
508 [label="Access variable R|<local>/b|"];
|
||||
509 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
subgraph cluster_97 {
|
||||
color=blue
|
||||
508 [label="Enter when"];
|
||||
510 [label="Enter when"];
|
||||
subgraph cluster_98 {
|
||||
color=blue
|
||||
509 [label="Enter when branch condition "];
|
||||
510 [label="Access variable R|<local>/a|"];
|
||||
511 [label="Const: Null(null)"];
|
||||
512 [label="Equality operator !="];
|
||||
513 [label="Exit when branch condition"];
|
||||
511 [label="Enter when branch condition "];
|
||||
512 [label="Access variable R|<local>/a|"];
|
||||
513 [label="Const: Null(null)"];
|
||||
514 [label="Equality operator !="];
|
||||
515 [label="Exit when branch condition"];
|
||||
}
|
||||
514 [label="Synthetic else branch"];
|
||||
515 [label="Enter when branch result"];
|
||||
516 [label="Synthetic else branch"];
|
||||
517 [label="Enter when branch result"];
|
||||
subgraph cluster_99 {
|
||||
color=blue
|
||||
516 [label="Enter block"];
|
||||
517 [label="Access variable R|<local>/b|"];
|
||||
518 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
519 [label="Exit block"];
|
||||
518 [label="Enter block"];
|
||||
519 [label="Access variable R|<local>/b|"];
|
||||
520 [label="Smart cast: R|<local>/b|"];
|
||||
521 [label="Access variable R|kotlin/String.length|"];
|
||||
522 [label="Exit block"];
|
||||
}
|
||||
520 [label="Exit when branch result"];
|
||||
521 [label="Exit when"];
|
||||
523 [label="Exit when branch result"];
|
||||
524 [label="Exit when"];
|
||||
}
|
||||
522 [label="Exit block"];
|
||||
525 [label="Exit block"];
|
||||
}
|
||||
523 [label="Exit function test_9" style="filled" fillcolor=red];
|
||||
526 [label="Exit function test_9" style="filled" fillcolor=red];
|
||||
}
|
||||
480 -> {481};
|
||||
481 -> {482};
|
||||
@@ -1346,15 +1349,18 @@ digraph boundSmartcastsInBranches_kt {
|
||||
510 -> {511};
|
||||
511 -> {512};
|
||||
512 -> {513};
|
||||
513 -> {515 514};
|
||||
514 -> {521};
|
||||
515 -> {516};
|
||||
516 -> {517};
|
||||
513 -> {514};
|
||||
514 -> {515};
|
||||
515 -> {517 516};
|
||||
516 -> {524};
|
||||
517 -> {518};
|
||||
518 -> {519};
|
||||
519 -> {520};
|
||||
520 -> {521};
|
||||
521 -> {522};
|
||||
522 -> {523};
|
||||
523 -> {524};
|
||||
524 -> {525};
|
||||
525 -> {526};
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -223,9 +223,10 @@ FILE: boundSmartcastsInBranches.kt
|
||||
}
|
||||
}
|
||||
|
||||
R|<local>/b|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
when () {
|
||||
!=(R|<local>/a|, Null(null)) -> {
|
||||
R|<local>/b|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/b|.R|kotlin/String.length|
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
compiler/fir/analysis-tests/testData/resolve/smartcasts/boundSmartcasts/boundSmartcastsInBranches.kt
Vendored
+2
-1
@@ -170,7 +170,8 @@ fun test_9() {
|
||||
} else {
|
||||
b = a
|
||||
}
|
||||
b<!UNSAFE_CALL!>.<!>length // bad
|
||||
if (a != null) {
|
||||
b<!UNSAFE_CALL!>.<!>length // ok
|
||||
b.length // ok
|
||||
}
|
||||
}
|
||||
|
||||
+9
-23
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
|
||||
class DataFlowAnalyzerContext<FLOW : Flow>(
|
||||
@@ -104,15 +103,13 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
val symbol = variable.identifier.symbol
|
||||
|
||||
val index = receiverStack.getReceiverIndex(symbol) ?: return
|
||||
val info = flow.getTypeStatement(variable)
|
||||
|
||||
val type = if (info == null) {
|
||||
receiverStack.getOriginalType(index)
|
||||
} else {
|
||||
val types = info.exactType.toMutableList().also {
|
||||
it += receiverStack.getOriginalType(index)
|
||||
}
|
||||
val info = flow.getType(variable)
|
||||
val type = if (info.isNotEmpty()) {
|
||||
val types = info.toMutableList()
|
||||
types += receiverStack.getOriginalType(index)
|
||||
context.intersectTypesOrNull(types)!!
|
||||
} else {
|
||||
receiverStack.getOriginalType(index)
|
||||
}
|
||||
receiverStack.replaceReceiverType(index, type)
|
||||
}
|
||||
@@ -200,15 +197,8 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
expression: FirExpression
|
||||
): Pair<PropertyStability, MutableList<ConeKotlinType>>? {
|
||||
val flow = graphBuilder.lastNode.flow
|
||||
var variable = variableStorage.getRealVariableWithoutUnwrappingAlias(flow, symbol, expression) ?: return null
|
||||
val stability = variable.stability
|
||||
val result = mutableListOf<ConeKotlinType>()
|
||||
flow.directAliasMap[variable]?.let {
|
||||
result.addIfNotNull(it.originalType)
|
||||
variable = it.variable
|
||||
}
|
||||
flow.getTypeStatement(variable)?.exactType?.let { result += it }
|
||||
return result.takeIf { it.isNotEmpty() }?.let { stability to it }
|
||||
val variable = variableStorage.getRealVariableWithoutUnwrappingAlias(flow, symbol, expression) ?: return null
|
||||
return flow.getType(variable)?.takeIf { it.isNotEmpty() }?.let { variable.stability to it.toMutableList() }
|
||||
}
|
||||
|
||||
fun returnExpressionsOfAnonymousFunction(function: FirAnonymousFunction): Collection<FirStatement> {
|
||||
@@ -1251,11 +1241,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
initializerVariable.isStable || (initializerVariable.hasLocalStability && initializer.isAccessToStableVariable())
|
||||
|
||||
if (!hasExplicitType && isInitializerStable && (propertyVariable.hasLocalStability || propertyVariable.isStable)) {
|
||||
logicSystem.addLocalVariableAlias(
|
||||
flow, propertyVariable,
|
||||
RealVariableAndType(initializerVariable, initializer.coneType)
|
||||
)
|
||||
// node.flow.addImplication((propertyVariable notEq null) implies (initializerVariable notEq null))
|
||||
logicSystem.addLocalVariableAlias(flow, propertyVariable, initializerVariable)
|
||||
} else {
|
||||
logicSystem.replaceVariableFromConditionInStatements(flow, initializerVariable, propertyVariable)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+2
-1
@@ -265,7 +265,8 @@ FILE fqName:<root> fileName:/suspendConversionOnArbitraryExpression.kt
|
||||
TYPE_OP type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=CAST typeOperand=kotlin.coroutines.SuspendFunction0<kotlin.Unit>
|
||||
GET_VAR 'var b: kotlin.Function0<kotlin.Unit> [var] declared in <root>.testSmartCastOnVarVsSuspendConversion' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0<kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
sfn: GET_VAR 'var b: kotlin.Function0<kotlin.Unit> [var] declared in <root>.testSmartCastOnVarVsSuspendConversion' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
sfn: TYPE_OP type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.coroutines.SuspendFunction0<kotlin.Unit>
|
||||
GET_VAR 'var b: kotlin.Function0<kotlin.Unit> [var] declared in <root>.testSmartCastOnVarVsSuspendConversion' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:testIntersectionVsSuspendConversion visibility:public modality:FINAL <T> (x:T of <root>.testIntersectionVsSuspendConversion) returnType:kotlin.Unit
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Function0<kotlin.Unit>; kotlin.coroutines.SuspendFunction0<kotlin.Unit>] reified:false
|
||||
VALUE_PARAMETER name:x index:0 type:T of <root>.testIntersectionVsSuspendConversion
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ fun testSmartCastVsSuspendConversion(a: Function0<Unit>) {
|
||||
fun testSmartCastOnVarVsSuspendConversion(a: Function0<Unit>) {
|
||||
var b: Function0<Unit> = a
|
||||
b as SuspendFunction0<Unit> /*~> Unit */
|
||||
useSuspend(sfn = b)
|
||||
useSuspend(sfn = b /*as SuspendFunction0<Unit> */)
|
||||
}
|
||||
|
||||
fun <T> testIntersectionVsSuspendConversion(x: T) where T : Function0<Unit>, T : SuspendFunction0<Unit> {
|
||||
|
||||
@@ -206,20 +206,20 @@ fun <T> T.case_7() {
|
||||
val x = this
|
||||
if (x is Interface1?) {
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.equals(null)
|
||||
x.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.propNullableAny
|
||||
x.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.itest1()
|
||||
|
||||
x.apply {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>
|
||||
equals(null)
|
||||
propT
|
||||
propAny
|
||||
@@ -230,29 +230,29 @@ fun <T> T.case_7() {
|
||||
funNullableT()
|
||||
funNullableAny()
|
||||
itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.itest1()
|
||||
}
|
||||
x.also {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.funNullableAny()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,20 +258,20 @@ fun <T> case_7(y: T) {
|
||||
val x = y
|
||||
if (x is Interface1?) {
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.equals(null)
|
||||
x.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.propNullableAny
|
||||
x.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T!! & Interface1")!>x<!>.itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & Interface1 & T!!")!>x<!>.itest()
|
||||
|
||||
x.apply {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>
|
||||
equals(null)
|
||||
propT
|
||||
propAny
|
||||
@@ -282,29 +282,29 @@ fun <T> case_7(y: T) {
|
||||
funNullableT()
|
||||
funNullableAny()
|
||||
itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>this<!>.itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>this<!>.itest()
|
||||
}
|
||||
x.also {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & Interface1")!>it<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T!!")!>it<!>.funNullableAny()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user