From 0c7edc2939a1939dd60b4ad96f6ed8b25789373b Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Tue, 21 May 2019 17:44:26 +0700 Subject: [PATCH] IDEA-168309 Completion inside Class.forName starts suggesting root packages again when something unknown entered 1. getCompletionContext() should not return root packages if context reference is present but cannot be resolved 2. InstanceofExpressionPostfixTemplate should not be available inside the string literals GitOrigin-RevId: ad08e280cec09ddb6896c9d358c41cfc68b2cb8e --- .../templates/InstanceofExpressionPostfixTemplate.java | 4 ++++ .../reference/impl/providers/JavaClassReference.java | 7 +++++-- .../completion/reflection/ClassForNameInvalidPackage.java | 5 +++++ .../reflection/ClassForNameInvalidPackage_after.java | 5 +++++ .../completion/JavaReflectionCompletionTest.java | 6 ++++++ 5 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/ClassForNameInvalidPackage.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/ClassForNameInvalidPackage_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java index d16c1906b9e8..f474b3d38d2f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java @@ -48,6 +48,10 @@ public class InstanceofExpressionPostfixTemplate extends PostfixTemplate { @Override public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) { + if (context instanceof PsiJavaToken && ((PsiJavaToken)context).getTokenType().equals(JavaTokenType.STRING_LITERAL)) { + // Do not suggest inside String literals as it could be confusing if literal is interpreted as the reference + return false; + } return JavaPostfixTemplatesUtils.isNotPrimitiveTypeExpression(JavaPostfixTemplatesUtils.getTopmostExpression(context)); } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java index 9c13544db441..c26bcdd5e726 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java @@ -259,8 +259,11 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer @Nullable public PsiElement getCompletionContext() { - PsiElement context = getContext(); - return context == null ? JavaPsiFacade.getInstance(getElement().getProject()).findPackage("") : context; + final PsiReference contextRef = getContextReference(); + if (contextRef == null) { + return JavaPsiFacade.getInstance(getElement().getProject()).findPackage(""); + } + return contextRef.resolve(); } /** @deprecated use {@link #getSuperClasses()} instead */ diff --git a/java/java-tests/testData/codeInsight/completion/reflection/ClassForNameInvalidPackage.java b/java/java-tests/testData/codeInsight/completion/reflection/ClassForNameInvalidPackage.java new file mode 100644 index 000000000000..b9e7fbc59772 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/ClassForNameInvalidPackage.java @@ -0,0 +1,5 @@ +class Main { + void foo() throws ReflectiveOperationException { + Class.forName("com.foooooo."); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/ClassForNameInvalidPackage_after.java b/java/java-tests/testData/codeInsight/completion/reflection/ClassForNameInvalidPackage_after.java new file mode 100644 index 000000000000..b9e7fbc59772 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/ClassForNameInvalidPackage_after.java @@ -0,0 +1,5 @@ +class Main { + void foo() throws ReflectiveOperationException { + Class.forName("com.foooooo."); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaReflectionCompletionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaReflectionCompletionTest.java index aa1c87b8fdd6..103a5f414bc5 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaReflectionCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaReflectionCompletionTest.java @@ -159,6 +159,12 @@ public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase doTest(1, "PackageLocalClass", "PublicClass"); } + public void testClassForNameInvalidPackage() { + myFixture.addClass("package foo.bar; public class PublicClass {}"); + myFixture.addClass("package foo.bar; class PackageLocalClass {}"); + doTest(-1); + } + public void testClassForNamePackages() { myFixture.addClass("package foo.bar.one; public class FirstClass {}"); myFixture.addClass("package foo.bar.two; public class SecondClass {}");