KT-12150 Smart completion suggests to compare non-nullable with null

#KT-12150 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-04-29 17:05:05 +03:00
parent 40900b0050
commit 941b415981
6 changed files with 30 additions and 12 deletions
@@ -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
View File
@@ -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
View File
@@ -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
@@ -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))
}
}
}