mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
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..
|
||||
*
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
*/
|
||||
public interface StructuredDocString {
|
||||
String getDescription();
|
||||
|
||||
String getSummary();
|
||||
|
||||
@Nullable
|
||||
Substring getTagValue(String... tagNames);
|
||||
|
||||
@Nullable
|
||||
Substring getTagValue(String tagName, @NotNull String argName);
|
||||
|
||||
@Nullable
|
||||
Substring getTagValue(String[] tagNames, @NotNull String argName);
|
||||
|
||||
List<Substring> getTagArguments(String... tagNames);
|
||||
|
||||
List<Substring> getParameterSubstrings();
|
||||
|
||||
@Nullable
|
||||
Substring getParamByNameAndKind(@NotNull String name, String kind);
|
||||
|
||||
List<String> getParameters();
|
||||
|
||||
List<String> getKeywordArguments();
|
||||
|
||||
@Nullable
|
||||
String getReturnType();
|
||||
|
||||
@Nullable
|
||||
String getReturnDescription();
|
||||
|
||||
@Nullable
|
||||
String getParamType(@Nullable String paramName);
|
||||
|
||||
@Nullable
|
||||
String getParamDescription(@Nullable String paramName);
|
||||
|
||||
@Nullable
|
||||
String getKeywordArgumentDescription(@Nullable String paramName);
|
||||
|
||||
List<String> getRaisedExceptions();
|
||||
|
||||
@Nullable
|
||||
String getRaisedExceptionDescription(@Nullable String exceptionName);
|
||||
|
||||
@Nullable
|
||||
String getAttributeDescription();
|
||||
|
||||
List<String> getAdditionalTags();
|
||||
|
||||
List<Substring> getKeywordArgumentSubstrings();
|
||||
|
||||
@Nullable
|
||||
Substring getReturnTypeSubstring();
|
||||
|
||||
@Nullable
|
||||
Substring getParamTypeSubstring(@Nullable String paramName);
|
||||
}
|
||||
+3
-5
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.documentation;
|
||||
package com.jetbrains.python.toolbox;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -8,15 +8,13 @@ import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
*/
|
||||
|
||||
/**
|
||||
* Substring with explicit offsets within its parent string.
|
||||
* <p>
|
||||
* Regular java.lang.String objects share a single char buffer for results of substring(), trim(), etc., but the offset and count
|
||||
* fields of Strings are unfortunately private.
|
||||
*
|
||||
* @author vlan
|
||||
*/
|
||||
public class Substring implements CharSequence {
|
||||
private static final Pattern RE_NL = Pattern.compile("(\\r?\\n)");
|
||||
@@ -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
-13
@@ -12,7 +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.documentation.StructuredDocString;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -83,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 = StructuredDocString.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 = StructuredDocString.parse(docstring);
|
||||
return structuredDocString != null && structuredDocString.getReturnType( ) != null;
|
||||
}
|
||||
return false;
|
||||
final StructuredDocString structuredDocString = function.getStructuredDocString();
|
||||
return structuredDocString != null && structuredDocString.getReturnType() != null;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +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.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyQualifiedName;
|
||||
@@ -280,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 StructuredDocString.parse(docString);
|
||||
return DocStringUtil.parse(docString);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -10,9 +10,11 @@ import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.psi.PyDocStringOwner;
|
||||
import com.jetbrains.python.psi.PyImportElement;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.psi.impl.PyStringLiteralExpressionImpl;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.PyTypeParser;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -40,17 +42,17 @@ 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 = StructuredDocString.parse(text);
|
||||
StructuredDocString docString = DocStringUtil.parse(text);
|
||||
if (docString != null) {
|
||||
result.addAll(referencesFromNames(element, offset, docString,
|
||||
docString.getTagArguments(StructuredDocString.PARAM_TAGS), StructuredDocString.PARAMETER));
|
||||
docString.getTagArguments(StructuredDocStringBase.PARAM_TAGS), StructuredDocStringBase.PARAMETER));
|
||||
result.addAll(referencesFromNames(element, offset, docString,
|
||||
docString.getTagArguments(StructuredDocString.PARAM_TYPE_TAGS), StructuredDocString.PARAMETER_TYPE));
|
||||
docString.getTagArguments(StructuredDocStringBase.PARAM_TYPE_TAGS), StructuredDocStringBase.PARAMETER_TYPE));
|
||||
result.addAll(referencesFromNames(element, offset, docString,
|
||||
docString.getKeywordArgumentSubstrings(), StructuredDocString.KEYWORD));
|
||||
docString.getKeywordArgumentSubstrings(), StructuredDocStringBase.KEYWORD));
|
||||
|
||||
result.addAll(referencesFromNames(element, offset, docString,
|
||||
docString.getTagArguments(StructuredDocString.VARIABLE_TAGS), StructuredDocString.VARIABLE));
|
||||
docString.getTagArguments(StructuredDocStringBase.VARIABLE_TAGS), StructuredDocStringBase.VARIABLE));
|
||||
result.addAll(returnTypes(element, docString, offset));
|
||||
}
|
||||
return result.toArray(new PsiReference[result.size()]);
|
||||
@@ -81,7 +83,7 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
|
||||
if (PyNames.isIdentifier(s)) {
|
||||
result.add(new DocStringParameterReference(element, name.getTextRange().shiftRight(offset), refType));
|
||||
}
|
||||
if (refType.equals(StructuredDocString.PARAMETER_TYPE)) {
|
||||
if (refType.equals(StructuredDocStringBase.PARAMETER_TYPE)) {
|
||||
final Substring type = docString.getParamTypeSubstring(s);
|
||||
if (type != null) {
|
||||
result.addAll(parseTypeReferences(element, type, offset));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.jetbrains.python.documentation;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.xml.util.XmlTagUtilBase;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -10,7 +11,7 @@ import java.util.*;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class EpydocString extends StructuredDocString {
|
||||
public class EpydocString extends StructuredDocStringBase {
|
||||
|
||||
public static String[] RTYPE_TAGS = new String[] { "rtype", "returntype" };
|
||||
public static String[] KEYWORD_ARGUMENT_TAGS = new String[] { "keyword", "kwarg", "kwparam" };
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import com.jetbrains.python.debugger.PySignature;
|
||||
import com.jetbrains.python.debugger.PySignatureCacheManager;
|
||||
import com.jetbrains.python.debugger.PySignatureUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -149,7 +150,7 @@ public class PyDocstringGenerator {
|
||||
public Pair<String, Integer> addParamToDocstring() {
|
||||
String text = getDocstringText();
|
||||
|
||||
StructuredDocString structuredDocString = StructuredDocString.parse(text);
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(text);
|
||||
|
||||
Collection<DocstringParam> paramsToAdd = getParamsToAdd(structuredDocString, myParams);
|
||||
|
||||
@@ -172,7 +173,7 @@ public class PyDocstringGenerator {
|
||||
private Collection<DocstringParam> collectParametersToAdd() {
|
||||
String text = getDocstringText();
|
||||
|
||||
StructuredDocString structuredDocString = StructuredDocString.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);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.jetbrains.python.psi.types.*;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import com.jetbrains.python.toolbox.ChainIterable;
|
||||
import com.jetbrains.python.toolbox.Maybe;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -365,7 +366,7 @@ class PyDocumentationBuilder {
|
||||
String[] lines = removeCommonIndentation(docstring);
|
||||
String preparedDocstring = StringUtil.join(lines, "\n");
|
||||
if (documentationSettings.isEpydocFormat(element.getContainingFile()) ||
|
||||
StructuredDocString.isEpydocDocstring(preparedDocstring)) {
|
||||
DocStringUtil.isEpydocDocString(preparedDocstring)) {
|
||||
final EpydocString epydocString = new EpydocString(preparedDocstring);
|
||||
|
||||
String formatted = epydocString.getDescription();
|
||||
@@ -375,7 +376,7 @@ class PyDocumentationBuilder {
|
||||
return;
|
||||
}
|
||||
else if (documentationSettings.isReSTFormat(element.getContainingFile()) ||
|
||||
StructuredDocString.isSphinxDocstring(preparedDocstring)) {
|
||||
DocStringUtil.isSphinxDocString(preparedDocstring)) {
|
||||
String formatted = null;
|
||||
Sdk pythonSdk = PythonSdkType.findPython2Sdk(module);
|
||||
if (pythonSdk != null) {
|
||||
@@ -451,7 +452,7 @@ class PyDocumentationBuilder {
|
||||
}
|
||||
|
||||
private static Pair<String, String> getTypeAndDescr(String docString, @NotNull PyNamedParameter followed) {
|
||||
StructuredDocString structuredDocString = StructuredDocString.parse(docString);
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(docString);
|
||||
String type = null;
|
||||
String desc = null;
|
||||
if (structuredDocString != null) {
|
||||
@@ -473,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 = StructuredDocString.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 = StructuredDocString.parse(docStringExpression.getStringValue());
|
||||
final StructuredDocString docString = DocStringUtil.parse(docStringExpression.getStringValue());
|
||||
if (docString != null) {
|
||||
summary = docString.getSummary();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.jetbrains.python.documentation;
|
||||
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -9,7 +10,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class SphinxDocString extends StructuredDocString {
|
||||
public class SphinxDocString extends StructuredDocStringBase {
|
||||
public static String[] KEYWORD_ARGUMENT_TAGS = new String[] { "keyword", "key" };
|
||||
public static String[] ALL_TAGS = new String[] { ":param", ":parameter", ":arg", ":argument", ":keyword", ":key",
|
||||
":type", ":raise", ":raises", ":var", ":cvar", ":ivar",
|
||||
|
||||
+12
-56
@@ -3,6 +3,8 @@ package com.jetbrains.python.documentation;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -16,7 +18,7 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public abstract class StructuredDocString {
|
||||
public abstract class StructuredDocStringBase implements StructuredDocString {
|
||||
protected final String myDescription;
|
||||
|
||||
protected final Map<String, Substring> mySimpleTagValues = Maps.newHashMap();
|
||||
@@ -38,26 +40,7 @@ public abstract class StructuredDocString {
|
||||
public static String KEYWORD = "keyword";
|
||||
public static String VARIABLE = "variable";
|
||||
|
||||
@Nullable
|
||||
public static StructuredDocString parse(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 StructuredDocString(@NotNull String docStringText, String tagPrefix) {
|
||||
protected StructuredDocStringBase(@NotNull String docStringText, String tagPrefix) {
|
||||
final Substring docString = new Substring(docStringText);
|
||||
final List<Substring> lines = docString.splitLines();
|
||||
final int nlines = lines.size();
|
||||
@@ -76,10 +59,12 @@ public abstract class StructuredDocString {
|
||||
myDescription = builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return myDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSummary() {
|
||||
final List<String> strings = StringUtil.split(StringUtil.trimLeading(myDescription), "\n", true, false);
|
||||
if (strings.size() > 1) {
|
||||
@@ -166,6 +151,7 @@ public abstract class StructuredDocString {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Substring getTagValue(String... tagNames) {
|
||||
for (String tagName : tagNames) {
|
||||
@@ -177,12 +163,14 @@ public abstract class StructuredDocString {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Substring getTagValue(String tagName, @NotNull String argName) {
|
||||
final Map<Substring, Substring> argValues = myArgTagValues.get(tagName);
|
||||
return argValues != null ? argValues.get(new Substring(argName)) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Substring getTagValue(String[] tagNames, @NotNull String argName) {
|
||||
for (String tagName : tagNames) {
|
||||
@@ -194,6 +182,7 @@ public abstract class StructuredDocString {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Substring> getTagArguments(String... tagNames) {
|
||||
for (String tagName : tagNames) {
|
||||
final Map<Substring, Substring> map = myArgTagValues.get(tagName);
|
||||
@@ -204,6 +193,7 @@ public abstract class StructuredDocString {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Substring> getParameterSubstrings() {
|
||||
final List<Substring> results = new ArrayList<Substring>();
|
||||
results.addAll(getTagArguments(PARAM_TAGS));
|
||||
@@ -211,6 +201,7 @@ public abstract class StructuredDocString {
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Substring getParamByNameAndKind(@NotNull String name, String kind) {
|
||||
for (Substring s: getTagArguments(kind)) {
|
||||
@@ -220,39 +211,4 @@ public abstract class StructuredDocString {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract List<String> getParameters();
|
||||
public abstract List<String> getKeywordArguments();
|
||||
|
||||
@Nullable
|
||||
public abstract String getReturnType();
|
||||
|
||||
@Nullable
|
||||
public abstract String getReturnDescription();
|
||||
|
||||
@Nullable
|
||||
public abstract String getParamType(@Nullable String paramName);
|
||||
|
||||
@Nullable
|
||||
public abstract String getParamDescription(@Nullable String paramName);
|
||||
|
||||
@Nullable
|
||||
public abstract String getKeywordArgumentDescription(@Nullable String paramName);
|
||||
|
||||
public abstract List<String> getRaisedExceptions();
|
||||
|
||||
@Nullable
|
||||
public abstract String getRaisedExceptionDescription(@Nullable String exceptionName);
|
||||
|
||||
@Nullable
|
||||
public abstract String getAttributeDescription();
|
||||
public abstract List<String> getAdditionalTags();
|
||||
|
||||
public abstract List<Substring> getKeywordArgumentSubstrings();
|
||||
|
||||
@Nullable
|
||||
public abstract Substring getReturnTypeSubstring();
|
||||
|
||||
@Nullable
|
||||
public abstract Substring getParamTypeSubstring(@Nullable String paramName);
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import com.jetbrains.python.documentation.*;
|
||||
import com.jetbrains.python.inspections.quickfix.DocstringQuickFix;
|
||||
import com.jetbrains.python.inspections.quickfix.PySuppressInspectionFix;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -117,7 +118,7 @@ public class PyDocstringInspection extends PyInspection {
|
||||
return false;
|
||||
}
|
||||
|
||||
StructuredDocString docString = StructuredDocString.parse(text);
|
||||
StructuredDocString docString = DocStringUtil.parse(text);
|
||||
|
||||
if (docString == null) {
|
||||
return false;
|
||||
|
||||
@@ -8,8 +8,9 @@ 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.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.Substring;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
@@ -72,7 +73,7 @@ public class PyDocstringTypesInspection extends PyInspection {
|
||||
return;
|
||||
}
|
||||
|
||||
StructuredDocString docString = StructuredDocString.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() {
|
||||
|
||||
@@ -12,17 +12,18 @@ import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
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.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
|
||||
import com.jetbrains.python.psi.stubs.PyClassStub;
|
||||
@@ -58,6 +59,17 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
|
||||
super(stub, nodeType);
|
||||
}
|
||||
|
||||
private class CachedStructuredDocStringProvider implements CachedValueProvider<StructuredDocString> {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<StructuredDocString> compute() {
|
||||
final PyFunctionImpl f = PyFunctionImpl.this;
|
||||
return Result.create(DocStringUtil.getStructuredDocString(f), f);
|
||||
}
|
||||
}
|
||||
|
||||
private CachedStructuredDocStringProvider myCachedStructuredDocStringProvider = new CachedStructuredDocStringProvider();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
@@ -305,8 +317,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;
|
||||
}
|
||||
|
||||
@@ -364,8 +375,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 CachedValuesManager.getManager(getProject()).getCachedValue(this, myCachedStructuredDocStringProvider);
|
||||
}
|
||||
|
||||
private boolean isGeneratedStub() {
|
||||
@@ -383,7 +399,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);
|
||||
@@ -395,9 +415,8 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
|
||||
return firstLine.substring(pos + 2).trim();
|
||||
}
|
||||
}
|
||||
|
||||
StructuredDocString epydocString = StructuredDocString.parse(docString);
|
||||
return epydocString != null ? epydocString.getReturnType() : null;
|
||||
final StructuredDocString structuredDocString = getStructuredDocString();
|
||||
return structuredDocString != null ? structuredDocString.getReturnType() : null;
|
||||
}
|
||||
|
||||
private static class ReturnVisitor extends PyRecursiveElementVisitor {
|
||||
@@ -456,7 +475,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,7 +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.documentation.StructuredDocString;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.stubs.PyNamedParameterStub;
|
||||
@@ -206,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 = StructuredDocString.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,7 +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.StructuredDocString;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.references.PyQualifiedReference;
|
||||
import com.jetbrains.python.psi.impl.references.PyTargetReference;
|
||||
@@ -247,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 = StructuredDocString.parse(docString);
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(docString);
|
||||
if (structuredDocString != null) {
|
||||
String typeName = structuredDocString.getParamType(null);
|
||||
if (typeName == null) {
|
||||
@@ -265,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 = StructuredDocString.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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class Pep8ExternalAnnotator extends ExternalAnnotator<Pep8ExternalAnnotator.State, Pep8ExternalAnnotator.State> {
|
||||
public class Pep8ExternalAnnotator extends ExternalAnnotator<Pep8ExternalAnnotator.State, Pep8ExternalAnnotator.Results> {
|
||||
private static final Logger LOG = Logger.getInstance(Pep8ExternalAnnotator.class);
|
||||
|
||||
public static class Problem {
|
||||
@@ -76,7 +76,6 @@ public class Pep8ExternalAnnotator extends ExternalAnnotator<Pep8ExternalAnnotat
|
||||
private final HighlightDisplayLevel level;
|
||||
private final List<String> ignoredErrors;
|
||||
private final int margin;
|
||||
public final List<Problem> problems = new ArrayList<Problem>();
|
||||
|
||||
public State(String interpreterPath, String fileText, HighlightDisplayLevel level,
|
||||
List<String> ignoredErrors, int margin) {
|
||||
@@ -88,6 +87,15 @@ public class Pep8ExternalAnnotator extends ExternalAnnotator<Pep8ExternalAnnotat
|
||||
}
|
||||
}
|
||||
|
||||
public static class Results {
|
||||
public final List<Problem> problems = new ArrayList<Problem>();
|
||||
private final HighlightDisplayLevel level;
|
||||
|
||||
public Results(HighlightDisplayLevel level) {
|
||||
this.level = level;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean myReportedMissingInterpreter;
|
||||
|
||||
@Nullable
|
||||
@@ -136,7 +144,7 @@ public class Pep8ExternalAnnotator extends ExternalAnnotator<Pep8ExternalAnnotat
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public State doAnnotate(State collectedInfo) {
|
||||
public Results doAnnotate(State collectedInfo) {
|
||||
if (collectedInfo == null) return null;
|
||||
final String pep8Path = PythonHelpersLocator.getHelperPath("pep8.py");
|
||||
ArrayList<String> options = new ArrayList<String>();
|
||||
@@ -151,23 +159,29 @@ public class Pep8ExternalAnnotator extends ExternalAnnotator<Pep8ExternalAnnotat
|
||||
null,
|
||||
5000,
|
||||
collectedInfo.fileText.getBytes());
|
||||
|
||||
Results results = new Results(collectedInfo.level);
|
||||
if (output.getStderrLines().isEmpty()) {
|
||||
for (String line : output.getStdoutLines()) {
|
||||
final Problem problem = parseProblem(line);
|
||||
if (problem != null) {
|
||||
collectedInfo.problems.add(problem);
|
||||
results.problems.add(problem);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (((ApplicationInfoImpl) ApplicationInfo.getInstance()).isEAP()) {
|
||||
LOG.info("Error running pep8.py: " + output.getStderr());
|
||||
}
|
||||
return collectedInfo;
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(@NotNull PsiFile file, State annotationResult, @NotNull AnnotationHolder holder) {
|
||||
if (annotationResult == null || !file.isValid()) return;
|
||||
public void apply(@NotNull PsiFile file, Results annotationResult, @NotNull AnnotationHolder holder) {
|
||||
if (annotationResult == null) return;
|
||||
if (!file.isValid()) {
|
||||
LOG.info("Trying to apply diagnostics to invalid PsiFile, skipped");
|
||||
return;
|
||||
}
|
||||
final String text = file.getText();
|
||||
Project project = file.getProject();
|
||||
final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
@@ -260,6 +274,9 @@ public class Pep8ExternalAnnotator extends ExternalAnnotator<Pep8ExternalAnnotat
|
||||
int column = Integer.parseInt(m.group(2));
|
||||
return new Problem(line, column, m.group(3), m.group(4));
|
||||
}
|
||||
if (((ApplicationInfoImpl) ApplicationInfo.getInstance()).isEAP()) {
|
||||
LOG.info("Failed to parse problem line from pep8.py: " + s);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.jetbrains.python;
|
||||
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.jetbrains.python.documentation.EpydocString;
|
||||
import com.jetbrains.python.documentation.Substring;
|
||||
import com.jetbrains.python.toolbox.Substring;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user