java: fix completing class name in its supertype's second generic type argument

This commit is contained in:
peter
2019-03-26 15:40:04 +01:00
parent 26e8df8cba
commit 0a4514d50f
4 changed files with 20 additions and 9 deletions

View File

@@ -26,10 +26,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PatternCondition;
import com.intellij.patterns.PsiJavaElementPattern;
import com.intellij.patterns.PsiNameValuePairPattern;
import com.intellij.patterns.*;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.filters.*;
@@ -73,7 +70,7 @@ public class JavaCompletionContributor extends CompletionContributor {
static final ElementPattern<PsiElement> ANNOTATION_NAME =
psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class).afterLeaf("@");
private static final PsiJavaElementPattern.Capture<PsiElement> UNEXPECTED_REFERENCE_AFTER_DOT =
private static final ElementPattern<PsiElement> UNEXPECTED_REFERENCE_AFTER_DOT =
psiElement().afterLeaf(".").insideStarting(psiExpressionStatement());
private static final PsiNameValuePairPattern NAME_VALUE_PAIR =
psiNameValuePair().withSuperParent(2, psiElement(PsiAnnotation.class));
@@ -110,10 +107,7 @@ public class JavaCompletionContributor extends CompletionContributor {
@Nullable
public static ElementFilter getReferenceFilter(PsiElement position) {
// Completion after extends in interface, type parameter and implements in class
PsiClass containingClass = PsiTreeUtil.getParentOfType(
position, PsiClass.class, false, PsiCodeBlock.class, PsiMethod.class, PsiExpressionList.class, PsiVariable.class, PsiAnnotation.class);
if (containingClass != null && psiElement().afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS, ",", "&").accepts(position)) {
if (isInExtendsOrImplementsList(position)) {
return new AndFilter(ElementClassFilter.CLASS, new NotFilter(new AssignableFromContextFilter()));
}
@@ -190,6 +184,17 @@ public class JavaCompletionContributor extends CompletionContributor {
return TrueFilter.INSTANCE;
}
private static boolean isInExtendsOrImplementsList(PsiElement position) {
PsiClass containingClass = PsiTreeUtil.getParentOfType(
position, PsiClass.class, false, PsiCodeBlock.class, PsiMethod.class, PsiExpressionList.class, PsiVariable.class, PsiAnnotation.class);
return containingClass != null &&
psiElement().afterLeaf(
psiElement()
.withText(string().oneOf(PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS, ",", "&"))
.withParent(PsiReferenceList.class)
).accepts(position);
}
private static boolean isInsideAnnotationName(PsiElement position) {
PsiAnnotation anno = PsiTreeUtil.getParentOfType(position, PsiAnnotation.class, true, PsiMember.class);
return anno != null && PsiTreeUtil.isAncestor(anno.getNameReferenceElement(), position, true);

View File

@@ -0,0 +1,2 @@
interface Super<A,B> {}
class Sub implements Super<Sub, Su<caret>> {}

View File

@@ -0,0 +1,2 @@
interface Super<A,B> {}
class Sub implements Super<Sub, Sub<caret>> {}

View File

@@ -1894,6 +1894,8 @@ class Abc {
void testPutCaretInsideParensInFixedPlusVarargOverloads() { doTest('\n') }
void testSuggestCurrentClassInSecondSuperGenericParameter() { doTest('\n') }
void "test after new editing prefix back and forth when sometimes there are expected type suggestions and sometimes not"() {
myFixture.addClass("class Super {}")
myFixture.addClass("class Sub extends Super {}")