diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index d194a8645d36..886d1eaf255b 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -181,6 +181,9 @@ INSP.NAME.default.argument=Default argument is mutable # PyRaisingNewStyleClassInspection INSP.NAME.raising.new.style.class=Raising a new style class +# PyDocstringInspection +INSP.NAME.docstring=Missing or empty docstring + # Refactoring # introduce refactoring.introduce.name.error=Incorrect name diff --git a/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java b/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java new file mode 100644 index 000000000000..5b3a7632ee6f --- /dev/null +++ b/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java @@ -0,0 +1,74 @@ +package com.jetbrains.python.inspections; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.PsiElementVisitor; +import com.jetbrains.python.PyBundle; +import com.jetbrains.python.psi.*; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +/** + * Created by IntelliJ IDEA. + * Author: Alexey.Ivanov + * Date: 10.03.2010 + * Time: 16:14:45 + */ +public class PyDocstringInspection 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.docstring"); + } + + @NotNull + @Override + public String getShortName() { + return "PyDocstringInspection"; + } + + @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 visitPyFile(PyFile node) { + checkDocString(node); + } + + @Override + public void visitPyFunction(PyFunction node) { + checkDocString(node); + } + + @Override + public void visitPyClass(PyClass node) { + checkDocString(node); + } + + private void checkDocString(PyDocStringOwner node) { + PyStringLiteralExpression docStringExpression = node.getDocStringExpression(); + if (docStringExpression == null) { + registerProblem(node, "Missing docstring"); // node? + } else if ("".equals(docStringExpression.getStringValue().trim())) { + registerProblem(docStringExpression, "Empty docstring"); + } + } + } +} diff --git a/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java b/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java index 2ebdd7ebd11d..0a5b87f0a7bc 100644 --- a/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java +++ b/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java @@ -30,6 +30,7 @@ public class PythonInspectionToolProvider implements InspectionToolProvider { PyDefaultArgumentInspection.class, PyRaisingNewStyleClassInspection.class, PyUnboundLocalVariableInspection.class, + PyDocstringInspection.class }; } } diff --git a/python/testData/inspections/PyDocstringInspection/expected.xml b/python/testData/inspections/PyDocstringInspection/expected.xml new file mode 100644 index 000000000000..7b6e3c7d5079 --- /dev/null +++ b/python/testData/inspections/PyDocstringInspection/expected.xml @@ -0,0 +1,28 @@ + + + + test.py + 1 + Missing docstring + + + test.py + 1 + Missing docstring + + + test.py + 4 + Missing docstring + + + test.py + 9 + Empty docstring + + + test.py + 13 + Empty docstring + + \ No newline at end of file diff --git a/python/testData/inspections/PyDocstringInspection/src/test.py b/python/testData/inspections/PyDocstringInspection/src/test.py new file mode 100644 index 000000000000..42a2cdf8cdf8 --- /dev/null +++ b/python/testData/inspections/PyDocstringInspection/src/test.py @@ -0,0 +1,14 @@ +class A: + pass + +def foo(): + pass + + +class B: + """""" + pass + +def bar(): + """""" + pass \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java index 850b97a291b7..645180771006 100644 --- a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java +++ b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java @@ -137,4 +137,9 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase { LocalInspectionTool inspection = new PyUnboundLocalVariableInspection(); doTest(getTestName(false), inspection); } + + public void testPyDocstringInspection() throws Throwable { + LocalInspectionTool inspection = new PyDocstringInspection(); + doTest(getTestName(false), inspection); + } }