diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index 8de8ed7e183..303d46c55f3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -903,6 +903,10 @@ public class KotlinBuiltIns { return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._boolean); } + public static boolean isBooleanOrNullableBoolean(@NotNull JetType type) { + return isConstructedFromGivenClass(type, FQ_NAMES._boolean); + } + public static boolean isBoolean(@NotNull ClassDescriptor classDescriptor) { return FQ_NAMES._boolean.equals(getFqName(classDescriptor)); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index 16dd7c14493..7d62c90b09a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -22,12 +22,12 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.utils.toReadOnlyList -import java.util.* +import java.util.ArrayDeque +import java.util.ArrayList +import java.util.LinkedHashSet public enum class TypeNullability { NOT_NULL, @@ -53,6 +53,7 @@ fun JetType.isNothing(): Boolean = KotlinBuiltIns.isNothing(this) fun JetType.isUnit(): Boolean = KotlinBuiltIns.isUnit(this) fun JetType.isAnyOrNullableAny(): Boolean = KotlinBuiltIns.isAnyOrNullableAny(this) fun JetType.isBoolean(): Boolean = KotlinBuiltIns.isBoolean(this) +fun JetType.isBooleanOrNullableBoolean(): Boolean = KotlinBuiltIns.isBooleanOrNullableBoolean(this) private fun JetType.getContainedTypeParameters(): Collection { val declarationDescriptor = getConstructor().getDeclarationDescriptor() diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt index 05f1edd4a86..76c94da377b 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt @@ -45,7 +45,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.typeUtil.TypeNullability -import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.nullability import java.util.ArrayList @@ -204,7 +203,7 @@ fun returnExpressionItems(bindingContext: BindingContext, position: JetElement): if (returnType != null && returnType.nullability() == TypeNullability.NULLABLE) { result.add(createKeywordWithLabelElement("return null", null, addSpace = false)) } - if (returnType != null && KotlinBuiltIns.isBoolean(returnType.makeNotNullable())) { + if (returnType != null && KotlinBuiltIns.isBooleanOrNullableBoolean(returnType)) { result.add(createKeywordWithLabelElement("return true", null, addSpace = false)) result.add(createKeywordWithLabelElement("return false", null, addSpace = false)) } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/KeywordValues.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/KeywordValues.kt index 3a557f9c5a0..10fa7df93be 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/KeywordValues.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/KeywordValues.kt @@ -20,13 +20,13 @@ import com.intellij.codeInsight.completion.InsertionContext import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.codeInsight.lookup.LookupElementDecorator -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.fuzzyType import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.typeUtil.isBooleanOrNullableBoolean object KeywordValues { public fun addToCollection(collection: MutableCollection, expectedInfos: Collection, expressionWithType: JetExpression) { @@ -52,7 +52,7 @@ object KeywordValues { if (!skipTrueFalse) { val booleanInfoClassifier = { info: ExpectedInfo -> - if (info.fuzzyType?.type == KotlinBuiltIns.getInstance().getBooleanType()) ExpectedInfoClassification.match(TypeSubstitutor.EMPTY) else ExpectedInfoClassification.noMatch + if (info.fuzzyType?.type?.isBooleanOrNullableBoolean() ?: false) ExpectedInfoClassification.match(TypeSubstitutor.EMPTY) else ExpectedInfoClassification.noMatch } collection.addLookupElements(null, expectedInfos, booleanInfoClassifier) { LookupElementBuilder.create("true").bold().assignSmartCompletionPriority(SmartCompletionItemPriority.TRUE) } collection.addLookupElements(null, expectedInfos, booleanInfoClassifier) { LookupElementBuilder.create("false").bold().assignSmartCompletionPriority(SmartCompletionItemPriority.FALSE) } diff --git a/idea/idea-completion/testData/smart/NullableBooleanExpected.kt b/idea/idea-completion/testData/smart/NullableBooleanExpected.kt new file mode 100644 index 00000000000..7e69ae4b60d --- /dev/null +++ b/idea/idea-completion/testData/smart/NullableBooleanExpected.kt @@ -0,0 +1,5 @@ +fun foo(): Boolean? = + +// EXIST: { itemText: "true", attributes: "bold" } +// EXIST: { itemText: "false", attributes: "bold" } +// EXIST: { itemText: "null", attributes: "bold" } diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java index ff3b5290054..78ffb99bffb 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java @@ -359,6 +359,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest(fileName); } + @TestMetadata("NullableBooleanExpected.kt") + public void testNullableBooleanExpected() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/NullableBooleanExpected.kt"); + doTest(fileName); + } + @TestMetadata("Object.kt") public void testObject() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/Object.kt");