mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-29717 Add proper links on methods
This commit is contained in:
@@ -425,7 +425,7 @@ public class PyDocumentationBuilder {
|
||||
: null;
|
||||
if (ancestorLink != null) {
|
||||
final ChainIterable<String> link = mySectionsMap.get(PyBundle.message("QDOC.documentation.is.copied.from"));
|
||||
link.addWith(TagCode, isFromClass ? $(ancestorLink) : $(ancestorLink).addItem("." + methodName));
|
||||
link.addWith(TagCode, isFromClass ? $(ancestorLink) : $(PyDocumentationLink.toFunction(inherited)));
|
||||
}
|
||||
myContent.add(formatDocString(pyFunction, inheritedDoc));
|
||||
return;
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.jetbrains.python.documentation
|
||||
import com.intellij.codeInsight.documentation.DocumentationManagerProtocol
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.util.QualifiedName
|
||||
import com.jetbrains.python.psi.PyClass
|
||||
import com.jetbrains.python.psi.PyFunction
|
||||
import com.jetbrains.python.psi.PyNamedParameter
|
||||
import com.jetbrains.python.psi.PyPsiFacade
|
||||
import com.jetbrains.python.psi.types.PyClassType
|
||||
import com.jetbrains.python.psi.types.PyTypeParser
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext
|
||||
@@ -30,6 +32,7 @@ object PyDocumentationLink {
|
||||
private const val LINK_TYPE_CLASS = "#class#"
|
||||
private const val LINK_TYPE_PARAM = "#param#"
|
||||
private const val LINK_TYPE_TYPENAME = "#typename#"
|
||||
private const val LINK_TYPE_FUNC = "#func#"
|
||||
|
||||
@JvmStatic
|
||||
fun toContainingClass(content: String?): String {
|
||||
@@ -57,20 +60,46 @@ object PyDocumentationLink {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun toFunction(func: PyFunction): String = toFunction(func.qualifiedName ?: func.name.orEmpty(), func)
|
||||
|
||||
@JvmStatic
|
||||
fun toFunction(content: String, func: PyFunction): String {
|
||||
val qualifiedName = func.qualifiedName
|
||||
return when {
|
||||
qualifiedName != null -> "<a href=\"${DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL}$LINK_TYPE_FUNC$qualifiedName\">$content</a>"
|
||||
else -> content
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun elementForLink(link: String, element: PsiElement, context: TypeEvalContext): PsiElement? {
|
||||
return if (link == LINK_TYPE_CLASS) {
|
||||
containingClass(element)
|
||||
return when {
|
||||
link == LINK_TYPE_CLASS -> containingClass(element)
|
||||
link == LINK_TYPE_PARAM -> parameterPossibleClass(element, context)
|
||||
link.startsWith(LINK_TYPE_TYPENAME) -> possibleClass(link.substring(LINK_TYPE_TYPENAME.length), element, context)
|
||||
link.startsWith(LINK_TYPE_FUNC) -> possibleFunction(link.substring(LINK_TYPE_FUNC.length), element)
|
||||
else -> null
|
||||
}
|
||||
else if (link == LINK_TYPE_PARAM) {
|
||||
parameterPossibleClass(element, context)
|
||||
}
|
||||
else if (link.startsWith(LINK_TYPE_TYPENAME)) {
|
||||
possibleClass(link.substring(LINK_TYPE_TYPENAME.length), element, context)
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun possibleFunction(qualifiedName: String, element: PsiElement): PyFunction? {
|
||||
// TODO a better, more general way to resolve qualified names of function
|
||||
val facade = PyPsiFacade.getInstance(element.project)
|
||||
val qName = QualifiedName.fromDottedString(qualifiedName)
|
||||
|
||||
val resolveContext = facade.createResolveContextFromFoothold(element).copyWithMembers()
|
||||
val topLevel = facade.resolveQualifiedName(qName, resolveContext).filterIsInstance<PyFunction>().firstOrNull()
|
||||
if (topLevel != null) {
|
||||
return topLevel
|
||||
}
|
||||
|
||||
return facade.resolveQualifiedName(qName.removeLastComponent(), resolveContext)
|
||||
.asSequence()
|
||||
.filterIsInstance<PyClass>()
|
||||
.map { it.findMethodByName(qName.lastComponent, false, null) }
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -1 +1 @@
|
||||
<html><body><div class='definition'><pre><small>class <a href="psi_element://#class#">Foo</a>(<a href="psi_element://#typename#ClassUndocumentedEmptyConstructor.Moo">Moo</a>)</small><br><br>def <b>__init__</b>(self: <a href="psi_element://#typename#Foo">Foo</a>) -> None</pre></div><div class='content'>Doc of 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://#typename#ClassUndocumentedEmptyConstructor.Moo">Moo</a>.__init__</code></td></table></body></html>
|
||||
<html><body><div class='definition'><pre><small>class <a href="psi_element://#class#">Foo</a>(<a href="psi_element://#typename#ClassUndocumentedEmptyConstructor.Moo">Moo</a>)</small><br><br>def <b>__init__</b>(self: <a href="psi_element://#typename#Foo">Foo</a>) -> None</pre></div><div class='content'>Doc of 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>
|
||||
@@ -1 +1 @@
|
||||
<html><body><div class='definition'><pre><small>class <a href="psi_element://#class#">B</a>(<a href="psi_element://#typename#InheritedMethod.A">A</a>)</small><br><br>def <b>foo</b>(self: <a href="psi_element://#typename#B">B</a>) -> None</pre></div><div class='content'>Doc from 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://#typename#InheritedMethod.A">A</a>.foo</code></td></table></body></html>
|
||||
<html><body><div class='definition'><pre><small>class <a href="psi_element://#class#">B</a>(<a href="psi_element://#typename#InheritedMethod.A">A</a>)</small><br><br>def <b>foo</b>(self: <a href="psi_element://#typename#B">B</a>) -> None</pre></div><div class='content'>Doc from 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>
|
||||
Reference in New Issue
Block a user