From 31ec6415ae2b46a8563e8b06ac79cc2fd0dbbb11 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 13 Sep 2017 09:15:31 +0200 Subject: [PATCH] DeleteHandler: break up long method to make code easier to follow and typos like IDEA-178586 less likely --- .../com/intellij/ide/util/DeleteHandler.java | 151 ++++++++++-------- 1 file changed, 81 insertions(+), 70 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java index ab42c138d6a8..8184aa7928eb 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java @@ -118,11 +118,7 @@ public class DeleteHandler { final PsiElement[] elements = PsiTreeUtil.filterAncestors(elementsToDelete); - boolean safeDeleteApplicable = true; - for (int i = 0; i < elements.length && safeDeleteApplicable; i++) { - PsiElement element = elements[i]; - safeDeleteApplicable = SafeDeleteProcessor.validElement(element); - } + boolean safeDeleteApplicable = Arrays.stream(elements).allMatch(SafeDeleteProcessor::validElement); final boolean dumb = DumbService.getInstance(project).isDumb(); if (safeDeleteApplicable && !dumb) { @@ -188,20 +184,26 @@ public class DeleteHandler { } } + deleteInCommand(project, elements); + } + + private static boolean makeWritable(Project project, PsiElement[] elements) { + Collection directories = ContainerUtil.newSmartList(); + for (PsiElement e : elements) { + if (e instanceof PsiFileSystemItem && e.getParent() != null) { + directories.add(e.getParent()); + } + } + + return CommonRefactoringUtil.checkReadOnlyStatus(project, Arrays.asList(elements), directories, false); + } + + private static void deleteInCommand(Project project, PsiElement[] elements) { CommandProcessor.getInstance().executeCommand(project, () -> NonProjectFileWritingAccessProvider.disableChecksDuring(() -> { SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project); List pointers = ContainerUtil.map(elements, smartPointerManager::createSmartPsiElementPointer); - - Collection directories = ContainerUtil.newSmartList(); - for (PsiElement e : elements) { - if (e instanceof PsiFileSystemItem && e.getParent() != null) { - directories.add(e.getParent()); - } - } - if (!CommonRefactoringUtil.checkReadOnlyStatus(project, Arrays.asList(elements), directories, false)) { - return; - } + if (!makeWritable(project, elements)) return; // deleted from project view or something like that. if (CommonDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext()) == null) { @@ -212,65 +214,74 @@ public class DeleteHandler { PsiElement elementToDelete = pointer.getElement(); if (elementToDelete == null) continue; //was already deleted - if (elementToDelete instanceof PsiDirectory) { - VirtualFile virtualFile = ((PsiDirectory)elementToDelete).getVirtualFile(); - if (virtualFile.isInLocalFileSystem() && !virtualFile.is(VFileProperty.SYMLINK)) { - ArrayList readOnlyFiles = new ArrayList<>(); - CommonRefactoringUtil.collectReadOnlyFiles(virtualFile, readOnlyFiles); - - if (!readOnlyFiles.isEmpty()) { - String message = IdeBundle.message("prompt.directory.contains.read.only.files", virtualFile.getPresentableUrl()); - int _result = Messages.showYesNoDialog(project, message, IdeBundle.message("title.delete"), Messages.getQuestionIcon()); - if (_result != Messages.YES) continue; - - boolean success = true; - for (VirtualFile file : readOnlyFiles) { - success = clearReadOnlyFlag(file, project); - if (!success) break; - } - if (!success) continue; - } - } - } - else if (!elementToDelete.isWritable() && - !(elementToDelete instanceof PsiFileSystemItem && PsiUtilBase.isSymLink((PsiFileSystemItem)elementToDelete))) { - final PsiFile file = elementToDelete.getContainingFile(); - if (file != null) { - final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile.isInLocalFileSystem()) { - int _result = MessagesEx.fileIsReadOnly(project, virtualFile) - .setTitle(IdeBundle.message("title.delete")) - .appendMessage(" " + IdeBundle.message("prompt.delete.it.anyway")) - .askYesNo(); - if (_result != Messages.YES) continue; - - boolean success = clearReadOnlyFlag(virtualFile, project); - if (!success) continue; - } - } - } - - try { - elementToDelete.checkDelete(); - } - catch (IncorrectOperationException ex) { - Messages.showMessageDialog(project, ex.getMessage(), CommonBundle.getErrorTitle(), Messages.getErrorIcon()); - continue; - } - - ApplicationManager.getApplication().runWriteAction(() -> { - try { - elementToDelete.delete(); - } - catch (final IncorrectOperationException ex) { - ApplicationManager.getApplication().invokeLater( - () -> Messages.showMessageDialog(project, ex.getMessage(), CommonBundle.getErrorTitle(), Messages.getErrorIcon())); - } - }); + doDelete(project, elementToDelete); } }), RefactoringBundle.message("safe.delete.command", RefactoringUIUtil.calculatePsiElementDescriptionList(elements)), null); } + private static boolean clearFileReadOnlyFlags(Project project, PsiElement elementToDelete) { + if (elementToDelete instanceof PsiDirectory) { + VirtualFile virtualFile = ((PsiDirectory)elementToDelete).getVirtualFile(); + if (virtualFile.isInLocalFileSystem() && !virtualFile.is(VFileProperty.SYMLINK)) { + ArrayList readOnlyFiles = new ArrayList<>(); + CommonRefactoringUtil.collectReadOnlyFiles(virtualFile, readOnlyFiles); + + if (!readOnlyFiles.isEmpty()) { + String message = IdeBundle.message("prompt.directory.contains.read.only.files", virtualFile.getPresentableUrl()); + int _result = Messages.showYesNoDialog(project, message, IdeBundle.message("title.delete"), Messages.getQuestionIcon()); + if (_result != Messages.YES) return false; + + boolean success = true; + for (VirtualFile file : readOnlyFiles) { + success = clearReadOnlyFlag(file, project); + if (!success) break; + } + if (!success) return false; + } + } + } + else if (!elementToDelete.isWritable() && + !(elementToDelete instanceof PsiFileSystemItem && PsiUtilBase.isSymLink((PsiFileSystemItem)elementToDelete))) { + final PsiFile file = elementToDelete.getContainingFile(); + if (file != null) { + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile.isInLocalFileSystem()) { + int _result = MessagesEx.fileIsReadOnly(project, virtualFile) + .setTitle(IdeBundle.message("title.delete")) + .appendMessage(" " + IdeBundle.message("prompt.delete.it.anyway")) + .askYesNo(); + if (_result != Messages.YES) return false; + + boolean success = clearReadOnlyFlag(virtualFile, project); + if (!success) return false; + } + } + } + return true; + } + + private static void doDelete(Project project, PsiElement element) { + if (!clearFileReadOnlyFlags(project, element)) return; + + try { + element.checkDelete(); + } + catch (IncorrectOperationException ex) { + Messages.showMessageDialog(project, ex.getMessage(), CommonBundle.getErrorTitle(), Messages.getErrorIcon()); + return; + } + + ApplicationManager.getApplication().runWriteAction(() -> { + try { + element.delete(); + } + catch (final IncorrectOperationException ex) { + ApplicationManager.getApplication().invokeLater( + () -> Messages.showMessageDialog(project, ex.getMessage(), CommonBundle.getErrorTitle(), Messages.getErrorIcon())); + } + }); + } + private static boolean clearReadOnlyFlag(final VirtualFile virtualFile, final Project project) { final boolean[] success = new boolean[1]; CommandProcessor.getInstance().executeCommand(project, () -> {