mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
make smart completion work in java extends/implements clauses (IDEA-38166)
This commit is contained in:
+21
-14
@@ -33,6 +33,7 @@ import com.intellij.psi.filters.types.AssignableFromFilter;
|
||||
import com.intellij.psi.filters.types.AssignableToFilter;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.proximity.ReferenceListWeigher;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
@@ -79,7 +80,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
psiElement().withText(")").withParent(PsiTypeCastExpression.class)));
|
||||
|
||||
@Nullable
|
||||
private static ElementFilter getClassReferenceFilter(PsiElement element) {
|
||||
private static ElementFilter getClassReferenceFilter(final PsiElement element, final boolean inRefList) {
|
||||
//throw new foo
|
||||
if (AFTER_THROW_NEW.accepts(element)) {
|
||||
return THROWABLES_FILTER;
|
||||
@@ -98,15 +99,25 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
|
||||
// extends/implements/throws
|
||||
if (inRefList) {
|
||||
return new ElementExtractorFilter(new ElementFilter() {
|
||||
@Override
|
||||
public boolean isAcceptable(Object aClass, @Nullable PsiElement context) {
|
||||
return aClass instanceof PsiClass && ReferenceListWeigher.INSTANCE.getApplicability((PsiClass)aClass, element) !=
|
||||
ReferenceListWeigher.ReferenceListApplicability.inapplicable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassAcceptable(Class hintClass) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isInsideThrowsList(PsiElement element) {
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
|
||||
return method != null && PsiTreeUtil.isAncestor(method.getThrowsList(), element, true);
|
||||
}
|
||||
|
||||
|
||||
public JavaSmartCompletionContributor() {
|
||||
extend(CompletionType.SMART, SmartCastProvider.TYPECAST_TYPE_CANDIDATE, new SmartCastProvider());
|
||||
|
||||
@@ -125,16 +136,13 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
final PsiJavaCodeReferenceElement reference =
|
||||
PsiTreeUtil.findElementOfClassAtOffset(element.getContainingFile(), parameters.getOffset(), PsiJavaCodeReferenceElement.class, false);
|
||||
if (reference != null) {
|
||||
ElementFilter filter = getClassReferenceFilter(element);
|
||||
boolean completeConstructor = filter != null;
|
||||
if (filter == null && isInsideThrowsList(element)) {
|
||||
filter = THROWABLES_FILTER;
|
||||
}
|
||||
boolean inRefList = ReferenceListWeigher.INSIDE_REFERENCE_LIST.accepts(element);
|
||||
ElementFilter filter = getClassReferenceFilter(element, inRefList);
|
||||
if (filter != null) {
|
||||
final List<ExpectedTypeInfo> infos = Arrays.asList(getExpectedTypes(parameters));
|
||||
for (LookupElement item : completeReference(element, reference, filter, true, false, parameters, result.getPrefixMatcher())) {
|
||||
if (item.getObject() instanceof PsiClass) {
|
||||
if (completeConstructor) {
|
||||
if (!inRefList) {
|
||||
item = LookupElementDecorator.withInsertHandler(item, ConstructorInsertHandler.SMART_INSTANCE);
|
||||
}
|
||||
result.addElement(decorate(item, infos));
|
||||
@@ -150,7 +158,6 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,8 +17,8 @@ package com.intellij.psi.util.proximity;
|
||||
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.ProximityLocation;
|
||||
@@ -33,7 +33,7 @@ import static com.intellij.psi.util.proximity.ReferenceListWeigher.ReferenceList
|
||||
public class ReferenceListWeigher extends ProximityWeigher {
|
||||
public static final ReferenceListWeigher INSTANCE = new ReferenceListWeigher();
|
||||
|
||||
private static final PsiElementPattern.Capture<PsiElement> INSIDE_REFERENCE_LIST =
|
||||
public static final ElementPattern<PsiElement> INSIDE_REFERENCE_LIST =
|
||||
PlatformPatterns.psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiReferenceList.class);
|
||||
|
||||
protected enum Preference {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public class Main implements XFooIntf<caret> {
|
||||
|
||||
}
|
||||
|
||||
class XFoo1 {}
|
||||
class XFoo2 {}
|
||||
interface XFooIntf {}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public class Main implements XF<caret> {
|
||||
|
||||
}
|
||||
|
||||
class XFoo1 {}
|
||||
class XFoo2 {}
|
||||
interface XFooIntf {}
|
||||
+2
@@ -1159,6 +1159,8 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
public void testSuggestCastReturnTypeByCalledMethod() { doTest(); }
|
||||
|
||||
public void testOnlyInterfacesInImplements() { doTest(); }
|
||||
|
||||
public void testNonStaticField() throws Exception { doAntiTest(); }
|
||||
|
||||
private void doActionTest() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user