Make completion for overriding functions respect suspend modifier
Fixes #KT-22200
This commit is contained in:
committed by
Alexander Udalov
parent
8bc020f31b
commit
b567817d1f
@@ -524,12 +524,16 @@ internal class DescriptorRendererImpl(
|
|||||||
functionDescriptor.isInfix && (functionDescriptor.overriddenDescriptors.none { it.isInfix } || alwaysRenderModifiers)
|
functionDescriptor.isInfix && (functionDescriptor.overriddenDescriptors.none { it.isInfix } || alwaysRenderModifiers)
|
||||||
|
|
||||||
renderModifier(builder, functionDescriptor.isTailrec, "tailrec")
|
renderModifier(builder, functionDescriptor.isTailrec, "tailrec")
|
||||||
renderModifier(builder, functionDescriptor.isSuspend, "suspend")
|
renderSuspendModifier(functionDescriptor, builder)
|
||||||
renderModifier(builder, functionDescriptor.isInline, "inline")
|
renderModifier(builder, functionDescriptor.isInline, "inline")
|
||||||
renderModifier(builder, isInfix, "infix")
|
renderModifier(builder, isInfix, "infix")
|
||||||
renderModifier(builder, isOperator, "operator")
|
renderModifier(builder, isOperator, "operator")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun renderSuspendModifier(functionDescriptor: FunctionDescriptor, builder: StringBuilder) {
|
||||||
|
renderModifier(builder, functionDescriptor.isSuspend, "suspend")
|
||||||
|
}
|
||||||
|
|
||||||
override fun render(declarationDescriptor: DeclarationDescriptor): String {
|
override fun render(declarationDescriptor: DeclarationDescriptor): String {
|
||||||
return buildString {
|
return buildString {
|
||||||
declarationDescriptor.accept(RenderDeclarationDescriptorVisitor(), this)
|
declarationDescriptor.accept(RenderDeclarationDescriptorVisitor(), this)
|
||||||
@@ -630,6 +634,8 @@ internal class DescriptorRendererImpl(
|
|||||||
|
|
||||||
if (includeAdditionalModifiers) {
|
if (includeAdditionalModifiers) {
|
||||||
renderAdditionalModifiers(function, builder)
|
renderAdditionalModifiers(function, builder)
|
||||||
|
} else {
|
||||||
|
renderSuspendModifier(function, builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMemberKind(function, builder)
|
renderMemberKind(function, builder)
|
||||||
|
|||||||
+9
-7
@@ -24,6 +24,7 @@ import com.intellij.icons.AllIcons
|
|||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.ui.RowIcon
|
import com.intellij.ui.RowIcon
|
||||||
|
import org.jetbrains.kotlin.backend.common.descriptors.isSuspend
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.KotlinDescriptorIconProvider
|
import org.jetbrains.kotlin.idea.KotlinDescriptorIconProvider
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
@@ -43,8 +44,8 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
|
||||||
class OverridesCompletion(
|
class OverridesCompletion(
|
||||||
private val collector: LookupElementsCollector,
|
private val collector: LookupElementsCollector,
|
||||||
private val lookupElementFactory: BasicLookupElementFactory
|
private val lookupElementFactory: BasicLookupElementFactory
|
||||||
) {
|
) {
|
||||||
private val PRESENTATION_RENDERER = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.withOptions {
|
private val PRESENTATION_RENDERER = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.withOptions {
|
||||||
modifiers = emptySet()
|
modifiers = emptySet()
|
||||||
@@ -85,7 +86,9 @@ class OverridesCompletion(
|
|||||||
val baseClassIcon = KotlinDescriptorIconProvider.getIcon(baseClass, baseClassDeclaration, 0)
|
val baseClassIcon = KotlinDescriptorIconProvider.getIcon(baseClass, baseClassDeclaration, 0)
|
||||||
|
|
||||||
lookupElement = object : LookupElementDecorator<LookupElement>(lookupElement) {
|
lookupElement = object : LookupElementDecorator<LookupElement>(lookupElement) {
|
||||||
override fun getLookupString() = if (declaration == null) "override" else delegate.lookupString // don't use "override" as lookup string when already in the name of declaration
|
override fun getLookupString() =
|
||||||
|
if (declaration == null) "override" else delegate.lookupString // don't use "override" as lookup string when already in the name of declaration
|
||||||
|
|
||||||
override fun getAllLookupStrings() = setOf(lookupString, delegate.lookupString)
|
override fun getAllLookupStrings() = setOf(lookupString, delegate.lookupString)
|
||||||
|
|
||||||
override fun renderElement(presentation: LookupElementPresentation) {
|
override fun renderElement(presentation: LookupElementPresentation) {
|
||||||
@@ -122,6 +125,7 @@ class OverridesCompletion(
|
|||||||
val prototype = memberObject.generateMember(classOrObject, false)
|
val prototype = memberObject.generateMember(classOrObject, false)
|
||||||
prototype.modifierList!!.replace(modifierList)
|
prototype.modifierList!!.replace(modifierList)
|
||||||
val insertedMember = dummyMember.replaced(prototype)
|
val insertedMember = dummyMember.replaced(prototype)
|
||||||
|
if (memberObject.descriptor.isSuspend) insertedMember.addModifier(KtTokens.SUSPEND_KEYWORD)
|
||||||
|
|
||||||
ShortenReferences.DEFAULT.process(insertedMember)
|
ShortenReferences.DEFAULT.process(insertedMember)
|
||||||
|
|
||||||
@@ -135,8 +139,7 @@ class OverridesCompletion(
|
|||||||
context.document.deleteString(offset, atCharOffset + 1)
|
context.document.deleteString(offset, atCharOffset + 1)
|
||||||
|
|
||||||
context.editor.moveCaret(offset)
|
context.editor.moveCaret(offset)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
moveCaretIntoGeneratedElement(context.editor, insertedMember)
|
moveCaretIntoGeneratedElement(context.editor, insertedMember)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,8 +159,7 @@ class OverridesCompletion(
|
|||||||
if (descriptorToOverride !is PropertyDescriptor) return false
|
if (descriptorToOverride !is PropertyDescriptor) return false
|
||||||
return if (declaration.valOrVarKeyword?.node?.elementType == KtTokens.VAL_KEYWORD) {
|
return if (declaration.valOrVarKeyword?.node?.elementType == KtTokens.VAL_KEYWORD) {
|
||||||
!descriptorToOverride.isVar
|
!descriptorToOverride.isVar
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
true // var can override either var or val
|
true // var can override either var or val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ interface I {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Base1 {
|
class Base1 {
|
||||||
protected open fun bar(){}
|
protected open suspend fun bar(){}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class Base2 : Base1() {
|
open class Base2 : Base1() {
|
||||||
@@ -16,7 +16,7 @@ class A : Base2(), I {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EXIST: { lookupString: "override", itemText: "override" }
|
// EXIST: { lookupString: "override", itemText: "override" }
|
||||||
// EXIST: { itemText: "override fun bar() {...}", lookupString: "override", allLookupStrings: "bar, override", tailText: null, typeText: "Base1", attributes: "" }
|
// EXIST: { itemText: "override suspend fun bar() {...}", lookupString: "override", allLookupStrings: "bar, override", tailText: null, typeText: "Base1", attributes: "" }
|
||||||
// EXIST: { itemText: "override fun equals(other: Any?): Boolean {...}", lookupString: "override", allLookupStrings: "equals, override", tailText: null, typeText: "Any", attributes: "" }
|
// EXIST: { itemText: "override fun equals(other: Any?): Boolean {...}", lookupString: "override", allLookupStrings: "equals, override", tailText: null, typeText: "Any", attributes: "" }
|
||||||
// EXIST: { itemText: "override fun foo(p: Int) {...}", lookupString: "override", allLookupStrings: "foo, override", tailText: null, typeText: "I", attributes: "bold" }
|
// EXIST: { itemText: "override fun foo(p: Int) {...}", lookupString: "override", allLookupStrings: "foo, override", tailText: null, typeText: "I", attributes: "bold" }
|
||||||
// EXIST: { itemText: "override fun hashCode(): Int {...}", lookupString: "override", allLookupStrings: "hashCode, override", tailText: null, typeText: "Any", attributes: "" }
|
// EXIST: { itemText: "override fun hashCode(): Int {...}", lookupString: "override", allLookupStrings: "hashCode, override", tailText: null, typeText: "Any", attributes: "" }
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
interface I {
|
||||||
|
suspend fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class A : I {
|
||||||
|
o<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT_TEXT: "override suspend fun foo() {...}"
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
interface I {
|
||||||
|
suspend fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class A : I {
|
||||||
|
override suspend fun foo() {
|
||||||
|
<caret><selection>TODO("not implemented") //To change body of created functions use File | Settings | File Templates.</selection>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT_TEXT: "override suspend fun foo() {...}"
|
||||||
+6
@@ -582,6 +582,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Suspend.kt")
|
||||||
|
public void testSuspend() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/override/Suspend.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("TypeFunctionName.kt")
|
@TestMetadata("TypeFunctionName.kt")
|
||||||
public void testTypeFunctionName() throws Exception {
|
public void testTypeFunctionName() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/override/TypeFunctionName.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/override/TypeFunctionName.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user