KT-8529 Code completion for parameter name and type together replaces wrong range on Tab
#KT-8529 Fixed
This commit is contained in:
+12
-4
@@ -108,9 +108,9 @@ class KotlinCompletionContributor : CompletionContributor() {
|
||||
?: DEFAULT_DUMMY_IDENTIFIER
|
||||
}
|
||||
|
||||
if (context.completionType == CompletionType.SMART && !isAtEndOfLine(offset, context.editor.document) /* do not use parent expression if we are at the end of line - it's probably parsed incorrectly */) {
|
||||
val tokenAt = psiFile.findElementAt(Math.max(0, offset))
|
||||
if (tokenAt != null) {
|
||||
val tokenAt = psiFile.findElementAt(Math.max(0, offset))
|
||||
if (tokenAt != null) {
|
||||
if (context.completionType == CompletionType.SMART && !isAtEndOfLine(offset, context.editor.document) /* do not use parent expression if we are at the end of line - it's probably parsed incorrectly */) {
|
||||
var parent = tokenAt.parent
|
||||
if (parent is KtExpression && parent !is KtBlockExpression) {
|
||||
// search expression to be replaced - go up while we are the first child of parent expression
|
||||
@@ -131,11 +131,19 @@ class KotlinCompletionContributor : CompletionContributor() {
|
||||
val argumentList = (expression.parent as? KtValueArgument)?.parent as? KtValueArgumentList
|
||||
if (argumentList != null) {
|
||||
context.offsetMap.addOffset(SmartCompletion.MULTIPLE_ARGUMENTS_REPLACEMENT_OFFSET,
|
||||
argumentList.rightParenthesis?.textRange?.startOffset ?: argumentList.endOffset)
|
||||
argumentList.rightParenthesis?.textRange?.startOffset ?: argumentList.endOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tokenAt.node.elementType == KtTokens.IDENTIFIER) {
|
||||
val parameter = tokenAt.parent as? KtParameter
|
||||
if (parameter != null) {
|
||||
context.offsetMap.addOffset(ParameterNameAndTypeCompletion.REPLACEMENT_OFFSET, parameter.endOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun replacementOffsetByExpression(expression: KtExpression): Int {
|
||||
|
||||
+24
-6
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionInitializationContext
|
||||
import com.intellij.codeInsight.completion.CompletionParameters
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher
|
||||
import com.intellij.codeInsight.lookup.*
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
@@ -30,9 +27,12 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import com.intellij.psi.codeStyle.NameUtil
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.isCharAt
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.skipSpaces
|
||||
import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
|
||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
||||
import org.jetbrains.kotlin.idea.quickfix.moveCaret
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
@@ -206,6 +206,22 @@ class ParameterNameAndTypeCompletion(
|
||||
}
|
||||
|
||||
override fun handleInsert(context: InsertionContext) {
|
||||
if (context.completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
||||
val replacementOffset = context.offsetMap.getOffset(REPLACEMENT_OFFSET)
|
||||
if (replacementOffset != -1) {
|
||||
val tailOffset = context.tailOffset
|
||||
context.document.deleteString(tailOffset, replacementOffset)
|
||||
|
||||
val chars = context.document.charsSequence
|
||||
var offset = chars.skipSpaces(tailOffset)
|
||||
if (chars.isCharAt(offset, ',')) {
|
||||
offset++
|
||||
offset = chars.skipSpaces(offset)
|
||||
context.editor.moveCaret(offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val settings = CodeStyleSettingsManager.getInstance(context.project).currentSettings.getCustomSettings(KotlinCodeStyleSettings::class.java)
|
||||
val spaceBefore = if (settings.SPACE_BEFORE_TYPE_COLON) " " else ""
|
||||
val spaceAfter = if (settings.SPACE_AFTER_TYPE_COLON) " " else ""
|
||||
@@ -224,8 +240,10 @@ class ParameterNameAndTypeCompletion(
|
||||
override fun hashCode() = parameterName.hashCode()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val PRIORITY_KEY = Key<Int>("ParameterNameAndTypeCompletion.PRIORITY_KEY")
|
||||
companion object {
|
||||
private val PRIORITY_KEY = Key<Int>("ParameterNameAndTypeCompletion.PRIORITY_KEY")
|
||||
|
||||
val REPLACEMENT_OFFSET = OffsetKey.create("ParameterNameAndTypeCompletion.REPLACEMENT_OFFSET")
|
||||
}
|
||||
|
||||
object Weigher : LookupElementWeigher("kotlin.parameterNameAndTypePriority") {
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class FooBar
|
||||
|
||||
fun f(b<caret>pp: (Int, Char) -> String)
|
||||
|
||||
// ELEMENT_TEXT: bar: FooBar
|
||||
// CHAR: '\t'
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class FooBar
|
||||
|
||||
fun f(bar: FooBar<caret>)
|
||||
|
||||
// ELEMENT_TEXT: bar: FooBar
|
||||
// CHAR: '\t'
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class FooBar
|
||||
|
||||
fun f(b<caret>pp: Int, c: Char)
|
||||
|
||||
// ELEMENT_TEXT: bar: FooBar
|
||||
// CHAR: '\t'
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class FooBar
|
||||
|
||||
fun f(bar: FooBar, <caret>c: Char)
|
||||
|
||||
// ELEMENT_TEXT: bar: FooBar
|
||||
// CHAR: '\t'
|
||||
+12
@@ -562,6 +562,18 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TabReplace1.kt")
|
||||
public void testTabReplace1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/parameterNameAndType/TabReplace1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TabReplace2.kt")
|
||||
public void testTabReplace2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/parameterNameAndType/TabReplace2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeParameter.kt")
|
||||
public void testTypeParameter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/parameterNameAndType/TypeParameter.kt");
|
||||
|
||||
Reference in New Issue
Block a user