IDEA-198968 Idea smart completion suggests non-accessible constructor

This commit is contained in:
peter
2018-09-17 17:57:56 +02:00
parent 15e27559b3
commit fba349c8a1
7 changed files with 17 additions and 12 deletions
@@ -557,18 +557,21 @@ public class JavaCompletionUtil {
return Collections.singletonList(LookupItemUtil.objectToLookupItem(completion));
}
public static boolean hasAccessibleConstructor(PsiType type) {
public static boolean hasAccessibleConstructor(@NotNull PsiType type, @NotNull PsiElement place) {
if (type instanceof PsiArrayType) return true;
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
if (psiClass == null || psiClass.isEnum() || psiClass.isAnnotationType()) return false;
PsiMethod[] methods = psiClass.getConstructors();
return methods.length == 0 || Arrays.stream(methods).anyMatch(JavaCompletionUtil::isConstructorCompletable);
return methods.length == 0 || Arrays.stream(methods).anyMatch(constructor -> isConstructorCompletable(constructor, place));
}
private static boolean isConstructorCompletable(@NotNull PsiMethod constructor) {
return !(constructor instanceof PsiCompiledElement) || !constructor.hasModifierProperty(PsiModifier.PRIVATE);
private static boolean isConstructorCompletable(@NotNull PsiMethod constructor, @NotNull PsiElement place) {
if (!(constructor instanceof PsiCompiledElement)) return true; // it's possible to use a quick fix to make accessible after completion
if (constructor.hasModifierProperty(PsiModifier.PRIVATE)) return false;
if (constructor.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) return PsiUtil.isAccessible(constructor, place, null);
return true;
}
public static LinkedHashSet<String> getAllLookupStrings(@NotNull PsiMember member) {
@@ -134,7 +134,7 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter
@Nullable
private LookupElement addExpectedType(final PsiType type,
final CompletionParameters parameters) {
if (!JavaCompletionUtil.hasAccessibleConstructor(type)) return null;
if (!JavaCompletionUtil.hasAccessibleConstructor(type, parameters.getPosition())) return null;
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
if (psiClass == null || psiClass.getName() == null) return null;
@@ -0,0 +1,5 @@
class Foo {
{
java.lang.Package c = new <caret>
}
}
@@ -1,5 +0,0 @@
class Foo {
{
Class c = new <caret>
}
}
@@ -292,4 +292,6 @@ public void testConvertToObjectStream() {
configureByTestName();
myFixture.assertPreferredCompletionItems(0, "String.class");
}
public void testFilterInaccessibleConstructors() { doAntiTest(); }
}
@@ -1044,7 +1044,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
public void testNewAbstractInsideAnonymous() { doTest(); }
public void testFilterPrivateConstructors() { doTest(); }
public void testFilterPrivateConstructors() { doAntiTest(); }
public void testExplicitMethodTypeParametersQualify() { doTest(); }
public void testExplicitMethodTypeParametersOverZealous() { doTest(); }
@@ -338,7 +338,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
@Nullable
private static LookupElement addExpectedType(PsiType type, final PsiElement place, CompletionParameters parameters, @Nullable PsiType diamond) {
if (!JavaCompletionUtil.hasAccessibleConstructor(type)) return null;
if (!JavaCompletionUtil.hasAccessibleConstructor(type, place)) return null;
final PsiClass psiClass = com.intellij.psi.util.PsiUtil.resolveClassInType(type);
if (psiClass == null) return null;