mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
added PyUnsupportedFeaturesInspection (PY-501)
This commit is contained in:
committed by
alexey.ivanov
parent
2e3a359292
commit
d1cc234bcd
@@ -32,6 +32,24 @@ QFIX.action.failed=Action failed
|
||||
|
||||
QFIX.remove.trailing.semicolon=Remove trailing semicolon
|
||||
|
||||
QFIX.replace.noteq.operator=Replace not equal operator
|
||||
|
||||
QFIX.replace.backquote.expression=Replace backquote expression
|
||||
|
||||
QFIX.replace.method=Replace method which not supported in current Python version
|
||||
|
||||
QFIX.remove.leading.u=Remove leading U
|
||||
|
||||
QFIX.remove.trailing.l=Remove trailing L
|
||||
|
||||
QFIX.replace.raise.statement=Convert raise statement to supported form
|
||||
|
||||
QFIX.replace.except.part=Convert except clause to supported form
|
||||
|
||||
QFIX.replace.list.comprehensions=Convert list comprehensions to supported form
|
||||
|
||||
QFIX.replace.octal.numeric.literal=Convert octal numeric literal to supported form
|
||||
|
||||
# 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'
|
||||
@@ -114,6 +132,11 @@ INSP.NAME.unused=Unused local variable
|
||||
INSP.unused.locals.parameter.isnot.used=Parameter ''{0}'' value is not used
|
||||
INSP.unused.locals.local.variable.isnot.used=Local variable ''{0}'' value is not used
|
||||
|
||||
# PyUnsupportedFeaturesInspection
|
||||
INSP.NAME.unsupported.features=Feature not supported by current Python version
|
||||
INSP.method.$0.removed.use.$1=Method ''{0}'' removed, use ''{1}'' instead
|
||||
INSP.method.$0.removed=Method ''{0}'' removed
|
||||
|
||||
# Refactoring
|
||||
# introduce
|
||||
refactoring.introduce.name.error=Incorrect name
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 10.02.2010
|
||||
* Time: 17:45:58
|
||||
*/
|
||||
public class ReamoveLeadingUQuickFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.remove.leading.u");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyStringLiteralExpression stringLiteralExpression = (PyStringLiteralExpression) descriptor.getPsiElement();
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
stringLiteralExpression.replace(elementGenerator.createExpressionFromText(project, stringLiteralExpression.getText().substring(1)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyNumericLiteralExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 10.02.2010
|
||||
* Time: 17:45:58
|
||||
*/
|
||||
public class ReamoveTrailingLQuickFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.remove.trailing.l");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyNumericLiteralExpression numericLiteralExpression = (PyNumericLiteralExpression) descriptor.getPsiElement();
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
String text = numericLiteralExpression.getText();
|
||||
numericLiteralExpression.replace(elementGenerator.createExpressionFromText(project, text.substring(0, text.length() - 1)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyReprExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 08.02.2010
|
||||
* Time: 20:23:53
|
||||
*/
|
||||
public class ReplaceBackquoteExpressionQuickFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.replace.backquote.expression");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyReprExpression problemElement = (PyReprExpression) descriptor.getPsiElement();
|
||||
if (problemElement != null && problemElement.getExpression() != null) {
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
problemElement.replace(elementGenerator.createExpressionFromText(project, "repr(" + problemElement.getExpression().getText() + ")"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyExceptPart;
|
||||
import com.jetbrains.python.psi.PyTryExceptStatement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 10.02.2010
|
||||
* Time: 19:24:17
|
||||
*/
|
||||
public class ReplaceExceptPartQuickFix implements LocalQuickFix {
|
||||
private final boolean myPy3KFlag;
|
||||
|
||||
public ReplaceExceptPartQuickFix(boolean py3KFlag) {
|
||||
myPy3KFlag = py3KFlag;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.replace.except.part");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyExceptPart exceptPart = (PyExceptPart) descriptor.getPsiElement();
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
PsiElement element = exceptPart.getExceptClass().getNextSibling();
|
||||
while (element instanceof PsiWhiteSpace) {
|
||||
element = element.getNextSibling();
|
||||
}
|
||||
assert element != null;
|
||||
if (myPy3KFlag) {
|
||||
PyTryExceptStatement newElement = elementGenerator.createFromText(project, PyTryExceptStatement.class, "try: pass except a as b: pass");
|
||||
ASTNode node = newElement.getExceptParts()[0].getNode().findChildByType(PyTokenTypes.AS_KEYWORD);
|
||||
assert node != null;
|
||||
element.replace(node.getPsi());
|
||||
} else {
|
||||
element.replace(elementGenerator.createComma(project).getPsi());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyParenthesizedExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 12.02.2010
|
||||
* Time: 18:15:24
|
||||
*/
|
||||
public class ReplaceListComprehensionsQuickFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.replace.list.comprehensions");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyExpression expression = (PyExpression) descriptor.getPsiElement();
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
expression.replace(elementGenerator.createFromText(project, PyParenthesizedExpression.class, "(" + expression.getText() + ")"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 10.02.2010
|
||||
* Time: 15:46:03
|
||||
*/
|
||||
public class ReplaceMethodQuickFix implements LocalQuickFix {
|
||||
private final String myNewName;
|
||||
|
||||
public ReplaceMethodQuickFix(String newName) {
|
||||
myNewName = newName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.replace.method");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyExpression problemElement = (PyExpression) descriptor.getPsiElement();
|
||||
if (problemElement != null) {
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
problemElement.replace(elementGenerator.createCallExpression(project, myNewName).getCallee());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
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.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyBinaryExpression;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 08.02.2010
|
||||
* Time: 19:28:35
|
||||
*/
|
||||
public class ReplaceNotEqOperatorQuickFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.replace.noteq.operator");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiElement operator = ((PyBinaryExpression) descriptor.getPsiElement()).getPsiOperator();
|
||||
if (operator != null) {
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
operator.replace(elementGenerator.createFromText(project, LeafPsiElement.class, "!="));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyNumericLiteralExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 12.02.2010
|
||||
* Time: 18:41:44
|
||||
*/
|
||||
public class ReplaceOctalNumericLiteralQuickFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.replace.octal.numeric.literal");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyNumericLiteralExpression numericLiteralExpression = (PyNumericLiteralExpression) descriptor.getPsiElement();
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
String text = numericLiteralExpression.getText();
|
||||
numericLiteralExpression.replace(elementGenerator.createExpressionFromText(project, "0o" + text.substring(1)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.jetbrains.python.actions;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyRaiseStatement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 10.02.2010
|
||||
* Time: 19:24:17
|
||||
*/
|
||||
public class ReplaceRaiseStatementQuickFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.replace.raise.statement");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyRaiseStatement raiseStatement = (PyRaiseStatement) descriptor.getPsiElement();
|
||||
PyExpression[] expressions = raiseStatement.getExpressions();
|
||||
assert expressions != null;
|
||||
PyElementGenerator elementGenerator = PythonLanguage.getInstance().getElementGenerator();
|
||||
String newExpressionText = expressions[0].getText() + "(" + expressions[1].getText() + ")";
|
||||
if (expressions.length == 2) {
|
||||
raiseStatement.replace(elementGenerator.createFromText(project, PyRaiseStatement.class, "raise " + newExpressionText));
|
||||
} else if (expressions.length == 3) {
|
||||
raiseStatement.replace(elementGenerator.createFromText(project, PyRaiseStatement.class,
|
||||
"raise " + newExpressionText + ".with_traceback(" + expressions[2].getText() + ")"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.actions.*;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Alexey.Ivanov
|
||||
* Date: 08.02.2010
|
||||
* Time: 18:05:36
|
||||
*/
|
||||
public class PyUnsupportedFeaturesInspection extends LocalInspectionTool {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getGroupDisplayName() {
|
||||
return PyBundle.message("INSP.GROUP.python");
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return PyBundle.message("INSP.NAME.unsupported.features");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getShortName() {
|
||||
return "PyUnsupportedFeaturesInspection";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new Visitor(holder);
|
||||
}
|
||||
|
||||
static class Visitor extends PyInspectionVisitor {
|
||||
private static Set<String> REMOVED_METHODS = new HashSet<String>();
|
||||
|
||||
static {
|
||||
REMOVED_METHODS.add("cmp");
|
||||
REMOVED_METHODS.add("apply");
|
||||
REMOVED_METHODS.add("callable");
|
||||
REMOVED_METHODS.add("coerce");
|
||||
REMOVED_METHODS.add("execfile");
|
||||
REMOVED_METHODS.add("reduce");
|
||||
REMOVED_METHODS.add("reload");
|
||||
}
|
||||
|
||||
public Visitor(final ProblemsHolder holder) {
|
||||
super(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyBinaryExpression(PyBinaryExpression node) {
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null && LanguageLevel.forFile(virtualFile).isPy3K()) {
|
||||
if (node.isOperator("<>")) {
|
||||
registerProblem(node, "<> not supported in Python3, use != instead", new ReplaceNotEqOperatorQuickFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyNumericLiteralExpression(PyNumericLiteralExpression node) {
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null && LanguageLevel.forFile(virtualFile).isPy3K()) {
|
||||
String text = node.getText();
|
||||
if (text.endsWith("l") || text.endsWith("L")) {
|
||||
registerProblem(node, "Integer literals no support trailing \'l\' or \'L\' in Python3", new ReamoveTrailingLQuickFix());
|
||||
}
|
||||
if (text.charAt(0) == '0' && (text.charAt(1) != 'o' || text.charAt(1) != 'b')) {
|
||||
registerProblem(node, "Python3 not supported such syntax", new ReplaceOctalNumericLiteralQuickFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyStringLiteralExpression(PyStringLiteralExpression node) {
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null && LanguageLevel.forFile(virtualFile).isPy3K()) {
|
||||
String text = node.getText();
|
||||
if (text.startsWith("u") || text.startsWith("U")) {
|
||||
registerProblem(node, "String literals no support a leading \'u\' or \'U\' in Python3", new ReamoveLeadingUQuickFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyListCompExpression(PyListCompExpression node) {
|
||||
List<ComprhForComponent> forComponents = node.getForComponents();
|
||||
for (ComprhForComponent forComponent: forComponents) {
|
||||
PyExpression iteratedList = forComponent.getIteratedList();
|
||||
if (iteratedList instanceof PyTupleExpression) {
|
||||
registerProblem(iteratedList, "List comprehensions no support such syntax in Python3", new ReplaceListComprehensionsQuickFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyExceptBlock(PyExceptPart node) {
|
||||
PyExpression exceptClass = node.getExceptClass();
|
||||
if (exceptClass != null && node.getTarget() != null) {
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
if (LanguageLevel.forFile(virtualFile).isPy3K()) {
|
||||
PsiElement element = exceptClass.getNextSibling();
|
||||
while (element instanceof PsiWhiteSpace) {
|
||||
element = element.getNextSibling();
|
||||
}
|
||||
if (element != null && ",".equals(element.getText())) {
|
||||
registerProblem(node, "Python3 not supported such syntax", new ReplaceExceptPartQuickFix(true));
|
||||
}
|
||||
} else {
|
||||
PsiElement element = exceptClass.getNextSibling();
|
||||
while (element instanceof PsiWhiteSpace) {
|
||||
element = element.getNextSibling();
|
||||
}
|
||||
if (element != null && "as".equals(element.getText())) {
|
||||
registerProblem(node, "Python2 not supported such syntax", new ReplaceExceptPartQuickFix(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyRaiseStatement(PyRaiseStatement node) {
|
||||
PyExpression[] expressions = node.getExpressions();
|
||||
assert(expressions != null);
|
||||
if (expressions.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
if (LanguageLevel.forFile(virtualFile).isPy3K()) {
|
||||
if (expressions.length == 3) {
|
||||
registerProblem(node, "Python3 not supported such syntax", new ReplaceRaiseStatementQuickFix());
|
||||
return;
|
||||
}
|
||||
PsiElement element = expressions[0].getNextSibling();
|
||||
while (element instanceof PsiWhiteSpace) {
|
||||
element = element.getNextSibling();
|
||||
}
|
||||
if (element != null && ",".equals(element.getText())) {
|
||||
registerProblem(node, "Python3 not supported such syntax", new ReplaceRaiseStatementQuickFix());
|
||||
}
|
||||
} else {
|
||||
if (expressions.length == 2) {
|
||||
PsiElement element = expressions[0].getNextSibling();
|
||||
while (element instanceof PsiWhiteSpace) {
|
||||
element = element.getNextSibling();
|
||||
}
|
||||
if (element != null && "from".equals(element.getText())) {
|
||||
registerProblem(node, "Python2 not supported such syntax");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyReprExpression(PyReprExpression node) {
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null && LanguageLevel.forFile(virtualFile).isPy3K()) {
|
||||
registerProblem(node, "Backquote not supported in Python3, use repr() instead", new ReplaceBackquoteExpressionQuickFix());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyCallExpression(PyCallExpression node) {
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
String name = node.getCallee().getName();
|
||||
if (LanguageLevel.forFile(virtualFile).isPy3K()) {
|
||||
if ("raw_input".equals(name)) {
|
||||
registerProblem(node.getCallee(), PyBundle.message("INSP.method.$0.removed.use.$1", name, "input"),
|
||||
new ReplaceMethodQuickFix("input"));
|
||||
} else if (REMOVED_METHODS.contains(name)) {
|
||||
registerProblem(node.getCallee(), PyBundle.message("INSP.method.$0.removed", name));
|
||||
}
|
||||
} else {
|
||||
if ("super".equals(name)) {
|
||||
PyArgumentList argumentList = node.getArgumentList();
|
||||
if (argumentList != null && argumentList.getArguments().length == 0) {
|
||||
registerProblem(node, "super() should have arguments in current language version");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,8 @@ public class PythonInspectionToolProvider implements InspectionToolProvider {
|
||||
PyMethodOverridingInspection.class,
|
||||
PyTrailingSemicolonInspection.class,
|
||||
PyReturnFromInitInspection.class,
|
||||
PyUnusedLocalVariableInspection.class
|
||||
PyUnusedLocalVariableInspection.class,
|
||||
PyUnsupportedFeaturesInspection.class
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,4 +213,8 @@ public class PyElementVisitor extends PsiElementVisitor {
|
||||
public void visitPyImportStatement(PyImportStatement node) {
|
||||
visitPyStatement(node);
|
||||
}
|
||||
|
||||
public void visitPyReprExpression(PyReprExpression node) {
|
||||
visitPyExpression(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: yole
|
||||
@@ -24,4 +26,6 @@ package com.jetbrains.python.psi;
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public interface PyRaiseStatement extends PyStatement {
|
||||
@Nullable
|
||||
PyExpression[] getExpressions();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: yole
|
||||
@@ -24,4 +26,6 @@ package com.jetbrains.python.psi;
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public interface PyReprExpression extends PyExpression {
|
||||
@Nullable
|
||||
PyExpression getExpression();
|
||||
}
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.jetbrains.python.psi.PyRaiseStatement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.psi.PyElementVisitor;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyRaiseStatement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Describes 'raise' statement.
|
||||
@@ -32,4 +35,9 @@ public class PyRaiseStatementImpl extends PyElementImpl implements PyRaiseStatem
|
||||
protected void acceptPyVisitor(PyElementVisitor pyVisitor) {
|
||||
pyVisitor.visitPyRaiseStatement(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PyExpression[] getExpressions() {
|
||||
return PsiTreeUtil.getChildrenOfType(this, PyExpression.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,12 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.psi.PyElementVisitor;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyReprExpression;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -28,9 +32,19 @@ import com.jetbrains.python.psi.types.PyType;
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class PyReprExpressionImpl extends PyElementImpl implements PyReprExpression {
|
||||
public PyReprExpressionImpl(ASTNode astNode) {
|
||||
super(astNode);
|
||||
}
|
||||
public PyReprExpressionImpl(ASTNode astNode) {
|
||||
super(astNode);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PyExpression getExpression() {
|
||||
return PsiTreeUtil.getChildOfType(this, PyExpression.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void acceptPyVisitor(PyElementVisitor pyVisitor) {
|
||||
pyVisitor.visitPyReprExpression(this);
|
||||
}
|
||||
|
||||
public PyType getType() {
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
a = <caret><warning descr="String literals no support a leading 'u' or 'U' in Python3">u"text"</warning>
|
||||
@@ -0,0 +1 @@
|
||||
a = "text"
|
||||
@@ -0,0 +1 @@
|
||||
a = <caret><warning descr="Integer literals no support trailing 'l' or 'L' in Python3">1223l</warning>
|
||||
@@ -0,0 +1 @@
|
||||
a = 1223
|
||||
@@ -0,0 +1 @@
|
||||
<caret><warning descr="Backquote not supported in Python3, use repr() instead">`a + b, 34 + a`</warning>
|
||||
@@ -0,0 +1 @@
|
||||
repr(a + b, 34 + a)
|
||||
@@ -0,0 +1,4 @@
|
||||
try:
|
||||
pass
|
||||
<caret><warning descr="Python2 not supported such syntax">except a as name:
|
||||
pass</warning>
|
||||
@@ -0,0 +1,4 @@
|
||||
try:
|
||||
pass
|
||||
except a , name:
|
||||
pass
|
||||
@@ -0,0 +1,4 @@
|
||||
try:
|
||||
pass
|
||||
<caret><warning descr="Python3 not supported such syntax">except a, name:
|
||||
pass</warning>
|
||||
@@ -0,0 +1,4 @@
|
||||
try:
|
||||
pass
|
||||
except a as name:
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
[x * 2 for x in <caret><warning descr="List comprehensions no support such syntax in Python3">[1, 2], [2, 3]</warning>]
|
||||
@@ -0,0 +1 @@
|
||||
[x * 2 for x in ([1, 2], [2, 3])]
|
||||
@@ -0,0 +1 @@
|
||||
a = <caret><warning descr="Method 'raw_input' removed, use 'input' instead">raw_input</warning>()
|
||||
@@ -0,0 +1 @@
|
||||
a = input()
|
||||
@@ -0,0 +1 @@
|
||||
print(<caret><warning descr="<> not supported in Python3, use != instead">a <> b</warning>)
|
||||
@@ -0,0 +1 @@
|
||||
print(a != b)
|
||||
@@ -0,0 +1 @@
|
||||
a = <caret><warning descr="Python3 not supported such syntax">01223</warning>
|
||||
@@ -0,0 +1 @@
|
||||
a = 0o1223
|
||||
@@ -0,0 +1 @@
|
||||
<caret><warning descr="Python3 not supported such syntax">raise a, b, c</warning>
|
||||
@@ -0,0 +1 @@
|
||||
raise a(b).with_traceback(c)
|
||||
@@ -12,6 +12,9 @@ import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
|
||||
import com.jetbrains.python.inspections.PyMethodParametersInspection;
|
||||
import com.jetbrains.python.inspections.PyTrailingSemicolonInspection;
|
||||
import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.PyUnsupportedFeaturesInspection;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
@@ -88,6 +91,69 @@ public class PyQuickFixTest extends PyLightFixtureTestCase {
|
||||
true, true);
|
||||
}
|
||||
|
||||
public void testReplaceExceptPartTo2() throws Exception {
|
||||
doInspectionTest("ReplaceExceptPartTo2.py", PyUnsupportedFeaturesInspection.class, PyBundle.message("QFIX.replace.except.part"), true,
|
||||
true);
|
||||
}
|
||||
|
||||
public void testReplaceNotEqOperator() throws Exception {
|
||||
doInspectionTestWithPy3k("ReplaceNotEqOperator.py", PyUnsupportedFeaturesInspection.class,
|
||||
PyBundle.message("QFIX.replace.noteq.operator"), true, true);
|
||||
}
|
||||
|
||||
public void testReplaceBackquoteExpression() throws Exception {
|
||||
doInspectionTestWithPy3k("ReplaceBackquoteExpression.py", PyUnsupportedFeaturesInspection.class,
|
||||
PyBundle.message("QFIX.replace.backquote.expression"), true, true);
|
||||
}
|
||||
|
||||
public void testReplaceMethod() throws Exception {
|
||||
doInspectionTestWithPy3k("ReplaceMethod.py", PyUnsupportedFeaturesInspection.class, PyBundle.message("QFIX.replace.method"),
|
||||
true, true);
|
||||
}
|
||||
|
||||
public void testRemoveLeadingU() throws Exception {
|
||||
doInspectionTestWithPy3k("RemoveLeadingU.py", PyUnsupportedFeaturesInspection.class, PyBundle.message("QFIX.remove.leading.u"), true, true);
|
||||
}
|
||||
|
||||
public void testTrailingL() throws Exception {
|
||||
doInspectionTestWithPy3k("RemoveTrailingL.py", PyUnsupportedFeaturesInspection.class, PyBundle.message("QFIX.remove.trailing.l"), true, true);
|
||||
}
|
||||
|
||||
public void testReplaceOctalNumericLiteral() throws Exception {
|
||||
doInspectionTestWithPy3k("ReplaceOctalNumericLiteral.py", PyUnsupportedFeaturesInspection.class,
|
||||
PyBundle.message("QFIX.replace.octal.numeric.literal"), true, true);
|
||||
}
|
||||
|
||||
public void testReplaceRaiseStatement() throws Exception {
|
||||
doInspectionTestWithPy3k("ReplaceRaiseStatement.py", PyUnsupportedFeaturesInspection.class,
|
||||
PyBundle.message("QFIX.replace.raise.statement"), true, true);
|
||||
}
|
||||
|
||||
public void testReplaceExceptPartTo3() throws Exception {
|
||||
doInspectionTestWithPy3k("ReplaceExceptPartTo3.py", PyUnsupportedFeaturesInspection.class, PyBundle.message("QFIX.replace.except.part"),
|
||||
true, true);
|
||||
}
|
||||
|
||||
public void testReplaceListComprehensions() throws Exception {
|
||||
doInspectionTestWithPy3k("ReplaceListComprehensions.py", PyUnsupportedFeaturesInspection.class,
|
||||
PyBundle.message("QFIX.replace.list.comprehensions"), true, true);
|
||||
}
|
||||
|
||||
protected void doInspectionTestWithPy3k(@NonNls String testFileName,
|
||||
final Class inspectionClass,
|
||||
@NonNls String quickFixName,
|
||||
boolean applyFix,
|
||||
boolean available) throws Exception {
|
||||
PythonLanguageLevelPusher.FORCE_LANGUAGE_LEVEL = LanguageLevel.PYTHON30;
|
||||
PythonLanguageLevelPusher.pushLanguageLevel(myFixture.getProject());
|
||||
try {
|
||||
doInspectionTest(testFileName, inspectionClass, quickFixName, applyFix, available);
|
||||
}
|
||||
finally {
|
||||
PythonLanguageLevelPusher.FORCE_LANGUAGE_LEVEL = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected
|
||||
@NonNls
|
||||
String getTestDataPath() {
|
||||
|
||||
@@ -19,6 +19,17 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
|
||||
private void doTest(String testName, LocalInspectionTool localInspectionTool) throws Throwable {
|
||||
myFixture.testInspection("inspections/" + testName, new LocalInspectionToolWrapper(localInspectionTool));
|
||||
}
|
||||
|
||||
private void doTestWithPy3k(String testName, LocalInspectionTool localInspectionTool) throws Throwable {
|
||||
PythonLanguageLevelPusher.FORCE_LANGUAGE_LEVEL = LanguageLevel.PYTHON30;
|
||||
PythonLanguageLevelPusher.pushLanguageLevel(myFixture.getProject());
|
||||
try {
|
||||
doTest(testName, localInspectionTool);
|
||||
}
|
||||
finally {
|
||||
PythonLanguageLevelPusher.FORCE_LANGUAGE_LEVEL = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void testPyMethodFirstArgAssignmentInspection() throws Throwable {
|
||||
LocalInspectionTool inspection = new PyMethodFirstArgAssignmentInspection();
|
||||
@@ -41,15 +52,8 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
|
||||
}
|
||||
|
||||
public void testPyArgumentListInspection3K() throws Throwable {
|
||||
PythonLanguageLevelPusher.FORCE_LANGUAGE_LEVEL = LanguageLevel.PYTHON30;
|
||||
PythonLanguageLevelPusher.pushLanguageLevel(myFixture.getProject());
|
||||
try {
|
||||
LocalInspectionTool inspection = new PyArgumentListInspection();
|
||||
doTest(getTestName(false), inspection);
|
||||
}
|
||||
finally {
|
||||
PythonLanguageLevelPusher.FORCE_LANGUAGE_LEVEL = null;
|
||||
}
|
||||
LocalInspectionTool inspection = new PyArgumentListInspection();
|
||||
doTestWithPy3k(getTestName(false), inspection);
|
||||
}
|
||||
|
||||
public void testPyRedeclarationInspection() throws Throwable {
|
||||
@@ -76,4 +80,9 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
|
||||
LocalInspectionTool inspection = new PyUnusedLocalVariableInspection();
|
||||
doTest(getTestName(false), inspection);
|
||||
}
|
||||
|
||||
public void testPyUnsupportedFeaturesInspection() throws Throwable {
|
||||
LocalInspectionTool inspection = new PyUnsupportedFeaturesInspection();
|
||||
doTestWithPy3k(getTestName(false), inspection);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user