Moving logic into ExpectedInfos
This commit is contained in:
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.types.TypeUtils
|
|||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||||
import org.jetbrains.kotlin.types.typeUtil.containsError
|
import org.jetbrains.kotlin.types.typeUtil.containsError
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||||
import java.util.LinkedHashSet
|
import java.util.LinkedHashSet
|
||||||
@@ -138,20 +139,22 @@ class ExpectedInfos(
|
|||||||
val useOuterCallsExpectedTypeCount: Int = 0
|
val useOuterCallsExpectedTypeCount: Int = 0
|
||||||
) {
|
) {
|
||||||
public fun calculate(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
public fun calculate(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
||||||
return calculateForArgument(expressionWithType)
|
val expectedInfos = calculateForArgument(expressionWithType)
|
||||||
?: calculateForFunctionLiteralArgument(expressionWithType)
|
?: calculateForFunctionLiteralArgument(expressionWithType)
|
||||||
?: calculateForEqAndAssignment(expressionWithType)
|
?: calculateForEqAndAssignment(expressionWithType)
|
||||||
?: calculateForIf(expressionWithType)
|
?: calculateForIf(expressionWithType)
|
||||||
?: calculateForElvis(expressionWithType)
|
?: calculateForElvis(expressionWithType)
|
||||||
?: calculateForBlockExpression(expressionWithType)
|
?: calculateForBlockExpression(expressionWithType)
|
||||||
?: calculateForWhenEntryValue(expressionWithType)
|
?: calculateForWhenEntryValue(expressionWithType)
|
||||||
?: calculateForExclOperand(expressionWithType)
|
?: calculateForExclOperand(expressionWithType)
|
||||||
?: calculateForInitializer(expressionWithType)
|
?: calculateForInitializer(expressionWithType)
|
||||||
?: calculateForExpressionBody(expressionWithType)
|
?: calculateForExpressionBody(expressionWithType)
|
||||||
?: calculateForReturn(expressionWithType)
|
?: calculateForReturn(expressionWithType)
|
||||||
?: calculateForLoopRange(expressionWithType)
|
?: calculateForLoopRange(expressionWithType)
|
||||||
?: calculateForInOperatorArgument(expressionWithType)
|
?: calculateForInOperatorArgument(expressionWithType)
|
||||||
?: getFromBindingContext(expressionWithType)
|
?: getFromBindingContext(expressionWithType)
|
||||||
|
?: return null
|
||||||
|
return expectedInfos.filterNot { it.fuzzyType?.type?.isError ?: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateForArgument(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
private fun calculateForArgument(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
||||||
@@ -328,12 +331,17 @@ class ExpectedInfos(
|
|||||||
val binaryExpression = expressionWithType.getParent() as? JetBinaryExpression
|
val binaryExpression = expressionWithType.getParent() as? JetBinaryExpression
|
||||||
if (binaryExpression != null) {
|
if (binaryExpression != null) {
|
||||||
val operationToken = binaryExpression.getOperationToken()
|
val operationToken = binaryExpression.getOperationToken()
|
||||||
if (operationToken == JetTokens.EQ || operationToken == JetTokens.EQEQ || operationToken == JetTokens.EXCLEQ
|
if (operationToken == JetTokens.EQ || operationToken in COMPARISON_TOKENS) {
|
||||||
|| operationToken == JetTokens.EQEQEQ || operationToken == JetTokens.EXCLEQEQEQ) {
|
|
||||||
val otherOperand = if (expressionWithType == binaryExpression.getRight()) binaryExpression.getLeft() else binaryExpression.getRight()
|
val otherOperand = if (expressionWithType == binaryExpression.getRight()) binaryExpression.getLeft() else binaryExpression.getRight()
|
||||||
if (otherOperand != null) {
|
if (otherOperand != null) {
|
||||||
val expressionType = bindingContext.getType(otherOperand) ?: return null
|
var expectedType = bindingContext.getType(otherOperand) ?: return null
|
||||||
return listOf(ExpectedInfo(expressionType, expectedNameFromExpression(otherOperand), null))
|
|
||||||
|
// if we complete argument of == or !=, make types in expected info's nullable to allow nullable items too
|
||||||
|
if (operationToken in COMPARISON_TOKENS) {
|
||||||
|
expectedType = expectedType.makeNullable()
|
||||||
|
}
|
||||||
|
|
||||||
|
return listOf(ExpectedInfo(expectedType, expectedNameFromExpression(otherOperand), null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -524,3 +532,6 @@ class ExpectedInfos(
|
|||||||
private fun String.unpluralize()
|
private fun String.unpluralize()
|
||||||
= StringUtil.unpluralize(this)
|
= StringUtil.unpluralize(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val COMPARISON_TOKENS = setOf(JetTokens.EQEQ, JetTokens.EXCLEQ, JetTokens.EQEQEQ, JetTokens.EXCLEQEQEQ)
|
||||||
|
|
||||||
|
|||||||
+17
-12
@@ -21,13 +21,11 @@ import com.intellij.codeInsight.lookup.LookupElement
|
|||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.idea.completion.COMPARISON_TOKENS
|
||||||
import org.jetbrains.kotlin.idea.completion.ExpectedInfo
|
import org.jetbrains.kotlin.idea.completion.ExpectedInfo
|
||||||
import org.jetbrains.kotlin.idea.completion.fuzzyType
|
import org.jetbrains.kotlin.idea.completion.fuzzyType
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
||||||
import org.jetbrains.kotlin.psi.JetExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.JetWhenConditionWithExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetWhenEntry
|
|
||||||
import org.jetbrains.kotlin.psi.JetWhenExpression
|
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
|
|
||||||
object KeywordValues {
|
object KeywordValues {
|
||||||
@@ -60,14 +58,21 @@ object KeywordValues {
|
|||||||
collection.addLookupElements(null, expectedInfos, booleanInfoClassifier) { LookupElementBuilder.create("false").bold().assignSmartCompletionPriority(SmartCompletionItemPriority.FALSE) }
|
collection.addLookupElements(null, expectedInfos, booleanInfoClassifier) { LookupElementBuilder.create("false").bold().assignSmartCompletionPriority(SmartCompletionItemPriority.FALSE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val classifier = { info: ExpectedInfo ->
|
if (!shouldSkipNull(expressionWithType)) {
|
||||||
if (info.fuzzyType != null && info.fuzzyType!!.type.isMarkedNullable())
|
val classifier = { info: ExpectedInfo ->
|
||||||
ExpectedInfoClassification.match(TypeSubstitutor.EMPTY)
|
if (info.fuzzyType != null && info.fuzzyType!!.type.isMarkedNullable())
|
||||||
else
|
ExpectedInfoClassification.match(TypeSubstitutor.EMPTY)
|
||||||
ExpectedInfoClassification.noMatch
|
else
|
||||||
}
|
ExpectedInfoClassification.noMatch
|
||||||
collection.addLookupElements(null, expectedInfos, classifier) {
|
}
|
||||||
LookupElementBuilder.create("null").bold().assignSmartCompletionPriority(SmartCompletionItemPriority.NULL)
|
collection.addLookupElements(null, expectedInfos, classifier) {
|
||||||
|
LookupElementBuilder.create("null").bold().assignSmartCompletionPriority(SmartCompletionItemPriority.NULL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun shouldSkipNull(expressionWithType: JetExpression): Boolean {
|
||||||
|
val binaryExpression = expressionWithType.parent as? JetBinaryExpression ?: return false
|
||||||
|
return binaryExpression.operationToken in COMPARISON_TOKENS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-13
@@ -30,10 +30,8 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.completion.*
|
import org.jetbrains.kotlin.idea.completion.*
|
||||||
import org.jetbrains.kotlin.idea.completion.SmartCastCalculator
|
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||||
import org.jetbrains.kotlin.idea.util.isAlmostEverything
|
import org.jetbrains.kotlin.idea.util.isAlmostEverything
|
||||||
import org.jetbrains.kotlin.idea.util.makeNullable
|
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
||||||
@@ -113,14 +111,7 @@ class SmartCompletion(
|
|||||||
|
|
||||||
val expressionWithType = expression.toExpressionWithType()
|
val expressionWithType = expression.toExpressionWithType()
|
||||||
|
|
||||||
var originalExpectedInfos = calcExpectedInfos(expressionWithType) ?: return null
|
val expectedInfos = calcExpectedInfos(expressionWithType) ?: return null
|
||||||
originalExpectedInfos = originalExpectedInfos.filterNot { it.fuzzyType?.type?.isError ?: false }
|
|
||||||
|
|
||||||
// if we complete argument of == or !=, make types in expected info's nullable to allow nullable items too
|
|
||||||
val expectedInfos = if ((expressionWithType.getParent() as? JetBinaryExpression)?.getOperationToken() in COMPARISON_TOKENS)
|
|
||||||
originalExpectedInfos.map { if (it.fuzzyType != null) ExpectedInfo(it.fuzzyType!!.makeNullable(), it.expectedName, it.tail) else it }
|
|
||||||
else
|
|
||||||
originalExpectedInfos
|
|
||||||
|
|
||||||
val smartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression)
|
val smartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression)
|
||||||
|
|
||||||
@@ -166,7 +157,7 @@ class SmartCompletion(
|
|||||||
|
|
||||||
LambdaItems.addToCollection(additionalItems, functionExpectedInfos)
|
LambdaItems.addToCollection(additionalItems, functionExpectedInfos)
|
||||||
|
|
||||||
KeywordValues.addToCollection(additionalItems, originalExpectedInfos/* use originalExpectedInfos to not include null after == */, expression)
|
KeywordValues.addToCollection(additionalItems, expectedInfos, expression)
|
||||||
|
|
||||||
MultipleArgumentsItemProvider(bindingContext, smartCastCalculator).addToCollection(additionalItems, expectedInfos, expression)
|
MultipleArgumentsItemProvider(bindingContext, smartCastCalculator).addToCollection(additionalItems, expectedInfos, expression)
|
||||||
}
|
}
|
||||||
@@ -349,7 +340,5 @@ class SmartCompletion(
|
|||||||
companion object {
|
companion object {
|
||||||
public val OLD_ARGUMENTS_REPLACEMENT_OFFSET: OffsetKey = OffsetKey.create("nonFunctionReplacementOffset")
|
public val OLD_ARGUMENTS_REPLACEMENT_OFFSET: OffsetKey = OffsetKey.create("nonFunctionReplacementOffset")
|
||||||
public val MULTIPLE_ARGUMENTS_REPLACEMENT_OFFSET: OffsetKey = OffsetKey.create("multipleArgumentsReplacementOffset")
|
public val MULTIPLE_ARGUMENTS_REPLACEMENT_OFFSET: OffsetKey = OffsetKey.create("multipleArgumentsReplacementOffset")
|
||||||
|
|
||||||
private val COMPARISON_TOKENS = setOf(JetTokens.EQEQ, JetTokens.EXCLEQ, JetTokens.EQEQEQ, JetTokens.EXCLEQEQEQ)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user