mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Extended PyDocStringOwner interface and moved docstring utilities into DocStringUtil
This commit is contained in:
@@ -3,6 +3,12 @@ package com.jetbrains.python.psi;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface PyDocStringOwner extends PyElement {
|
||||
@Nullable
|
||||
String getDocStringValue();
|
||||
|
||||
@Nullable
|
||||
StructuredDocString getStructuredDocString();
|
||||
|
||||
@Nullable
|
||||
PyStringLiteralExpression getDocStringExpression();
|
||||
}
|
||||
|
||||
@@ -48,9 +48,6 @@ extends
|
||||
@Nullable
|
||||
PyType getReturnTypeFromDocString();
|
||||
|
||||
@Nullable
|
||||
String getDocStringValue();
|
||||
|
||||
/**
|
||||
* If the function raises a DeprecationWarning or a PendingDeprecationWarning, returns the explanation text provided for the warning..
|
||||
*
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import com.jetbrains.python.psi.PyExpressionStatement;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
// TODO: find a better place for this.
|
||||
/**
|
||||
* Utility class for finding an expression which would fit as a doc string.
|
||||
* User: dcheryasov
|
||||
* Date: Jun 7, 2009 5:06:12 AM
|
||||
*/
|
||||
public class PythonDocStringFinder {
|
||||
private PythonDocStringFinder() {}
|
||||
|
||||
/**
|
||||
* Looks for a doc string under given parent.
|
||||
* @param parent where to look. For classes and functions, this would be PyStatementList, for modules, PyFile.
|
||||
* @return the defining expression, or null.
|
||||
*/
|
||||
@Nullable
|
||||
public static PyStringLiteralExpression find(PyElement parent) {
|
||||
if (parent != null) {
|
||||
PsiElement seeker = PyUtil.getFirstNonCommentAfter(parent.getFirstChild());
|
||||
if (seeker instanceof PyExpressionStatement) seeker = PyUtil.getFirstNonCommentAfter(seeker.getFirstChild());
|
||||
if (seeker instanceof PyStringLiteralExpression) return (PyStringLiteralExpression)seeker;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.PythonDocStringFinder;
|
||||
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyQualifiedName;
|
||||
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
|
||||
@@ -63,7 +63,7 @@ public class AddImportHelper {
|
||||
// maybe we arrived at the doc comment stmt; skip over it, too
|
||||
else if (!skippedOverImports && !skippedOverDoc && file instanceof PyFile) {
|
||||
PsiElement doc_elt =
|
||||
PythonDocStringFinder.find((PyElement)file); // this gives the literal; its parent is the expr seeker may have encountered
|
||||
DocStringUtil.findDocStringExpression((PyElement)file); // this gives the literal; its parent is the expr seeker may have encountered
|
||||
if (doc_elt != null && doc_elt.getParent() == feeler) {
|
||||
feeler = feeler.getNextSibling();
|
||||
seeker = feeler; // skip over doc even if there's nothing below it
|
||||
|
||||
+4
-14
@@ -12,8 +12,6 @@ import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.debugger.PySignature;
|
||||
import com.jetbrains.python.debugger.PySignatureCacheManager;
|
||||
import com.jetbrains.python.documentation.PyDocstringGenerator;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.StructuredDocStringBase;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -84,23 +82,15 @@ public class SpecifyTypeInDocstringIntention extends TypeIntention {
|
||||
protected boolean isParamTypeDefined(PyParameter parameter) {
|
||||
PyFunction pyFunction = PsiTreeUtil.getParentOfType(parameter, PyFunction.class);
|
||||
if (pyFunction != null && parameter != null) {
|
||||
final String docstring = pyFunction.getDocStringValue();
|
||||
if (docstring != null) {
|
||||
StructuredDocString structuredDocString = StructuredDocStringBase.parse(docstring);
|
||||
return structuredDocString != null && structuredDocString.getParamType(StringUtil.notNullize(parameter.getName())) != null;
|
||||
}
|
||||
return false;
|
||||
final StructuredDocString structuredDocString = pyFunction.getStructuredDocString();
|
||||
return structuredDocString != null && structuredDocString.getParamType(StringUtil.notNullize(parameter.getName())) != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReturnTypeDefined(@NotNull PyFunction function) {
|
||||
final String docstring = function.getDocStringValue();
|
||||
if (docstring != null) {
|
||||
StructuredDocString structuredDocString = StructuredDocStringBase.parse(docstring);
|
||||
return structuredDocString != null && structuredDocString.getReturnType( ) != null;
|
||||
}
|
||||
return false;
|
||||
final StructuredDocString structuredDocString = function.getStructuredDocString();
|
||||
return structuredDocString != null && structuredDocString.getReturnType() != null;
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PythonHelpersLocator;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.StructuredDocStringBase;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyQualifiedName;
|
||||
@@ -281,7 +281,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase {
|
||||
if (docString == null && level.isPy3K()) { //if we couldn't find for Py3K will search in Python2 db
|
||||
return getStructuredDocString(qualifiedName, LanguageLevel.PYTHON27);
|
||||
}
|
||||
return StructuredDocStringBase.parse(docString);
|
||||
return DocStringUtil.parse(docString);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -42,7 +42,7 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
|
||||
final List<PsiReference> result = new ArrayList<PsiReference>();
|
||||
final int offset = ranges.get(0).getStartOffset();
|
||||
// XXX: It does not work with multielement docstrings
|
||||
StructuredDocString docString = StructuredDocStringBase.parse(text);
|
||||
StructuredDocString docString = DocStringUtil.parse(text);
|
||||
if (docString != null) {
|
||||
result.addAll(referencesFromNames(element, offset, docString,
|
||||
docString.getTagArguments(StructuredDocStringBase.PARAM_TAGS), StructuredDocStringBase.PARAMETER));
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
package com.jetbrains.python.documentation;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: catherine
|
||||
*/
|
||||
@@ -12,4 +25,128 @@ public class DocStringUtil {
|
||||
.replaceFirst("^((:py)?:class:`[~!]?|[A-Z]\\{)", "")
|
||||
.replaceFirst("(`|\\})?\\.?$", "");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getDocStringValue(@NotNull PyDocStringOwner owner) {
|
||||
return PyPsiUtils.strValue(owner.getDocStringExpression());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static StructuredDocString parse(@Nullable String text) {
|
||||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
if (isSphinxDocString(text)) {
|
||||
return new SphinxDocString(text);
|
||||
}
|
||||
return new EpydocString(text);
|
||||
}
|
||||
|
||||
public static boolean isSphinxDocString(@NotNull String text) {
|
||||
return text.contains(":param ") || text.contains(":rtype") || text.contains(":type");
|
||||
}
|
||||
|
||||
public static boolean isEpydocDocString(@NotNull String text) {
|
||||
return text.contains("@param ") || text.contains("@rtype") || text.contains("@type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a doc string under given parent.
|
||||
* @param parent where to look. For classes and functions, this would be PyStatementList, for modules, PyFile.
|
||||
* @return the defining expression, or null.
|
||||
*/
|
||||
@Nullable
|
||||
public static PyStringLiteralExpression findDocStringExpression(@Nullable PyElement parent) {
|
||||
if (parent != null) {
|
||||
PsiElement seeker = PyUtil.getFirstNonCommentAfter(parent.getFirstChild());
|
||||
if (seeker instanceof PyExpressionStatement) seeker = PyUtil.getFirstNonCommentAfter(seeker.getFirstChild());
|
||||
if (seeker instanceof PyStringLiteralExpression) return (PyStringLiteralExpression)seeker;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static StructuredDocString getStructuredDocString(PyDocStringOwner owner) {
|
||||
return parse(owner.getDocStringValue());
|
||||
}
|
||||
|
||||
public static boolean isDocStringExpression(@Nullable PyExpression expression) {
|
||||
final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(expression, PyDocStringOwner.class);
|
||||
if (docStringOwner != null) {
|
||||
if (docStringOwner.getDocStringExpression() == expression) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (expression instanceof PyStringLiteralExpression) {
|
||||
return isVariableDocString((PyStringLiteralExpression)expression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyStringLiteralExpression getAttributeDocString(@NotNull PyTargetExpression attr) {
|
||||
if (attr.getParent() instanceof PyAssignmentStatement) {
|
||||
final PyAssignmentStatement assignment = (PyAssignmentStatement)attr.getParent();
|
||||
PsiElement nextSibling = assignment.getNextSibling();
|
||||
while (nextSibling != null && (nextSibling instanceof PsiWhiteSpace || nextSibling instanceof PsiComment)) {
|
||||
nextSibling = nextSibling.getNextSibling();
|
||||
}
|
||||
if (nextSibling instanceof PyExpressionStatement) {
|
||||
final PyExpression expression = ((PyExpressionStatement)nextSibling).getExpression();
|
||||
if (expression instanceof PyStringLiteralExpression) {
|
||||
return (PyStringLiteralExpression)expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getAttributeDocComment(@NotNull PyTargetExpression attr) {
|
||||
if (attr.getParent() instanceof PyAssignmentStatement) {
|
||||
final PyAssignmentStatement assignment = (PyAssignmentStatement)attr.getParent();
|
||||
PsiElement prevSibling = assignment.getPrevSibling();
|
||||
while (prevSibling != null && (prevSibling instanceof PsiWhiteSpace)) {
|
||||
prevSibling = prevSibling.getPrevSibling();
|
||||
}
|
||||
if (prevSibling instanceof PsiComment && prevSibling.getText().startsWith("#:")) {
|
||||
return prevSibling.getText().substring(2);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isVariableDocString(@NotNull PyStringLiteralExpression expr) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(expr);
|
||||
if (module == null) return false;
|
||||
final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(module);
|
||||
if (settings.isEpydocFormat(expr.getContainingFile()) || settings.isReSTFormat(expr.getContainingFile())) {
|
||||
final PsiElement parent = expr.getParent();
|
||||
if (!(parent instanceof PyExpressionStatement)) {
|
||||
return false;
|
||||
}
|
||||
PsiElement prevElement = parent.getPrevSibling();
|
||||
while (prevElement instanceof PsiWhiteSpace || prevElement instanceof PsiComment) {
|
||||
prevElement = prevElement.getPrevSibling();
|
||||
}
|
||||
if (prevElement instanceof PyAssignmentStatement) {
|
||||
final PyAssignmentStatement assignmentStatement = (PyAssignmentStatement)prevElement;
|
||||
final ScopeOwner scope = PsiTreeUtil.getParentOfType(prevElement, ScopeOwner.class);
|
||||
if (scope instanceof PyClass || scope instanceof PyFile) {
|
||||
return true;
|
||||
}
|
||||
if (scope instanceof PyFunction) {
|
||||
PyFunction function = (PyFunction) scope;
|
||||
if (!PyNames.INIT.equals(function.getName())) {
|
||||
return false;
|
||||
}
|
||||
for (PyExpression target : assignmentStatement.getTargets()) {
|
||||
if (PyUtil.isInstanceAttribute(target)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package com.jetbrains.python.documentation;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.psi.*;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class EpydocUtil {
|
||||
private EpydocUtil() {
|
||||
}
|
||||
|
||||
public static boolean isVariableDocString(PyStringLiteralExpression expr) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(expr);
|
||||
if (module == null) return false;
|
||||
final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(module);
|
||||
if (settings.isEpydocFormat(expr.getContainingFile()) || settings.isReSTFormat(expr.getContainingFile())) {
|
||||
final PsiElement parent = expr.getParent();
|
||||
if (!(parent instanceof PyExpressionStatement)) {
|
||||
return false;
|
||||
}
|
||||
PsiElement prevElement = parent.getPrevSibling();
|
||||
while (prevElement instanceof PsiWhiteSpace || prevElement instanceof PsiComment) {
|
||||
prevElement = prevElement.getPrevSibling();
|
||||
}
|
||||
if (prevElement instanceof PyAssignmentStatement) {
|
||||
final PyAssignmentStatement assignmentStatement = (PyAssignmentStatement)prevElement;
|
||||
final ScopeOwner scope = PsiTreeUtil.getParentOfType(prevElement, ScopeOwner.class);
|
||||
if (scope instanceof PyClass || scope instanceof PyFile) {
|
||||
return true;
|
||||
}
|
||||
if (scope instanceof PyFunction) {
|
||||
PyFunction function = (PyFunction) scope;
|
||||
if (!PyNames.INIT.equals(function.getName())) {
|
||||
return false;
|
||||
}
|
||||
for (PyExpression target : assignmentStatement.getTargets()) {
|
||||
if (PyUtil.isInstanceAttribute(target)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -150,7 +150,7 @@ public class PyDocstringGenerator {
|
||||
public Pair<String, Integer> addParamToDocstring() {
|
||||
String text = getDocstringText();
|
||||
|
||||
StructuredDocString structuredDocString = StructuredDocStringBase.parse(text);
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(text);
|
||||
|
||||
Collection<DocstringParam> paramsToAdd = getParamsToAdd(structuredDocString, myParams);
|
||||
|
||||
@@ -173,7 +173,7 @@ public class PyDocstringGenerator {
|
||||
private Collection<DocstringParam> collectParametersToAdd() {
|
||||
String text = getDocstringText();
|
||||
|
||||
StructuredDocString structuredDocString = StructuredDocStringBase.parse(text); //TODO: do we need to cache it?
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(text); //TODO: do we need to cache it?
|
||||
|
||||
return getParamsToAdd(structuredDocString, myParams);
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ class PyDocumentationBuilder {
|
||||
String[] lines = removeCommonIndentation(docstring);
|
||||
String preparedDocstring = StringUtil.join(lines, "\n");
|
||||
if (documentationSettings.isEpydocFormat(element.getContainingFile()) ||
|
||||
StructuredDocStringBase.isEpydocDocstring(preparedDocstring)) {
|
||||
DocStringUtil.isEpydocDocString(preparedDocstring)) {
|
||||
final EpydocString epydocString = new EpydocString(preparedDocstring);
|
||||
|
||||
String formatted = epydocString.getDescription();
|
||||
@@ -376,7 +376,7 @@ class PyDocumentationBuilder {
|
||||
return;
|
||||
}
|
||||
else if (documentationSettings.isReSTFormat(element.getContainingFile()) ||
|
||||
StructuredDocStringBase.isSphinxDocstring(preparedDocstring)) {
|
||||
DocStringUtil.isSphinxDocString(preparedDocstring)) {
|
||||
String formatted = null;
|
||||
Sdk pythonSdk = PythonSdkType.findPython2Sdk(module);
|
||||
if (pythonSdk != null) {
|
||||
@@ -452,7 +452,7 @@ class PyDocumentationBuilder {
|
||||
}
|
||||
|
||||
private static Pair<String, String> getTypeAndDescr(String docString, @NotNull PyNamedParameter followed) {
|
||||
StructuredDocString structuredDocString = StructuredDocStringBase.parse(docString);
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(docString);
|
||||
String type = null;
|
||||
String desc = null;
|
||||
if (structuredDocString != null) {
|
||||
@@ -474,7 +474,7 @@ class PyDocumentationBuilder {
|
||||
.addItem(" of class ").addWith(PythonDocumentationProvider.LinkMyClass, $().addWith(TagCode, $(cls.getName()))).addItem(BR)
|
||||
;
|
||||
|
||||
final String docString = PyPsiUtils.strValue(PyUtil.getAttributeDocString((PyTargetExpression)myElement));
|
||||
final String docString = PyPsiUtils.strValue(DocStringUtil.getAttributeDocString((PyTargetExpression)myElement));
|
||||
if (docString != null) {
|
||||
addFormattedDocString(myElement, docString, myBody, myEpilog);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
String summary = "";
|
||||
final PyStringLiteralExpression docStringExpression = func.getDocStringExpression();
|
||||
if (docStringExpression != null) {
|
||||
final StructuredDocString docString = StructuredDocStringBase.parse(docStringExpression.getStringValue());
|
||||
final StructuredDocString docString = DocStringUtil.parse(docStringExpression.getStringValue());
|
||||
if (docString != null) {
|
||||
summary = docString.getSummary();
|
||||
}
|
||||
@@ -92,7 +92,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
}
|
||||
}
|
||||
if (docStringExpression != null) {
|
||||
final StructuredDocString docString = StructuredDocStringBase.parse(docStringExpression.getStringValue());
|
||||
final StructuredDocString docString = DocStringUtil.parse(docStringExpression.getStringValue());
|
||||
if (docString != null) {
|
||||
summary = docString.getSummary();
|
||||
}
|
||||
|
||||
@@ -40,25 +40,6 @@ public abstract class StructuredDocStringBase implements StructuredDocString {
|
||||
public static String KEYWORD = "keyword";
|
||||
public static String VARIABLE = "variable";
|
||||
|
||||
@Nullable
|
||||
public static StructuredDocString parse(@Nullable String text) {
|
||||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
if (isSphinxDocstring(text)) {
|
||||
return new SphinxDocString(text);
|
||||
}
|
||||
return new EpydocString(text);
|
||||
}
|
||||
|
||||
public static boolean isSphinxDocstring(String text) {
|
||||
return text.contains(":param ") || text.contains(":rtype") || text.contains(":type");
|
||||
}
|
||||
|
||||
public static boolean isEpydocDocstring(String text) {
|
||||
return text.contains("@param ") || text.contains("@rtype") || text.contains("@type");
|
||||
}
|
||||
|
||||
protected StructuredDocStringBase(@NotNull String docStringText, String tagPrefix) {
|
||||
final Substring docString = new Substring(docStringText);
|
||||
final List<Substring> lines = docString.splitLines();
|
||||
|
||||
@@ -118,7 +118,7 @@ public class PyDocstringInspection extends PyInspection {
|
||||
return false;
|
||||
}
|
||||
|
||||
StructuredDocString docString = StructuredDocStringBase.parse(text);
|
||||
StructuredDocString docString = DocStringUtil.parse(text);
|
||||
|
||||
if (docString == null) {
|
||||
return false;
|
||||
|
||||
@@ -8,8 +8,8 @@ import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.debugger.PySignature;
|
||||
import com.jetbrains.python.debugger.PySignatureCacheManager;
|
||||
import com.jetbrains.python.debugger.PySignatureUtil;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.StructuredDocStringBase;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
@@ -73,7 +73,7 @@ public class PyDocstringTypesInspection extends PyInspection {
|
||||
return;
|
||||
}
|
||||
|
||||
StructuredDocString docString = StructuredDocStringBase.parse(text);
|
||||
StructuredDocString docString = DocStringUtil.parse(text);
|
||||
if (docString == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.inspections.quickfix.StatementEffectDocstringQuickFix;
|
||||
import com.jetbrains.python.inspections.quickfix.StatementEffectFunctionCallQuickFix;
|
||||
import com.jetbrains.python.inspections.quickfix.StatementEffectIntroduceVariableQuickFix;
|
||||
@@ -81,7 +82,7 @@ public class PyStatementEffectInspection extends PyInspection {
|
||||
prevSibling = prevSibling.getPrevSibling();
|
||||
if (prevSibling instanceof PyAssignmentStatement) {
|
||||
for (PyExpression target : ((PyAssignmentStatement)prevSibling).getTargets()) {
|
||||
if (PyUtil.getAttributeDocString((PyTargetExpression)target) == expression) {
|
||||
if (DocStringUtil.getAttributeDocString((PyTargetExpression)target) == expression) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -107,7 +108,7 @@ public class PyStatementEffectInspection extends PyInspection {
|
||||
}
|
||||
|
||||
if (expression instanceof PyStringLiteralExpression) {
|
||||
if (PyUtil.isDocString(expression)) return true;
|
||||
if (DocStringUtil.isDocStringExpression(expression)) return true;
|
||||
}
|
||||
else if (expression instanceof PyListCompExpression) {
|
||||
if (hasEffect(((PyListCompExpression)expression).getResultExpression())) {
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.codeInsight.stdlib.PyNamedTupleType;
|
||||
import com.jetbrains.python.documentation.EpydocUtil;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
@@ -459,50 +458,6 @@ public class PyUtil {
|
||||
return element instanceof PyTargetExpression && ScopeUtil.getScopeOwner(element) instanceof PyClass;
|
||||
}
|
||||
|
||||
public static boolean isDocString(PyExpression expression) {
|
||||
final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(expression, PyDocStringOwner.class);
|
||||
if (docStringOwner != null) {
|
||||
if (docStringOwner.getDocStringExpression() == expression) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (EpydocUtil.isVariableDocString((PyStringLiteralExpression)expression)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyStringLiteralExpression getAttributeDocString(PyTargetExpression attr) {
|
||||
if (attr.getParent() instanceof PyAssignmentStatement) {
|
||||
final PyAssignmentStatement assignment = (PyAssignmentStatement)attr.getParent();
|
||||
PsiElement nextSibling = assignment.getNextSibling();
|
||||
while (nextSibling != null && (nextSibling instanceof PsiWhiteSpace || nextSibling instanceof PsiComment)) {
|
||||
nextSibling = nextSibling.getNextSibling();
|
||||
}
|
||||
if (nextSibling instanceof PyExpressionStatement) {
|
||||
final PyExpression expression = ((PyExpressionStatement)nextSibling).getExpression();
|
||||
if (expression instanceof PyStringLiteralExpression) {
|
||||
return (PyStringLiteralExpression)expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getAttributeDocComment(PyTargetExpression attr) {
|
||||
if (attr.getParent() instanceof PyAssignmentStatement) {
|
||||
final PyAssignmentStatement assignment = (PyAssignmentStatement)attr.getParent();
|
||||
PsiElement prevSibling = assignment.getPrevSibling();
|
||||
while (prevSibling != null && (prevSibling instanceof PsiWhiteSpace)) {
|
||||
prevSibling = prevSibling.getPrevSibling();
|
||||
}
|
||||
if (prevSibling instanceof PsiComment && prevSibling.getText().startsWith("#:")) {
|
||||
return prevSibling.getText().substring(2);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isIfNameEqualsMain(PyIfStatement ifStatement) {
|
||||
final PyExpression condition = ifStatement.getIfPart().getCondition();
|
||||
return isNameEqualsMain(condition);
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.jetbrains.python.*;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveUtil;
|
||||
@@ -1003,7 +1004,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
|
||||
}
|
||||
|
||||
public PyStringLiteralExpression getDocStringExpression() {
|
||||
return PythonDocStringFinder.find(getStatementList());
|
||||
return DocStringUtil.findDocStringExpression(getStatementList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1012,7 +1013,13 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
|
||||
if (stub != null) {
|
||||
return stub.getDocString();
|
||||
}
|
||||
return PyPsiUtils.strValue(getDocStringExpression());
|
||||
return DocStringUtil.getDocStringValue(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StructuredDocString getStructuredDocString() {
|
||||
return DocStringUtil.getStructuredDocString(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.indexing.IndexingDataKeys;
|
||||
import com.jetbrains.python.*;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.inspections.PythonVisitorFilter;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.RatedResolveResult;
|
||||
@@ -719,8 +720,22 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
|
||||
return myType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getDocStringValue() {
|
||||
return DocStringUtil.getDocStringValue(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StructuredDocString getStructuredDocString() {
|
||||
return DocStringUtil.getStructuredDocString(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyStringLiteralExpression getDocStringExpression() {
|
||||
return PythonDocStringFinder.find(this);
|
||||
return DocStringUtil.findDocStringExpression(this);
|
||||
}
|
||||
|
||||
public void subtreeChanged() {
|
||||
|
||||
@@ -18,12 +18,11 @@ import com.intellij.util.PlatformIcons;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonDocStringFinder;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.StructuredDocStringBase;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
|
||||
import com.jetbrains.python.psi.stubs.PyClassStub;
|
||||
@@ -306,8 +305,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
|
||||
@Nullable
|
||||
@Override
|
||||
public PyType getReturnTypeFromDocString() {
|
||||
final String value = getDocStringValue();
|
||||
final String typeName = value != null ? extractReturnType(value) : null;
|
||||
final String typeName = extractReturnType();
|
||||
return typeName != null ? PyTypeParser.getTypeByName(this, typeName) : null;
|
||||
}
|
||||
|
||||
@@ -365,8 +363,13 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
|
||||
if (stub != null) {
|
||||
return stub.getDocString();
|
||||
}
|
||||
final PyStringLiteralExpression docStringExpression = getDocStringExpression();
|
||||
return PyPsiUtils.strValue(docStringExpression);
|
||||
return DocStringUtil.getDocStringValue(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StructuredDocString getStructuredDocString() {
|
||||
return DocStringUtil.getStructuredDocString(this);
|
||||
}
|
||||
|
||||
private boolean isGeneratedStub() {
|
||||
@@ -384,7 +387,11 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String extractReturnType(String docString) {
|
||||
private String extractReturnType() {
|
||||
final String docString = getDocStringValue();
|
||||
if (docString == null) {
|
||||
return null;
|
||||
}
|
||||
final List<String> lines = StringUtil.split(docString, "\n");
|
||||
while (lines.size() > 0 && lines.get(0).trim().length() == 0) {
|
||||
lines.remove(0);
|
||||
@@ -396,9 +403,8 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
|
||||
return firstLine.substring(pos + 2).trim();
|
||||
}
|
||||
}
|
||||
|
||||
StructuredDocString epydocString = StructuredDocStringBase.parse(docString);
|
||||
return epydocString != null ? epydocString.getReturnType() : null;
|
||||
final StructuredDocString structuredDocString = getStructuredDocString();
|
||||
return structuredDocString != null ? structuredDocString.getReturnType() : null;
|
||||
}
|
||||
|
||||
private static class ReturnVisitor extends PyRecursiveElementVisitor {
|
||||
@@ -457,7 +463,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
|
||||
|
||||
public PyStringLiteralExpression getDocStringExpression() {
|
||||
final PyStatementList stmtList = getStatementList();
|
||||
return stmtList != null ? PythonDocStringFinder.find(stmtList) : null;
|
||||
return stmtList != null ? DocStringUtil.findDocStringExpression(stmtList) : null;
|
||||
}
|
||||
|
||||
protected String getElementLocation() {
|
||||
|
||||
@@ -17,8 +17,6 @@ import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
import com.jetbrains.python.codeInsight.stdlib.PyStdlibTypeProvider;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.StructuredDocStringBase;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.stubs.PyNamedParameterStub;
|
||||
@@ -207,15 +205,15 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame
|
||||
}
|
||||
}
|
||||
|
||||
String docString = func.getDocStringValue();
|
||||
StructuredDocString docString = func.getStructuredDocString();
|
||||
if (PyNames.INIT.equals(func.getName()) && docString == null) {
|
||||
PyClass pyClass = func.getContainingClass();
|
||||
if (pyClass != null)
|
||||
docString = pyClass.getDocStringValue();
|
||||
if (pyClass != null) {
|
||||
docString = pyClass.getStructuredDocString();
|
||||
}
|
||||
}
|
||||
StructuredDocString epydocString = StructuredDocStringBase.parse(docString);
|
||||
if (epydocString != null) {
|
||||
String typeName = epydocString.getParamType(getName());
|
||||
if (docString != null) {
|
||||
String typeName = docString.getParamType(getName());
|
||||
if (typeName != null) {
|
||||
return PyTypeParser.getTypeByName(this, typeName);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.Scope;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.StructuredDocStringBase;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.references.PyQualifiedReference;
|
||||
import com.jetbrains.python.psi.impl.references.PyTargetReference;
|
||||
@@ -248,9 +248,9 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
|
||||
@Nullable
|
||||
public static PyType getTypeFromDocString(PyTargetExpressionImpl targetExpression) {
|
||||
final String docString = PyPsiUtils.strValue(PyUtil.getAttributeDocString(targetExpression));
|
||||
final String docString = PyPsiUtils.strValue(DocStringUtil.getAttributeDocString(targetExpression));
|
||||
if (docString != null) {
|
||||
StructuredDocString structuredDocString = StructuredDocStringBase.parse(docString);
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(docString);
|
||||
if (structuredDocString != null) {
|
||||
String typeName = structuredDocString.getParamType(null);
|
||||
if (typeName == null) {
|
||||
@@ -266,9 +266,9 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
|
||||
@Nullable
|
||||
public static PyType getTypeFromComment(PyTargetExpressionImpl targetExpression) {
|
||||
String docComment = PyUtil.getAttributeDocComment(targetExpression);
|
||||
String docComment = DocStringUtil.getAttributeDocComment(targetExpression);
|
||||
if (docComment != null) {
|
||||
StructuredDocString structuredDocString = StructuredDocStringBase.parse(docComment);
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(docComment);
|
||||
if (structuredDocString != null) {
|
||||
String typeName = structuredDocString.getParamType(null);
|
||||
if (typeName == null) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.jetbrains.python.PythonDocStringFinder;
|
||||
import com.jetbrains.python.documentation.*;
|
||||
import com.jetbrains.python.highlighting.PyHighlighter;
|
||||
import com.jetbrains.python.psi.*;
|
||||
@@ -16,17 +15,17 @@ public class DocStringAnnotator extends PyAnnotator {
|
||||
|
||||
@Override
|
||||
public void visitPyFile(final PyFile node) {
|
||||
annotateDocStringStmt(PythonDocStringFinder.find(node));
|
||||
annotateDocStringStmt(DocStringUtil.findDocStringExpression(node));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyFunction(final PyFunction node) {
|
||||
annotateDocStringStmt(PythonDocStringFinder.find(node.getStatementList()));
|
||||
annotateDocStringStmt(DocStringUtil.findDocStringExpression(node.getStatementList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyClass(final PyClass node) {
|
||||
annotateDocStringStmt(PythonDocStringFinder.find(node.getStatementList()));
|
||||
annotateDocStringStmt(DocStringUtil.findDocStringExpression(node.getStatementList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,7 +44,7 @@ public class DocStringAnnotator extends PyAnnotator {
|
||||
@Override
|
||||
public void visitPyExpressionStatement(PyExpressionStatement node) {
|
||||
if (node.getExpression() instanceof PyStringLiteralExpression &&
|
||||
EpydocUtil.isVariableDocString((PyStringLiteralExpression)node.getExpression())) {
|
||||
DocStringUtil.isVariableDocString((PyStringLiteralExpression)node.getExpression())) {
|
||||
annotateDocStringStmt((PyStringLiteralExpression)node.getExpression());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user