Use DataFlowValue instead of Descriptor for equality of ESDataFlowValue

Equality of those values is crucial for intersecting data-flow info
coming from expressions like: 'this.x != null || other.x != null'.

Using 'ValueDescriptor' for equality is obviously wrong, because then 'this.x'
and 'other.x' will be treated as equal, leading to unsound smartcasts.

This commit adds proper overload of 'equals' to 'ESDataFlowValue' that
will compare them based on underlying 'DataFlowValue' (which already
distinguish those values)

^KT-27260 Fixed
This commit is contained in:
Dmitry Savvinov
2018-10-01 14:16:36 +03:00
parent dd682bd37d
commit 62edf29cbf
2 changed files with 17 additions and 2 deletions
@@ -23,7 +23,22 @@ import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
class ESDataFlowValue(descriptor: ValueDescriptor, val dataFlowValue: DataFlowValue) : ESVariable(descriptor)
class ESDataFlowValue(descriptor: ValueDescriptor, val dataFlowValue: DataFlowValue) : ESVariable(descriptor) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as ESDataFlowValue
if (dataFlowValue != other.dataFlowValue) return false
return true
}
override fun hashCode(): Int {
return dataFlowValue.hashCode()
}
}
class ESLambda(val lambda: KtLambdaExpression) : ESValue(null) {
override fun <T> accept(visitor: ESExpressionVisitor<T>): T {
@@ -5,7 +5,7 @@ class A(val x: String?) {
fun foo(other: A) {
when {
x == null && other.x == null -> "1"
<!DEBUG_INFO_SMARTCAST!>x<!>.length > 0 -> "2"
x<!UNSAFE_CALL!>.<!>length > 0 -> "2"
}
}
}