No useless null in return value of ExpectedInfos.calculate

This commit is contained in:
Valentin Kipyatkov
2015-08-06 20:35:40 +03:00
parent e6f5cefce3
commit 2728047acd
5 changed files with 28 additions and 30 deletions
@@ -149,7 +149,7 @@ class ExpectedInfos(
val useHeuristicSignatures: Boolean = true,
val useOuterCallsExpectedTypeCount: Int = 0
) {
public fun calculate(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
public fun calculate(expressionWithType: JetExpression): Collection<ExpectedInfo> {
val expectedInfos = calculateForArgument(expressionWithType)
?: calculateForFunctionLiteralArgument(expressionWithType)
?: calculateForEqAndAssignment(expressionWithType)
@@ -164,7 +164,7 @@ class ExpectedInfos(
?: calculateForLoopRange(expressionWithType)
?: calculateForInOperatorArgument(expressionWithType)
?: getFromBindingContext(expressionWithType)
?: return null
?: return emptyList()
return expectedInfos.filterNot { it.fuzzyType?.type?.isError ?: false }
}
@@ -188,8 +188,8 @@ class ExpectedInfos(
return calculateForArgument(call, argument)
}
public fun calculateForArgument(call: Call, argument: ValueArgument): Collection<ExpectedInfo>? {
val results = calculateForArgument(call, TypeUtils.NO_EXPECTED_TYPE, argument) ?: return null
public fun calculateForArgument(call: Call, argument: ValueArgument): Collection<ExpectedInfo> {
val results = calculateForArgument(call, TypeUtils.NO_EXPECTED_TYPE, argument)
fun makesSenseToUseOuterCallExpectedType(info: ExpectedInfo): Boolean {
val data = info.additionalData as ArgumentAdditionalData
@@ -202,21 +202,21 @@ class ExpectedInfos(
val callExpression = (call.callElement as? JetExpression)?.getQualifiedExpressionForSelectorOrThis() ?: return results
val expectedFuzzyTypes = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useHeuristicSignatures, useOuterCallsExpectedTypeCount - 1)
.calculate(callExpression)
?.map { it.fuzzyType }
?.filterNotNull() ?: return results
.map { it.fuzzyType }
.filterNotNull()
if (expectedFuzzyTypes.isEmpty() || expectedFuzzyTypes.any { it.freeParameters.isNotEmpty() }) return results
return expectedFuzzyTypes
.map { it.type }
.toSet()
.flatMap { calculateForArgument(call, it, argument) ?: emptyList() }
.flatMap { calculateForArgument(call, it, argument) }
.toSet()
}
return results
}
private fun calculateForArgument(call: Call, callExpectedType: JetType, argument: ValueArgument): Collection<ExpectedInfo>? {
private fun calculateForArgument(call: Call, callExpectedType: JetType, argument: ValueArgument): Collection<ExpectedInfo> {
val argumentIndex = call.getValueArguments().indexOf(argument)
assert(argumentIndex >= 0) {
"Could not find argument '$argument' among arguments of call: $call"
@@ -236,7 +236,7 @@ class ExpectedInfos(
override fun getFunctionLiteralArguments() = emptyList<FunctionLiteralArgument>()
override fun getValueArgumentList() = null
}
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, call.calleeExpression] ?: return null //TODO: discuss it
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, call.calleeExpression] ?: return emptyList() //TODO: discuss it
val dataFlowInfo = bindingContext.getDataFlowInfo(call.calleeExpression)
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for completion")
@@ -371,13 +371,13 @@ class ExpectedInfos(
return when (expressionWithType) {
ifExpression.getCondition() -> listOf(ExpectedInfo(KotlinBuiltIns.getInstance().getBooleanType(), null, Tail.RPARENTH))
ifExpression.getThen() -> calculate(ifExpression)?.map { ExpectedInfo(it.filter, it.expectedName, Tail.ELSE) }
ifExpression.getThen() -> calculate(ifExpression).map { ExpectedInfo(it.filter, it.expectedName, Tail.ELSE) }
ifExpression.getElse() -> {
val ifExpectedInfo = calculate(ifExpression)
val thenType = ifExpression.getThen()?.let { bindingContext.getType(it) }
if (thenType != null && !thenType.isError())
ifExpectedInfo?.filter { it.matchingSubstitutor(thenType) != null }
ifExpectedInfo.filter { it.matchingSubstitutor(thenType) != null }
else
ifExpectedInfo
}
@@ -395,7 +395,7 @@ class ExpectedInfos(
val leftType = bindingContext.getType(leftExpression)
val leftTypeNotNullable = leftType?.makeNotNullable()
val expectedInfos = calculate(binaryExpression)
if (expectedInfos != null) {
if (expectedInfos.isNotEmpty()) {
return if (leftTypeNotNullable != null)
expectedInfos.filter { it.matchingSubstitutor(leftTypeNotNullable) != null }
else
@@ -417,16 +417,16 @@ class ExpectedInfos(
if (functionLiteral != null) {
val literalExpression = functionLiteral.parent as JetFunctionLiteralExpression
return calculate(literalExpression)
?.map { it.fuzzyType }
?.filterNotNull()
?.filter { KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it.type) }
?.map {
.map { it.fuzzyType }
.filterNotNull()
.filter { KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it.type) }
.map {
val returnType = KotlinBuiltIns.getReturnTypeFromFunctionType(it.type)
ExpectedInfo(FuzzyType(returnType, it.freeParameters), null, Tail.RBRACE)
}
}
else {
return calculate(block)?.map { ExpectedInfo(it.filter, it.expectedName, null) }
return calculate(block).map { ExpectedInfo(it.filter, it.expectedName, null) }
}
}
@@ -217,7 +217,7 @@ class SmartCompletionInBasicWeigher(private val smartCompletion: SmartCompletion
if ((o as? DeclarationLookupObject)?.descriptor in descriptorsToSkip) return DESCRIPTOR_TO_SKIP_WEIGHT
if (expectedInfos == null || expectedInfos.isEmpty()) return NO_MATCH_WEIGHT
if (expectedInfos.isEmpty()) return NO_MATCH_WEIGHT
val smartCastCalculator = smartCompletion.smartCastCalculator
@@ -79,7 +79,7 @@ private fun needExplicitParameterTypes(context: InsertionContext, placeholderRan
val resolutionFacade = file.getResolutionFacade()
val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL)
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, resolutionFacade.findModuleDescriptor(file), useHeuristicSignatures = false)
.calculate(expression) ?: return false
.calculate(expression)
val functionTypes = expectedInfos
.map { it.fuzzyType?.type }
.filterNotNull()
@@ -63,7 +63,7 @@ class SmartCompletion(
private val receiver = if (expression is JetSimpleNameExpression) expression.getReceiverExpression() else null
private val expressionWithType = receiver?.parent as? JetExpression ?: expression
public val expectedInfos: Collection<ExpectedInfo>? = calcExpectedInfos(expressionWithType)
public val expectedInfos: Collection<ExpectedInfo> = calcExpectedInfos(expressionWithType)
public val smartCastCalculator: SmartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression)
@@ -113,7 +113,7 @@ class SmartCompletion(
private fun executeInternal(): Result? {
val (additionalItems, inheritanceSearcher) = additionalItems()
if (expectedInfos == null || expectedInfos.isEmpty()) {
if (expectedInfos.isEmpty()) {
return Result(null, additionalItems, inheritanceSearcher)
}
@@ -147,14 +147,14 @@ class SmartCompletion(
public fun additionalItems(): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
val asTypePositionItems = buildForAsTypePosition()
if (asTypePositionItems != null) {
assert(expectedInfos == null)
assert(expectedInfos.isEmpty())
return Pair(asTypePositionItems, null)
}
val items = ArrayList<LookupElement>()
val inheritanceSearchers = ArrayList<InheritanceItemsSearcher>()
if (expectedInfos != null && expectedInfos.isNotEmpty() && receiver == null) {
if (expectedInfos.isNotEmpty() && receiver == null) {
TypeInstantiationItems(resolutionFacade, moduleDescriptor, bindingContext, visibilityFilter, toFromOriginalFileMapper, inheritorSearchScope, lookupElementFactory, forBasicCompletion)
.addTo(items, inheritanceSearchers, expectedInfos)
@@ -198,11 +198,11 @@ class SmartCompletion(
}
}
private fun calcExpectedInfos(expression: JetExpression): Collection<ExpectedInfo>? {
private fun calcExpectedInfos(expression: JetExpression): Collection<ExpectedInfo> {
if (forBasicCompletion) {
return ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useOuterCallsExpectedTypeCount = 0)
.calculate(expression)
?.map { it.copy(tail = null) }
.map { it.copy(tail = null) }
}
// if our expression is initializer of implicitly typed variable - take type of variable from original file (+ the same for function)
@@ -222,7 +222,7 @@ class SmartCompletion(
var count = 0
while (true) {
val infos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useOuterCallsExpectedTypeCount = count)
.calculate(expression) ?: return null
.calculate(expression)
if (count == 2 /* use two outer calls maximum */ || infos.none { it.fuzzyType?.isAlmostEverything() ?: false }) return infos
count++
}
@@ -342,7 +342,7 @@ class SmartCompletion(
?: return null
val elementType = binaryExpression.getOperationReference().getReferencedNameElementType()
if (elementType != JetTokens.AS_KEYWORD && elementType != JetTokens.AS_SAFE) return null
val expectedInfos = calcExpectedInfos(binaryExpression) ?: return null
val expectedInfos = calcExpectedInfos(binaryExpression)
val expectedInfosGrouped: Map<JetType?, List<ExpectedInfo>> = expectedInfos.groupBy { it.fuzzyType?.type?.makeNotNullable() }
@@ -106,9 +106,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor)
.calculateForArgument(dummyCall, dummyArgument)
if (expectedInfos != null) {
collector.addElements(LambdaItems.collect(expectedInfos))
}
collector.addElements(LambdaItems.collect(expectedInfos))
}
}
}