mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
prefix matching is more important than element kind and statistics
This commit is contained in:
@@ -64,9 +64,6 @@ public class JavaCompletionSorting {
|
||||
else {
|
||||
afterPriority.add(new PreferDefaultTypeWeigher(expectedTypes, parameters));
|
||||
}
|
||||
if (!JavaCompletionData.START_FOR.accepts(position)) {
|
||||
afterPriority.add(new PreferByKindWeigher(type, position));
|
||||
}
|
||||
ContainerUtil.addIfNotNull(afterPriority, recursion(parameters, expectedTypes));
|
||||
if (!smart && !afterNew) {
|
||||
afterPriority.add(new PreferExpected(false, expectedTypes));
|
||||
@@ -117,7 +114,8 @@ public class JavaCompletionSorting {
|
||||
});
|
||||
}
|
||||
sorter = sorter.weighAfter("priority", afterPriority.toArray(new LookupElementWeigher[afterPriority.size()]));
|
||||
sorter = sorter.weighAfter("prefix", new PreferNonGeneric(), new PreferAccessible(position), new PreferSimple(), new PreferEnumConstants(parameters));
|
||||
sorter = sorter.weighAfter("prefix", new PreferByKindWeigher(type, position));
|
||||
sorter = sorter.weighAfter("stats", new PreferNonGeneric(), new PreferAccessible(position), new PreferSimple(), new PreferEnumConstants(parameters));
|
||||
sorter = sorter.weighAfter("proximity", afterProximity.toArray(new LookupElementWeigher[afterProximity.size()]));
|
||||
return result.withRelevanceSorter(sorter);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.patterns.StandardPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.filters.AndFilter;
|
||||
import com.intellij.psi.filters.ClassFilter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
@@ -53,7 +51,7 @@ class RecursionWeigher extends LookupElementWeigher {
|
||||
|
||||
public RecursionWeigher(PsiElement position,
|
||||
@NotNull PsiReferenceExpression reference,
|
||||
PsiMethodCallExpression expression,
|
||||
@Nullable PsiMethodCallExpression expression,
|
||||
ExpectedTypeInfo[] expectedInfos) {
|
||||
super("recursion");
|
||||
myFilter = recursionFilter(position);
|
||||
@@ -70,7 +68,7 @@ class RecursionWeigher extends LookupElementWeigher {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiExpression normalizeQualifier(PsiElement qualifier) {
|
||||
private static PsiExpression normalizeQualifier(@Nullable PsiElement qualifier) {
|
||||
return qualifier instanceof PsiThisExpression || !(qualifier instanceof PsiExpression) ? null : (PsiExpression)qualifier;
|
||||
}
|
||||
|
||||
@@ -127,21 +125,23 @@ class RecursionWeigher extends LookupElementWeigher {
|
||||
return Result.passingObjectToItself;
|
||||
}
|
||||
|
||||
if (myExpression != null) {
|
||||
if (myExpectedInfos != null) {
|
||||
final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
|
||||
for (final ExpectedTypeInfo expectedInfo : myExpectedInfos) {
|
||||
PsiMethod calledMethod = expectedInfo.getCalledMethod();
|
||||
if (calledMethod != null && itemType != null) {
|
||||
if (calledMethod.equals(myPositionMethod) && expectedInfo.getType().isAssignableFrom(itemType)) {
|
||||
return myDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
if (isGetterSetterAssignment(object, calledMethod)) {
|
||||
return myDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
if (myExpectedInfos != null) {
|
||||
final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
|
||||
for (final ExpectedTypeInfo expectedInfo : myExpectedInfos) {
|
||||
PsiMethod calledMethod = expectedInfo.getCalledMethod();
|
||||
if (itemType != null &&
|
||||
calledMethod != null &&
|
||||
calledMethod.equals(myPositionMethod) &&
|
||||
expectedInfo.getType().isAssignableFrom(itemType)) {
|
||||
return myDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
String propertyName = getSetterPropertyName(calledMethod);
|
||||
if (propertyName != null && isGetterSetterAssignment(object, propertyName)) {
|
||||
return myDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myExpression != null) {
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
@@ -159,16 +159,25 @@ class RecursionWeigher extends LookupElementWeigher {
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
private static boolean isGetterSetterAssignment(Object lookupObject, PsiMethod calledMethod) {
|
||||
if (!PropertyUtil.isSimplePropertySetter(calledMethod)) {
|
||||
return false;
|
||||
@Nullable
|
||||
private String getSetterPropertyName(@Nullable PsiMethod calledMethod) {
|
||||
if (PropertyUtil.isSimplePropertySetter(calledMethod)) {
|
||||
assert calledMethod != null;
|
||||
return PropertyUtil.getPropertyName(calledMethod);
|
||||
}
|
||||
PsiReferenceExpression reference = ExcludeSillyAssignment.getAssignedReference(myPosition);
|
||||
if (reference != null) {
|
||||
PsiElement target = reference.resolve();
|
||||
if (target instanceof PsiField) {
|
||||
return PropertyUtil.suggestPropertyName((PsiField)target);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String prop = PropertyUtil.getPropertyName(calledMethod);
|
||||
assert prop != null;
|
||||
private static boolean isGetterSetterAssignment(Object lookupObject, String prop) {
|
||||
if (lookupObject instanceof PsiField &&
|
||||
prop.equals(JavaCodeStyleManager.getInstance(calledMethod.getProject())
|
||||
.variableNameToPropertyName(((PsiField)lookupObject).getName(), VariableKind.FIELD))) {
|
||||
prop.equals(PropertyUtil.suggestPropertyName((PsiField)lookupObject))) {
|
||||
return true;
|
||||
}
|
||||
if (lookupObject instanceof PsiMethod &&
|
||||
@@ -181,7 +190,7 @@ class RecursionWeigher extends LookupElementWeigher {
|
||||
|
||||
private boolean isPassingObjectToItself(Object object) {
|
||||
if (object instanceof PsiThisExpression) {
|
||||
return !myDelegate || myCallQualifier instanceof PsiSuperExpression;
|
||||
return myCallQualifier != null && !myDelegate || myCallQualifier instanceof PsiSuperExpression;
|
||||
}
|
||||
return myCallQualifier instanceof PsiReferenceExpression &&
|
||||
object.equals(((PsiReferenceExpression)myCallQualifier).advancedResolve(true).getElement());
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.psi.filters.element;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -26,14 +27,13 @@ import com.intellij.psi.filters.ElementFilter;
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class ExcludeSillyAssignment implements ElementFilter {
|
||||
@Override
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
if(!(element instanceof PsiElement)) return true;
|
||||
|
||||
PsiElement each = context;
|
||||
@Nullable
|
||||
public static PsiReferenceExpression getAssignedReference(PsiElement position) {
|
||||
PsiElement each = position;
|
||||
while (each != null && !(each instanceof PsiFile)) {
|
||||
if (each instanceof PsiExpressionList || each instanceof PsiPrefixExpression || each instanceof PsiPolyadicExpression) {
|
||||
return true;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (each instanceof PsiAssignmentExpression) {
|
||||
@@ -43,18 +43,29 @@ public class ExcludeSillyAssignment implements ElementFilter {
|
||||
final PsiElement qualifier = referenceExpression.getQualifier();
|
||||
if (qualifier != null) {
|
||||
if (!(qualifier instanceof PsiThisExpression) || ((PsiThisExpression)qualifier).getQualifier() != null) {
|
||||
return true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return !referenceExpression.isReferenceTo((PsiElement)element);
|
||||
return referenceExpression;
|
||||
}
|
||||
return true;
|
||||
return null;
|
||||
}
|
||||
|
||||
each = each.getContext();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
if(!(element instanceof PsiElement)) return true;
|
||||
|
||||
PsiReferenceExpression referenceExpression = getAssignedReference(context);
|
||||
if (referenceExpression != null && referenceExpression.isReferenceTo((PsiElement)element)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -506,6 +506,9 @@ public class PropertyUtil {
|
||||
modifierList.addAfter(factory.createAnnotationFromText("@" + annotationQName, listOwner), null);
|
||||
}
|
||||
|
||||
public static String suggestPropertyName(PsiField field) {
|
||||
return suggestPropertyName(field.getProject(), field);
|
||||
}
|
||||
public static String suggestPropertyName(Project project, PsiField field) {
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
VariableKind kind = codeStyleManager.getVariableKind(field);
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class PsiElement {}
|
||||
|
||||
public class Foo {
|
||||
|
||||
Object psiElement() {}
|
||||
|
||||
void foo() {
|
||||
Psi<caret>
|
||||
}
|
||||
}
|
||||
+3
-11
@@ -1,22 +1,14 @@
|
||||
class T {
|
||||
I myLastI;
|
||||
I getLastI() { return myLastI; }
|
||||
I lastI;
|
||||
I getLastI() { return lastI; }
|
||||
|
||||
void setLastI(I a) {
|
||||
myLastI = <caret>
|
||||
lastI = <caret>
|
||||
}
|
||||
}
|
||||
|
||||
class I {
|
||||
static final I _1 = new I();
|
||||
static final I _2a = new I();
|
||||
static final I _3a = new I();
|
||||
static final I _4a = new I();
|
||||
static final I _5a = new I();
|
||||
static final I _6a = new I();
|
||||
static final I _7a = new I();
|
||||
static final I _8a = new I();
|
||||
static final I _9a = new I();
|
||||
|
||||
static I valueOf(String sth) {
|
||||
return null;
|
||||
|
||||
+9
-4
@@ -200,7 +200,7 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
}
|
||||
|
||||
public void testLocalVarsOverMethods() {
|
||||
checkPreferredItems(0, "value", "validate", "validateTree", "valueOf");
|
||||
checkPreferredItems(1, "value", "valueOf");
|
||||
}
|
||||
|
||||
public void testCurrentClassBest() {
|
||||
@@ -281,12 +281,12 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
public void testPreselectMostRelevantInTheMiddleAlpha() {
|
||||
UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = true;
|
||||
|
||||
myFixture.addClass("package foo; public class Elxaaaaaaaaaaaaaaaaaaaa {}");
|
||||
myFixture.addClass("package foo; public class ELXaaaaaaaaaaaaaaaaaaaa {}");
|
||||
invokeCompletion(getTestName(false) + ".java");
|
||||
myFixture.completeBasic();
|
||||
LookupImpl lookup = getLookup();
|
||||
assertPreferredItems(lookup.getList().getSelectedIndex());
|
||||
assertEquals("Elxaaaaaaaaaaaaaaaaaaaa", lookup.getItems().get(0).getLookupString());
|
||||
assertEquals("ELXaaaaaaaaaaaaaaaaaaaa", lookup.getItems().get(0).getLookupString());
|
||||
assertEquals("ELXEMENT_A", lookup.getCurrentItem().getLookupString());
|
||||
}
|
||||
|
||||
@@ -395,7 +395,7 @@ import java.lang.annotation.Target;
|
||||
myFixture.addClass('public class fooAClass {}')
|
||||
configureNoCompletion(getTestName(false) + ".java");
|
||||
myFixture.complete(CompletionType.BASIC, 2);
|
||||
assertPreferredItems(0, 'fooy', 'foox', 'fooAClass', 'fooBar');
|
||||
assertPreferredItems(0, 'fooy', 'fooAClass', 'fooBar', 'foox');
|
||||
}
|
||||
|
||||
public void testChangePreselectionOnSecondInvocation() {
|
||||
@@ -499,4 +499,9 @@ import java.lang.annotation.Target;
|
||||
assertPreferredItems 0, 'contains', 'containsAll'
|
||||
}
|
||||
|
||||
public void testCommonPrefixMoreImportantThanKind() {
|
||||
CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE;
|
||||
checkPreferredItems(0, 'PsiElement', 'psiElement')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -21,7 +21,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
}
|
||||
|
||||
public void testJComponentAdd() throws Throwable {
|
||||
checkPreferredItems(0, "name", "b", "foo", "fooBean239", "this", "getName");
|
||||
checkPreferredItems(0, "name", "getName", "b", "foo", "fooBean239", "this");
|
||||
}
|
||||
|
||||
public void testJComponentAddNew() throws Throwable {
|
||||
@@ -161,7 +161,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
}
|
||||
|
||||
public void testPreferParametersToGetters() throws Throwable {
|
||||
checkPreferredItems(0, "a", "getLastI");
|
||||
checkPreferredItems(0, "a", "I._1", "valueOf", "getLastI");
|
||||
}
|
||||
|
||||
public void testExpectedInterfaceShouldGoFirst() throws Throwable {
|
||||
@@ -178,7 +178,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
}
|
||||
|
||||
public void testPreferNonRecursiveMethodParams() throws Throwable {
|
||||
checkPreferredItems(0, "b", "s", "a", "hashCode");
|
||||
checkPreferredItems(0, "b", "hashCode", "s", "a");
|
||||
}
|
||||
|
||||
public void testPreferDelegatingMethodParams() throws Throwable {
|
||||
@@ -222,7 +222,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
}
|
||||
|
||||
public void testFactoryMethodForDefaultType() throws Throwable {
|
||||
checkPreferredItems(0, "create", "this", "map", "getClass");
|
||||
checkPreferredItems(0, "create", "this", "getClass");
|
||||
}
|
||||
|
||||
public void testLocalVarsBeforeClassLiterals() throws Throwable {
|
||||
|
||||
@@ -464,12 +464,12 @@
|
||||
order="after sameModule"/>
|
||||
|
||||
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.PriorityWeigher" id="priority" order="first"/>
|
||||
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.StatisticsWeigher" id="stats"
|
||||
order="after priority"/>
|
||||
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.PrefixMatchingWeigher" id="prefix"
|
||||
order="after stats"/>
|
||||
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.LookupElementProximityWeigher" id="proximity"
|
||||
order="after priority"/>
|
||||
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.StatisticsWeigher" id="stats"
|
||||
order="after prefix"/>
|
||||
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.LookupElementProximityWeigher" id="proximity"
|
||||
order="after stats"/>
|
||||
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.GroupingWeigher" id="grouping"
|
||||
order="last"/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user