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.ExpectedInfoMatch
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority
|
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.matchExpectedInfo
|
import org.jetbrains.kotlin.idea.completion.smart.matchExpectedInfo
|
||||||
import org.jetbrains.kotlin.idea.core.ExpectedInfo
|
import org.jetbrains.kotlin.idea.core.*
|
||||||
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.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||||
@@ -83,10 +80,13 @@ object KeywordValues {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val nullMatcher = { info: ExpectedInfo ->
|
val nullMatcher = { info: ExpectedInfo ->
|
||||||
if (info.fuzzyType != null && info.fuzzyType!!.type.isMarkedNullable)
|
when {
|
||||||
ExpectedInfoMatch.match(TypeSubstitutor.EMPTY)
|
(info.additionalData as? ComparisonOperandAdditionalData)?.suppressNullLiteral == true -> ExpectedInfoMatch.noMatch
|
||||||
else
|
|
||||||
ExpectedInfoMatch.noMatch
|
info.fuzzyType?.type?.isMarkedNullable == true -> ExpectedInfoMatch.match(TypeSubstitutor.EMPTY)
|
||||||
|
|
||||||
|
else -> ExpectedInfoMatch.noMatch
|
||||||
|
}
|
||||||
}
|
}
|
||||||
consumer.consume("null", nullMatcher, SmartCompletionItemPriority.NULL) {
|
consumer.consume("null", nullMatcher, SmartCompletionItemPriority.NULL) {
|
||||||
LookupElementBuilder.create(KeywordLookupObject(), "null").bold()
|
LookupElementBuilder.create(KeywordLookupObject(), "null").bold()
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ fun f(e1: E, e2: E?, x: Any) {
|
|||||||
// EXIST: { itemText:"e2" }
|
// EXIST: { itemText:"e2" }
|
||||||
// EXIST: { lookupString:"A", itemText:"E.A", typeText:"E" }
|
// EXIST: { lookupString:"A", itemText:"E.A", typeText:"E" }
|
||||||
// EXIST: { lookupString:"B", itemText:"E.B", typeText:"E" }
|
// EXIST: { lookupString:"B", itemText:"E.B", typeText:"E" }
|
||||||
// EXIST: null
|
// ABSENT: null
|
||||||
// ABSENT: { itemText:"!! e2" }
|
// ABSENT: { itemText:"!! e2" }
|
||||||
// ABSENT: e1
|
// ABSENT: e1
|
||||||
// ABSENT: x
|
// 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
|
B
|
||||||
}
|
}
|
||||||
|
|
||||||
fun f(e1: E, e2: E?, x: Any) {
|
fun f(e1: E?, e2: E, x: Any) {
|
||||||
if (e1 != <caret>
|
if (e1 != <caret>
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXIST: { lookupString:"A", itemText:"E.A" }
|
// EXIST: { lookupString:"A", itemText:"E.A" }
|
||||||
// EXIST: { lookupString:"B", itemText:"E.B" }
|
// EXIST: { lookupString:"B", itemText:"E.B" }
|
||||||
// EXIST: e2
|
// EXIST: e2
|
||||||
|
// EXIST: null
|
||||||
// ABSENT: e1
|
// ABSENT: e1
|
||||||
// ABSENT: x
|
// ABSENT: x
|
||||||
|
|||||||
+6
@@ -137,6 +137,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("ExtensionFunctionTypeVariables.kt")
|
||||||
public void testExtensionFunctionTypeVariables() throws Exception {
|
public void testExtensionFunctionTypeVariables() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/ExtensionFunctionTypeVariables.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/ExtensionFunctionTypeVariables.kt");
|
||||||
|
|||||||
@@ -148,6 +148,8 @@ object IfConditionAdditionalData : ExpectedInfo.AdditionalData
|
|||||||
|
|
||||||
object PropertyDelegateAdditionalData : ExpectedInfo.AdditionalData
|
object PropertyDelegateAdditionalData : ExpectedInfo.AdditionalData
|
||||||
|
|
||||||
|
class ComparisonOperandAdditionalData(val suppressNullLiteral: Boolean) : ExpectedInfo.AdditionalData
|
||||||
|
|
||||||
class ExpectedInfos(
|
class ExpectedInfos(
|
||||||
private val bindingContext: BindingContext,
|
private val bindingContext: BindingContext,
|
||||||
private val resolutionFacade: ResolutionFacade,
|
private val resolutionFacade: ResolutionFacade,
|
||||||
@@ -414,12 +416,14 @@ class ExpectedInfos(
|
|||||||
return listOf(ExpectedInfo(NullableTypesFilter, expectedName, null))
|
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 (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()
|
expectedType = expectedType.makeNullable()
|
||||||
}
|
}
|
||||||
|
|
||||||
return listOf(ExpectedInfo(expectedType, expectedName, null))
|
return listOf(ExpectedInfo(expectedType, expectedName, null, additionalData = additionalData))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user