diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java index 22f23d0fb46e..60ec2387c397 100644 --- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java @@ -330,6 +330,9 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { else if (usage instanceof SafeDeleteParameterCallHierarchyUsageInfo) { delegatingParams.add((SafeDeleteParameterCallHierarchyUsageInfo)usage); } + else if (usage instanceof SafeDeleteAnnotation) { + result.add(new SafeDeleteAnnotation((PsiAnnotation)usage.getElement(), ((SafeDeleteAnnotation)usage).getReferencedElement(), true)); + } else { result.add(usage); } @@ -518,6 +521,8 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { private static void findClassUsages(final PsiClass psiClass, final PsiElement[] allElementsToDelete, final List usages) { final boolean justPrivates = containsOnlyPrivates(psiClass); + final String qualifiedName = psiClass.getQualifiedName(); + final boolean annotationType = psiClass.isAnnotationType() && qualifiedName != null; ReferencesSearch.search(psiClass).forEach(new Processor() { public boolean process(final PsiReference reference) { @@ -547,7 +552,14 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { classes[0] == psiClass && element.getContainingFile() == containingFile; } - usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(element, psiClass, sameFileWithSingleClass || isInNonStaticImport(element))); + + final boolean safeDelete = sameFileWithSingleClass || isInNonStaticImport(element); + if (annotationType && parent instanceof PsiAnnotation) { + usages.add(new SafeDeleteAnnotation((PsiAnnotation)parent, psiClass, safeDelete)); + } + else { + usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(element, psiClass, safeDelete)); + } } return true; } diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteAnnotation.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteAnnotation.java new file mode 100644 index 000000000000..10afca493b01 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteAnnotation.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.refactoring.safeDelete.usageInfo; + +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; + +public class SafeDeleteAnnotation extends SafeDeleteReferenceUsageInfo { + public SafeDeleteAnnotation(PsiAnnotation element, PsiElement referencedElement, boolean safeDelete) { + super(element, referencedElement, safeDelete); + } + + @Override + public void deleteElement() throws IncorrectOperationException { + final PsiElement element = getElement(); + if (element != null) { + element.delete(); + } + } +} diff --git a/java/java-tests/testData/refactoring/safeDelete/ShowConflictsButRemoveAnnotationsIfAnnotationTypeIsDeleted.java b/java/java-tests/testData/refactoring/safeDelete/ShowConflictsButRemoveAnnotationsIfAnnotationTypeIsDeleted.java new file mode 100644 index 000000000000..6213e74bd7f0 --- /dev/null +++ b/java/java-tests/testData/refactoring/safeDelete/ShowConflictsButRemoveAnnotationsIfAnnotationTypeIsDeleted.java @@ -0,0 +1,3 @@ +@interface A {} +@A +class Test {} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/safeDelete/ShowConflictsButRemoveAnnotationsIfAnnotationTypeIsDeleted_after.java b/java/java-tests/testData/refactoring/safeDelete/ShowConflictsButRemoveAnnotationsIfAnnotationTypeIsDeleted_after.java new file mode 100644 index 000000000000..183c3f5b3be0 --- /dev/null +++ b/java/java-tests/testData/refactoring/safeDelete/ShowConflictsButRemoveAnnotationsIfAnnotationTypeIsDeleted_after.java @@ -0,0 +1 @@ +class Test {} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java index 4e0fa5cd73bd..72e38d92cddd 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java @@ -305,6 +305,16 @@ public class SafeDeleteTest extends MultiFileTestCase { doSingleFileTest(); } + public void testShowConflictsButRemoveAnnotationsIfAnnotationTypeIsDeleted() throws Exception { + try { + BaseRefactoringProcessor.ConflictsInTestsException.setTestIgnore(true); + doSingleFileTest(); + } + finally { + BaseRefactoringProcessor.ConflictsInTestsException.setTestIgnore(false); + } + } + private void doTest(@NonNls final String qClassName) throws Exception { doTest((rootDir, rootAfter) -> { SafeDeleteTest.this.performAction(qClassName);