diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 85d45e784f15..1a02d07a38ce 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -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 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 { } } } - } } }); diff --git a/java/java-impl/src/com/intellij/psi/util/proximity/ReferenceListWeigher.java b/java/java-impl/src/com/intellij/psi/util/proximity/ReferenceListWeigher.java index e2c4d759b281..93660576de22 100644 --- a/java/java-impl/src/com/intellij/psi/util/proximity/ReferenceListWeigher.java +++ b/java/java-impl/src/com/intellij/psi/util/proximity/ReferenceListWeigher.java @@ -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 INSIDE_REFERENCE_LIST = + public static final ElementPattern INSIDE_REFERENCE_LIST = PlatformPatterns.psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiReferenceList.class); protected enum Preference { diff --git a/java/java-tests/testData/codeInsight/completion/smartType/OnlyInterfacesInImplements-out.java b/java/java-tests/testData/codeInsight/completion/smartType/OnlyInterfacesInImplements-out.java new file mode 100644 index 000000000000..304514290e85 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/OnlyInterfacesInImplements-out.java @@ -0,0 +1,7 @@ +public class Main implements XFooIntf { + +} + +class XFoo1 {} +class XFoo2 {} +interface XFooIntf {} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/OnlyInterfacesInImplements.java b/java/java-tests/testData/codeInsight/completion/smartType/OnlyInterfacesInImplements.java new file mode 100644 index 000000000000..2bab18cdb808 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/OnlyInterfacesInImplements.java @@ -0,0 +1,7 @@ +public class Main implements XF { + +} + +class XFoo1 {} +class XFoo2 {} +interface XFooIntf {} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index e8452836bd90..0b2c868a147b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -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 {