mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
added PY-3120 Inspection to replace set built-in function with set literal
This commit is contained in:
@@ -81,6 +81,9 @@ QFIX.default.argument=Replace mutable default argument
|
||||
#RemoveArgumentEqualDefaultQuickFix
|
||||
QFIX.remove.argument.equal.default=Remove argument equal to default
|
||||
|
||||
# ReplaceFunctionWithSetLiteralQuickFix
|
||||
QFIX.replace.function.set.with.literal=Replace function call with set literal
|
||||
|
||||
# Intentions: INTN
|
||||
INTN.Family.convert.import.unqualify=Convert 'import module' to 'from module import'
|
||||
INTN.Family.convert.import.qualify=Convert 'from module import' to 'import module'
|
||||
@@ -381,6 +384,9 @@ INSP.NAME.single.quoted.docstring=Single quoted docstring
|
||||
# PyMissingConstructorInspection
|
||||
INSP.NAME.missing.super.constructor=Missed call to constructor of super class
|
||||
|
||||
# PySetFunctionToLiteralInspection
|
||||
INSP.NAME.set.function.to.literal=Function call can be replaced with set literal
|
||||
|
||||
# Refactoring
|
||||
# introduce
|
||||
refactoring.introduce.name.error=Incorrect name
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User : catherine
|
||||
* Quick Fix to replace function call of built-in function "set" with
|
||||
* set literal if applicable
|
||||
*/
|
||||
public class ReplaceFunctionWithSetLiteralQuickFix implements LocalQuickFix {
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.replace.function.set.with.literal");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
|
||||
PsiElement functionCall = descriptor.getPsiElement();
|
||||
StringBuilder str = new StringBuilder("{");
|
||||
if (functionCall instanceof PyCallExpression) {
|
||||
PyExpression[] arguments = ((PyCallExpression)functionCall).getArguments();
|
||||
if (arguments.length > 0) {
|
||||
PyExpression argument= arguments[0];
|
||||
PyElement[] elements = {};
|
||||
if (argument instanceof PySequenceExpression)
|
||||
elements = ((PySequenceExpression)argument).getElements();
|
||||
if (argument instanceof PyParenthesizedExpression) {
|
||||
PyExpression tuple = ((PyParenthesizedExpression)argument).getContainedExpression();
|
||||
if (tuple instanceof PyTupleExpression)
|
||||
elements = ((PyTupleExpression)(tuple)).getElements();
|
||||
}
|
||||
for (int i = 0; i != elements.length; ++i) {
|
||||
PyElement e = elements[i];
|
||||
str.append(e.getText());
|
||||
if (i != elements.length-1)
|
||||
str.append(", ");
|
||||
}
|
||||
}
|
||||
str.append("}");
|
||||
functionCall.replace(elementGenerator.createFromText(LanguageLevel.forElement(functionCall), PyExpressionStatement.class,
|
||||
str.toString()).getExpression());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.actions.ReplaceFunctionWithSetLiteralQuickFix;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: catherine
|
||||
*
|
||||
* Inspection to find set built-in function and replace it with set literal
|
||||
* available if the selected language level supports set literals.
|
||||
*/
|
||||
public class PySetFunctionToLiteralInspection extends PyInspection {
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return PyBundle.message("INSP.NAME.set.function.to.literal");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new Visitor(holder);
|
||||
}
|
||||
|
||||
private static class Visitor extends PyInspectionVisitor {
|
||||
public Visitor(final ProblemsHolder holder) {
|
||||
super(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyCallExpression(final PyCallExpression node) {
|
||||
if (LanguageLevel.forElement(node).supportsSetLiterals()) {
|
||||
PyExpression callee = node.getCallee();
|
||||
if (callee != null) {
|
||||
if (isBuiltinSet(callee)) {
|
||||
PyExpression[] arguments = node.getArguments();
|
||||
if (arguments.length == 0 ||(arguments.length == 1) &&
|
||||
(arguments[0] instanceof PySequenceExpression ||
|
||||
(arguments[0] instanceof PyParenthesizedExpression &&
|
||||
((PyParenthesizedExpression)arguments[0]).getContainedExpression() instanceof PyTupleExpression)))
|
||||
registerProblem(node, "Function call can be replaced with set literal",
|
||||
new ReplaceFunctionWithSetLiteralQuickFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isBuiltinSet(PyExpression callee) {
|
||||
ProjectFileIndex ind = ProjectRootManager.getInstance(callee.getProject()).getFileIndex();
|
||||
PsiReference reference = callee.getReference();
|
||||
if (reference != null) {
|
||||
PsiElement resolved = reference.resolve();
|
||||
if (resolved != null) {
|
||||
PsiFile file = resolved.getContainingFile();
|
||||
if (file != null && file.getVirtualFile() != null && ind.isInLibraryClasses(file.getVirtualFile())) {
|
||||
if (callee.getText().equals("set")) {
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ public class PythonInspectionToolProvider implements InspectionToolProvider {
|
||||
PySingleQuotedDocstringInspection.class,
|
||||
PyMissingConstructorInspection.class,
|
||||
PyArgumentEqualDefaultInspection.class,
|
||||
PySetFunctionToLiteralInspection.class,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
my_set = <warning descr="Function call can be replaced with set literal">set()</warning>
|
||||
my_set = <warning descr="Function call can be replaced with set literal">set([1,2,3])</warning>
|
||||
my_set = <warning descr="Function call can be replaced with set literal">set((1,2,3))</warning>
|
||||
|
||||
my_set = set(var)
|
||||
|
||||
def set(fake=None):
|
||||
pass
|
||||
|
||||
my_fake_set = set()
|
||||
my_fake_set = set([1,2,3])
|
||||
@@ -0,0 +1 @@
|
||||
my_set = <warning descr="Function call can be replaced with set literal">set([1<caret>,2,3])</warning>
|
||||
@@ -0,0 +1 @@
|
||||
my_set = {1, 2, 3}
|
||||
@@ -240,6 +240,12 @@ public class PyQuickFixTest extends PyLightFixtureTestCase {
|
||||
PyBundle.message("QFIX.remove.argument.equal.default"), true, true);
|
||||
}
|
||||
|
||||
public void testSetFunctionToLiteral() { //PY-3120
|
||||
setLanguageLevel(LanguageLevel.PYTHON27);
|
||||
doInspectionTest("SetFunctionToLiteral.py", PySetFunctionToLiteralInspection.class,
|
||||
PyBundle.message("QFIX.replace.function.set.with.literal"), true, true);
|
||||
}
|
||||
|
||||
public void testUnnecessaryBackslash() {
|
||||
String[] testFiles = new String[]{"UnnecessaryBackslash.py"};
|
||||
myFixture.enableInspections(PyUnnecessaryBackslashInspection.class);
|
||||
|
||||
@@ -326,4 +326,9 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
|
||||
public void testPyArgumentEqualDefaultInspection() { //PY-3125
|
||||
doHighlightingTest(PyArgumentEqualDefaultInspection.class);
|
||||
}
|
||||
|
||||
public void testPySetFunctionToLiteralInspection() { //PY-3120
|
||||
setLanguageLevel(LanguageLevel.PYTHON27);
|
||||
doHighlightingTest(PySetFunctionToLiteralInspection.class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user