diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java index c71ae2d7c2f1..8a621585ea93 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java @@ -82,7 +82,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { @NotNull final Consumer consumer) { final PsiElement insertedElement = parameters.getPosition(); - if (JavaCompletionContributor.ANNOTATION_NAME.accepts(insertedElement)) { + if (JavaCompletionContributor.getAnnotationNameIfInside(insertedElement) != null) { MultiMap annoMap = getAllAnnotationClasses(insertedElement, matcher); Processor processor = new LimitedAccessibleClassPreprocessor(parameters, filterByScope, anno -> { JavaPsiClassReferenceElement item = AllClassesGetter.createLookupItem(anno, JAVA_CLASS_INSERT_HANDLER); 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 8f9e4951dba9..1ff8905a8b59 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -65,9 +65,6 @@ import static com.intellij.util.ObjectUtils.assertNotNull; public class JavaCompletionContributor extends CompletionContributor { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.JavaCompletionContributor"); - static final ElementPattern ANNOTATION_NAME = - psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class).afterLeaf("@"); - private static final ElementPattern UNEXPECTED_REFERENCE_AFTER_DOT = psiElement().afterLeaf(".").insideStarting(psiExpressionStatement()); private static final PsiNameValuePairPattern NAME_VALUE_PAIR = @@ -78,7 +75,7 @@ public class JavaCompletionContributor extends CompletionContributor { public static final ElementPattern IN_SWITCH_LABEL = psiElement().withSuperParent(2, psiElement(PsiExpressionList.class).withParent(psiElement(PsiSwitchLabelStatementBase.class).withSuperParent(2, PsiSwitchBlock.class))); - private static final ElementPattern IN_ENUM_SWITCH_LABEL = + private static final ElementPattern IN_ENUM_SWITCH_LABEL = psiElement().withSuperParent(2, psiElement(PsiExpressionList.class).withParent(psiElement(PsiSwitchLabelStatementBase.class).withSuperParent(2, psiElement(PsiSwitchBlock.class).with(new PatternCondition("enumExpressionType") { @Override @@ -109,8 +106,8 @@ public class JavaCompletionContributor extends CompletionContributor { return new AndFilter(ElementClassFilter.CLASS, new NotFilter(new AssignableFromContextFilter())); } - if (ANNOTATION_NAME.accepts(position)) { - return new AnnotationTypeFilter(); + if (getAnnotationNameIfInside(position) != null) { + return new OrFilter(ElementClassFilter.PACKAGE, new AnnotationTypeFilter()); } if (JavaKeywordCompletion.isDeclarationStart(position) || @@ -468,7 +465,7 @@ public class JavaCompletionContributor extends CompletionContributor { items.putValue(result1, new IndentingDecorator(TailTypeDecorator.withTail(element, switchLabelTail))); } else { - final LookupItem item = element.as(LookupItem.CLASS_CONDITION_KEY); + LookupItem item = element.as(LookupItem.CLASS_CONDITION_KEY); if (originalFile instanceof PsiJavaCodeReferenceCodeFragment && !((PsiJavaCodeReferenceCodeFragment)originalFile).isClassesAccepted() && item != null) { item.setTailType(TailType.NONE); @@ -814,9 +811,21 @@ public class JavaCompletionContributor extends CompletionContributor { context.setReplacementOffset(range.getEndOffset()); } } + + PsiJavaCodeReferenceElement ref = getAnnotationNameIfInside(file.findElementAt(context.getStartOffset())); + if (ref != null) { + context.setReplacementOffset(ref.getTextRange().getEndOffset()); + } } } + @Nullable + static PsiJavaCodeReferenceElement getAnnotationNameIfInside(@Nullable PsiElement position) { + PsiAnnotation anno = PsiTreeUtil.getParentOfType(position, PsiAnnotation.class); + PsiJavaCodeReferenceElement ref = anno == null ? null : anno.getNameReferenceElement(); + return ref != null && PsiTreeUtil.isAncestor(ref, position, false) ? ref : null; + } + @Nullable private static String customizeDummyIdentifier(@NotNull CompletionInitializationContext context, PsiFile file) { if (context.getCompletionType() != CompletionType.BASIC) return null; diff --git a/java/java-tests/testData/codeInsight/completion/normal/InnerAnnotation.java b/java/java-tests/testData/codeInsight/completion/normal/InnerAnnotation.java index 4fd5cc0138d4..96f6e62433ef 100644 --- a/java/java-tests/testData/codeInsight/completion/normal/InnerAnnotation.java +++ b/java/java-tests/testData/codeInsight/completion/normal/InnerAnnotation.java @@ -4,8 +4,10 @@ final class MyModule { public static @interface Dependency { } } +class MyAnotherModule {} + final class SomeService { - SomeService(@My) { + SomeService(@My.Inner) { } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/InnerAnnotation_after.java b/java/java-tests/testData/codeInsight/completion/normal/InnerAnnotation_after.java index 9ad5271d6b8d..2b0b0cb7e67b 100644 --- a/java/java-tests/testData/codeInsight/completion/normal/InnerAnnotation_after.java +++ b/java/java-tests/testData/codeInsight/completion/normal/InnerAnnotation_after.java @@ -4,6 +4,8 @@ final class MyModule { public static @interface Dependency { } } +class MyAnotherModule {} + final class SomeService { SomeService(@MyModule.Dependency) { 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 a342579f5ba0..2f139171ff64 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 @@ -995,7 +995,12 @@ public class ListUtils { void testMethodParameterAnnotationClass() throws Throwable { doTest() } - void testInnerAnnotation() { doTest('\n') } + void testInnerAnnotation() { + configure() + assert myFixture.lookupElementStrings == ['Dependency'] + type '\t' + checkResult() + } void testPrimitiveCastOverwrite() throws Throwable { doTest() }