added PyUnsupportedFeaturesInspection (PY-501)

This commit is contained in:
Alexey Ivanov
2010-02-12 21:42:04 +03:00
committed by alexey.ivanov
parent 2e3a359292
commit d1cc234bcd
39 changed files with 743 additions and 14 deletions
@@ -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);
}
}