From b1a0879478a70994cf3dff4aa0a63a02f25b0490 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 14 Oct 2015 21:25:08 +0300 Subject: [PATCH] Docstring inspections correctly trim quotes and string prefixes before parsing docstring I also updated javadoc of related methods in DocStringUtil to point out the difference. --- .../docstrings/DocStringUtil.java | 43 ++++++++++++++----- .../PyDocstringTypesInspection.java | 7 +-- .../PyIncorrectDocstringInspection.java | 8 +--- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/python/src/com/jetbrains/python/documentation/docstrings/DocStringUtil.java b/python/src/com/jetbrains/python/documentation/docstrings/DocStringUtil.java index bc4ef7068b8f..ca0e57a6ac13 100644 --- a/python/src/com/jetbrains/python/documentation/docstrings/DocStringUtil.java +++ b/python/src/com/jetbrains/python/documentation/docstrings/DocStringUtil.java @@ -55,8 +55,9 @@ public class DocStringUtil { * Attempts to detect docstring format from given text and parses it into corresponding structured docstring. * It's recommended to use more reliable {@link #parse(String, PsiElement)} that fallbacks to format specified in settings. * + * @param text docstring text with both quotes and string prefix stripped * @return structured docstring for one of supported formats or instance of {@link PlainDocString} if none was recognized. - * @see #parse(String, PsiElement) + * @see #parse(String, PsiElement) */ @NotNull public static StructuredDocString parse(@NotNull String text) { @@ -66,6 +67,8 @@ public class DocStringUtil { /** * Attempts to detects docstring format first from given text, next from settings and parses text into corresponding structured docstring. * + * @param text docstring text with both quotes and string prefix stripped + * @param anchor PSI element that will be used to retrieve docstring format from the containing file or the project module * @return structured docstring for one of supported formats or instance of {@link PlainDocString} if none was recognized. * @see DocStringFormat#ALL_NAMES_BUT_PLAIN * @see #guessDocStringFormat(String, PsiElement) @@ -75,11 +78,22 @@ public class DocStringUtil { final DocStringFormat format = guessDocStringFormat(text, anchor); return parseDocStringContent(format, text); } - + + /** + * Attempts to detects docstring format first from the text of given string node, next from settings using given expression as an anchor + * and parses text into corresponding structured docstring. + * + * @param stringLiteral supposedly result of {@link PyDocStringOwner#getDocStringExpression()} + * @return structured docstring for one of supported formats or instance of {@link PlainDocString} if none was recognized. + */ + @NotNull + public static StructuredDocString parseDocString(@NotNull PyStringLiteralExpression stringLiteral) { + return parseDocString(guessDocStringFormat(stringLiteral.getStringValue(), stringLiteral), stringLiteral); + } + @NotNull - public static StructuredDocString parseDocString(@NotNull DocStringFormat format, - @NotNull PyStringLiteralExpression literalExpression) { - return parseDocString(format, literalExpression.getStringNodes().get(0)); + public static StructuredDocString parseDocString(@NotNull DocStringFormat format, @NotNull PyStringLiteralExpression stringLiteral) { + return parseDocString(format, stringLiteral.getStringNodes().get(0)); } @NotNull @@ -88,12 +102,18 @@ public class DocStringUtil { return parseDocString(format, node.getText()); } - + /** + * @param stringText docstring text with possible string prefix and quotes + */ @NotNull public static StructuredDocString parseDocString(@NotNull DocStringFormat format, @NotNull String stringText) { - return parseDocString(format, stripSuffixAndQuotes(stringText)); + return parseDocString(format, stripPrefixAndQuotes(stringText)); } + /** + * @param stringContent docstring text without string prefix and quotes, but not escaped, otherwise ranges of {@link Substring} returned + * from {@link StructuredDocString} may be invalid + */ @NotNull public static StructuredDocString parseDocStringContent(@NotNull DocStringFormat format, @NotNull String stringContent) { return parseDocString(format, new Substring(stringContent)); @@ -116,7 +136,7 @@ public class DocStringUtil { } @NotNull - private static Substring stripSuffixAndQuotes(@NotNull String text) { + private static Substring stripPrefixAndQuotes(@NotNull String text) { final TextRange contentRange = PyStringLiteralExpressionImpl.getNodeTextRange(text); return new Substring(text, contentRange.getStartOffset(), contentRange.getEndOffset()); } @@ -144,8 +164,10 @@ public class DocStringUtil { } /** - * @return docstring inferred heuristically and if unsuccessful fallback to configured format retrieved from anchor PSI element - * @see #getConfiguredDocStringFormat(PsiElement) + * @param text docstring text with both quotes and string prefix stripped + * @param anchor PSI element that will be used to retrieve docstring format from the containing file or the project module + * @return docstring inferred heuristically and if unsuccessful fallback to configured format retrieved from anchor PSI element + * @see #getConfiguredDocStringFormat(PsiElement) */ @NotNull public static DocStringFormat guessDocStringFormat(@NotNull String text, @Nullable PsiElement anchor) { @@ -154,6 +176,7 @@ public class DocStringUtil { } /** + * @param anchor PSI element that will be used to retrieve docstring format from the containing file or the project module * @return docstring format configured for file or module containing given anchor PSI element * @see PyDocumentationSettings#getFormatForFile(PsiFile) */ diff --git a/python/src/com/jetbrains/python/inspections/PyDocstringTypesInspection.java b/python/src/com/jetbrains/python/inspections/PyDocstringTypesInspection.java index fc500948f6ee..13fab23dce28 100644 --- a/python/src/com/jetbrains/python/inspections/PyDocstringTypesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyDocstringTypesInspection.java @@ -84,12 +84,7 @@ public class PyDocstringTypesInspection extends PyInspection { } private void checkParameters(PyFunction function, PyStringLiteralExpression node, PySignature signature) { - final String text = node.getText(); - if (text == null) { - return; - } - - StructuredDocString docString = DocStringUtil.parse(text, function); + final StructuredDocString docString = DocStringUtil.parseDocString(node); if (docString instanceof PlainDocString) { return; } diff --git a/python/src/com/jetbrains/python/inspections/PyIncorrectDocstringInspection.java b/python/src/com/jetbrains/python/inspections/PyIncorrectDocstringInspection.java index 350bba6f906c..8d5a0a2b340b 100644 --- a/python/src/com/jetbrains/python/inspections/PyIncorrectDocstringInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyIncorrectDocstringInspection.java @@ -50,13 +50,7 @@ public class PyIncorrectDocstringInspection extends PyBaseDocstringInspection { } private void checkParameters(@NotNull PyDocStringOwner pyDocStringOwner, @NotNull PyStringLiteralExpression node) { - final String text = node.getText(); - if (text == null) { - return; - } - - final StructuredDocString docString = DocStringUtil.parse(text, node); - + final StructuredDocString docString = DocStringUtil.parseDocString(node); if (docString instanceof PlainDocString) { return; } -- 2.32.0