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.*;
@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;
}
/**
* @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:") ||
* @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) {
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;
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);
}
/**
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);
}