KT-5157 Code completion named parameter items should have lowest priority

KT-4157 Auto-popup code completion pre-selects wrong item

 #KT-5157 Fixed
 #KT-4157 Fixed
This commit is contained in:
Valentin Kipyatkov
2014-07-29 12:49:17 +04:00
parent f4a0031cf0
commit 6221de9849
10 changed files with 103 additions and 59 deletions
+23 -11
View File
@@ -223,23 +223,35 @@
<codeInsight.gotoSuper language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.GotoSuperActionHandler"/>
<typeDeclarationProvider implementation="org.jetbrains.jet.plugin.codeInsight.JetTypeDeclarationProvider"/>
<completion.contributor language="jet" id="JetKeywordCompletionContributor" order="first"
implementationClass="org.jetbrains.jet.plugin.completion.JetKeywordCompletionContributor"/>
<completion.contributor language="jet" id="JetPackagesContributor" order="after JetKeywordCompletionContributor"
<completion.contributor language="jet"
id="JetPackagesContributor"
order="first"
implementationClass="org.jetbrains.jet.plugin.completion.JetPackagesContributor"/>
<completion.contributor language="jet" id="JetExtensionFunctionReceiverContributor" order="after JetPackagesContributor"
<completion.contributor language="jet"
id="JetExtensionFunctionReceiverContributor"
order="after JetPackagesContributor"
implementationClass="org.jetbrains.jet.plugin.completion.JetExtensionReceiverTypeContributor"/>
<completion.contributor language="jet" id="KotlinNamedParametersContributor" order="after JetExtensionFunctionReceiverContributor"
implementationClass="org.jetbrains.jet.plugin.completion.KotlinNamedParametersContributor"/>
<completion.contributor language="jet" id="JetCompletionContributor" order="after KotlinNamedParametersContributor"
<completion.contributor language="jet"
id="JetCompletionContributor"
order="after JetExtensionFunctionReceiverContributor"
implementationClass="org.jetbrains.jet.plugin.completion.JetCompletionContributor"/>
<completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.liveTemplates.JetLiveTemplateCompletionContributor"
id="liveTemplates" order="first"/>
<completion.contributor language="jet"
id="JetKeywordCompletionContributor"
order="after JetCompletionContributor"
implementationClass="org.jetbrains.jet.plugin.completion.JetKeywordCompletionContributor"/>
<completion.contributor language="jet"
id="JetLiveTemplateCompletionContributor"
order="after JetKeywordCompletionContributor"
implementationClass="org.jetbrains.jet.plugin.liveTemplates.JetLiveTemplateCompletionContributor"/>
<completion.contributor language="jet"
id="KotlinNamedParametersContributor"
order="after JetLiveTemplateCompletionContributor"
implementationClass="org.jetbrains.jet.plugin.completion.KotlinNamedParametersContributor"/>
<completion.confidence language="jet" implementationClass="com.intellij.codeInsight.completion.UnfocusedNameIdentifier"/>
<completion.confidence language="jet"
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.completion
import com.intellij.openapi.util.Key
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.AutoCompletionPolicy
enum class ItemPriority {
DEFAULT
NAMED_PARAMETER
}
val ITEM_PRIORITY_KEY = Key<ItemPriority>("ITEM_PRIORITY_KEY")
fun LookupElement.assignPriority(priority: ItemPriority): LookupElement {
putUserData(ITEM_PRIORITY_KEY, priority)
return this
}
fun LookupElement.suppressAutoInsertion() = AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(this)
val KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY = Key<Unit>("KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY")
fun LookupElement.keepOldArgumentListOnTab(): LookupElement {
putUserData(KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY, Unit)
return this
}
@@ -19,6 +19,7 @@ package org.jetbrains.jet.plugin.completion;
import com.intellij.codeInsight.completion.*;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
@@ -29,10 +30,18 @@ import org.jetbrains.jet.lang.psi.JetBlockExpression;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.completion.smart.SmartCompletion;
import org.jetbrains.jet.plugin.references.JetSimpleNameReference;
import static com.intellij.patterns.PsiJavaPatterns.elementType;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
public class JetCompletionContributor extends CompletionContributor {
private static final ElementPattern<PsiElement> AFTER_NUMBER_LITERAL = psiElement().afterLeafSkipping(
psiElement().withText(""),
psiElement().withElementType(elementType().oneOf(JetTokens.FLOAT_LITERAL, JetTokens.INTEGER_LITERAL)));
public JetCompletionContributor() {
CompletionProvider<CompletionParameters> provider = new CompletionProvider<CompletionParameters>() {
@Override
@@ -51,7 +60,11 @@ public class JetCompletionContributor extends CompletionContributor {
public static void doSimpleReferenceCompletion(CompletionParameters parameters, CompletionResultSet result) {
PsiElement position = parameters.getPosition();
if (!(position.getContainingFile() instanceof JetFile)) {
if (!(position.getContainingFile() instanceof JetFile)) return;
if (AFTER_NUMBER_LITERAL.accepts(parameters.getPosition())) {
// First Kotlin completion contributors - stop here will stop all completion
result.stopHere();
return;
}
@@ -72,7 +72,7 @@ public class KotlinNamedParametersContributor : CompletionContributor() {
})
}
fun doParamsCompletion(parameters: CompletionParameters, result: CompletionResultSet) {
private fun doParamsCompletion(parameters: CompletionParameters, result: CompletionResultSet) {
val valueArgument = PsiTreeUtil.getParentOfType(parameters.getPosition(), javaClass<JetValueArgument>())!!
val callElement = PsiTreeUtil.getParentOfType(valueArgument, javaClass<JetCallElement>())
@@ -95,13 +95,14 @@ public class KotlinNamedParametersContributor : CompletionContributor() {
for (parameter in funDescriptor.getValueParameters()) {
val name = parameter.getName().asString()
if (result.getPrefixMatcher().prefixMatches(name) && name !in usedArguments) {
val lookupElementBuilder = LookupElementBuilder.create(NamedParameterLookupObject(parameter.getName()), "${name}")
val lookupElement = LookupElementBuilder.create(NamedParameterLookupObject(parameter.getName()), "${name}")
.withPresentableText("${name} = ")
.withTailText("${DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(parameter.getType())}")
.withIcon(JetIcons.PARAMETER)
.withInsertHandler(NamedParameterInsertHandler)
.assignPriority(ItemPriority.NAMED_PARAMETER)
kotlinResultSet.addElement(lookupElementBuilder)
kotlinResultSet.addElement(lookupElement)
}
}
}
@@ -22,7 +22,7 @@ import com.intellij.psi.PsiDocumentManager
import com.intellij.codeInsight.AutoPopupController
import com.intellij.codeInsight.lookup.Lookup
import org.jetbrains.jet.plugin.completion.smart.SmartCompletion
import org.jetbrains.jet.plugin.completion.smart.KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY
import org.jetbrains.jet.plugin.completion.KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY
import com.intellij.openapi.util.TextRange
class WithTailInsertHandler(val tailText: String,
@@ -19,13 +19,12 @@ package org.jetbrains.jet.plugin.completion.smart
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.plugin.completion.handlers.functionParameterTypes
import org.jetbrains.jet.renderer.DescriptorRenderer
import org.jetbrains.jet.plugin.completion.handlers.insertLambdaTemplate
import com.intellij.openapi.util.TextRange
import org.jetbrains.jet.plugin.completion.JetCompletionCharFilter
import org.jetbrains.jet.plugin.completion.ExpectedInfo
import org.jetbrains.jet.plugin.completion.handlers.buildLambdaPresentation
import org.jetbrains.jet.plugin.completion.suppressAutoInsertion
object LambdaItems {
public fun addToCollection(collection: MutableCollection<LookupElement>, functionExpectedInfos: Collection<ExpectedInfo>) {
@@ -90,15 +90,6 @@ fun LookupElement.addTail(tail: Tail?): LookupElement {
fun LookupElement.addTail(matchedExpectedInfos: Collection<ExpectedInfo>): LookupElement
= addTail(mergeTails(matchedExpectedInfos.map { it.tail }))
fun LookupElement.suppressAutoInsertion() = AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(this)
val KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY = Key<Unit>("KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY")
fun LookupElement.keepOldArgumentListOnTab(): LookupElement {
putUserData(KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY, Unit)
return this
}
enum class ExpectedInfoClassification {
MATCHES
MAKE_NOT_NULLABLE
@@ -23,25 +23,30 @@ import org.jetbrains.jet.lang.psi.JetFile
import com.intellij.codeInsight.lookup.LookupElementWeigher
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.WeighingContext
import org.jetbrains.jet.plugin.completion.*
public fun CompletionResultSet.addJetSorting(parameters: CompletionParameters): CompletionResultSet {
var sorter = CompletionSorter.defaultSorter(parameters, getPrefixMatcher())!!
sorter = sorter.weighBefore("stats", JetKindWeigher())
object PriorityWeigher : LookupElementWeigher("priority", false, false) {
override fun weigh(element: LookupElement, context: WeighingContext)
= (element.getUserData(ITEM_PRIORITY_KEY) ?: ItemPriority.DEFAULT).ordinal()
}
sorter = sorter.weighBefore("stats", PriorityWeigher, JetKindWeigher())
sorter = sorter.weighAfter(
"stats",
JetDeclarationRemotenessWeigher(parameters.getOriginalFile() as JetFile),
JetAccessibleWeigher())
sorter = sorter.weighBefore("middleMatching", PreferMatchingItemWeigher())
object PreferMatchingItemWeigher : LookupElementWeigher("preferMatching", false, true) {
override fun weigh(element: LookupElement, context: WeighingContext): Comparable<Int> {
val prefix = context.itemPattern(element)
return if (element.getLookupString() == prefix) 0 else 1
}
}
sorter = sorter.weighBefore("middleMatching", PreferMatchingItemWeigher)
return withRelevanceSorter(sorter)
}
class PreferMatchingItemWeigher : LookupElementWeigher("preferMatching", false, true) {
override fun weigh(element: LookupElement, context: WeighingContext): Comparable<Int> {
val prefix = context.itemPattern(element)
return if (element.getLookupString() == prefix) 0 else 1
}
}
@@ -21,45 +21,25 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.template.TemplateContextType;
import com.intellij.codeInsight.template.impl.*;
import com.intellij.openapi.util.Ref;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Consumer;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.intellij.patterns.PsiJavaPatterns.elementType;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
public class JetLiveTemplateCompletionContributor extends CompletionContributor {
private static final ElementPattern<PsiElement> AFTER_NUMBER_LITERAL = psiElement().afterLeafSkipping(
psiElement().withText(""),
psiElement().withElementType(elementType().oneOf(JetTokens.FLOAT_LITERAL, JetTokens.INTEGER_LITERAL)));
public JetLiveTemplateCompletionContributor() {
extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new CompletionProvider<CompletionParameters>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@NotNull final CompletionResultSet result) {
if (AFTER_NUMBER_LITERAL.accepts(parameters.getPosition())) {
// First Kotlin completion contributors - stop here will stop all completion
result.stopHere();
return;
}
if (parameters.getInvocationCount() == 0) {
return;
}
if (parameters.getInvocationCount() == 0) return;
PsiFile file = parameters.getPosition().getContainingFile();
int offset = parameters.getOffset();
@@ -16,7 +16,7 @@ fun test(listParam: Int) {
// ORDER: listParam
// ORDER: listThisFileVal
// ORDER: listImportedVal
// ORDER: listThisFileFun
// ORDER: listImportedFun
// ORDER: listMatch
// ORDER: listNew
// ORDER: listThisFileFun
// ORDER: listImportedFun