Data flow values: more accurate handling of postfix ++ and --
This commit is contained in:
+8
-5
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.cfg.ControlFlowInformationProvider
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||||
|
import org.jetbrains.kotlin.lexer.KtToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.before
|
import org.jetbrains.kotlin.psi.psiUtil.before
|
||||||
@@ -140,10 +141,11 @@ object DataFlowValueFactory {
|
|||||||
type: KotlinType
|
type: KotlinType
|
||||||
) = DataFlowValue(ExpressionIdentifierInfo(expression, stableComplex = true), type)
|
) = 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 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 {
|
class ExpressionIdentifierInfo(val expression: KtExpression, stableComplex: Boolean = false) : IdentifierInfo {
|
||||||
@@ -157,12 +159,12 @@ object DataFlowValueFactory {
|
|||||||
override fun toString() = expression.text ?: "(empty expression)"
|
override fun toString() = expression.text ?: "(empty expression)"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postfix(argumentInfo: IdentifierInfo) =
|
private fun postfix(argumentInfo: IdentifierInfo, op: KtToken) =
|
||||||
if (argumentInfo == IdentifierInfo.NO) {
|
if (argumentInfo == IdentifierInfo.NO) {
|
||||||
IdentifierInfo.NO
|
IdentifierInfo.NO
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PostfixIdentifierInfo(argumentInfo)
|
PostfixIdentifierInfo(argumentInfo, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIdForStableIdentifier(
|
private fun getIdForStableIdentifier(
|
||||||
@@ -195,7 +197,8 @@ object DataFlowValueFactory {
|
|||||||
is KtPostfixExpression -> {
|
is KtPostfixExpression -> {
|
||||||
val operationType = expression.operationReference.getReferencedNameElementType()
|
val operationType = expression.operationReference.getReferencedNameElementType()
|
||||||
if (operationType === KtTokens.PLUSPLUS || operationType === KtTokens.MINUSMINUS) {
|
if (operationType === KtTokens.PLUSPLUS || operationType === KtTokens.MINUSMINUS) {
|
||||||
postfix(getIdForStableIdentifier(expression.baseExpression, bindingContext, containingDeclarationOrModule))
|
postfix(getIdForStableIdentifier(expression.baseExpression, bindingContext, containingDeclarationOrModule),
|
||||||
|
operationType)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IdentifierInfo.NO
|
IdentifierInfo.NO
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
fun foo(arg: Int?): Int {
|
||||||
|
var i = arg
|
||||||
|
if (i != null && <!DEBUG_INFO_SMARTCAST!>i<!>++ == 5) {
|
||||||
|
return <!DEBUG_INFO_SMARTCAST!><!DEBUG_INFO_SMARTCAST!>i<!>--<!> + <!DEBUG_INFO_SMARTCAST!>i<!>
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun Long?.inc() = this?.let { it + 1 }
|
||||||
|
|
||||||
|
fun bar(arg: Long?): Long {
|
||||||
|
var i = arg
|
||||||
|
if (i++ == 5L) {
|
||||||
|
return i<!UNSAFE_CALL!>--<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> i
|
||||||
|
}
|
||||||
|
if (i++ == 7L) {
|
||||||
|
return i++ <!NONE_APPLICABLE!>+<!> i
|
||||||
|
}
|
||||||
|
return 0L
|
||||||
|
}
|
||||||
+5
@@ -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?
|
||||||
@@ -18728,6 +18728,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("postfixNotnullClassIncrement.kt")
|
||||||
public void testPostfixNotnullClassIncrement() throws Exception {
|
public void testPostfixNotnullClassIncrement() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user