diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowValueFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowValueFactory.kt index 09141d1c64d..eaf0786766f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowValueFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowValueFactory.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.cfg.ControlFlowInformationProvider import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor +import org.jetbrains.kotlin.lexer.KtToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.before @@ -140,10 +141,11 @@ object DataFlowValueFactory { type: KotlinType ) = DataFlowValue(ExpressionIdentifierInfo(expression, stableComplex = true), type) - private data class PostfixIdentifierInfo(val argumentInfo: IdentifierInfo) : IdentifierInfo { + // For only ++ and -- postfix operations + private data class PostfixIdentifierInfo(val argumentInfo: IdentifierInfo, val op: KtToken) : IdentifierInfo { override val kind: DataFlowValue.Kind get() = argumentInfo.kind - override fun toString() = "$argumentInfo (postfix)" + override fun toString() = "$argumentInfo($op)" } class ExpressionIdentifierInfo(val expression: KtExpression, stableComplex: Boolean = false) : IdentifierInfo { @@ -157,12 +159,12 @@ object DataFlowValueFactory { override fun toString() = expression.text ?: "(empty expression)" } - private fun postfix(argumentInfo: IdentifierInfo) = + private fun postfix(argumentInfo: IdentifierInfo, op: KtToken) = if (argumentInfo == IdentifierInfo.NO) { IdentifierInfo.NO } else { - PostfixIdentifierInfo(argumentInfo) + PostfixIdentifierInfo(argumentInfo, op) } private fun getIdForStableIdentifier( @@ -195,7 +197,8 @@ object DataFlowValueFactory { is KtPostfixExpression -> { val operationType = expression.operationReference.getReferencedNameElementType() if (operationType === KtTokens.PLUSPLUS || operationType === KtTokens.MINUSMINUS) { - postfix(getIdForStableIdentifier(expression.baseExpression, bindingContext, containingDeclarationOrModule)) + postfix(getIdForStableIdentifier(expression.baseExpression, bindingContext, containingDeclarationOrModule), + operationType) } else { IdentifierInfo.NO diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.kt new file mode 100644 index 00000000000..98bbe9f7ac8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.kt @@ -0,0 +1,20 @@ +fun foo(arg: Int?): Int { + var i = arg + if (i != null && i++ == 5) { + return i-- + i + } + return 0 +} + +operator fun Long?.inc() = this?.let { it + 1 } + +fun bar(arg: Long?): Long { + var i = arg + if (i++ == 5L) { + return i-- + i + } + if (i++ == 7L) { + return i++ + i + } + return 0L +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.txt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.txt new file mode 100644 index 00000000000..ac4298f10c5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.txt @@ -0,0 +1,5 @@ +package + +public fun bar(/*0*/ arg: kotlin.Long?): kotlin.Long +public fun foo(/*0*/ arg: kotlin.Int?): kotlin.Int +public operator fun kotlin.Long?.inc(): kotlin.Long? diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 23cd5aa9031..2da5ef43d2f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -18728,6 +18728,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("plusplusMinusminus.kt") + public void testPlusplusMinusminus() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.kt"); + doTest(fileName); + } + @TestMetadata("postfixNotnullClassIncrement.kt") public void testPostfixNotnullClassIncrement() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.kt");