private void showUsages(final UsageInfo[] usages) { UsageViewPresentation presentation = new UsageViewPresentation(); presentation.setTabText("Safe Delete Conflicts"); presentation.setTargetsNodeText( RefactoringBundle.message("attempting.to.delete.targets.node.text")); presentation.setShowReadOnlyStatusAsRed(true); presentation.setShowCancelButton(true); presentation.setCodeUsagesString(RefactoringBundle.message("references.found.in.code")); presentation.setUsagesInGeneratedCodeString( RefactoringBundle.message("references.found.in.generated.code")); presentation.setNonCodeUsagesString( RefactoringBundle.message("occurrences.found.in.comments.strings.and.non.java.files")); presentation.setUsagesString(RefactoringBundle.message("usageView.usagesText")); UsageViewManager manager = UsageViewManager.getInstance(myProject); final UsageView usageView = showUsages(usages, presentation, manager); usageView.addPerformOperationAction( new RerunSafeDelete(myProject, myElements, usageView), RefactoringBundle.message("retry.command"), null, RefactoringBundle.message("rerun.safe.delete")); usageView.addPerformOperationAction( () -> { UsageInfo[] preprocessedUsages = usages; for (SafeDeleteProcessorDelegate delegate : Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) { preprocessedUsages = delegate.preprocessUsages(myProject, preprocessedUsages); if (preprocessedUsages == null) return; } final UsageInfo[] filteredUsages = UsageViewUtil.removeDuplicatedUsages(preprocessedUsages); execute(filteredUsages); }, "Delete Anyway", RefactoringBundle.message("usageView.need.reRun"), RefactoringBundle.message("usageView.doAction")); }
@Override protected boolean preprocessUsages(@NotNull Ref<UsageInfo[]> refUsages) { UsageInfo[] usages = refUsages.get(); ArrayList<String> conflicts = new ArrayList<String>(); for (PsiElement element : myElements) { for (SafeDeleteProcessorDelegate delegate : Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) { if (delegate.handlesElement(element)) { Collection<String> foundConflicts = delegate instanceof SafeDeleteProcessorDelegateBase ? ((SafeDeleteProcessorDelegateBase) delegate) .findConflicts(element, myElements, usages) : delegate.findConflicts(element, myElements); if (foundConflicts != null) { conflicts.addAll(foundConflicts); } break; } } } final HashMap<PsiElement, UsageHolder> elementsToUsageHolders = sortUsages(usages); final Collection<UsageHolder> usageHolders = elementsToUsageHolders.values(); for (UsageHolder usageHolder : usageHolders) { if (usageHolder.hasUnsafeUsagesInCode()) { conflicts.add(usageHolder.getDescription()); } } if (!conflicts.isEmpty()) { final RefactoringEventData conflictData = new RefactoringEventData(); conflictData.putUserData(RefactoringEventData.CONFLICTS_KEY, conflicts); myProject .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .conflictsDetected("refactoring.safeDelete", conflictData); if (ApplicationManager.getApplication().isUnitTestMode()) { if (!ConflictsInTestsException.isTestIgnore()) throw new ConflictsInTestsException(conflicts); } else { UnsafeUsagesDialog dialog = new UnsafeUsagesDialog(ArrayUtil.toStringArray(conflicts), myProject); if (!dialog.showAndGet()) { final int exitCode = dialog.getExitCode(); prepareSuccessful(); // dialog is always dismissed; if (exitCode == UnsafeUsagesDialog.VIEW_USAGES_EXIT_CODE) { showUsages( Arrays.stream(usages) .filter( usage -> usage instanceof SafeDeleteReferenceUsageInfo && !((SafeDeleteReferenceUsageInfo) usage).isSafeDelete()) .toArray(UsageInfo[]::new)); } return false; } else { myPreviewNonCodeUsages = false; } } } UsageInfo[] preprocessedUsages = usages; for (SafeDeleteProcessorDelegate delegate : Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) { preprocessedUsages = delegate.preprocessUsages(myProject, preprocessedUsages); if (preprocessedUsages == null) return false; } final UsageInfo[] filteredUsages = UsageViewUtil.removeDuplicatedUsages(preprocessedUsages); prepareSuccessful(); // dialog is always dismissed if (filteredUsages == null) { return false; } refUsages.set(filteredUsages); return true; }