diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index aae5b0b4b2e2..c0d5654259eb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -595,6 +595,19 @@ public class JavaCompletionContributor extends CompletionContributor implements PsiElement position = parameters.getPosition(); ElementFilter filter = getReferenceFilter(position); if (filter == null) return Collections.emptyList(); + if (parameters.getInvocationCount() <= 1 && JavaClassNameCompletionContributor.AFTER_NEW.accepts(position)) { + filter = new AndFilter(filter, new ElementFilter() { + @Override + public boolean isAcceptable(Object element, @Nullable PsiElement context) { + return !JavaPsiClassReferenceElement.isInaccessibleConstructorSuggestion(position, tryCast(element, PsiClass.class)); + } + + @Override + public boolean isClassAcceptable(Class hintClass) { + return true; + } + }); + } boolean smart = parameters.getCompletionType() == CompletionType.SMART; if (smart) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java index 8fd399aec77b..ab51cda2be22 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java @@ -210,11 +210,16 @@ public class JavaNoVariantsDelegator extends CompletionContributor implements Du return; } JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); + PsiElement position = parameters.getPosition(); if (classElement != null && parameters.getInvocationCount() < 2) { + if (JavaClassNameCompletionContributor.AFTER_NEW.accepts(position) && + JavaPsiClassReferenceElement.isInaccessibleConstructorSuggestion(position, classElement.getObject())) { + return; + } classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); } - element = JavaCompletionUtil.highlightIfNeeded(null, element, element.getObject(), parameters.getPosition()); + element = JavaCompletionUtil.highlightIfNeeded(null, element, element.getObject(), position); if (!sameNamedBatch.isEmpty() && !element.getLookupString().equals(sameNamedBatch.get(0).getLookupString())) { result.addAllElements(sameNamedBatch); sameNamedBatch.clear(); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java index 733732bd4fe9..b62590830865 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java @@ -24,8 +24,10 @@ import com.intellij.openapi.util.ClassConditionKey; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.JavaResolveUtil; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -221,4 +223,13 @@ public class JavaPsiClassReferenceElement extends LookupItem implements return CodeStyle.getLanguageSettings(element.getContainingFile(), JavaLanguage.INSTANCE).SPACE_AFTER_COMMA; } + static boolean isInaccessibleConstructorSuggestion(@NotNull PsiElement position, @Nullable PsiClass cls) { + if (cls == null || cls.hasModifierProperty(PsiModifier.ABSTRACT)) return false; + PsiMethod[] constructors = cls.getConstructors(); + if (constructors.length > 0) { + return !ContainerUtil.exists(constructors, ctor -> + JavaResolveUtil.isAccessible(ctor, cls, ctor.getModifierList(), position, null, null)); + } + return false; + } } diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInnersTab.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInnersTab.java index 2c1cada0ad5c..5a22f9ff9281 100644 --- a/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInnersTab.java +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInnersTab.java @@ -7,7 +7,7 @@ public class TestClass { } class Xxx { - private Xxx(String x) { + Xxx(String x) { } static class Yyy { diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInnersTab_after.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInnersTab_after.java index 868142c0653f..92bdf4cefc30 100644 --- a/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInnersTab_after.java +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInnersTab_after.java @@ -7,7 +7,7 @@ public class TestClass { } class Xxx { - private Xxx(String x) { + Xxx(String x) { } static class Yyy { diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy index 9f60414c51f0..c3b6e5a76cdc 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy @@ -22,6 +22,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleSettings import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.NeedsIndex import com.intellij.testFramework.PlatformTestUtil +import com.intellij.util.containers.ContainerUtil import com.intellij.util.ui.UIUtil import com.siyeh.ig.style.UnqualifiedFieldAccessInspection import groovy.transform.CompileStatic @@ -2298,4 +2299,11 @@ class Abc { assert myFixture.getLookupElementStrings().stream().filter({ it.contains("sss") }).collect(Collectors.toList()) == ["A.sss", "sss"] } + + @NeedsIndex.ForStandardLibrary + void "test private constructor"() { + myFixture.configureByText("A.java", "class A {{new Syst}}") + myFixture.completeBasic() + assert ContainerUtil.filter(myFixture.getLookupElementStrings(), {it.startsWith("S")}) == ['System.Logger', 'System.LoggerFinder'] + } }