diff --git a/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java b/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java index 38fb4182c772..0d1f406aaf17 100644 --- a/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java @@ -366,7 +366,7 @@ public class PyCompatibilityInspection extends PyInspection { registerOnFirstMatchingVersion(level -> level.isAtLeast(LanguageLevel.PYTHON37), "'async' and 'await' are keywords in Python 3.7 and newer", nameIdentifier, - new PyRenameElementQuickFix()); + new PyRenameElementQuickFix(nameIdentifierOwner)); } } } diff --git a/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java b/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java index d3f089d07672..c37a8ac6907b 100644 --- a/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java @@ -155,7 +155,7 @@ public class PyPep8NamingInspection extends PyInspection { private void registerAndAddRenameAndIgnoreErrorQuickFixes(@Nullable final PsiElement node, @NotNull final String errorCode) { if (getHolder() != null && getHolder().isOnTheFly()) - registerProblem(node, ERROR_CODES_DESCRIPTION.get(errorCode), new PyRenameElementQuickFix(), new IgnoreErrorFix(errorCode)); + registerProblem(node, ERROR_CODES_DESCRIPTION.get(errorCode), new PyRenameElementQuickFix(node), new IgnoreErrorFix(errorCode)); else registerProblem(node, ERROR_CODES_DESCRIPTION.get(errorCode), new IgnoreErrorFix(errorCode)); } @@ -174,7 +174,7 @@ public class PyPep8NamingInspection extends PyInspection { if (nameNode != null) { final List quickFixes = Lists.newArrayList(); if (getHolder() != null && getHolder().isOnTheFly()) - quickFixes.add(new PyRenameElementQuickFix()); + quickFixes.add(new PyRenameElementQuickFix(nameNode.getPsi())); if (containingClass != null) { quickFixes.add(new IgnoreBaseClassQuickFix(containingClass, myTypeEvalContext)); diff --git a/python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java b/python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java index efc3609c43bd..83b2bfbb98e2 100644 --- a/python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java @@ -106,7 +106,7 @@ public class PyProtectedMemberInspection extends PyInspection { private void checkReference(@NotNull final PyReferenceExpression node, @NotNull final PyExpression qualifier) { final String name = node.getName(); final List quickFixes = new ArrayList<>(); - quickFixes.add(new PyRenameElementQuickFix()); + quickFixes.add(new PyRenameElementQuickFix(node)); if (name != null && name.startsWith("_") && !name.startsWith("__") && !name.endsWith("__")) { final PsiReference reference = node.getReference(getResolveContext()); diff --git a/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java b/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java index 04747c166f50..52c0a8eb75b1 100644 --- a/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java @@ -156,7 +156,7 @@ public class PyRedeclarationInspection extends PyInspection { if (writeElement != null && readElementRef.get() == null) { final List quickFixes = new ArrayList<>(); if (suggestRename(element, writeElement)) { - quickFixes.add(new PyRenameElementQuickFix()); + quickFixes.add(new PyRenameElementQuickFix(element)); } final PsiElement identifier = element.getNameIdentifier(); registerProblem(identifier != null ? identifier : element, diff --git a/python/src/com/jetbrains/python/inspections/PyShadowingBuiltinsInspection.java b/python/src/com/jetbrains/python/inspections/PyShadowingBuiltinsInspection.java index d44851a5b36d..21662d54f116 100644 --- a/python/src/com/jetbrains/python/inspections/PyShadowingBuiltinsInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyShadowingBuiltinsInspection.java @@ -110,7 +110,7 @@ public class PyShadowingBuiltinsInspection extends PyInspection { final PsiElement identifier = element.getNameIdentifier(); final PsiElement problemElement = identifier != null ? identifier : element; registerProblem(problemElement, String.format("Shadows built-in name '%s'", name), - ProblemHighlightType.WEAK_WARNING, null, new PyRenameElementQuickFix(), new PyIgnoreBuiltinQuickFix(name)); + ProblemHighlightType.WEAK_WARNING, null, new PyRenameElementQuickFix(problemElement), new PyIgnoreBuiltinQuickFix(name)); } } } diff --git a/python/src/com/jetbrains/python/inspections/PyShadowingNamesInspection.java b/python/src/com/jetbrains/python/inspections/PyShadowingNamesInspection.java index b337b3f7b74d..e1f63f380588 100644 --- a/python/src/com/jetbrains/python/inspections/PyShadowingNamesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyShadowingNamesInspection.java @@ -118,7 +118,7 @@ public class PyShadowingNamesInspection extends PyInspection { return; } registerProblem(problemElement, String.format("Shadows name '%s' from outer scope", name), - ProblemHighlightType.WEAK_WARNING, null, new PyRenameElementQuickFix()); + ProblemHighlightType.WEAK_WARNING, null, new PyRenameElementQuickFix(problemElement)); return; } } diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyMakePublicQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PyMakePublicQuickFix.java index 64e21614737b..f0050e0accb1 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/PyMakePublicQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/PyMakePublicQuickFix.java @@ -21,10 +21,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; import com.intellij.refactoring.rename.RenameProcessor; import com.jetbrains.python.PyBundle; -import com.jetbrains.python.psi.PyReferenceExpression; import com.jetbrains.python.psi.PyTargetExpression; import org.jetbrains.annotations.NotNull; @@ -38,11 +36,9 @@ public class PyMakePublicQuickFix implements LocalQuickFix { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - PsiElement element = descriptor.getPsiElement(); - if (element instanceof PyReferenceExpression) { - final PsiReference reference = element.getReference(); - if (reference == null) return; - element = reference.resolve(); + final PsiElement element = PyQuickFixUtil.dereference(descriptor.getPsiElement()); + if (element == null) { + return; } if (element instanceof PyTargetExpression) { final String name = ((PyTargetExpression)element).getName(); diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyQuickFixUtil.java b/python/src/com/jetbrains/python/inspections/quickfix/PyQuickFixUtil.java index 3ad435445642..38f65249e30a 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/PyQuickFixUtil.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/PyQuickFixUtil.java @@ -20,6 +20,8 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.jetbrains.python.psi.PyReferenceExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,4 +42,13 @@ public class PyQuickFixUtil { } return null; } + + @Nullable + public static PsiElement dereference(PsiElement element) { + if (element instanceof PyReferenceExpression) { + final PsiReference reference = element.getReference(); + return reference != null ? reference.resolve() : null; + } + return element; + } } diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyRenameElementQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PyRenameElementQuickFix.java index d38ea496aa7d..f3584f73ff63 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/PyRenameElementQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/PyRenameElementQuickFix.java @@ -1,18 +1,13 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.jetbrains.python.inspections.quickfix; -import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiNameIdentifierOwner; -import com.intellij.psi.PsiReference; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.PsiSearchHelper; import com.intellij.psi.search.SearchScope; @@ -24,12 +19,18 @@ import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer; import com.jetbrains.python.PyBundle; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.psi.PyNamedParameter; -import com.jetbrains.python.psi.PyReferenceExpression; import com.jetbrains.python.psi.PyTargetExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class PyRenameElementQuickFix implements LocalQuickFix { +/** + * @see com.intellij.psi.util.PsiUtilBase#findEditor + */ +public class PyRenameElementQuickFix extends LocalQuickFixAndIntentionActionOnPsiElement { + + public PyRenameElementQuickFix(@Nullable PsiElement element) { + super(element); + } @NotNull @Override @@ -37,31 +38,35 @@ public class PyRenameElementQuickFix implements LocalQuickFix { return PyBundle.message("QFIX.NAME.rename.element"); } + @NotNull @Override - public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - PsiElement element = descriptor.getPsiElement(); - if (element instanceof PyReferenceExpression) { - final PsiReference reference = element.getReference(); - if (reference == null) return; - element = reference.resolve(); + public String getText() { + return PyBundle.message("QFIX.NAME.rename.element"); + } + + @Override + public void invoke(@NotNull Project project, + @NotNull PsiFile file, + @Nullable Editor editor, + @NotNull PsiElement startElement, + @NotNull PsiElement endElement) { + final PsiElement element = PyQuickFixUtil.dereference(startElement); + if (element == null) { + return; } final PsiNameIdentifierOwner nameOwner = element instanceof PsiNameIdentifierOwner ? (PsiNameIdentifierOwner)element : PsiTreeUtil.getParentOfType(element, PsiNameIdentifierOwner.class, true); - if (nameOwner != null) { - final VirtualFile virtualFile = nameOwner.getContainingFile().getVirtualFile(); - if (virtualFile != null) { - final Editor editor = FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, virtualFile), true); - if (ApplicationManager.getApplication().isUnitTestMode()) { - renameInUnitTestMode(project, nameOwner, editor); + if (nameOwner != null && editor != null) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + renameInUnitTestMode(project, nameOwner, editor); + } + else { + if (checkLocalScope(element) != null && (nameOwner instanceof PyNamedParameter || nameOwner instanceof PyTargetExpression)) { + new VariableInplaceRenamer(nameOwner, editor).performInplaceRename(); } else { - if (checkLocalScope(element) != null && (nameOwner instanceof PyNamedParameter || nameOwner instanceof PyTargetExpression)) { - new VariableInplaceRenamer(nameOwner, editor).performInplaceRename(); - } - else { - PsiElementRenameHandler.invoke(nameOwner, project, ScopeUtil.getScopeOwner(nameOwner), editor); - } + PsiElementRenameHandler.invoke(nameOwner, project, ScopeUtil.getScopeOwner(nameOwner), editor); } } }