From 0c094c0a67bc36bcfb40cc61efc215238a89e4ab Mon Sep 17 00:00:00 2001 From: "alexey.ivanov" Date: Fri, 19 Feb 2010 20:30:12 +0300 Subject: [PATCH] PyDeprecatedModulesInspection (PY-580) --- .../com/jetbrains/python/PyBundle.properties | 13 +++ .../PyDeprecatedModulesInspection.java | 110 ++++++++++++++++++ .../PythonInspectionToolProvider.java | 3 +- .../python/PythonInspectionsTest.java | 14 ++- 4 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 python/src/com/jetbrains/python/inspections/PyDeprecatedModulesInspection.java diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index bc9d112939e4..87aa317dd111 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -54,6 +54,9 @@ QFIX.replace.octal.numeric.literal=Convert octal numeric literal to supported fo INTN.Family.convert.import.unqualify=Convert 'import module' to 'from module import' INTN.Family.convert.import.qualify=Convert 'from module import' to 'import module' INTN.Family.toggle.import.alias=Toggle import alias +INTN.Family.convert.except.part=Convert except part to supported form +INTN.Family.convert.set.literal=Convert set literal two supported forms +INTN.Family.convert.builtin=Convert builtin module import INTN.convert.to.from.$0.import.$1=Convert to ''from {0} import {1}'' INTN.convert.to.import.$0=Convert to ''import {0}'' @@ -62,6 +65,12 @@ INTN.alias.for.$0.dialog.title=Alias for ''{0}''? INTN.add.alias.for.import.$0=Add alias to ''{0}'' INTN.remove.alias.for.import.$0=Remove alias ''{0}'' +INTN.convert.except.to=Convert 'except exceptClass as Target' to 'except exceptClass, Target' + +INTN.convert.set.literal.to=Convert set literal to 'set' method call + +INTN.convert.builtin.import=Convert builtin module import to supported form + # Conflict checker CONFLICT.name.$0.obscured=Name ''{0}'' obscured by local definitions CONFLICT.name.$0.obscured.cannot.convert=Name ''{0}'' obscured. Cannot convert. @@ -137,6 +146,10 @@ INSP.NAME.unsupported.features=Feature is not supported by Python 3 INSP.method.$0.removed.use.$1=Method ''{0}'' has been removed, use ''{1}'' instead INSP.method.$0.removed=Method ''{0}'' removed +# PyDeprecatedModulesInspection +INSP.NAME.deprecated.modules=Module marked as deprecated +INSP.module.$0.is.deprecated.in.version=Module ''{0}'' is deprecated in current Python version + # Refactoring # introduce refactoring.introduce.name.error=Incorrect name diff --git a/python/src/com/jetbrains/python/inspections/PyDeprecatedModulesInspection.java b/python/src/com/jetbrains/python/inspections/PyDeprecatedModulesInspection.java new file mode 100644 index 000000000000..0c0da86a992d --- /dev/null +++ b/python/src/com/jetbrains/python/inspections/PyDeprecatedModulesInspection.java @@ -0,0 +1,110 @@ +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.PsiElementVisitor; +import com.intellij.util.containers.HashSet; +import com.jetbrains.python.PyBundle; +import com.jetbrains.python.psi.*; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Created by IntelliJ IDEA. + * User: Alexey.Ivanov + * Date: 19.02.2010 + * Time: 14:54:45 + */ +public class PyDeprecatedModulesInspection 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.deprecated.modules"); + } + + @NotNull + @Override + public String getShortName() { + return "PyDeprecatedModulesInspection"; + } + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new Visitor(holder); + } + + private static class Visitor extends PyInspectionVisitor { + private static final Map> DEPRECATED_MODULES = new HashMap>(); + + static { + Set deprecated24 = new HashSet(); + deprecated24.add("whrandom"); + deprecated24.add("rfc822"); + deprecated24.add("mimetools"); + deprecated24.add("MimeWriter"); + deprecated24.add("mimify"); + deprecated24.add("statcashe"); + deprecated24.add("buildtools"); + deprecated24.add("cfmfile"); + deprecated24.add("macfs"); + DEPRECATED_MODULES.put(LanguageLevel.PYTHON24, deprecated24); + + Set deprecated25 = new HashSet(); + deprecated25.addAll(deprecated24); + deprecated25.remove("whrandom"); + deprecated25.remove("statcashe"); + deprecated25.add("gopherlib"); + deprecated25.add("rgbimg"); + deprecated25.add("multifile"); + deprecated25.add("md5"); + deprecated25.add("sha"); + DEPRECATED_MODULES.put(LanguageLevel.PYTHON25, deprecated25); + + Set deprecated26 = new HashSet(); + deprecated26.addAll(deprecated25); + deprecated26.remove("macfs"); + deprecated26.remove("gopherlib"); + deprecated26.remove("rgbimg"); + deprecated26.add("sets"); + DEPRECATED_MODULES.put(LanguageLevel.PYTHON26, deprecated26); + } + + private static LanguageLevel getLanguageLevel(PyElement node) { + VirtualFile virtualFile = node.getContainingFile().getVirtualFile(); + return (virtualFile != null) ? LanguageLevel.forFile(virtualFile) : LanguageLevel.getDefault(); + } + + public Visitor(final ProblemsHolder holder) { + super(holder); + } + + @Override + public void visitPyImportStatement(PyImportStatement node) { + PyImportElement[] importElements = node.getImportElements(); + for (PyImportElement importElement: importElements) { + PyReferenceExpression importReference = importElement.getImportReference(); + if (importReference != null) { + String name = importReference.getName(); + Set deprecated = DEPRECATED_MODULES.get(getLanguageLevel(node)); + if (deprecated != null && deprecated.contains(name)) { + registerProblem(node, PyBundle.message("INSP.module.$0.is.deprecated.in.version", name)); + } + } + } + } + } +} diff --git a/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java b/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java index 359a75bced96..0c1fa936381f 100644 --- a/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java +++ b/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java @@ -21,7 +21,8 @@ public class PythonInspectionToolProvider implements InspectionToolProvider { PyTrailingSemicolonInspection.class, PyReturnFromInitInspection.class, PyUnusedLocalVariableInspection.class, - PyUnsupportedFeaturesInspection.class + PyUnsupportedFeaturesInspection.class, + PyDeprecatedModulesInspection.class }; } } diff --git a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java index 2bda35178d80..60fec00b6850 100644 --- a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java +++ b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java @@ -19,7 +19,7 @@ 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()); @@ -85,4 +85,16 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase { LocalInspectionTool inspection = new PyUnsupportedFeaturesInspection(); doTestWithPy3k(getTestName(false), inspection); } + + public void testPyDeprecatedModulesInspection() throws Throwable { + PythonLanguageLevelPusher.FORCE_LANGUAGE_LEVEL = LanguageLevel.PYTHON25; + PythonLanguageLevelPusher.pushLanguageLevel(myFixture.getProject()); + try { + LocalInspectionTool inspection = new PyDeprecatedModulesInspection(); + doTest(getTestName(false), inspection); + } + finally { + PythonLanguageLevelPusher.FORCE_LANGUAGE_LEVEL = null; + } + } }