x?.y != null and x?.call() != null provoke now x != null, a set of tests #KT-2127 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
9001b9bcc0
commit
11f50186fa
+22
-9
@@ -180,10 +180,11 @@ object DataFlowValueFactory {
|
||||
is KtQualifiedExpression -> {
|
||||
val receiverExpression = expression.receiverExpression
|
||||
val selectorExpression = expression.selectorExpression
|
||||
val receiverId = getIdForStableIdentifier(receiverExpression, bindingContext, containingDeclarationOrModule)
|
||||
val selectorId = getIdForStableIdentifier(selectorExpression, bindingContext, containingDeclarationOrModule)
|
||||
val receiverInfo = getIdForStableIdentifier(receiverExpression, bindingContext, containingDeclarationOrModule)
|
||||
val selectorInfo = getIdForStableIdentifier(selectorExpression, bindingContext, containingDeclarationOrModule)
|
||||
|
||||
IdentifierInfo.qualified(receiverId, selectorId, expression.operationSign === KtTokens.SAFE_ACCESS)
|
||||
IdentifierInfo.qualified(receiverInfo, bindingContext.getType(receiverExpression),
|
||||
selectorInfo, expression.operationSign === KtTokens.SAFE_ACCESS)
|
||||
}
|
||||
is KtSimpleNameExpression ->
|
||||
getIdForSimpleNameExpression(expression, bindingContext, containingDeclarationOrModule)
|
||||
@@ -219,13 +220,25 @@ object DataFlowValueFactory {
|
||||
// for now it fails for resolving 'invoke' convention, return it after 'invoke' algorithm changes
|
||||
// assert resolvedCall != null : "Cannot create right identifier info if the resolved call is not known yet for
|
||||
val usageModuleDescriptor = DescriptorUtils.getContainingModuleOrNull(containingDeclarationOrModule)
|
||||
val receiverInfo = resolvedCall?.let { getIdForImplicitReceiver(it.dispatchReceiver, simpleNameExpression) }
|
||||
val selectorInfo = IdentifierInfo.Variable(declarationDescriptor,
|
||||
variableKind(declarationDescriptor, usageModuleDescriptor,
|
||||
bindingContext, simpleNameExpression))
|
||||
|
||||
IdentifierInfo.qualified(receiverInfo,
|
||||
IdentifierInfo.Variable(declarationDescriptor,
|
||||
variableKind(declarationDescriptor, usageModuleDescriptor,
|
||||
bindingContext, simpleNameExpression)),
|
||||
resolvedCall?.call?.isSafeCall() ?: false)
|
||||
val implicitReceiver = resolvedCall?.dispatchReceiver
|
||||
if (implicitReceiver == null) {
|
||||
selectorInfo
|
||||
}
|
||||
else {
|
||||
val receiverInfo = getIdForImplicitReceiver(implicitReceiver, simpleNameExpression)
|
||||
|
||||
if (receiverInfo == null) {
|
||||
selectorInfo
|
||||
}
|
||||
else {
|
||||
IdentifierInfo.qualified(receiverInfo, implicitReceiver.type,
|
||||
selectorInfo, resolvedCall?.call?.isSafeCall() ?: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
is PackageViewDescriptor, is ClassDescriptor -> IdentifierInfo.PackageOrClass(declarationDescriptor)
|
||||
else -> IdentifierInfo.NO
|
||||
|
||||
+13
-3
@@ -90,8 +90,18 @@ internal class DelegatingDataFlowInfo private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun putNullability(map: MutableMap<DataFlowValue, Nullability>, value: DataFlowValue, nullability: Nullability): Boolean {
|
||||
private fun putNullability(map: MutableMap<DataFlowValue, Nullability>, value: DataFlowValue,
|
||||
nullability: Nullability, affectReceiver: Boolean = true): Boolean {
|
||||
map.put(value, nullability)
|
||||
|
||||
val identifierInfo = value.identifierInfo
|
||||
if (affectReceiver && !nullability.canBeNull() && identifierInfo is IdentifierInfo.Qualified) {
|
||||
val receiverType = identifierInfo.receiverType
|
||||
if (identifierInfo.safe && receiverType != null) {
|
||||
putNullability(map, DataFlowValue(identifierInfo.receiverInfo, receiverType), nullability)
|
||||
}
|
||||
}
|
||||
|
||||
return nullability != getCollectedNullability(value)
|
||||
}
|
||||
|
||||
@@ -135,7 +145,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
||||
override fun assign(a: DataFlowValue, b: DataFlowValue): DataFlowInfo {
|
||||
val nullability = Maps.newHashMap<DataFlowValue, Nullability>()
|
||||
val nullabilityOfB = getPredictableNullability(b)
|
||||
putNullability(nullability, a, nullabilityOfB)
|
||||
putNullability(nullability, a, nullabilityOfB, affectReceiver = false)
|
||||
|
||||
val newTypeInfo = newTypeInfo()
|
||||
var typesForB = getPredictableTypes(b)
|
||||
@@ -212,7 +222,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
||||
val nullabilityOfA = getPredictableNullability(a)
|
||||
val nullabilityOfB = getPredictableNullability(b)
|
||||
|
||||
var changed = putNullability(builder, a, nullabilityOfA.refine(nullabilityOfB.invert())) or
|
||||
val changed = putNullability(builder, a, nullabilityOfA.refine(nullabilityOfB.invert())) or
|
||||
putNullability(builder, b, nullabilityOfB.refine(nullabilityOfA.invert()))
|
||||
return if (changed) create(this, ImmutableMap.copyOf(builder), EMPTY_TYPE_INFO) else this
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user