mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 15:09:39 +07:00
PY-29717 Display information about property access type in sections
This commit is contained in:
@@ -77,7 +77,7 @@ public class PyDocumentationBuilder {
|
||||
|
||||
private static final Pattern ourSpacesPattern = Pattern.compile("^\\s+");
|
||||
|
||||
public PyDocumentationBuilder(PsiElement element, PsiElement originalElement) {
|
||||
public PyDocumentationBuilder(@NotNull PsiElement element, @Nullable PsiElement originalElement) {
|
||||
myElement = element;
|
||||
myOriginalElement = originalElement;
|
||||
myProlog = new ChainIterable<>();
|
||||
@@ -142,12 +142,17 @@ public class PyDocumentationBuilder {
|
||||
return null; // got nothing substantial to say!
|
||||
}
|
||||
else {
|
||||
ChainIterable<String> result = new ChainIterable<>();
|
||||
final ChainIterable<String> result = new ChainIterable<>();
|
||||
if (!myProlog.isEmpty() || !myBody.isEmpty()) {
|
||||
result.addItem(DocumentationMarkup.DEFINITION_START)
|
||||
.add(myProlog)
|
||||
.add(myBody)
|
||||
.addItem(DocumentationMarkup.DEFINITION_END);
|
||||
.add(myProlog);
|
||||
|
||||
if (!myBody.isEmpty() && !myProlog.isEmpty()) {
|
||||
result.addItem(BR);
|
||||
}
|
||||
|
||||
result.add(myBody)
|
||||
.addItem(DocumentationMarkup.DEFINITION_END);
|
||||
}
|
||||
if (!myContent.isEmpty()) {
|
||||
result.addItem(DocumentationMarkup.CONTENT_START)
|
||||
@@ -188,8 +193,7 @@ public class PyDocumentationBuilder {
|
||||
.addWith(TagBold, $().addWith(TagCode, $(parameter.getName())))
|
||||
.addItem(" of ")
|
||||
// TODO links to functions
|
||||
.addWith(TagCode, $(funcName))
|
||||
.addItem(BR);
|
||||
.addWith(TagCode, $(funcName));
|
||||
|
||||
if (func != null) {
|
||||
final PyStringLiteralExpression docString = getEffectiveDocStringExpression(func);
|
||||
@@ -251,16 +255,10 @@ public class PyDocumentationBuilder {
|
||||
}
|
||||
if (accessor.isDefined() && accessor.value() == null) elementDefinition = null;
|
||||
final String accessorKind = getAccessorKind(direction);
|
||||
if (elementDefinition != null) {
|
||||
myEpilog.addWith(TagSmall, $(BR, BR, accessorKind, " of property")).addItem(BR);
|
||||
}
|
||||
mySectionsMap.get(PyBundle.message("QDOC.accessor.kind"))
|
||||
.addItem(accessorKind)
|
||||
.addItem(elementDefinition == null ? " (not defined)" : "");
|
||||
|
||||
if (!(elementDefinition instanceof PyDocStringOwner)) {
|
||||
myBody.addWith(TagItalic, elementDefinition != null ? $("Declaration: ") : $(accessorKind + " is not defined.")).addItem(BR);
|
||||
if (elementDefinition != null) {
|
||||
myBody.addItem(combUp(PyUtil.getReadableRepr(elementDefinition, false)));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -323,8 +321,7 @@ public class PyDocumentationBuilder {
|
||||
.addItem(type)
|
||||
.addWith(TagBold, $().addWith(TagCode, $(elementDefinition.getName())))
|
||||
.addItem(" of class ")
|
||||
.addItem(PyDocumentationLink.toContainingClass(WRAP_IN_CODE.apply(target.getContainingClass().getName())))
|
||||
.addItem(BR);
|
||||
.addItem(PyDocumentationLink.toContainingClass(WRAP_IN_CODE.apply(target.getContainingClass().getName())));
|
||||
}
|
||||
myBody.add(PythonDocumentationProvider.describeTarget(target, context));
|
||||
}
|
||||
|
||||
@@ -433,9 +433,8 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
|
||||
// provides ctrl+Q doc
|
||||
@Override
|
||||
public String generateDoc(@Nullable PsiElement element, @Nullable PsiElement originalElement) {
|
||||
if (element != null && PydevConsoleRunner.isInPydevConsole(element) ||
|
||||
originalElement != null && PydevConsoleRunner.isInPydevConsole(originalElement)) {
|
||||
public String generateDoc(@NotNull PsiElement element, @Nullable PsiElement originalElement) {
|
||||
if (PydevConsoleRunner.isInPydevConsole(element) || originalElement != null && PydevConsoleRunner.isInPydevConsole(originalElement)) {
|
||||
return PydevDocumentationProvider.createDoc(element, originalElement);
|
||||
}
|
||||
return new PyDocumentationBuilder(element, originalElement).build();
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
<html><body><div class='definition'><pre>property <b><code>m</code></b> of class <a href="psi_element://#class#">C</a><br><i>Copied from getter:</i><br>
|
||||
Foo
|
||||
<br><br>@<i>m.setter</i><br>def <b>m</b>(self: <a href="psi_element://#typename#C">C</a>, x: Any) -> None</pre></div><small><br><br>Setter of property</small><br></body></html>
|
||||
<html><body><div class='definition'><pre>property <b><code>m</code></b> of class <a href="psi_element://#class#">C</a><br>@<i>m.setter</i><br>def <b>m</b>(self: <a href="psi_element://#typename#C">C</a>, x: Any) -> None</pre></div><div class='content'><br>Foo<br></div><table class='sections'><tr><td valign='top' class='section'><p>Documentation is copied from:</td><td valign='top'>property getter</td><tr><td valign='top' class='section'><p>Accessor kind:</td><td valign='top'>Setter</td></table></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br><i>Copied from getter:</i><br>Does things to X<br><br>@<i>x.deleter</i><br>def <b>x</b>(self: <a href="psi_element://#typename#A">A</a>, v: Any) -> None</pre></div><div class='content'>Deletes X</div><small><br><br>Deleter of property</small><br></body></html>
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br>@<i>x.deleter</i><br>def <b>x</b>(self: <a href="psi_element://#typename#A">A</a>, v: Any) -> None</pre></div><div class='content'>Does things to XDeletes X</div><table class='sections'><tr><td valign='top' class='section'><p>Accessor kind:</td><td valign='top'>Deleter</td><tr><td valign='top' class='section'><p>Documentation is copied from:</td><td valign='top'>property getter</td></table></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br><br>@<i>property</i><br>def <b>x</b>(self: <a href="psi_element://#typename#A">A</a>) -> <a href="psi_element://#typename#int">int</a></pre></div><div class='content'>Does things to X</div><small><br><br>Getter of property</small><br></body></html>
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br>@<i>property</i><br>def <b>x</b>(self: <a href="psi_element://#typename#A">A</a>) -> <a href="psi_element://#typename#int">int</a></pre></div><div class='content'>Does things to X</div><table class='sections'><tr><td valign='top' class='section'><p>Accessor kind:</td><td valign='top'>Getter</td></table></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br><i>Copied from getter:</i><br>Does things to X<br><br>@<i>x.setter</i><br>def <b>x</b>(self: <a href="psi_element://#typename#A">A</a>, v: Any) -> None</pre></div><div class='content'>Sets X</div><small><br><br>Setter of property</small><br></body></html>
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br>@<i>x.setter</i><br>def <b>x</b>(self: <a href="psi_element://#typename#A">A</a>, v: Any) -> None</pre></div><div class='content'>Does things to XSets X</div><table class='sections'><tr><td valign='top' class='section'><p>Accessor kind:</td><td valign='top'>Setter</td><tr><td valign='top' class='section'><p>Documentation is copied from:</td><td valign='top'>property getter</td></table></body></html>
|
||||
8
python/testData/quickdoc/PropNewUndefinedSetter.py
Normal file
8
python/testData/quickdoc/PropNewUndefinedSetter.py
Normal file
@@ -0,0 +1,8 @@
|
||||
class C(object):
|
||||
@property
|
||||
def attr(self):
|
||||
"""Docstring."""
|
||||
return 42
|
||||
|
||||
|
||||
C().at<the_ref>tr = 42
|
||||
@@ -1 +1 @@
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br><br>def <b>__getX</b>(self: <a href="psi_element://#typename#A">A</a>) -> Any</pre></div><div class='content'>Doc of getter</div><small><br><br>Deleter of property</small><br></body></html>
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br>def <b>__getX</b>(self: <a href="psi_element://#typename#A">A</a>) -> Any</pre></div><div class='content'>Doc of getter</div><table class='sections'><tr><td valign='top' class='section'><p>Accessor kind:</td><td valign='top'>Deleter</td></table></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br><br>def <b>__getX</b>(self: <a href="psi_element://#typename#A">A</a>) -> Any</pre></div><div class='content'>Doc of getter</div><small><br><br>Getter of property</small><br></body></html>
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br>def <b>__getX</b>(self: <a href="psi_element://#typename#A">A</a>) -> Any</pre></div><div class='content'>Doc of getter</div><table class='sections'><tr><td valign='top' class='section'><p>Accessor kind:</td><td valign='top'>Getter</td></table></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br><br>def <b>__getX</b>(self: <a href="psi_element://#typename#A">A</a>, x: Any) -> None</pre></div><div class='content'>Doc of getter</div><small><br><br>Setter of property</small><br></body></html>
|
||||
<html><body><div class='definition'><pre>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#typename#object">object</a>)<br>def <b>__getX</b>(self: <a href="psi_element://#typename#A">A</a>, x: Any) -> None</pre></div><div class='content'>Doc of getter</div><table class='sections'><tr><td valign='top' class='section'><p>Accessor kind:</td><td valign='top'>Setter</td></table></body></html>
|
||||
8
python/testData/quickdoc/PropOldUndefinedSetter.py
Normal file
8
python/testData/quickdoc/PropOldUndefinedSetter.py
Normal file
@@ -0,0 +1,8 @@
|
||||
class C(object):
|
||||
def _get(self):
|
||||
"""Docstring."""
|
||||
return 42
|
||||
|
||||
attr = property(fget=_get)
|
||||
|
||||
C().at<the_ref>tr = 42
|
||||
1
python/testData/quickdoc/PropUndefinedSetter.html
Normal file
1
python/testData/quickdoc/PropUndefinedSetter.html
Normal file
@@ -0,0 +1 @@
|
||||
<html><body><div class='definition'><pre>property <b><code>attr</code></b> of class <a href="psi_element://#class#">C</a>(<a href="psi_element://#typename#object">object</a>)<br>attr: <a href="psi_element://#typename#int">int</a></pre></div><div class='content'>Docstring.</div><table class='sections'><tr><td valign='top' class='section'><p>Documentation is copied from:</td><td valign='top'>property getter</td><tr><td valign='top' class='section'><p>Accessor kind:</td><td valign='top'>Setter (not defined)</td></table></body></html>
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtil;
|
||||
import com.intellij.codeInsight.documentation.DocumentationManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.documentation.PyDocumentationSettings;
|
||||
import com.jetbrains.python.documentation.PythonDocumentationProvider;
|
||||
@@ -62,12 +64,14 @@ public class PyQuickDocTest extends LightMarkedTestCase {
|
||||
}
|
||||
|
||||
private void checkHTMLOnly() {
|
||||
Map<String, PsiElement> marks = loadTest();
|
||||
final Map<String, PsiElement> marks = loadTest();
|
||||
final PsiElement originalElement = marks.get("<the_ref>");
|
||||
PsiElement referenceElement = originalElement.getParent(); // ident -> expr
|
||||
assertInstanceOf(referenceElement, PyReferenceOwner.class);
|
||||
final PsiElement docOwner = referenceElement.getReference().resolve();
|
||||
checkByHTML(myProvider.generateDoc(docOwner, originalElement));
|
||||
final DocumentationManager manager = DocumentationManager.getInstance(myFixture.getProject());
|
||||
final PsiElement target = manager.findTargetElement(myFixture.getEditor(),
|
||||
originalElement.getTextOffset(),
|
||||
myFixture.getFile(),
|
||||
originalElement);
|
||||
checkByHTML(myProvider.generateDoc(target, originalElement));
|
||||
}
|
||||
|
||||
private void checkHover() {
|
||||
@@ -183,6 +187,14 @@ public class PyQuickDocTest extends LightMarkedTestCase {
|
||||
checkHTMLOnly();
|
||||
}
|
||||
|
||||
public void testPropNewUndefinedSetter() {
|
||||
checkHTMLOnly();
|
||||
}
|
||||
|
||||
public void testPropOldUndefinedSetter() {
|
||||
checkHTMLOnly();
|
||||
}
|
||||
|
||||
public void testParam() {
|
||||
checkHTMLOnly();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user