KT-12150 Smart completion suggests to compare non-nullable with null
#KT-12150 Fixed
This commit is contained in:
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||
import org.jetbrains.kotlin.idea.completion.smart.ExpectedInfoMatch
|
||||
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority
|
||||
import org.jetbrains.kotlin.idea.completion.smart.matchExpectedInfo
|
||||
import org.jetbrains.kotlin.idea.core.ExpectedInfo
|
||||
import org.jetbrains.kotlin.idea.core.IfConditionAdditionalData
|
||||
import org.jetbrains.kotlin.idea.core.WhenEntryAdditionalData
|
||||
import org.jetbrains.kotlin.idea.core.fuzzyType
|
||||
import org.jetbrains.kotlin.idea.core.*
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
@@ -83,10 +80,13 @@ object KeywordValues {
|
||||
}
|
||||
|
||||
val nullMatcher = { info: ExpectedInfo ->
|
||||
if (info.fuzzyType != null && info.fuzzyType!!.type.isMarkedNullable)
|
||||
ExpectedInfoMatch.match(TypeSubstitutor.EMPTY)
|
||||
else
|
||||
ExpectedInfoMatch.noMatch
|
||||
when {
|
||||
(info.additionalData as? ComparisonOperandAdditionalData)?.suppressNullLiteral == true -> ExpectedInfoMatch.noMatch
|
||||
|
||||
info.fuzzyType?.type?.isMarkedNullable == true -> ExpectedInfoMatch.match(TypeSubstitutor.EMPTY)
|
||||
|
||||
else -> ExpectedInfoMatch.noMatch
|
||||
}
|
||||
}
|
||||
consumer.consume("null", nullMatcher, SmartCompletionItemPriority.NULL) {
|
||||
LookupElementBuilder.create(KeywordLookupObject(), "null").bold()
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ fun f(e1: E, e2: E?, x: Any) {
|
||||
// EXIST: { itemText:"e2" }
|
||||
// EXIST: { lookupString:"A", itemText:"E.A", typeText:"E" }
|
||||
// EXIST: { lookupString:"B", itemText:"E.B", typeText:"E" }
|
||||
// EXIST: null
|
||||
// ABSENT: null
|
||||
// ABSENT: { itemText:"!! e2" }
|
||||
// ABSENT: e1
|
||||
// ABSENT: x
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.io.File
|
||||
|
||||
fun foo(file: File) {
|
||||
if (file.name == <caret>)
|
||||
}
|
||||
|
||||
// EXIST: null
|
||||
+2
-1
@@ -3,12 +3,13 @@ enum class E {
|
||||
B
|
||||
}
|
||||
|
||||
fun f(e1: E, e2: E?, x: Any) {
|
||||
fun f(e1: E?, e2: E, x: Any) {
|
||||
if (e1 != <caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString:"A", itemText:"E.A" }
|
||||
// EXIST: { lookupString:"B", itemText:"E.B" }
|
||||
// EXIST: e2
|
||||
// EXIST: null
|
||||
// ABSENT: e1
|
||||
// ABSENT: x
|
||||
|
||||
+6
@@ -137,6 +137,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("EqOperatorPlatformType.kt")
|
||||
public void testEqOperatorPlatformType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/EqOperatorPlatformType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ExtensionFunctionTypeVariables.kt")
|
||||
public void testExtensionFunctionTypeVariables() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/ExtensionFunctionTypeVariables.kt");
|
||||
|
||||
@@ -148,6 +148,8 @@ object IfConditionAdditionalData : ExpectedInfo.AdditionalData
|
||||
|
||||
object PropertyDelegateAdditionalData : ExpectedInfo.AdditionalData
|
||||
|
||||
class ComparisonOperandAdditionalData(val suppressNullLiteral: Boolean) : ExpectedInfo.AdditionalData
|
||||
|
||||
class ExpectedInfos(
|
||||
private val bindingContext: BindingContext,
|
||||
private val resolutionFacade: ResolutionFacade,
|
||||
@@ -414,12 +416,14 @@ class ExpectedInfos(
|
||||
return listOf(ExpectedInfo(NullableTypesFilter, expectedName, null))
|
||||
}
|
||||
|
||||
// if we complete argument of == or !=, make types in expected info's nullable to allow nullable items too
|
||||
var additionalData: ExpectedInfo.AdditionalData? = null
|
||||
if (operationToken in COMPARISON_TOKENS) {
|
||||
// if we complete argument of == or !=, make types in expected info's nullable to allow items of nullable type too
|
||||
additionalData = ComparisonOperandAdditionalData(suppressNullLiteral = expectedType.nullability() == TypeNullability.NOT_NULL)
|
||||
expectedType = expectedType.makeNullable()
|
||||
}
|
||||
|
||||
return listOf(ExpectedInfo(expectedType, expectedName, null))
|
||||
return listOf(ExpectedInfo(expectedType, expectedName, null, additionalData = additionalData))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user