From ed6b45b2c9b6b64ed447a7aca376232ae3a628b2 Mon Sep 17 00:00:00 2001 From: "Irina.Chernushina" Date: Tue, 16 May 2017 18:38:26 +0200 Subject: [PATCH] WEB-26859 PsiInvalidElementAccessException when call 'Remove unused export' in vue files Fix: do not format in the middle (before the actual refactoring). Element gets invalidated before the actual operation. Also, it does not have much sense. - in the platform part, I introduced additional callback to be called _after_ refactoring. I did not want to change the behaviour of other parts - since the element is being deleted, after-reformatting should remove extra new lines/spaces, with respect to whether the element was inline Special problem is evaluating the range where to remove new lines/spaces after the refactoring; in the presence of the fact that actually parent-of-the-parent of the passed element can be removed (if the was wrapping statement which does not contain no more meaningful elements) That's why I am creating the collection of contexts around the element being deleted, and for its parents One test became worse :( - with deleting also the js doc, which became empty (UnusedLocalSymbols6) Do not know how it managed to work before and I think in this particular case the extra newline does not cost the price of possible error, if we try to also process this (cherry picked from commit 9f08aa4) --- .../safeDelete/SafeDeleteHandler.java | 26 +++++++++++++------ .../safeDelete/SafeDeleteProcessor.java | 6 +++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java index a752cc6b706f..ddc22788634d 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java @@ -64,7 +64,7 @@ public class SafeDeleteHandler implements RefactoringActionHandler { @Override public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) { - invoke(project, elements, LangDataKeys.MODULE.getData(dataContext), true, null); + invoke(project, elements, LangDataKeys.MODULE.getData(dataContext), true, null, null); } public static void invoke(final Project project, PsiElement[] elements, boolean checkDelegates) { @@ -72,10 +72,16 @@ public class SafeDeleteHandler implements RefactoringActionHandler { } public static void invoke(final Project project, PsiElement[] elements, boolean checkDelegates, @Nullable final Runnable successRunnable) { - invoke(project, elements, null, checkDelegates, successRunnable); + invoke(project, elements, null, checkDelegates, successRunnable, null); } - public static void invoke(final Project project, PsiElement[] elements, @Nullable Module module, boolean checkDelegates, @Nullable final Runnable successRunnable) { + public static void invoke(final Project project, PsiElement[] elements, @Nullable Module module, boolean checkDelegates, + @Nullable final Runnable successRunnable) { + invoke(project, elements, module, checkDelegates, successRunnable, null); + } + + public static void invoke(final Project project, PsiElement[] elements, @Nullable Module module, boolean checkDelegates, + @Nullable final Runnable successRunnable, @Nullable final Runnable afterRefactoring) { for (PsiElement element : elements) { if (!SafeDeleteProcessor.validElement(element)) { return; @@ -113,22 +119,26 @@ public class SafeDeleteHandler implements RefactoringActionHandler { if (ApplicationManager.getApplication().isUnitTestMode()) { RefactoringSettings settings = RefactoringSettings.getInstance(); - SafeDeleteProcessor.createInstance(project, null, elementsToDelete, settings.SAFE_DELETE_SEARCH_IN_COMMENTS, - settings.SAFE_DELETE_SEARCH_IN_NON_JAVA, true).run(); + final SafeDeleteProcessor processor = + SafeDeleteProcessor.createInstance(project, null, elementsToDelete, settings.SAFE_DELETE_SEARCH_IN_COMMENTS, + settings.SAFE_DELETE_SEARCH_IN_NON_JAVA, true); + if (afterRefactoring != null) processor.setAfterRefactoringCallback(afterRefactoring); + processor.run(); if (successRunnable != null) successRunnable.run(); } else { final SafeDeleteDialog.Callback callback = new SafeDeleteDialog.Callback() { @Override public void run(final SafeDeleteDialog dialog) { - SafeDeleteProcessor.createInstance(project, () -> { + final SafeDeleteProcessor processor = SafeDeleteProcessor.createInstance(project, () -> { if (successRunnable != null) { successRunnable.run(); } dialog.close(DialogWrapper.CANCEL_EXIT_CODE); - }, elementsToDelete, dialog.isSearchInComments(), dialog.isSearchForTextOccurences(), true).run(); + }, elementsToDelete, dialog.isSearchInComments(), dialog.isSearchForTextOccurences(), true); + if (afterRefactoring != null) processor.setAfterRefactoringCallback(afterRefactoring); + processor.run(); } - }; SafeDeleteDialog dialog = new SafeDeleteDialog(project, elementsToDelete, callback); diff --git a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java index 713e43cabc4d..45a6b526ab49 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java @@ -64,6 +64,7 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor { private boolean mySearchInCommentsAndStrings; private boolean mySearchNonJava; private boolean myPreviewNonCodeUsages = true; + private Runnable myAfterRefactoringCallback; private SafeDeleteProcessor(Project project, @Nullable Runnable prepareSuccessfulCallback, PsiElement[] elementsToDelete, boolean isSearchInComments, boolean isSearchNonJava) { @@ -391,6 +392,7 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor { element.delete(); } + if (myAfterRefactoringCallback != null) myAfterRefactoringCallback.run(); } catch (IncorrectOperationException e) { RefactoringUIUtil.processIncorrectOperation(myProject, e); } @@ -497,4 +499,8 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor { protected boolean skipNonCodeUsages() { return true; } + + public void setAfterRefactoringCallback(Runnable afterRefactoringCallback) { + myAfterRefactoringCallback = afterRefactoringCallback; + } }