diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanAction.java b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanAction.java index d1f722e7..dbea4f9a 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanAction.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanAction.java @@ -16,6 +16,7 @@ package com.jetbrains.python.impl.refactoring.invertBoolean; +import consulo.annotation.access.RequiredReadAction; import jakarta.annotation.Nonnull; import consulo.language.Language; @@ -36,50 +37,61 @@ * User : ktisha */ public class PyInvertBooleanAction extends BaseRefactoringAction { - @Override - protected boolean isAvailableInEditorOnly() { - return true; - } - - @Override - protected boolean isEnabledOnElements(@Nonnull PsiElement[] elements) { - if (elements.length == 1) { - return isApplicable(elements[0], elements[0].getContainingFile()); + @Override + protected boolean isAvailableInEditorOnly() { + return true; } - return false; - } - private static boolean isApplicable(@Nonnull final PsiElement element, @Nonnull final PsiFile file) { - final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile != null && ProjectRootManager.getInstance(element.getProject()).getFileIndex().isInLibraryClasses(virtualFile)) return false; - if (element instanceof PyTargetExpression) { - final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); - if (assignmentStatement != null) { - final PyExpression assignedValue = assignmentStatement.getAssignedValue(); - if (assignedValue == null) return false; - final String name = assignedValue.getText(); - return name != null && (PyNames.TRUE.equals(name) || PyNames.FALSE.equals(name)); - } + @Override + @RequiredReadAction + protected boolean isEnabledOnElements(@Nonnull PsiElement[] elements) { + return elements.length == 1 && isApplicable(elements[0], elements[0].getContainingFile()); } - if (element instanceof PyNamedParameter) { - final PyExpression defaultValue = ((PyNamedParameter)element).getDefaultValue(); - if (defaultValue instanceof PyBoolLiteralExpression) return true; + + @RequiredReadAction + private static boolean isApplicable(@Nonnull PsiElement element, @Nonnull PsiFile file) { + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null && ProjectRootManager.getInstance(element.getProject()).getFileIndex().isInLibraryClasses(virtualFile)) { + return false; + } + if (element instanceof PyTargetExpression) { + PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); + if (assignmentStatement != null) { + PyExpression assignedValue = assignmentStatement.getAssignedValue(); + if (assignedValue == null) { + return false; + } + String name = assignedValue.getText(); + return name != null && (PyNames.TRUE.equals(name) || PyNames.FALSE.equals(name)); + } + } + if (element instanceof PyNamedParameter namedParam) { + PyExpression defaultValue = namedParam.getDefaultValue(); + if (defaultValue instanceof PyBoolLiteralExpression) { + return true; + } + } + return element.getParent() instanceof PyBoolLiteralExpression; } - return element.getParent() instanceof PyBoolLiteralExpression; - } - @Override - protected boolean isAvailableOnElementInEditorAndFile(@Nonnull final PsiElement element, @Nonnull final Editor editor, @Nonnull PsiFile file, @Nonnull DataContext context) { - return isApplicable(element, element.getContainingFile()); - } + @Override + @RequiredReadAction + protected boolean isAvailableOnElementInEditorAndFile( + @Nonnull PsiElement element, + @Nonnull Editor editor, + @Nonnull PsiFile file, + @Nonnull DataContext context + ) { + return isApplicable(element, element.getContainingFile()); + } - @Override - protected RefactoringActionHandler getHandler(@Nonnull DataContext dataContext) { - return new PyInvertBooleanHandler(); - } + @Override + protected RefactoringActionHandler getHandler(@Nonnull DataContext dataContext) { + return new PyInvertBooleanHandler(); + } - @Override - protected boolean isAvailableForLanguage(Language language) { - return language.isKindOf(PythonLanguage.getInstance()); - } + @Override + protected boolean isAvailableForLanguage(Language language) { + return language.isKindOf(PythonLanguage.getInstance()); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanDialog.java b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanDialog.java index 55e3a20e..fd35bc42 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanDialog.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanDialog.java @@ -16,14 +16,16 @@ package com.jetbrains.python.impl.refactoring.invertBoolean; -import consulo.language.editor.refactoring.RefactoringBundle; +import consulo.annotation.access.RequiredReadAction; +import consulo.language.editor.refactoring.localize.RefactoringLocalize; import consulo.language.editor.refactoring.rename.RenameUtil; import consulo.language.editor.refactoring.ui.RefactoringDialog; import consulo.language.editor.refactoring.util.CommonRefactoringUtil; import consulo.language.findUsage.DescriptiveNameUtil; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiNamedElement; +import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.usage.UsageViewUtil; import jakarta.annotation.Nullable; @@ -32,57 +34,62 @@ /** * User : ktisha */ -public class PyInvertBooleanDialog extends RefactoringDialog -{ - private JTextField myNameField; - private JPanel myPanel; - private JLabel myLabel; - private JLabel myCaptionLabel; +public class PyInvertBooleanDialog extends RefactoringDialog { + private JTextField myNameField; + private JPanel myPanel; + private JLabel myLabel; + private JLabel myCaptionLabel; - private final PsiElement myElement; - private final String myName; + private final PsiElement myElement; + private final String myName; - public PyInvertBooleanDialog(final PsiElement element) { - super(element.getProject(), false); - myElement = element; - myName = element instanceof PsiNamedElement ? ((PsiNamedElement)element).getName() : element.getText(); - myNameField.setText(myName); - myLabel.setLabelFor(myNameField); - final String typeString = UsageViewUtil.getType(myElement); - myLabel.setText(RefactoringBundle.message("invert.boolean.name.of.inverted.element", typeString)); - myCaptionLabel.setText(RefactoringBundle.message("invert.0.1", - typeString, - DescriptiveNameUtil.getDescriptiveName(myElement))); + @RequiredReadAction + public PyInvertBooleanDialog(PsiElement element) { + super(element.getProject(), false); + myElement = element; + myName = element instanceof PsiNamedElement namedElement ? namedElement.getName() : element.getText(); + myNameField.setText(myName); + myLabel.setLabelFor(myNameField); + String typeString = UsageViewUtil.getType(myElement); + myLabel.setText(RefactoringLocalize.invertBooleanNameOfInvertedElement(typeString).get()); + myCaptionLabel.setText(RefactoringLocalize.invert01(typeString, DescriptiveNameUtil.getDescriptiveName(myElement)).get()); - setTitle(PyInvertBooleanHandler.REFACTORING_NAME); - init(); - } - - public JComponent getPreferredFocusedComponent() { - return myNameField; - } + setTitle(RefactoringLocalize.invertBooleanTitle()); + init(); + } - protected void doAction() { - Project project = myElement.getProject(); - final String name = myNameField.getText().trim(); - if (name.length() == 0 || (!name.equals(myName) && !RenameUtil.isValidName(myProject, myElement, name))) { - CommonRefactoringUtil.showErrorMessage(PyInvertBooleanHandler.REFACTORING_NAME, - RefactoringBundle.message("please.enter.a.valid.name.for.inverted.element", - UsageViewUtil.getType(myElement)), - "refactoring.invertBoolean", project); - return; + @Override + @RequiredUIAccess + public JComponent getPreferredFocusedComponent() { + return myNameField; } - invokeRefactoring(new PyInvertBooleanProcessor(myElement, name)); - } + @Override + @RequiredUIAccess + protected void doAction() { + Project project = myElement.getProject(); + String name = myNameField.getText().trim(); + if (name.isEmpty() || (!name.equals(myName) && !RenameUtil.isValidName(myProject, myElement, name))) { + CommonRefactoringUtil.showErrorMessage( + RefactoringLocalize.invertBooleanTitle().get(), + RefactoringLocalize.pleaseEnterAValidNameForInvertedElement(UsageViewUtil.getType(myElement)).get(), + "refactoring.invertBoolean", + project + ); + return; + } - protected JComponent createCenterPanel() { - return myPanel; - } + invokeRefactoring(new PyInvertBooleanProcessor(myElement, name)); + } + + @Override + protected JComponent createCenterPanel() { + return myPanel; + } - @Nullable - @Override - protected String getHelpId() { - return "reference.invert.boolean"; - } + @Nullable + @Override + protected String getHelpId() { + return "reference.invert.boolean"; + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanHandler.java b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanHandler.java index 38411be1..be669e85 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanHandler.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanHandler.java @@ -16,8 +16,9 @@ package com.jetbrains.python.impl.refactoring.invertBoolean; +import consulo.language.editor.refactoring.localize.RefactoringLocalize; +import consulo.ui.annotation.RequiredUIAccess; import jakarta.annotation.Nonnull; -import consulo.language.editor.CommonDataKeys; import consulo.dataContext.DataContext; import consulo.codeEditor.Editor; import consulo.project.Project; @@ -34,38 +35,44 @@ * User : ktisha */ public class PyInvertBooleanHandler implements RefactoringActionHandler { - static final String REFACTORING_NAME = RefactoringBundle.message("invert.boolean.title"); - - @Override - public void invoke(@Nonnull Project project, Editor editor, PsiFile file, DataContext dataContext) { - PsiElement element = dataContext.getData(CommonDataKeys.PSI_ELEMENT); - if (element == null && editor != null && file != null) { - element = file.findElementAt(editor.getCaretModel().getOffset()); - } - final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); - if (assignmentStatement != null) { - invoke(assignmentStatement.getTargets()[0]); - } - else if (element instanceof PyNamedParameter) { - invoke(element); + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, Editor editor, PsiFile file, DataContext dataContext) { + PsiElement element = dataContext.getData(PsiElement.KEY); + if (element == null && editor != null && file != null) { + element = file.findElementAt(editor.getCaretModel().getOffset()); + } + final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); + if (assignmentStatement != null) { + invoke(assignmentStatement.getTargets()[0]); + } + else if (element instanceof PyNamedParameter namedParameter) { + invoke(namedParameter); + } + else { + CommonRefactoringUtil.showErrorHint( + project, + editor, + RefactoringBundle.getCannotRefactorMessage(RefactoringLocalize.errorWrongCaretPositionLocalOrExpressionName().get()), + RefactoringLocalize.invertBooleanTitle().get(), + "refactoring.invertBoolean" + ); + } } - else { - CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage( - RefactoringBundle.message("error.wrong.caret.position.local.or.expression.name")), REFACTORING_NAME, "refactoring.invertBoolean"); - } - } - @Override - public void invoke(@Nonnull Project project, @Nonnull PsiElement[] elements, DataContext dataContext) { - if (elements.length == 1) { - final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(elements[0], PyAssignmentStatement.class); - if (assignmentStatement != null) { - invoke(assignmentStatement.getTargets()[0]); - } + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, @Nonnull PsiElement[] elements, DataContext dataContext) { + if (elements.length == 1) { + final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(elements[0], PyAssignmentStatement.class); + if (assignmentStatement != null) { + invoke(assignmentStatement.getTargets()[0]); + } + } } - } - private static void invoke(@Nonnull final PsiElement element) { - new PyInvertBooleanDialog(element).show(); - } + @RequiredUIAccess + private static void invoke(@Nonnull final PsiElement element) { + new PyInvertBooleanDialog(element).show(); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanProcessor.java b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanProcessor.java index ae95afbc..d6cc342a 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanProcessor.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanProcessor.java @@ -19,182 +19,195 @@ import com.jetbrains.python.PyNames; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.psi.*; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.language.editor.refactoring.BaseRefactoringProcessor; +import consulo.language.editor.refactoring.localize.RefactoringLocalize; import consulo.language.editor.refactoring.rename.RenameProcessor; import consulo.language.editor.refactoring.rename.RenameUtil; import consulo.language.psi.*; import consulo.language.psi.search.ReferencesSearch; import consulo.language.psi.util.PsiTreeUtil; import consulo.language.util.IncorrectOperationException; +import consulo.ui.annotation.RequiredUIAccess; import consulo.usage.MoveRenameUsageInfo; import consulo.usage.UsageInfo; import consulo.usage.UsageViewDescriptor; -import consulo.util.lang.ref.Ref; - +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; + import java.util.*; /** * User : ktisha */ -public class PyInvertBooleanProcessor extends BaseRefactoringProcessor -{ - private PsiElement myElement; - private String myNewName; - private final RenameProcessor myRenameProcessor; - private final Map myToInvert = new HashMap(); - private final SmartPointerManager mySmartPointerManager; - - public PyInvertBooleanProcessor(@Nonnull final PsiElement namedElement, @Nonnull final String newName) { - super(namedElement.getProject()); - myElement = namedElement; - myNewName = newName; - mySmartPointerManager = SmartPointerManager.getInstance(myProject); - myRenameProcessor = new RenameProcessor(myProject, namedElement, newName, false, false); - } - - @Override - @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - return new PyInvertBooleanUsageViewDescriptor(myElement); - } - - @Override - protected boolean preprocessUsages(Ref refUsages) { - if (!myNewName.equals(myElement instanceof PsiNamedElement ? ((PsiNamedElement)myElement).getName() : myElement.getText())) { - if (myRenameProcessor.preprocessUsages(refUsages)) { +public class PyInvertBooleanProcessor extends BaseRefactoringProcessor { + private PsiElement myElement; + private String myNewName; + private final RenameProcessor myRenameProcessor; + private final Map myToInvert = new HashMap<>(); + private final SmartPointerManager mySmartPointerManager; + + public PyInvertBooleanProcessor(@Nonnull PsiElement namedElement, @Nonnull String newName) { + super(namedElement.getProject()); + myElement = namedElement; + myNewName = newName; + mySmartPointerManager = SmartPointerManager.getInstance(myProject); + myRenameProcessor = new RenameProcessor(myProject, namedElement, newName, false, false); + } + + @Override + @Nonnull + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { + return new PyInvertBooleanUsageViewDescriptor(myElement); + } + + @Override + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { + if (!myNewName.equals(myElement instanceof PsiNamedElement namedElement ? namedElement.getName() : myElement.getText())) { + if (myRenameProcessor.preprocessUsages(refUsages)) { + prepareSuccessful(); + return true; + } + return false; + } prepareSuccessful(); return true; - } - return false; } - prepareSuccessful(); - return true; - } - @Override - @Nonnull - protected UsageInfo[] findUsages() { - final List toInvert = new ArrayList(); + @Nonnull + @Override + @RequiredReadAction + protected UsageInfo[] findUsages() { + List toInvert = new ArrayList<>(); - addRefsToInvert(toInvert, myElement); + addRefsToInvert(toInvert, myElement); - final UsageInfo[] renameUsages = myRenameProcessor.findUsages(); + UsageInfo[] renameUsages = myRenameProcessor.findUsages(); - final Map expressionsToUsages = new HashMap(); - final List result = new ArrayList(); - for (UsageInfo renameUsage : renameUsages) { - expressionsToUsages.put(renameUsage.getElement(), renameUsage); - result.add(renameUsage); - } + Map expressionsToUsages = new HashMap<>(); + List result = new ArrayList<>(); + for (UsageInfo renameUsage : renameUsages) { + expressionsToUsages.put(renameUsage.getElement(), renameUsage); + result.add(renameUsage); + } - for (SmartPsiElementPointer pointer : toInvert) { - final PyExpression expression = (PyExpression)pointer.getElement(); - if (!expressionsToUsages.containsKey(expression) && expression != null) { - final UsageInfo usageInfo = new UsageInfo(expression); - expressionsToUsages.put(expression, usageInfo); - result.add(usageInfo); - myToInvert.put(usageInfo, pointer); - } else { - myToInvert.put(expressionsToUsages.get(expression), pointer); - } + for (SmartPsiElementPointer pointer : toInvert) { + PyExpression expression = (PyExpression)pointer.getElement(); + if (!expressionsToUsages.containsKey(expression) && expression != null) { + UsageInfo usageInfo = new UsageInfo(expression); + expressionsToUsages.put(expression, usageInfo); + result.add(usageInfo); + myToInvert.put(usageInfo, pointer); + } + else { + myToInvert.put(expressionsToUsages.get(expression), pointer); + } + } + + return result.toArray(new UsageInfo[result.size()]); } - return result.toArray(new UsageInfo[result.size()]); - } - - private void addRefsToInvert(@Nonnull final List toInvert, @Nonnull final PsiElement psiElement) { - final Collection refs = ReferencesSearch.search(psiElement).findAll(); - - for (PsiReference ref : refs) { - final PsiElement element = ref.getElement(); - if (element instanceof PyTargetExpression) { - final PyTargetExpression target = (PyTargetExpression)element; - final PyAssignmentStatement parent = PsiTreeUtil.getParentOfType(target, PyAssignmentStatement.class); - if (parent != null && parent.getTargets().length == 1) { - final PyExpression value = parent.getAssignedValue(); - if (value != null) - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(value)); + @RequiredReadAction + private void addRefsToInvert(@Nonnull List toInvert, @Nonnull PsiElement psiElement) { + Collection refs = ReferencesSearch.search(psiElement).findAll(); + + for (PsiReference ref : refs) { + PsiElement element = ref.getElement(); + if (element instanceof PyTargetExpression target) { + PyAssignmentStatement parent = PsiTreeUtil.getParentOfType(target, PyAssignmentStatement.class); + if (parent != null && parent.getTargets().length == 1) { + PyExpression value = parent.getAssignedValue(); + if (value != null) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(value)); + } + } + } + else if (element.getParent() instanceof PyPrefixExpression prefixExpression) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(prefixExpression)); + } + else if (element instanceof PyReferenceExpression refExpr) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(refExpr)); + } } - } - else if (element.getParent() instanceof PyPrefixExpression) { - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(element.getParent())); - } - else if (element instanceof PyReferenceExpression) { - final PyReferenceExpression refExpr = (PyReferenceExpression)element; - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(refExpr)); - } - } - if (psiElement instanceof PyNamedParameter) { - final PyExpression defaultValue = ((PyNamedParameter)psiElement).getDefaultValue(); - if (defaultValue != null) - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(defaultValue)); - } - } - - @Nonnull - private static UsageInfo[] extractUsagesForElement(@Nonnull final PsiElement element, @Nonnull final UsageInfo[] usages) { - final ArrayList extractedUsages = new ArrayList(usages.length); - for (UsageInfo usage : usages) { - if (usage instanceof MoveRenameUsageInfo) { - MoveRenameUsageInfo usageInfo = (MoveRenameUsageInfo)usage; - if (element.equals(usageInfo.getReferencedElement())) { - extractedUsages.add(usageInfo); + if (psiElement instanceof PyNamedParameter namedParam) { + PyExpression defaultValue = namedParam.getDefaultValue(); + if (defaultValue != null) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(defaultValue)); + } } - } - } - return extractedUsages.toArray(new UsageInfo[extractedUsages.size()]); - } - - - @Override - protected void performRefactoring(UsageInfo[] usages) { - for (final PsiElement element : myRenameProcessor.getElements()) { - try { - RenameUtil.doRename(element, myRenameProcessor.getNewName(element), extractUsagesForElement(element, usages), myProject, null); - } - catch (final IncorrectOperationException e) { - RenameUtil.showErrorMessage(e, element, myProject); - return; - } } - for (UsageInfo usage : usages) { - final SmartPsiElementPointer pointerToInvert = myToInvert.get(usage); - if (pointerToInvert != null) { - PsiElement expression = pointerToInvert.getElement(); - if (expression != null && PsiTreeUtil.getParentOfType(expression, PyImportStatementBase.class, false) == null) { - final PyExpression replacement = invertExpression(expression); - expression.replace(replacement); + + @Nonnull + private static UsageInfo[] extractUsagesForElement(@Nonnull PsiElement element, @Nonnull UsageInfo[] usages) { + ArrayList extractedUsages = new ArrayList<>(usages.length); + for (UsageInfo usage : usages) { + if (usage instanceof MoveRenameUsageInfo usageInfo && element.equals(usageInfo.getReferencedElement())) { + extractedUsages.add(usageInfo); + } } - } + return extractedUsages.toArray(new UsageInfo[extractedUsages.size()]); } - } - - @Nonnull - private PyExpression invertExpression(@Nonnull final PsiElement expression) { - final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(myProject); - if (expression instanceof PyBoolLiteralExpression) { - final String value = ((PyBoolLiteralExpression)expression).getValue() ? PyNames.FALSE : PyNames.TRUE; - return elementGenerator.createExpressionFromText(LanguageLevel.forElement(expression), value); - } - if (expression instanceof PyReferenceExpression && (PyNames.FALSE.equals(expression.getText()) || - PyNames.TRUE.equals(expression.getText()))) { - final String value = PyNames.TRUE.equals(expression.getText()) ? PyNames.FALSE : PyNames.TRUE; - return elementGenerator.createExpressionFromText(LanguageLevel.forElement(expression), value); + @Override + @RequiredWriteAction + protected void performRefactoring(@Nonnull UsageInfo[] usages) { + for (PsiElement element : myRenameProcessor.getElements()) { + try { + RenameUtil.doRename( + element, + myRenameProcessor.getNewName(element), + extractUsagesForElement(element, usages), + myProject, + null + ); + } + catch (IncorrectOperationException e) { + RenameUtil.showErrorMessage(e, element, myProject); + return; + } + } + for (UsageInfo usage : usages) { + SmartPsiElementPointer pointerToInvert = myToInvert.get(usage); + if (pointerToInvert != null) { + PsiElement expression = pointerToInvert.getElement(); + if (expression != null && PsiTreeUtil.getParentOfType(expression, PyImportStatementBase.class, false) == null) { + PyExpression replacement = invertExpression(expression); + expression.replace(replacement); + } + } + } } - else if (expression instanceof PyPrefixExpression) { - if (((PyPrefixExpression)expression).getOperator() == PyTokenTypes.NOT_KEYWORD) { - final PyExpression operand = ((PyPrefixExpression)expression).getOperand(); - if (operand != null) - return elementGenerator.createExpressionFromText(LanguageLevel.forElement(expression), operand.getText()); - } + + @Nonnull + @RequiredReadAction + private PyExpression invertExpression(@Nonnull PsiElement expression) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(myProject); + if (expression instanceof PyBoolLiteralExpression boolLiteralExpression) { + String value = boolLiteralExpression.getValue() ? PyNames.FALSE : PyNames.TRUE; + return elementGenerator.createExpressionFromText(LanguageLevel.forElement(expression), value); + } + if (expression instanceof PyReferenceExpression + && (PyNames.FALSE.equals(expression.getText()) || PyNames.TRUE.equals(expression.getText()))) { + + String value = PyNames.TRUE.equals(expression.getText()) ? PyNames.FALSE : PyNames.TRUE; + return elementGenerator.createExpressionFromText(LanguageLevel.forElement(expression), value); + } + else if (expression instanceof PyPrefixExpression prefixExpression) { + if (prefixExpression.getOperator() == PyTokenTypes.NOT_KEYWORD) { + PyExpression operand = prefixExpression.getOperand(); + if (operand != null) { + return elementGenerator.createExpressionFromText(LanguageLevel.forElement(expression), operand.getText()); + } + } + } + return elementGenerator.createExpressionFromText(LanguageLevel.forElement(expression), "not " + expression.getText()); } - return elementGenerator.createExpressionFromText(LanguageLevel.forElement(expression), "not " + expression.getText()); - } - @Override - protected String getCommandName() { - return PyInvertBooleanHandler.REFACTORING_NAME; - } + @Nonnull + @Override + protected String getCommandName() { + return RefactoringLocalize.invertBooleanTitle().get(); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanUsageViewDescriptor.java b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanUsageViewDescriptor.java index 929941ad..3db088bc 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanUsageViewDescriptor.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/refactoring/invertBoolean/PyInvertBooleanUsageViewDescriptor.java @@ -16,39 +16,41 @@ package com.jetbrains.python.impl.refactoring.invertBoolean; +import consulo.language.editor.refactoring.localize.RefactoringLocalize; import consulo.language.psi.PsiElement; -import consulo.language.editor.refactoring.RefactoringBundle; import consulo.usage.UsageViewBundle; import consulo.usage.UsageViewDescriptor; import consulo.usage.UsageViewUtil; - import jakarta.annotation.Nonnull; /** * User : ktisha */ -public class PyInvertBooleanUsageViewDescriptor implements UsageViewDescriptor -{ - private final PsiElement myElement; - - public PyInvertBooleanUsageViewDescriptor(final PsiElement element) { - myElement = element; - } - - @Nonnull - public PsiElement[] getElements() { - return new PsiElement[] {myElement}; - } - - public String getProcessedElementsHeader() { - return RefactoringBundle.message("invert.boolean.elements.header", UsageViewUtil.getType(myElement)); - } - - public String getCodeReferencesText(int usagesCount, int filesCount) { - return RefactoringBundle.message("invert.boolean.refs.to.invert", UsageViewBundle.getReferencesString(usagesCount, filesCount)); - } - - public String getCommentReferencesText(int usagesCount, int filesCount) { - return null; - } +public class PyInvertBooleanUsageViewDescriptor implements UsageViewDescriptor { + private final PsiElement myElement; + + public PyInvertBooleanUsageViewDescriptor(final PsiElement element) { + myElement = element; + } + + @Nonnull + @Override + public PsiElement[] getElements() { + return new PsiElement[]{myElement}; + } + + @Override + public String getProcessedElementsHeader() { + return RefactoringLocalize.invertBooleanElementsHeader(UsageViewUtil.getType(myElement)).get(); + } + + @Override + public String getCodeReferencesText(int usagesCount, int filesCount) { + return RefactoringLocalize.invertBooleanRefsToInvert(UsageViewBundle.getReferencesString(usagesCount, filesCount)).get(); + } + + @Override + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } }