diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/quickfix/PyRemoveAssignmentStatementTargetQuickFix.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/quickfix/PyRemoveAssignmentStatementTargetQuickFix.java new file mode 100644 index 000000000000..24d7b6496777 --- /dev/null +++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/quickfix/PyRemoveAssignmentStatementTargetQuickFix.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.inspections.quickfix; + +import com.intellij.codeInsight.intention.HighPriorityAction; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.jetbrains.python.PyPsiBundle; +import com.jetbrains.python.psi.*; +import org.jetbrains.annotations.NotNull; + +public class PyRemoveAssignmentStatementTargetQuickFix implements LocalQuickFix, HighPriorityAction { + @NotNull + @Override + public String getFamilyName() { + return PyPsiBundle.message("QFIX.NAME.remove.target.expr"); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); + if (assignmentStatement == null) return; + final PyExpression expression = assignmentStatement.getAssignedValue(); + if (expression == null) return; + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + PyExpressionStatement statement = elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpressionStatement.class, + expression.getText()); + assignmentStatement.replace(statement); + } +} diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/unusedLocal/PyUnusedLocalInspectionVisitor.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/unusedLocal/PyUnusedLocalInspectionVisitor.java index d0865f17988e..e3c517b000b7 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/inspections/unusedLocal/PyUnusedLocalInspectionVisitor.java +++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/unusedLocal/PyUnusedLocalInspectionVisitor.java @@ -4,6 +4,7 @@ package com.jetbrains.python.inspections.unusedLocal; import com.google.common.collect.ImmutableMap; import com.intellij.codeInsight.controlflow.ControlFlowUtil; import com.intellij.codeInsight.controlflow.Instruction; +import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.codeInspection.*; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.project.Project; @@ -424,7 +425,18 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { continue; } - registerWarning(element, warningMsg, new PyRemoveStatementQuickFix()); + final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); + if (assignmentStatement != null && PsiTreeUtil.isAncestor(assignmentStatement.getLeftHandSideExpression(), element, false)) { + if (assignmentStatement.getRawTargets().length > 1) { + // TODO: consider assignmentStatement.getRawTargets().length > 1 in PY-28782 + continue; + } + if (assignmentStatement.getLeftHandSideExpression() != element) { + registerWarning(element, warningMsg, new ReplaceWithWildCard()); + continue; + } + registerWarning(element, warningMsg, new PyRemoveAssignmentStatementTargetQuickFix(), new PyRemoveStatementQuickFix()); + } } } } diff --git a/python/testData/quickFixes/PyRemoveUnusedLocalQuickFixTest/removeAssignmentStatementTarget.py b/python/testData/quickFixes/PyRemoveUnusedLocalQuickFixTest/removeAssignmentStatementTarget.py new file mode 100644 index 000000000000..3d9c7879aeee --- /dev/null +++ b/python/testData/quickFixes/PyRemoveUnusedLocalQuickFixTest/removeAssignmentStatementTarget.py @@ -0,0 +1,4 @@ +class MyClass(object): + def __init__(self, **kwargs): + thing = kwargs.pop("stuff", None) + print("that's all folks!") \ No newline at end of file diff --git a/python/testData/quickFixes/PyRemoveUnusedLocalQuickFixTest/removeAssignmentStatementTarget_after.py b/python/testData/quickFixes/PyRemoveUnusedLocalQuickFixTest/removeAssignmentStatementTarget_after.py new file mode 100644 index 000000000000..794b6c4b3d90 --- /dev/null +++ b/python/testData/quickFixes/PyRemoveUnusedLocalQuickFixTest/removeAssignmentStatementTarget_after.py @@ -0,0 +1,4 @@ +class MyClass(object): + def __init__(self, **kwargs): + kwargs.pop("stuff", None) + print("that's all folks!") \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/quickFixes/PyRemoveUnusedLocalQuickFixTest.java b/python/testSrc/com/jetbrains/python/quickFixes/PyRemoveUnusedLocalQuickFixTest.java index 769f9aaaff9c..ed187db02826 100644 --- a/python/testSrc/com/jetbrains/python/quickFixes/PyRemoveUnusedLocalQuickFixTest.java +++ b/python/testSrc/com/jetbrains/python/quickFixes/PyRemoveUnusedLocalQuickFixTest.java @@ -59,6 +59,13 @@ public class PyRemoveUnusedLocalQuickFixTest extends PyQuickFixTestCase { }); } + // PY-17901 + public void testRemoveAssignmentStatementTarget() { + runWithLanguageLevel(LanguageLevel.getLatest(), () -> { + doQuickFixTest(PyUnusedLocalInspection.class, PyPsiBundle.message("QFIX.NAME.remove.target.expr")); + }); + } + // PY-32037 public void testGeneratorIterator() { doQuickFixTest(PyUnusedLocalInspection.class, PyPsiBundle.message("INSP.unused.locals.replace.with.wildcard"));