Implementation of smart casts for public / protected immutable properties that are not open and used in the same module.

DataFlowValueFactory and its environment refactoring: containing declaration is added into factory functions
as an argument and used to determine identifier stability. A few minor fixes. #KT-5907 Fixed. #KT-4450 Fixed. #KT-4409 Fixed.

New tests for KT-4409, KT-4450, KT-5907 (public and protected value properties used from the same module or not,
open properties, variable properties, delegated properties, properties with non-default getter).
Public val test and KT-362 test changed accordingly.
This commit is contained in:
Mikhail Glukhikh
2015-03-24 17:03:01 +03:00
parent 0b27d9181a
commit 9c1551bca9
39 changed files with 502 additions and 116 deletions
@@ -100,7 +100,10 @@ public class ReferenceVariantsHelper(
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
val dataFlowInfo = context.getDataFlowInfo(expression)
for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, dataFlowInfo)) {
for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue,
context,
resolutionScope.getContainingDeclaration(),
dataFlowInfo)) {
descriptors.addMembersFromReceiver(variant, callType, kindFilter, nameFilter)
}
@@ -48,12 +48,12 @@ public fun CallableDescriptor.substituteExtensionIfCallable(
dataFlowInfo: DataFlowInfo,
callType: CallType
): Collection<CallableDescriptor> {
val stream = receivers.stream().flatMap { substituteExtensionIfCallable(it, callType, context, dataFlowInfo).stream() }
val sequence = receivers.sequence().flatMap { substituteExtensionIfCallable(it, callType, context, dataFlowInfo).sequence() }
if (getTypeParameters().isEmpty()) { // optimization for non-generic callables
return stream.firstOrNull()?.let { listOf(it) } ?: listOf()
return sequence.firstOrNull()?.let { listOf(it) } ?: listOf()
}
else {
return stream.toList()
return sequence.toList()
}
}
@@ -69,7 +69,7 @@ public fun CallableDescriptor.substituteExtensionIfCallable(
if (!receiver.exists()) return listOf()
if (!callType.canCall(this)) return listOf()
var types = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, dataFlowInfo).stream()
var types = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, getContainingDeclaration(), dataFlowInfo).sequence()
if (callType == CallType.SAFE) {
types = types.map { it.makeNotNullable() }