PY-29717 Add links to the containing function in the header for parameters

Also, display shorter function names in "Documentation is copied from"
section of the table.
This commit is contained in:
Mikhail Golubev
2018-06-09 15:59:38 +03:00
parent 17c690d0ab
commit 67ebed5232
4 changed files with 30 additions and 26 deletions
@@ -190,13 +190,14 @@ public class PyDocumentationBuilder {
private void buildFromParameter(@NotNull PyNamedParameter parameter) {
final PyFunction func = PsiTreeUtil.getParentOfType(parameter, PyFunction.class, true, PyLambdaExpression.class);
final String funcName = func == null ? PyNames.UNNAMED_ELEMENT : func.getName();
myProlog
.addItem("Parameter ")
.addWith(TagBold, $().addWith(TagCode, $(parameter.getName())))
.addItem(" of ")
// TODO links to functions
.addWith(TagCode, $(funcName));
final String link = func != null ? getLinkToFunction(func, true) : PyNames.UNNAMED_ELEMENT;
if (link != null) {
myProlog
.addItem("Parameter ")
.addWith(TagBold, $(parameter.getName()))
.addItem(" of ")
.addItem(link);
}
if (func != null) {
final PyStringLiteralExpression docString = getEffectiveDocStringExpression(func);
@@ -420,22 +421,7 @@ public class PyDocumentationBuilder {
if (docstringElement != null) {
final String inheritedDoc = docstringElement.getStringValue();
if (inheritedDoc.length() > 1) {
final String ancestorName = ancestor.getName();
final String ancestorLink;
if (!isFromClass) {
final String qualified = inherited.getQualifiedName();
if (qualified != null) {
ancestorLink = PyDocumentationLink.toFunction(inherited);
}
else {
// TODO add a way to reference such local methods
ancestorLink = ancestorName + "." + inherited.getName();
}
}
else {
ancestorLink = getLinkToClass(ancestor, false);
}
final String ancestorLink = isFromClass ? getLinkToClass(ancestor, false) : getLinkToFunction(inherited, false);
if (ancestorLink != null) {
mySectionsMap.get(PyBundle.message("QDOC.documentation.is.copied.from")).addWith(TagCode, $(ancestorLink));
}
@@ -553,6 +539,24 @@ public class PyDocumentationBuilder {
return linkText;
}
@Nullable
private String getLinkToFunction(@NotNull PyFunction function, boolean preferQualifiedName) {
final String qualifiedName = function.getQualifiedName();
final PyClass pyClass = function.getContainingClass();
// Preserve name of a containing class even if the whole qualified name can't be constructed
final String shortName = pyClass == null ? function.getName() : pyClass.getName() + "." + function.getName();
final String linkText = preferQualifiedName && qualifiedName != null ? qualifiedName : shortName;
if (linkText == null || function.getName() == null || (pyClass != null && pyClass.getName() == null)) {
return null;
}
if (qualifiedName != null) {
return PyDocumentationLink.toFunction(linkText, function);
}
return linkText;
}
@Nullable
static PyStringLiteralExpression getEffectiveDocStringExpression(@NotNull PyDocStringOwner owner) {
final PyStringLiteralExpression expression = owner.getDocStringExpression();
@@ -1 +1 @@
<html><body><div class='definition'><pre><a href="psi_element://#typename#ClassUndocumentedEmptyConstructor.Foo">ClassUndocumentedEmptyConstructor.Foo</a><br>def&nbsp;<b>__init__</b>(self:&nbsp;<a href="psi_element://#typename#Foo">Foo</a>)&nbsp;-&gt;&nbsp;None</pre></div><div class='content'>Doc&nbsp;of&nbsp;Moo()</div><table class='sections'><tr><td valign='top' class='section'><p>Documentation is copied from:</td><td valign='top'><code><a href="psi_element://#func#ClassUndocumentedEmptyConstructor.Moo.__init__">ClassUndocumentedEmptyConstructor.Moo.__init__</a></code></td></table></body></html>
<html><body><div class='definition'><pre><a href="psi_element://#typename#ClassUndocumentedEmptyConstructor.Foo">ClassUndocumentedEmptyConstructor.Foo</a><br>def&nbsp;<b>__init__</b>(self:&nbsp;<a href="psi_element://#typename#Foo">Foo</a>)&nbsp;-&gt;&nbsp;None</pre></div><div class='content'>Doc&nbsp;of&nbsp;Moo()</div><table class='sections'><tr><td valign='top' class='section'><p>Documentation is copied from:</td><td valign='top'><code><a href="psi_element://#func#ClassUndocumentedEmptyConstructor.Moo.__init__">Moo.__init__</a></code></td></table></body></html>
@@ -1 +1 @@
<html><body><div class='definition'><pre><a href="psi_element://#typename#InheritedMethod.B">InheritedMethod.B</a><br>def&nbsp;<b>foo</b>(self:&nbsp;<a href="psi_element://#typename#B">B</a>)&nbsp;-&gt;&nbsp;None</pre></div><div class='content'>Doc&nbsp;from&nbsp;A.foo.</div><table class='sections'><tr><td valign='top' class='section'><p>Documentation is copied from:</td><td valign='top'><code><a href="psi_element://#func#InheritedMethod.A.foo">InheritedMethod.A.foo</a></code></td></table></body></html>
<html><body><div class='definition'><pre><a href="psi_element://#typename#InheritedMethod.B">InheritedMethod.B</a><br>def&nbsp;<b>foo</b>(self:&nbsp;<a href="psi_element://#typename#B">B</a>)&nbsp;-&gt;&nbsp;None</pre></div><div class='content'>Doc&nbsp;from&nbsp;A.foo.</div><table class='sections'><tr><td valign='top' class='section'><p>Documentation is copied from:</td><td valign='top'><code><a href="psi_element://#func#InheritedMethod.A.foo">A.foo</a></code></td></table></body></html>
+1 -1
View File
@@ -1 +1 @@
<html><body><div class='definition'><pre>Parameter <b><code>name</code></b> of <code>foo</code><br>name: <a href="psi_element://#typename#str">str</a></pre></div><div class='content'>The name to convert to a label. This must be a string which could be used as a Python identifier. Strings which do not take this form will result in unpredictable behavior.</div></body></html>
<html><body><div class='definition'><pre>Parameter <b>name</b> of <a href="psi_element://#func#Param.foo">Param.foo</a><br>name: <a href="psi_element://#typename#str">str</a></pre></div><div class='content'>The name to convert to a label. This must be a string which could be used as a Python identifier. Strings which do not take this form will result in unpredictable behavior.</div></body></html>