java smart completion sorting: split getter kind into 3 kinds with different priority (getter should have a higher priority then any relevant method chain)

This commit is contained in:
Dmitry Batkovich
2017-07-04 11:17:59 +03:00
parent 3a8d9002e4
commit d55416e473
4 changed files with 81 additions and 10 deletions
@@ -73,12 +73,13 @@ public class PreferByKindWeigher extends LookupElementWeigher {
psiElement(PsiReferenceExpression.class).withParent(PsiResourceExpression.class)));
private final CompletionType myCompletionType;
@NotNull
private final PsiElement myPosition;
private final Set<PsiField> myNonInitializedFields;
private final Condition<PsiClass> myRequiredSuper;
private final ExpectedTypeInfo[] myExpectedTypes;
public PreferByKindWeigher(CompletionType completionType, final PsiElement position, ExpectedTypeInfo[] expectedTypes) {
public PreferByKindWeigher(CompletionType completionType, @NotNull final PsiElement position, ExpectedTypeInfo[] expectedTypes) {
super("kind");
myCompletionType = completionType;
myPosition = position;
@@ -134,12 +135,14 @@ public class PreferByKindWeigher extends LookupElementWeigher {
probableKeyword,
castVariable,
variable,
getter,
qualifiedWithField,
qualifiedWithGetter,
superMethodParameters,
expectedTypeConstant,
expectedTypeArgument,
getter,
getterQualifiedByMethod,
accessibleFieldGetter,
normal,
collectionFactory,
expectedTypeMethod,
@@ -209,12 +212,15 @@ public class PreferByKindWeigher extends LookupElementWeigher {
if (chain.getQualifier().getUserData(INTRODUCED_VARIABLE) == Boolean.TRUE) {
return MyResult.introducedVariable;
}
if (myCompletionType == CompletionType.SMART && qualifier instanceof PsiMethod && isGetter(object)) {
return MyResult.getterQualifiedByMethod;
}
}
if (myCompletionType == CompletionType.SMART) {
if (isGetter(object)) return MyResult.getter;
if (isGetter(object)) {
return chain == null && isAccessibleFieldGetter(object) ? MyResult.accessibleFieldGetter : MyResult.getter;
}
return MyResult.normal;
}
@@ -281,6 +287,13 @@ public class PreferByKindWeigher extends LookupElementWeigher {
return ThreeState.UNSURE;
}
private boolean isAccessibleFieldGetter(Object object) {
if (!(object instanceof PsiMethod)) return false;
PsiField field = PropertyUtil.getFieldOfGetter((PsiMethod)object);
return field != null && PsiResolveHelper.SERVICE.getInstance(myPosition.getProject()).isAccessible(field, myPosition, null);
}
static boolean isInMethodTypeArg(PsiElement position) {
return psiElement().inside(PsiReferenceParameterList.class).accepts(position);
}
@@ -0,0 +1,26 @@
class EditorFactory {
static EditorFactory getInstance() {
return null;
}
Editor getEditor() {
return null;
}
}
class Editor {
}
class Main {
void stats() {
Editor e = <caret>
}
Editor getEditor() {
return null;
}
}
@@ -0,0 +1,28 @@
class EditorFactory {
static EditorFactory getInstance() {
return null;
}
Editor getEditor() {
return null;
}
}
class Editor {
}
class Main {
void stats() {
EditorFactory.getInstance().getEditor();
EditorFactory.getInstance().getEditor();
EditorFactory.getInstance().getEditor();
EditorFactory.getInstance().getEditor();
EditorFactory.getInstance().getEditor();
EditorFactory.getInstance().getEditor();
EditorFactory.getInstance().getEditor();
}
}
@@ -172,6 +172,11 @@ public class MethodChainsCompletionTest extends AbstractCompilerAwareTest {
assertEmpty(doCompletion());
}
public void testPreferGetterToMethodChain() {
compileAndComplete();
myFixture.assertPreferredCompletionItems(0, "getEditor", "getInstance().getEditor");
}
public void testResultOrdering() {
List<JavaRelevantChainLookupElement> lookupElements = doCompletion();
assertSize(4, lookupElements);
@@ -267,8 +272,7 @@ public class MethodChainsCompletionTest extends AbstractCompilerAwareTest {
}
private List<JavaRelevantChainLookupElement> doCompletion() {
compileAndIndexData(TEST_INDEX_FILE_NAME);
LookupElement[] allLookupElements = runCompletion();
LookupElement[] allLookupElements = compileAndComplete();
List<JavaRelevantChainLookupElement> targetLookupElements = new SmartList<>();
for (LookupElement lookupElement : allLookupElements) {
if (lookupElement instanceof JavaRelevantChainLookupElement) {
@@ -278,10 +282,10 @@ public class MethodChainsCompletionTest extends AbstractCompilerAwareTest {
return targetLookupElements;
}
private LookupElement[] runCompletion() {
private LookupElement[] compileAndComplete() {
compileAndIndexData(TEST_INDEX_FILE_NAME);
myFixture.configureByFiles(getTestCompletionFilePath());
LookupElement[] lookupElements =
myFixture.complete(CompletionType.SMART);
LookupElement[] lookupElements = myFixture.complete(CompletionType.SMART);
return lookupElements == null ? LookupElement.EMPTY_ARRAY : lookupElements;
}