No useless null in return value of ExpectedInfos.calculate
This commit is contained in:
@@ -149,7 +149,7 @@ class ExpectedInfos(
|
|||||||
val useHeuristicSignatures: Boolean = true,
|
val useHeuristicSignatures: Boolean = true,
|
||||||
val useOuterCallsExpectedTypeCount: Int = 0
|
val useOuterCallsExpectedTypeCount: Int = 0
|
||||||
) {
|
) {
|
||||||
public fun calculate(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
public fun calculate(expressionWithType: JetExpression): Collection<ExpectedInfo> {
|
||||||
val expectedInfos = calculateForArgument(expressionWithType)
|
val expectedInfos = calculateForArgument(expressionWithType)
|
||||||
?: calculateForFunctionLiteralArgument(expressionWithType)
|
?: calculateForFunctionLiteralArgument(expressionWithType)
|
||||||
?: calculateForEqAndAssignment(expressionWithType)
|
?: calculateForEqAndAssignment(expressionWithType)
|
||||||
@@ -164,7 +164,7 @@ class ExpectedInfos(
|
|||||||
?: calculateForLoopRange(expressionWithType)
|
?: calculateForLoopRange(expressionWithType)
|
||||||
?: calculateForInOperatorArgument(expressionWithType)
|
?: calculateForInOperatorArgument(expressionWithType)
|
||||||
?: getFromBindingContext(expressionWithType)
|
?: getFromBindingContext(expressionWithType)
|
||||||
?: return null
|
?: return emptyList()
|
||||||
return expectedInfos.filterNot { it.fuzzyType?.type?.isError ?: false }
|
return expectedInfos.filterNot { it.fuzzyType?.type?.isError ?: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,8 +188,8 @@ class ExpectedInfos(
|
|||||||
return calculateForArgument(call, argument)
|
return calculateForArgument(call, argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun calculateForArgument(call: Call, argument: ValueArgument): Collection<ExpectedInfo>? {
|
public fun calculateForArgument(call: Call, argument: ValueArgument): Collection<ExpectedInfo> {
|
||||||
val results = calculateForArgument(call, TypeUtils.NO_EXPECTED_TYPE, argument) ?: return null
|
val results = calculateForArgument(call, TypeUtils.NO_EXPECTED_TYPE, argument)
|
||||||
|
|
||||||
fun makesSenseToUseOuterCallExpectedType(info: ExpectedInfo): Boolean {
|
fun makesSenseToUseOuterCallExpectedType(info: ExpectedInfo): Boolean {
|
||||||
val data = info.additionalData as ArgumentAdditionalData
|
val data = info.additionalData as ArgumentAdditionalData
|
||||||
@@ -202,21 +202,21 @@ class ExpectedInfos(
|
|||||||
val callExpression = (call.callElement as? JetExpression)?.getQualifiedExpressionForSelectorOrThis() ?: return results
|
val callExpression = (call.callElement as? JetExpression)?.getQualifiedExpressionForSelectorOrThis() ?: return results
|
||||||
val expectedFuzzyTypes = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useHeuristicSignatures, useOuterCallsExpectedTypeCount - 1)
|
val expectedFuzzyTypes = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useHeuristicSignatures, useOuterCallsExpectedTypeCount - 1)
|
||||||
.calculate(callExpression)
|
.calculate(callExpression)
|
||||||
?.map { it.fuzzyType }
|
.map { it.fuzzyType }
|
||||||
?.filterNotNull() ?: return results
|
.filterNotNull()
|
||||||
if (expectedFuzzyTypes.isEmpty() || expectedFuzzyTypes.any { it.freeParameters.isNotEmpty() }) return results
|
if (expectedFuzzyTypes.isEmpty() || expectedFuzzyTypes.any { it.freeParameters.isNotEmpty() }) return results
|
||||||
|
|
||||||
return expectedFuzzyTypes
|
return expectedFuzzyTypes
|
||||||
.map { it.type }
|
.map { it.type }
|
||||||
.toSet()
|
.toSet()
|
||||||
.flatMap { calculateForArgument(call, it, argument) ?: emptyList() }
|
.flatMap { calculateForArgument(call, it, argument) }
|
||||||
.toSet()
|
.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
return results
|
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)
|
val argumentIndex = call.getValueArguments().indexOf(argument)
|
||||||
assert(argumentIndex >= 0) {
|
assert(argumentIndex >= 0) {
|
||||||
"Could not find argument '$argument' among arguments of call: $call"
|
"Could not find argument '$argument' among arguments of call: $call"
|
||||||
@@ -236,7 +236,7 @@ class ExpectedInfos(
|
|||||||
override fun getFunctionLiteralArguments() = emptyList<FunctionLiteralArgument>()
|
override fun getFunctionLiteralArguments() = emptyList<FunctionLiteralArgument>()
|
||||||
override fun getValueArgumentList() = null
|
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 dataFlowInfo = bindingContext.getDataFlowInfo(call.calleeExpression)
|
||||||
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for completion")
|
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for completion")
|
||||||
@@ -371,13 +371,13 @@ class ExpectedInfos(
|
|||||||
return when (expressionWithType) {
|
return when (expressionWithType) {
|
||||||
ifExpression.getCondition() -> listOf(ExpectedInfo(KotlinBuiltIns.getInstance().getBooleanType(), null, Tail.RPARENTH))
|
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() -> {
|
ifExpression.getElse() -> {
|
||||||
val ifExpectedInfo = calculate(ifExpression)
|
val ifExpectedInfo = calculate(ifExpression)
|
||||||
val thenType = ifExpression.getThen()?.let { bindingContext.getType(it) }
|
val thenType = ifExpression.getThen()?.let { bindingContext.getType(it) }
|
||||||
if (thenType != null && !thenType.isError())
|
if (thenType != null && !thenType.isError())
|
||||||
ifExpectedInfo?.filter { it.matchingSubstitutor(thenType) != null }
|
ifExpectedInfo.filter { it.matchingSubstitutor(thenType) != null }
|
||||||
else
|
else
|
||||||
ifExpectedInfo
|
ifExpectedInfo
|
||||||
}
|
}
|
||||||
@@ -395,7 +395,7 @@ class ExpectedInfos(
|
|||||||
val leftType = bindingContext.getType(leftExpression)
|
val leftType = bindingContext.getType(leftExpression)
|
||||||
val leftTypeNotNullable = leftType?.makeNotNullable()
|
val leftTypeNotNullable = leftType?.makeNotNullable()
|
||||||
val expectedInfos = calculate(binaryExpression)
|
val expectedInfos = calculate(binaryExpression)
|
||||||
if (expectedInfos != null) {
|
if (expectedInfos.isNotEmpty()) {
|
||||||
return if (leftTypeNotNullable != null)
|
return if (leftTypeNotNullable != null)
|
||||||
expectedInfos.filter { it.matchingSubstitutor(leftTypeNotNullable) != null }
|
expectedInfos.filter { it.matchingSubstitutor(leftTypeNotNullable) != null }
|
||||||
else
|
else
|
||||||
@@ -417,16 +417,16 @@ class ExpectedInfos(
|
|||||||
if (functionLiteral != null) {
|
if (functionLiteral != null) {
|
||||||
val literalExpression = functionLiteral.parent as JetFunctionLiteralExpression
|
val literalExpression = functionLiteral.parent as JetFunctionLiteralExpression
|
||||||
return calculate(literalExpression)
|
return calculate(literalExpression)
|
||||||
?.map { it.fuzzyType }
|
.map { it.fuzzyType }
|
||||||
?.filterNotNull()
|
.filterNotNull()
|
||||||
?.filter { KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it.type) }
|
.filter { KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it.type) }
|
||||||
?.map {
|
.map {
|
||||||
val returnType = KotlinBuiltIns.getReturnTypeFromFunctionType(it.type)
|
val returnType = KotlinBuiltIns.getReturnTypeFromFunctionType(it.type)
|
||||||
ExpectedInfo(FuzzyType(returnType, it.freeParameters), null, Tail.RBRACE)
|
ExpectedInfo(FuzzyType(returnType, it.freeParameters), null, Tail.RBRACE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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 ((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
|
val smartCastCalculator = smartCompletion.smartCastCalculator
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ private fun needExplicitParameterTypes(context: InsertionContext, placeholderRan
|
|||||||
val resolutionFacade = file.getResolutionFacade()
|
val resolutionFacade = file.getResolutionFacade()
|
||||||
val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL)
|
val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL)
|
||||||
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, resolutionFacade.findModuleDescriptor(file), useHeuristicSignatures = false)
|
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, resolutionFacade.findModuleDescriptor(file), useHeuristicSignatures = false)
|
||||||
.calculate(expression) ?: return false
|
.calculate(expression)
|
||||||
val functionTypes = expectedInfos
|
val functionTypes = expectedInfos
|
||||||
.map { it.fuzzyType?.type }
|
.map { it.fuzzyType?.type }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
|
|||||||
+8
-8
@@ -63,7 +63,7 @@ class SmartCompletion(
|
|||||||
private val receiver = if (expression is JetSimpleNameExpression) expression.getReceiverExpression() else null
|
private val receiver = if (expression is JetSimpleNameExpression) expression.getReceiverExpression() else null
|
||||||
private val expressionWithType = receiver?.parent as? JetExpression ?: expression
|
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)
|
public val smartCastCalculator: SmartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression)
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ class SmartCompletion(
|
|||||||
private fun executeInternal(): Result? {
|
private fun executeInternal(): Result? {
|
||||||
val (additionalItems, inheritanceSearcher) = additionalItems()
|
val (additionalItems, inheritanceSearcher) = additionalItems()
|
||||||
|
|
||||||
if (expectedInfos == null || expectedInfos.isEmpty()) {
|
if (expectedInfos.isEmpty()) {
|
||||||
return Result(null, additionalItems, inheritanceSearcher)
|
return Result(null, additionalItems, inheritanceSearcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,14 +147,14 @@ class SmartCompletion(
|
|||||||
public fun additionalItems(): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
public fun additionalItems(): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
||||||
val asTypePositionItems = buildForAsTypePosition()
|
val asTypePositionItems = buildForAsTypePosition()
|
||||||
if (asTypePositionItems != null) {
|
if (asTypePositionItems != null) {
|
||||||
assert(expectedInfos == null)
|
assert(expectedInfos.isEmpty())
|
||||||
return Pair(asTypePositionItems, null)
|
return Pair(asTypePositionItems, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
val items = ArrayList<LookupElement>()
|
val items = ArrayList<LookupElement>()
|
||||||
val inheritanceSearchers = ArrayList<InheritanceItemsSearcher>()
|
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)
|
TypeInstantiationItems(resolutionFacade, moduleDescriptor, bindingContext, visibilityFilter, toFromOriginalFileMapper, inheritorSearchScope, lookupElementFactory, forBasicCompletion)
|
||||||
.addTo(items, inheritanceSearchers, expectedInfos)
|
.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) {
|
if (forBasicCompletion) {
|
||||||
return ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useOuterCallsExpectedTypeCount = 0)
|
return ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useOuterCallsExpectedTypeCount = 0)
|
||||||
.calculate(expression)
|
.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)
|
// 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
|
var count = 0
|
||||||
while (true) {
|
while (true) {
|
||||||
val infos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useOuterCallsExpectedTypeCount = count)
|
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
|
if (count == 2 /* use two outer calls maximum */ || infos.none { it.fuzzyType?.isAlmostEverything() ?: false }) return infos
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
@@ -342,7 +342,7 @@ class SmartCompletion(
|
|||||||
?: return null
|
?: return null
|
||||||
val elementType = binaryExpression.getOperationReference().getReferencedNameElementType()
|
val elementType = binaryExpression.getOperationReference().getReferencedNameElementType()
|
||||||
if (elementType != JetTokens.AS_KEYWORD && elementType != JetTokens.AS_SAFE) return null
|
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() }
|
val expectedInfosGrouped: Map<JetType?, List<ExpectedInfo>> = expectedInfos.groupBy { it.fuzzyType?.type?.makeNotNullable() }
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -106,9 +106,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
|||||||
|
|
||||||
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor)
|
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor)
|
||||||
.calculateForArgument(dummyCall, dummyArgument)
|
.calculateForArgument(dummyCall, dummyArgument)
|
||||||
if (expectedInfos != null) {
|
collector.addElements(LambdaItems.collect(expectedInfos))
|
||||||
collector.addElements(LambdaItems.collect(expectedInfos))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user