Fixed bug in completion with double insertion of "::class.java"
This commit is contained in:
@@ -89,7 +89,7 @@ fun LookupElement.withReceiverCast(): LookupElement {
|
|||||||
return object: LookupElementDecorator<LookupElement>(this) {
|
return object: LookupElementDecorator<LookupElement>(this) {
|
||||||
override fun handleInsert(context: InsertionContext) {
|
override fun handleInsert(context: InsertionContext) {
|
||||||
super.handleInsert(context)
|
super.handleInsert(context)
|
||||||
CastReceiverInsertHandler.handleInsert(context, getDelegate())
|
CastReceiverInsertHandler.postHandleInsert(context, delegate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-11
@@ -19,22 +19,14 @@ package org.jetbrains.kotlin.idea.completion.handlers
|
|||||||
import com.intellij.codeInsight.completion.InsertHandler
|
import com.intellij.codeInsight.completion.InsertHandler
|
||||||
import com.intellij.codeInsight.completion.InsertionContext
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
import com.intellij.openapi.util.TextRange
|
|
||||||
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|
||||||
import org.jetbrains.kotlin.renderer.render
|
import org.jetbrains.kotlin.renderer.render
|
||||||
|
|
||||||
open class BaseDeclarationInsertHandler : InsertHandler<LookupElement> {
|
open class BaseDeclarationInsertHandler : InsertHandler<LookupElement> {
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
val name = (item.getObject() as? DeclarationLookupObject)?.name
|
val name = (item.`object` as? DeclarationLookupObject)?.name
|
||||||
if (name != null) {
|
if (name != null && !name.isSpecial) {
|
||||||
val nameInCode = name.render()
|
context.document.replaceString(context.startOffset, context.tailOffset, name.render())
|
||||||
val document = context.getDocument()
|
|
||||||
val needEscaping = nameInCode != name.asString()
|
|
||||||
// we check that text inserted matches the name because something else can be inserted by custom insert handler
|
|
||||||
if (needEscaping && document.getText(TextRange(context.getStartOffset(), context.getTailOffset())) == name.asString()) {
|
|
||||||
document.replaceString(context.getStartOffset(), context.getTailOffset(), nameInCode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -26,10 +26,8 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
object CastReceiverInsertHandler : KotlinCallableInsertHandler() {
|
object CastReceiverInsertHandler {
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
fun postHandleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
super.handleInsert(context, item)
|
|
||||||
|
|
||||||
val expression = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), javaClass<JetSimpleNameExpression>(), false)
|
val expression = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), javaClass<JetSimpleNameExpression>(), false)
|
||||||
val qualifiedExpression = PsiTreeUtil.getParentOfType(expression, javaClass<JetQualifiedExpression>(), true)
|
val qualifiedExpression = PsiTreeUtil.getParentOfType(expression, javaClass<JetQualifiedExpression>(), true)
|
||||||
if (qualifiedExpression != null) {
|
if (qualifiedExpression != null) {
|
||||||
|
|||||||
+16
-6
@@ -33,15 +33,14 @@ import org.jetbrains.kotlin.types.JetType
|
|||||||
|
|
||||||
class GenerateLambdaInfo(val lambdaType: JetType, val explicitParameters: Boolean)
|
class GenerateLambdaInfo(val lambdaType: JetType, val explicitParameters: Boolean)
|
||||||
|
|
||||||
sealed class KotlinFunctionInsertHandler(
|
sealed class KotlinFunctionInsertHandler : KotlinCallableInsertHandler() {
|
||||||
|
|
||||||
) : KotlinCallableInsertHandler() {
|
|
||||||
|
|
||||||
class Normal(
|
class Normal(
|
||||||
val inputTypeArguments: Boolean,
|
val inputTypeArguments: Boolean,
|
||||||
val inputValueArguments: Boolean,
|
val inputValueArguments: Boolean,
|
||||||
val argumentText: String = "",
|
val argumentText: String = "",
|
||||||
val lambdaInfo: GenerateLambdaInfo? = null
|
val lambdaInfo: GenerateLambdaInfo? = null,
|
||||||
|
val argumentsOnly: Boolean = false
|
||||||
) : KotlinFunctionInsertHandler() {
|
) : KotlinFunctionInsertHandler() {
|
||||||
init {
|
init {
|
||||||
if (lambdaInfo != null) {
|
if (lambdaInfo != null) {
|
||||||
@@ -49,8 +48,19 @@ sealed class KotlinFunctionInsertHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
//TODO: add 'data' or special annotation when supported
|
||||||
super.handleInsert(context, item)
|
fun copy(
|
||||||
|
inputTypeArguments: Boolean = this.inputTypeArguments,
|
||||||
|
inputValueArguments: Boolean = this.inputValueArguments,
|
||||||
|
argumentText: String = this.argumentText,
|
||||||
|
lambdaInfo: GenerateLambdaInfo? = this.lambdaInfo,
|
||||||
|
argumentsOnly: Boolean = this.argumentsOnly
|
||||||
|
) = Normal(inputTypeArguments, inputValueArguments, argumentText, lambdaInfo, argumentsOnly)
|
||||||
|
|
||||||
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
|
if (!argumentsOnly) {
|
||||||
|
super.handleInsert(context, item)
|
||||||
|
}
|
||||||
|
|
||||||
val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
|
val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
|
||||||
psiDocumentManager.commitAllDocuments()
|
psiDocumentManager.commitAllDocuments()
|
||||||
|
|||||||
+10
-11
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.completion.smart
|
package org.jetbrains.kotlin.idea.completion.smart
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.CompletionInitializationContext
|
||||||
import com.intellij.codeInsight.completion.InsertionContext
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||||
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.completion.ExpectedInfo
|
import org.jetbrains.kotlin.idea.completion.ExpectedInfo
|
||||||
import org.jetbrains.kotlin.idea.completion.LookupElementFactory
|
import org.jetbrains.kotlin.idea.completion.LookupElementFactory
|
||||||
@@ -30,7 +32,6 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|||||||
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
|
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
|
||||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.renderer.render
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||||
@@ -109,9 +110,7 @@ class StaticMembers(
|
|||||||
|
|
||||||
return lookupElements.map {
|
return lookupElements.map {
|
||||||
object: LookupElementDecorator<LookupElement>(it) {
|
object: LookupElementDecorator<LookupElement>(it) {
|
||||||
override fun getAllLookupStrings(): Set<String> {
|
override fun getAllLookupStrings() = setOf(delegate.lookupString, qualifierPresentation)
|
||||||
return setOf(it.lookupString, qualifierPresentation)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun renderElement(presentation: LookupElementPresentation) {
|
override fun renderElement(presentation: LookupElementPresentation) {
|
||||||
getDelegate().renderElement(presentation)
|
getDelegate().renderElement(presentation)
|
||||||
@@ -132,16 +131,16 @@ class StaticMembers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun handleInsert(context: InsertionContext) {
|
override fun handleInsert(context: InsertionContext) {
|
||||||
var text = qualifierText + "." + memberDescriptor.getName().render()
|
val prefix = qualifierText + "."
|
||||||
|
|
||||||
context.getDocument().replaceString(context.getStartOffset(), context.getTailOffset(), text)
|
val offset = context.startOffset
|
||||||
context.setTailOffset(context.getStartOffset() + text.length())
|
context.document.insertString(offset, prefix)
|
||||||
|
context.offsetMap.addOffset(CompletionInitializationContext.START_OFFSET, offset + prefix.length)
|
||||||
|
|
||||||
if (memberDescriptor is FunctionDescriptor) {
|
shortenReferences(context, offset, offset + prefix.length)
|
||||||
getDelegate().handleInsert(context)
|
PsiDocumentManager.getInstance(context.project).doPostponedOperationsAndUnblockDocument(context.document)
|
||||||
}
|
|
||||||
|
|
||||||
shortenReferences(context, context.getStartOffset(), context.getTailOffset())
|
super.handleInsert(context)
|
||||||
}
|
}
|
||||||
}.assignSmartCompletionPriority(SmartCompletionItemPriority.STATIC_MEMBER)
|
}.assignSmartCompletionPriority(SmartCompletionItemPriority.STATIC_MEMBER)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -202,10 +202,13 @@ class TypeInstantiationItems(
|
|||||||
else -> "(...)"
|
else -> "(...)"
|
||||||
}
|
}
|
||||||
|
|
||||||
val baseInsertHandler = when (visibleConstructors.size()) {
|
val baseInsertHandler = when (visibleConstructors.size) {
|
||||||
0 -> KotlinFunctionInsertHandler.Normal(inputTypeArguments = false, inputValueArguments = false)
|
0 -> KotlinFunctionInsertHandler.Normal(inputTypeArguments = false, inputValueArguments = false, argumentsOnly = true)
|
||||||
1 -> lookupElementFactory.insertHandlerProvider.insertHandler(visibleConstructors.single()) as KotlinFunctionInsertHandler.Normal
|
|
||||||
else -> KotlinFunctionInsertHandler.Normal(inputTypeArguments = false, inputValueArguments = true)
|
1 -> (lookupElementFactory.insertHandlerProvider.insertHandler(visibleConstructors.single()) as KotlinFunctionInsertHandler.Normal)
|
||||||
|
.copy(argumentsOnly = true)
|
||||||
|
|
||||||
|
else -> KotlinFunctionInsertHandler.Normal(inputTypeArguments = false, inputValueArguments = true, argumentsOnly = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
insertHandler = object : InsertHandler<LookupElement> {
|
insertHandler = object : InsertHandler<LookupElement> {
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun <T> foo(klass: Class<T>) {}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo<String>(<caret>)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: "String::class.java"
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun <T> foo(klass: Class<T>) {}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo<String>(String::class.java)<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: "String::class.java"
|
||||||
|
|
||||||
+6
@@ -269,6 +269,12 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ConcreteJavaClass2.kt")
|
||||||
|
public void testConcreteJavaClass2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ConcreteKClass.kt")
|
@TestMetadata("ConcreteKClass.kt")
|
||||||
public void testConcreteKClass() throws Exception {
|
public void testConcreteKClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user