From df4d5e648630b6291c6596f71587ae748ce35ee3 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 5 May 2022 11:03:49 +0200 Subject: [PATCH] [java-completion] IDEA-292773 autocomplete should expand also the ".class" automatically when requested argument type is a java.lang.Class GitOrigin-RevId: 064de8edd56681c0ef9720199ae002eb12e4ca92 --- .../completion/JavaCompletionContributor.java | 7 ++++++ .../filters/getters/ClassLiteralGetter.java | 5 ++++- ...sLiteralInArrayAnnoInitializer2_after.java | 2 +- ...ssLiteralInArrayAnnoInitializer_after.java | 2 +- .../NormalCompletionOrderingTest.groovy | 2 +- .../completion/NormalCompletionTest.groovy | 22 ++++++++++++++++--- 6 files changed, 33 insertions(+), 7 deletions(-) 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 2b2a33b54b8c..58b5406bbf30 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -46,6 +46,7 @@ import com.intellij.psi.filters.classes.AssignableFromContextFilter; import com.intellij.psi.filters.classes.NoFinalLibraryClassesFilter; import com.intellij.psi.filters.element.ExcludeDeclaredFilter; import com.intellij.psi.filters.element.ModifierFilter; +import com.intellij.psi.filters.getters.ClassLiteralGetter; import com.intellij.psi.filters.getters.ExpectedTypesGetter; import com.intellij.psi.filters.getters.JavaMembersGetter; import com.intellij.psi.filters.types.AssignableFromFilter; @@ -437,6 +438,12 @@ public final class JavaCompletionContributor extends CompletionContributor imple if (smart) { hasTypeMatchingSuggestions |= smartCompleteExpression(parameters, result, expectedInfos); smartCompleteNonExpression(parameters, result); + } else { + if (!JavaKeywordCompletion.AFTER_DOT.accepts(position)) { + for (ExpectedTypeInfo info : expectedInfos) { + ClassLiteralGetter.addCompletions(new JavaSmartCompletionParameters(parameters, info), result, matcher); + } + } } if ((!hasTypeMatchingSuggestions || parameters.getInvocationCount() >= 2) && diff --git a/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java b/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java index 6c29ffe2b2d8..6fa264cfaddc 100644 --- a/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java +++ b/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java @@ -4,6 +4,7 @@ package com.intellij.psi.filters.getters; import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.codeInsight.completion.JavaSmartCompletionParameters; import com.intellij.codeInsight.completion.PrefixMatcher; +import com.intellij.codeInsight.completion.PrioritizedLookupElement; import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.util.text.StringUtil; @@ -12,6 +13,7 @@ import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; import com.intellij.util.IncorrectOperationException; +import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,7 +36,8 @@ public final class ClassLiteralGetter { if (classParameter instanceof PsiWildcardType) { final PsiWildcardType wildcardType = (PsiWildcardType)classParameter; classParameter = wildcardType.isSuper() ? wildcardType.getSuperBound() : wildcardType.getExtendsBound(); - addInheritors = wildcardType.isExtends() && classParameter instanceof PsiClassType; + addInheritors = !wildcardType.isSuper() && classParameter instanceof PsiClassType && + !(matcher.getPrefix().isEmpty() && TypeUtils.isJavaLangObject(classParameter)); } else if (!matcher.getPrefix().isEmpty()) { addInheritors = true; classParameter = PsiType.getJavaLangObject(position.getManager(), position.getResolveScope()); diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassLiteralInArrayAnnoInitializer2_after.java b/java/java-tests/testData/codeInsight/completion/normal/ClassLiteralInArrayAnnoInitializer2_after.java index f957157a064d..90af2e0697d0 100644 --- a/java/java-tests/testData/codeInsight/completion/normal/ClassLiteralInArrayAnnoInitializer2_after.java +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassLiteralInArrayAnnoInitializer2_after.java @@ -3,7 +3,7 @@ } class Foo { - @TestFor(testForClass = { Object.class, Aaaaaaaaaaaaaaaaaaaaa } ) + @TestFor(testForClass = { Object.class, Aaaaaaaaaaaaaaaaaaaaa.class } ) public void foo22() {} } diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassLiteralInArrayAnnoInitializer_after.java b/java/java-tests/testData/codeInsight/completion/normal/ClassLiteralInArrayAnnoInitializer_after.java index 6ab28d5a3612..cd292b1f4d34 100644 --- a/java/java-tests/testData/codeInsight/completion/normal/ClassLiteralInArrayAnnoInitializer_after.java +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassLiteralInArrayAnnoInitializer_after.java @@ -3,7 +3,7 @@ } class Foo { - @TestFor(testForClass = { Aaaaaaaaaaaaaaaaaaaaa } ) + @TestFor(testForClass = { Aaaaaaaaaaaaaaaaaaaaa.class } ) public void foo22() {} } diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionOrderingTest.groovy index 5772a0e9ee0d..9becdfbc56f3 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionOrderingTest.groovy @@ -621,7 +621,7 @@ interface TxANotAnno {} @NeedsIndex.ForStandardLibrary void testPreferClassesOfExpectedClassType() { myFixture.addClass "class XException extends Exception {}" - checkPreferredItems 0, 'XException', 'XClass', 'XIntf' + checkPreferredItems 0, 'XException.class', 'XException', 'XClass', 'XIntf' } void testNoNumberValueOf() { 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 9ffb23a50c94..5ee67365458f 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 @@ -204,9 +204,11 @@ class NormalCompletionTest extends NormalCompletionTestCase { assertTrue("Exception not found", Arrays.binarySearch(myItems, "xxx") > 0) } - void testClassLiteralInArrayAnnoInitializer() throws Throwable { doTest() } + @NeedsIndex.ForStandardLibrary + void testClassLiteralInArrayAnnoInitializer() throws Throwable { doTest('\n') } - void testClassLiteralInArrayAnnoInitializer2() throws Throwable { doTest() } + @NeedsIndex.ForStandardLibrary + void testClassLiteralInArrayAnnoInitializer2() throws Throwable { doTest('\n') } void testReferenceParameters() throws Exception { configureByFile("ReferenceParameters.java") @@ -1368,7 +1370,7 @@ class XInternalError {} @Anno(XInternal) """ myFixture.complete(CompletionType.BASIC, 2) - assertFirstStringItems "XInternalError", "XInternalTimerServiceController" + assertFirstStringItems "XInternalError.class", "XInternalError", "XInternalTimerServiceController.class", "XInternalTimerServiceController" } @NeedsIndex.Full @@ -2660,4 +2662,18 @@ class Abc { myFixture.completeBasic() myFixture.checkResult("class Test {static void test() {int \u89D2\u8272 = 3;\u89D2\u8272}}") } + + @NeedsIndex.ForStandardLibrary + void testClassLiteralCompletion() { + myFixture.configureByText("Test.java", "class Test {Class get() {return String}}") + myFixture.completeBasic() + myFixture.assertPreferredCompletionItems(0, 'String', 'String.class', 'StringBuffer.class', 'StringBuffer', 'StringBuilder.class', 'StringBuilder', 'StringIndexOutOfBoundsException') + } + + @NeedsIndex.ForStandardLibrary + void testClassLiteralCompletionNoBound() { + myFixture.configureByText("Test.java", "class Test {Class get() {return String}}") + myFixture.completeBasic() + myFixture.assertPreferredCompletionItems(0, 'String', 'String.class', 'StringBuffer.class', 'StringBuffer', 'StringBuilder.class', 'StringBuilder', 'StringIndexOutOfBoundsException.class', 'StringIndexOutOfBoundsException') + } }