PyConvertMethodToPropertyIntention: find usages outside write action (EA-97938 - assert: NoSwingUnderWriteAction.lambda$watchForEvents$)

This commit is contained in:
peter
2017-03-02 14:02:47 +01:00
parent fb6ce87ca8
commit 2f1b2efdad
@@ -15,17 +15,22 @@
*/
package com.jetbrains.python.codeInsight.intentions;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.refactoring.PyRefactoringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -76,6 +81,11 @@ public class PyConvertMethodToPropertyIntention extends PyBaseIntentionAction {
return available[0];
}
@Override
public boolean startInWriteAction() {
return false;
}
public void doInvoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final PsiElement element = PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset());
PyFunction problemFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class);
@@ -84,6 +94,8 @@ public class PyConvertMethodToPropertyIntention extends PyBaseIntentionAction {
if (containingClass == null) return;
final List<UsageInfo> usages = PyRefactoringUtil.findUsages(problemFunction, false);
if (!prepareForWrite(file, usages)) return;
final PyDecoratorList problemDecoratorList = problemFunction.getDecoratorList();
List<String> decoTexts = new ArrayList<>();
decoTexts.add("@property");
@@ -94,8 +106,22 @@ public class PyConvertMethodToPropertyIntention extends PyBaseIntentionAction {
}
}
PyElementGenerator generator = PyElementGenerator.getInstance(project);
final PyDecoratorList decoratorList = generator.createDecoratorList(decoTexts.toArray(new String[decoTexts.size()]));
WriteAction.run(() -> {
ensureDecoratorList(problemFunction, problemDecoratorList, decoTexts);
deleteUsages(usages);
});
}
private static boolean prepareForWrite(PsiFile file, List<UsageInfo> usages) {
List<PsiElement> toWrite = ContainerUtil.newArrayList(file);
toWrite.addAll(ContainerUtil.mapNotNull(usages, UsageInfo::getElement));
if (!FileModificationService.getInstance().preparePsiElementsForWrite(toWrite)) return false;
return true;
}
private static void ensureDecoratorList(PyFunction problemFunction, @Nullable PyDecoratorList problemDecoratorList, List<String> decoTexts) {
PyElementGenerator generator = PyElementGenerator.getInstance(problemFunction.getProject());
PyDecoratorList decoratorList = generator.createDecoratorList(ArrayUtil.toStringArray(decoTexts));
if (problemDecoratorList != null) {
problemDecoratorList.replace(decoratorList);
@@ -103,7 +129,9 @@ public class PyConvertMethodToPropertyIntention extends PyBaseIntentionAction {
else {
problemFunction.addBefore(decoratorList, problemFunction.getFirstChild());
}
}
private static void deleteUsages(List<UsageInfo> usages) {
for (UsageInfo usage : usages) {
final PsiElement usageElement = usage.getElement();
if (usageElement instanceof PyReferenceExpression) {