KT-7756 Completion of "return null", "return true" and "return false"
#KT-7756 Fixed
This commit is contained in:
@@ -28,9 +28,7 @@ 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.completion.handlers.CastReceiverInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.CastReceiverInsertHandler
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
import org.jetbrains.kotlin.idea.util.*
|
||||||
import org.jetbrains.kotlin.idea.util.findLabelAndCall
|
|
||||||
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstanceToExpression
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
@@ -41,6 +39,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
|
import org.jetbrains.kotlin.types.JetType
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
||||||
import org.jetbrains.kotlin.types.typeUtil.equalTypesOrNulls
|
import org.jetbrains.kotlin.types.typeUtil.equalTypesOrNulls
|
||||||
@@ -223,11 +222,12 @@ fun returnExpressionItems(bindingContext: BindingContext, position: JetElement):
|
|||||||
val result = ArrayList<LookupElement>()
|
val result = ArrayList<LookupElement>()
|
||||||
for (parent in position.parentsWithSelf) {
|
for (parent in position.parentsWithSelf) {
|
||||||
if (parent is JetDeclarationWithBody) {
|
if (parent is JetDeclarationWithBody) {
|
||||||
val returnsUnit = returnsUnit(parent, bindingContext)
|
val returnType = parent.returnType(bindingContext)
|
||||||
|
val isUnit = returnType == null || KotlinBuiltIns.isUnit(returnType)
|
||||||
if (parent is JetFunctionLiteral) {
|
if (parent is JetFunctionLiteral) {
|
||||||
val (label, call) = parent.findLabelAndCall()
|
val (label, call) = parent.findLabelAndCall()
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
result.add(createKeywordWithLabelElement("return", label, addSpace = !returnsUnit))
|
result.add(createKeywordWithLabelElement("return", label, addSpace = !isUnit))
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the current function literal is inlined and stop processing outer declarations if it's not
|
// check if the current function literal is inlined and stop processing outer declarations if it's not
|
||||||
@@ -236,7 +236,15 @@ fun returnExpressionItems(bindingContext: BindingContext, position: JetElement):
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (parent.hasBlockBody()) {
|
if (parent.hasBlockBody()) {
|
||||||
result.add(createKeywordWithLabelElement("return", null, addSpace = !returnsUnit))
|
result.add(createKeywordWithLabelElement("return", null, addSpace = !isUnit))
|
||||||
|
|
||||||
|
if (returnType != null && returnType.nullability() == TypeNullability.NULLABLE) {
|
||||||
|
result.add(createKeywordWithLabelElement("return null", null, addSpace = false))
|
||||||
|
}
|
||||||
|
if (returnType != null && KotlinBuiltIns.isBoolean(returnType.makeNotNullable())) {
|
||||||
|
result.add(createKeywordWithLabelElement("return true", null, addSpace = false))
|
||||||
|
result.add(createKeywordWithLabelElement("return false", null, addSpace = false))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -245,10 +253,9 @@ fun returnExpressionItems(bindingContext: BindingContext, position: JetElement):
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun returnsUnit(declaration: JetDeclarationWithBody, bindingContext: BindingContext): Boolean {
|
private fun JetDeclarationWithBody.returnType(bindingContext: BindingContext): JetType? {
|
||||||
val callable = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] as? CallableDescriptor ?: return true
|
val callable = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, this] as? CallableDescriptor ?: return null
|
||||||
val returnType = callable.getReturnType() ?: return true
|
return callable.getReturnType()
|
||||||
return KotlinBuiltIns.isUnit(returnType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createKeywordWithLabelElement(keyword: String, label: Name?, addSpace: Boolean): LookupElement {
|
private fun createKeywordWithLabelElement(keyword: String, label: Name?, addSpace: Boolean): LookupElement {
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(): String? {
|
||||||
|
ret<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: "return null"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(): String? {
|
||||||
|
return null<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: "return null"
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
fun foo(): Boolean {
|
||||||
|
ret<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 1
|
||||||
|
// EXIST: { lookupString: "return", itemText: "return", tailText: null, attributes: "bold" }
|
||||||
|
// EXIST: { lookupString: "return true", itemText: "return true", tailText: null, attributes: "bold" }
|
||||||
|
// EXIST: { lookupString: "return false", itemText: "return false", tailText: null, attributes: "bold" }
|
||||||
|
// NOTHING_ELSE: true
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(): String {
|
||||||
|
ret<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 1
|
||||||
|
// ABSENT: "return null"
|
||||||
|
// ABSENT: "return true"
|
||||||
|
// ABSENT: "return false"
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(): String? {
|
||||||
|
ret<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 1
|
||||||
|
// EXIST: { lookupString: "return", itemText: "return", tailText: null, attributes: "bold" }
|
||||||
|
// EXIST: { lookupString: "return null", itemText: "return null", tailText: null, attributes: "bold" }
|
||||||
|
// NOTHING_ELSE: true
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun foo(): Boolean? {
|
||||||
|
ret<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 1
|
||||||
|
// EXIST: { lookupString: "return", itemText: "return", tailText: null, attributes: "bold" }
|
||||||
|
// EXIST: { lookupString: "return null", itemText: "return null", tailText: null, attributes: "bold" }
|
||||||
|
// EXIST: { lookupString: "return true", itemText: "return true", tailText: null, attributes: "bold" }
|
||||||
|
// EXIST: { lookupString: "return false", itemText: "return false", tailText: null, attributes: "bold" }
|
||||||
|
// NOTHING_ELSE: true
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun foo(): Boolean {
|
||||||
|
ret<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORDER: return
|
||||||
|
// ORDER: return false
|
||||||
|
// ORDER: return true
|
||||||
+24
@@ -401,12 +401,36 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ReturnBoolean.kt")
|
||||||
|
public void testReturnBoolean() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/ReturnBoolean.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ReturnKeywordName.kt")
|
@TestMetadata("ReturnKeywordName.kt")
|
||||||
public void testReturnKeywordName() throws Exception {
|
public void testReturnKeywordName() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/ReturnKeywordName.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/ReturnKeywordName.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ReturnNotNull.kt")
|
||||||
|
public void testReturnNotNull() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/ReturnNotNull.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ReturnNull.kt")
|
||||||
|
public void testReturnNull() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/ReturnNull.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ReturnNullableBoolean.kt")
|
||||||
|
public void testReturnNullableBoolean() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/ReturnNullableBoolean.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("This.kt")
|
@TestMetadata("This.kt")
|
||||||
public void testThis() throws Exception {
|
public void testThis() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/This.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/This.kt");
|
||||||
|
|||||||
+6
@@ -107,6 +107,12 @@ public class KeywordCompletionHandlerTestGenerated extends AbstractKeywordComple
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ReturnNull.kt")
|
||||||
|
public void testReturnNull() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/ReturnNull.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("SpaceAfterImport.kt")
|
@TestMetadata("SpaceAfterImport.kt")
|
||||||
public void testSpaceAfterImport() throws Exception {
|
public void testSpaceAfterImport() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/SpaceAfterImport.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/SpaceAfterImport.kt");
|
||||||
|
|||||||
+6
@@ -124,4 +124,10 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
|||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/PropertiesBeforeKeywords.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/PropertiesBeforeKeywords.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ReturnBoolean.kt")
|
||||||
|
public void testReturnBoolean() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/ReturnBoolean.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user