diff --git a/python/src/com/jetbrains/python/documentation/docstrings/DocStringUtil.java b/python/src/com/jetbrains/python/documentation/docstrings/DocStringUtil.java index 7ffcd24ac742..e29e68898b10 100644 --- a/python/src/com/jetbrains/python/documentation/docstrings/DocStringUtil.java +++ b/python/src/com/jetbrains/python/documentation/docstrings/DocStringUtil.java @@ -27,6 +27,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; +import com.intellij.util.ObjectUtils; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.documentation.PyDocumentationSettings; import com.jetbrains.python.psi.*; @@ -172,7 +173,7 @@ public class DocStringUtil { @NotNull public static DocStringFormat guessDocStringFormat(@NotNull String text, @Nullable PsiElement anchor) { final DocStringFormat guessed = guessDocStringFormat(text); - return guessed == DocStringFormat.PLAIN && anchor != null ? getConfiguredDocStringFormat(anchor) : guessed; + return guessed == DocStringFormat.PLAIN && anchor != null ? getConfiguredDocStringFormatOrPlain(anchor) : guessed; } /** @@ -180,12 +181,22 @@ public class DocStringUtil { * @return docstring format configured for file or module containing given anchor PSI element * @see PyDocumentationSettings#getFormatForFile(PsiFile) */ - @NotNull + @Nullable public static DocStringFormat getConfiguredDocStringFormat(@NotNull PsiElement anchor) { - final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(getModuleForElement(anchor)); + final Module module = getModuleForElement(anchor); + if (module == null) { + return null; + } + + final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(module); return settings.getFormatForFile(anchor.getContainingFile()); } + @NotNull + public static DocStringFormat getConfiguredDocStringFormatOrPlain(@NotNull PsiElement anchor) { + return ObjectUtils.chooseNotNull(getConfiguredDocStringFormat(anchor), DocStringFormat.PLAIN); + } + public static boolean isLikeSphinxDocString(@NotNull String text) { return text.contains(":param ") || text.contains(":return:") || text.contains(":returns:") || @@ -313,16 +324,24 @@ public class DocStringUtil { * @return false if no structured docstring format was specified initially and user didn't select any, true otherwise */ public static boolean ensureNotPlainDocstringFormat(@NotNull PsiElement anchor) { - return ensureNotPlainDocstringFormatForFile(anchor.getContainingFile(), getModuleForElement(anchor)); + final Module module = getModuleForElement(anchor); + if (module == null) { + return false; + } + + return ensureNotPlainDocstringFormatForFile(anchor.getContainingFile(), module); } - @NotNull + // Might return {@code null} in some rare cases when PSI element doesn't have an associated module. + // For instance, an empty IDEA project with a Python scratch file. + @Nullable private static Module getModuleForElement(@NotNull PsiElement element) { - Module module = ModuleUtilCore.findModuleForPsiElement(element); - if (module == null) { - module = ModuleManager.getInstance(element.getProject()).getModules()[0]; + final Module module = ModuleUtilCore.findModuleForPsiElement(element); + if (module != null) { + return module; } - return module; + + return ArrayUtil.getFirstElement(ModuleManager.getInstance(element.getProject()).getModules()); } private static boolean ensureNotPlainDocstringFormatForFile(@NotNull PsiFile file, @NotNull Module module) { diff --git a/python/src/com/jetbrains/python/documentation/docstrings/PyDocstringGenerator.java b/python/src/com/jetbrains/python/documentation/docstrings/PyDocstringGenerator.java index 7fc0694fba06..11f24d7320d2 100644 --- a/python/src/com/jetbrains/python/documentation/docstrings/PyDocstringGenerator.java +++ b/python/src/com/jetbrains/python/documentation/docstrings/PyDocstringGenerator.java @@ -26,7 +26,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; @@ -92,7 +91,7 @@ public class PyDocstringGenerator { indentation = PyIndentUtil.getElementIndent(((PyStatementListContainer)owner).getStatementList()); } final String docStringText = owner.getDocStringExpression() == null ? null : owner.getDocStringExpression().getText(); - return new PyDocstringGenerator(owner, docStringText, DocStringUtil.getConfiguredDocStringFormat(owner), indentation, owner); + return new PyDocstringGenerator(owner, docStringText, DocStringUtil.getConfiguredDocStringFormatOrPlain(owner), indentation, owner); } /** @@ -109,7 +108,7 @@ public class PyDocstringGenerator { public static PyDocstringGenerator update(@NotNull PyStringLiteralExpression docString) { return new PyDocstringGenerator(PsiTreeUtil.getParentOfType(docString, PyDocStringOwner.class), docString.getText(), - DocStringUtil.getConfiguredDocStringFormat(docString), + DocStringUtil.getConfiguredDocStringFormatOrPlain(docString), PyIndentUtil.getElementIndent(docString), docString); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java index e2456210d268..e4469a12ade4 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java @@ -87,7 +87,7 @@ public class PyFunctionBuilder { */ public PyFunctionBuilder(@NotNull String name, @NotNull PsiElement settingsAnchor) { myName = name; - myDocStringGenerator = PyDocstringGenerator.create(DocStringUtil.getConfiguredDocStringFormat(settingsAnchor), + myDocStringGenerator = PyDocstringGenerator.create(DocStringUtil.getConfiguredDocStringFormatOrPlain(settingsAnchor), PyIndentUtil.getIndentFromSettings(settingsAnchor.getProject()), settingsAnchor); }