mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-9795, PY-4717 References in section-based docstrings
This commit is contained in:
@@ -41,13 +41,15 @@ import java.util.Set;
|
||||
* @author yole
|
||||
*/
|
||||
public class DocStringParameterReference extends PsiReferenceBase<PyStringLiteralExpression> implements PsiReferenceEx {
|
||||
private final TagBasedDocString.ReferenceType myType;
|
||||
private final ReferenceType myType;
|
||||
|
||||
public DocStringParameterReference(PyStringLiteralExpression element, TextRange range, TagBasedDocString.ReferenceType refType) {
|
||||
public DocStringParameterReference(PyStringLiteralExpression element, TextRange range, ReferenceType refType) {
|
||||
super(element, range);
|
||||
myType = refType;
|
||||
}
|
||||
|
||||
public enum ReferenceType {PARAMETER, PARAMETER_TYPE, KEYWORD, VARIABLE, CLASS_VARIABLE, INSTANCE_VARIABLE}
|
||||
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
PyDocStringOwner owner = PsiTreeUtil.getParentOfType(getElement(), PyDocStringOwner.class);
|
||||
@@ -58,20 +60,20 @@ public class DocStringParameterReference extends PsiReferenceBase<PyStringLitera
|
||||
final PyFunction init = ((PyClass)owner).findMethodByName(PyNames.INIT, false);
|
||||
if (init != null) {
|
||||
PsiElement element = resolveParameter(init);
|
||||
if (element == null && (myType.equals(TagBasedDocString.ReferenceType.CLASS_VARIABLE) ||
|
||||
myType.equals(TagBasedDocString.ReferenceType.PARAMETER_TYPE)))
|
||||
if (element == null && (myType.equals(ReferenceType.CLASS_VARIABLE) ||
|
||||
myType.equals(ReferenceType.PARAMETER_TYPE)))
|
||||
element = resolveClassVariable((PyClass)owner);
|
||||
if (element == null && (myType.equals(TagBasedDocString.ReferenceType.INSTANCE_VARIABLE) ||
|
||||
myType.equals(TagBasedDocString.ReferenceType.PARAMETER_TYPE)))
|
||||
if (element == null && (myType.equals(ReferenceType.INSTANCE_VARIABLE) ||
|
||||
myType.equals(ReferenceType.PARAMETER_TYPE)))
|
||||
element = resolveInstanceVariable((PyClass)owner);
|
||||
return element;
|
||||
}
|
||||
else {
|
||||
if (myType.equals(TagBasedDocString.ReferenceType.CLASS_VARIABLE) ||
|
||||
myType.equals(TagBasedDocString.ReferenceType.PARAMETER_TYPE))
|
||||
if (myType.equals(ReferenceType.CLASS_VARIABLE) ||
|
||||
myType.equals(ReferenceType.PARAMETER_TYPE))
|
||||
return resolveClassVariable((PyClass)owner);
|
||||
if (myType.equals(TagBasedDocString.ReferenceType.INSTANCE_VARIABLE) ||
|
||||
myType.equals(TagBasedDocString.ReferenceType.PARAMETER_TYPE))
|
||||
if (myType.equals(ReferenceType.INSTANCE_VARIABLE) ||
|
||||
myType.equals(ReferenceType.PARAMETER_TYPE))
|
||||
return resolveInstanceVariable((PyClass)owner);
|
||||
}
|
||||
}
|
||||
@@ -141,8 +143,8 @@ public class DocStringParameterReference extends PsiReferenceBase<PyStringLitera
|
||||
}
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
|
||||
public TagBasedDocString.ReferenceType getType() {
|
||||
|
||||
public ReferenceType getType() {
|
||||
return myType;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import com.intellij.psi.PsiReferenceProvider;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.documentation.DocStringParameterReference.ReferenceType;
|
||||
import com.jetbrains.python.documentation.SectionBasedDocString.SectionField;
|
||||
import com.jetbrains.python.psi.PyDocStringOwner;
|
||||
import com.jetbrains.python.psi.PyImportElement;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
@@ -62,24 +64,31 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
|
||||
final TagBasedDocString taggedDocString = (TagBasedDocString)docString;
|
||||
result.addAll(referencesFromNames(expr, offset, docString,
|
||||
taggedDocString.getTagArguments(TagBasedDocString.PARAM_TAGS),
|
||||
TagBasedDocString.ReferenceType.PARAMETER));
|
||||
ReferenceType.PARAMETER));
|
||||
result.addAll(referencesFromNames(expr, offset, docString,
|
||||
taggedDocString.getTagArguments(TagBasedDocString.PARAM_TYPE_TAGS),
|
||||
TagBasedDocString.ReferenceType.PARAMETER_TYPE));
|
||||
ReferenceType.PARAMETER_TYPE));
|
||||
result.addAll(referencesFromNames(expr, offset, docString,
|
||||
docString.getKeywordArgumentSubstrings(), TagBasedDocString.ReferenceType.KEYWORD));
|
||||
docString.getKeywordArgumentSubstrings(), ReferenceType.KEYWORD));
|
||||
|
||||
result.addAll(referencesFromNames(expr, offset, docString,
|
||||
taggedDocString.getTagArguments("var"),
|
||||
TagBasedDocString.ReferenceType.VARIABLE));
|
||||
ReferenceType.VARIABLE));
|
||||
result.addAll(referencesFromNames(expr, offset, docString,
|
||||
taggedDocString.getTagArguments("cvar"),
|
||||
TagBasedDocString.ReferenceType.CLASS_VARIABLE));
|
||||
ReferenceType.CLASS_VARIABLE));
|
||||
result.addAll(referencesFromNames(expr, offset, docString,
|
||||
taggedDocString.getTagArguments("ivar"),
|
||||
TagBasedDocString.ReferenceType.INSTANCE_VARIABLE));
|
||||
ReferenceType.INSTANCE_VARIABLE));
|
||||
result.addAll(returnTypes(element, docString, offset));
|
||||
}
|
||||
else if (docString instanceof SectionBasedDocString) {
|
||||
final SectionBasedDocString sectioned = (SectionBasedDocString)docString;
|
||||
result.addAll(referencesFromFields(expr, offset, sectioned.getParameterFields(), ReferenceType.PARAMETER));
|
||||
result.addAll(referencesFromFields(expr, offset, sectioned.getKeywordArgumentFields(), ReferenceType.KEYWORD));
|
||||
result.addAll(referencesFromFields(expr, offset, sectioned.getAttributeFields(), ReferenceType.INSTANCE_VARIABLE));
|
||||
result.addAll(referencesFromFields(expr, offset, sectioned.getReturnFields(), null));
|
||||
}
|
||||
return result.toArray(new PsiReference[result.size()]);
|
||||
}
|
||||
}
|
||||
@@ -97,11 +106,11 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private static List<PsiReference> referencesFromNames(PyStringLiteralExpression element,
|
||||
private static List<PsiReference> referencesFromNames(@NotNull PyStringLiteralExpression element,
|
||||
int offset,
|
||||
StructuredDocString docString,
|
||||
List<Substring> paramNames,
|
||||
TagBasedDocString.ReferenceType refType) {
|
||||
@NotNull StructuredDocString docString,
|
||||
@NotNull List<Substring> paramNames,
|
||||
@NotNull ReferenceType refType) {
|
||||
List<PsiReference> result = new ArrayList<PsiReference>();
|
||||
for (Substring name : paramNames) {
|
||||
final String s = name.toString();
|
||||
@@ -109,7 +118,7 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
|
||||
final TextRange range = name.getTextRange().shiftRight(offset);
|
||||
result.add(new DocStringParameterReference(element, range, refType));
|
||||
}
|
||||
if (refType.equals(TagBasedDocString.ReferenceType.PARAMETER_TYPE)) {
|
||||
if (refType.equals(ReferenceType.PARAMETER_TYPE)) {
|
||||
final Substring type = docString.getParamTypeSubstring(s);
|
||||
if (type != null) {
|
||||
result.addAll(parseTypeReferences(element, type, offset));
|
||||
@@ -119,7 +128,28 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<PsiReference> parseTypeReferences(PsiElement anchor, Substring s, int offset) {
|
||||
@NotNull
|
||||
private static List<PsiReference> referencesFromFields(@NotNull PyStringLiteralExpression element,
|
||||
int offset,
|
||||
@NotNull List<SectionField> fields,
|
||||
@Nullable ReferenceType nameRefType) {
|
||||
final List<PsiReference> result = new ArrayList<PsiReference>();
|
||||
for (SectionField field : fields) {
|
||||
final Substring nameSub = field.getNameAsSubstring();
|
||||
if (nameRefType != null && nameSub != null && !nameSub.isEmpty()) {
|
||||
final TextRange range = nameSub.getTextRange().shiftRight(offset);
|
||||
result.add(new DocStringParameterReference(element, range, nameRefType));
|
||||
}
|
||||
final Substring typeSub = field.getTypeAsSubstring();
|
||||
if (typeSub != null && !typeSub.isEmpty()) {
|
||||
result.addAll(parseTypeReferences(element, typeSub, offset));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PsiReference> parseTypeReferences(@NotNull PsiElement anchor, @NotNull Substring s, int offset) {
|
||||
final List<PsiReference> result = new ArrayList<PsiReference>();
|
||||
final PyTypeParser.ParseResult parseResult = PyTypeParser.parse(anchor, s.toString());
|
||||
final Map<TextRange, ? extends PyType> types = parseResult.getTypes();
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.jetbrains.python.documentation;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
@@ -29,7 +28,6 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
@@ -80,7 +78,7 @@ public class DocStringUtil {
|
||||
|
||||
@NotNull
|
||||
public static StructuredDocString parseDocString(@NotNull DocStringFormat format, @NotNull ASTNode node) {
|
||||
Preconditions.checkArgument(node.getElementType() == PyTokenTypes.DOCSTRING);
|
||||
//Preconditions.checkArgument(node.getElementType() == PyTokenTypes.DOCSTRING);
|
||||
return parseDocString(format, node.getText());
|
||||
}
|
||||
|
||||
|
||||
@@ -400,14 +400,10 @@ public abstract class SectionBasedDocString extends DocStringLineParser implemen
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<SectionField> getParameterFields() {
|
||||
public List<SectionField> getParameterFields() {
|
||||
final List<SectionField> result = new ArrayList<SectionField>();
|
||||
for (Section section : mySections) {
|
||||
if (section.getNormalizedTitle().equals(PARAMETERS_SECTION)) {
|
||||
for (SectionField field : section.getFields()) {
|
||||
result.add(field);
|
||||
}
|
||||
}
|
||||
for (Section section : getSectionsWithNormalizedTitle(PARAMETERS_SECTION)) {
|
||||
result.addAll(section.getFields());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -445,14 +441,10 @@ public abstract class SectionBasedDocString extends DocStringLineParser implemen
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<SectionField> getKeywordArgumentFields() {
|
||||
public List<SectionField> getKeywordArgumentFields() {
|
||||
final List<SectionField> result = new ArrayList<SectionField>();
|
||||
for (Section section : mySections) {
|
||||
if (section.getNormalizedTitle().equals(KEYWORD_ARGUMENTS_SECTION)) {
|
||||
for (SectionField field : section.getFields()) {
|
||||
result.add(field);
|
||||
}
|
||||
}
|
||||
for (Section section : getSectionsWithNormalizedTitle(KEYWORD_ARGUMENTS_SECTION)) {
|
||||
result.addAll(section.getFields());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -488,14 +480,19 @@ public abstract class SectionBasedDocString extends DocStringLineParser implemen
|
||||
return field != null ? field.getDescription() : null;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public List<SectionField> getReturnFields() {
|
||||
final List<SectionField> result = new ArrayList<SectionField>();
|
||||
for (Section section : getSectionsWithNormalizedTitle(RETURNS_SECTION)) {
|
||||
result.addAll(section.getFields());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SectionField getFirstReturnField() {
|
||||
for (Section section : mySections) {
|
||||
if (section.getNormalizedTitle().equals(RETURNS_SECTION) && !section.getFields().isEmpty()) {
|
||||
return section.getFields().get(0);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return ContainerUtil.getFirstItem(getReturnFields());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -521,12 +518,10 @@ public abstract class SectionBasedDocString extends DocStringLineParser implemen
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<SectionField> getExceptionFields() {
|
||||
public List<SectionField> getExceptionFields() {
|
||||
final List<SectionField> result = new ArrayList<SectionField>();
|
||||
for (Section section : mySections) {
|
||||
if (section.getNormalizedTitle().equals(RAISES_SECTION)) {
|
||||
result.addAll(section.getFields());
|
||||
}
|
||||
for (Section section : getSectionsWithNormalizedTitle(RAISES_SECTION)) {
|
||||
result.addAll(section.getFields());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -541,6 +536,25 @@ public abstract class SectionBasedDocString extends DocStringLineParser implemen
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<SectionField> getAttributeFields() {
|
||||
final List<SectionField> result = new ArrayList<SectionField>();
|
||||
for (Section section : getSectionsWithNormalizedTitle(ATTRIBUTES_SECTION)) {
|
||||
result.addAll(section.getFields());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<Section> getSectionsWithNormalizedTitle(@NotNull final String title) {
|
||||
return ContainerUtil.mapNotNull(mySections, new Function<Section, Section>() {
|
||||
@Override
|
||||
public Section fun(Section section) {
|
||||
return section.getNormalizedTitle().equals(title) ? section : null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getAttributeDescription() {
|
||||
|
||||
@@ -52,8 +52,6 @@ public abstract class TagBasedDocString extends DocStringLineParser implements S
|
||||
@NotNull
|
||||
private final String myTagPrefix;
|
||||
|
||||
public enum ReferenceType {PARAMETER, PARAMETER_TYPE, KEYWORD, VARIABLE, CLASS_VARIABLE, INSTANCE_VARIABLE}
|
||||
|
||||
public static String TYPE = "type";
|
||||
|
||||
protected TagBasedDocString(@NotNull Substring docStringText, @NotNull String tagPrefix) {
|
||||
|
||||
Reference in New Issue
Block a user