[devkit] Extension Point Docs: enumerate EP's beanClass properties (IDEA-228390)

GitOrigin-RevId: cc681134d848128abec2740aa84cb20aa5f92d40
This commit is contained in:
Yann Cébron
2020-04-24 16:46:26 +02:00
committed by intellij-monorepo-bot
parent e858a51cdb
commit 85546692bc
5 changed files with 62 additions and 28 deletions

View File

@@ -8,25 +8,19 @@ import com.intellij.lang.documentation.DocumentationMarkup;
import com.intellij.lang.documentation.DocumentationProvider;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.PomTarget;
import com.intellij.pom.PomTargetPsiElement;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.psi.*;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomTarget;
import com.intellij.util.xml.DomUtil;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.dom.ExtensionPoint;
import org.jetbrains.idea.devkit.dom.With;
import org.jetbrains.idea.devkit.util.DescriptorUtil;
import java.util.List;
public class ExtensionPointDocumentationProvider implements DocumentationProvider {
@Override
@@ -63,26 +57,51 @@ public class ExtensionPointDocumentationProvider implements DocumentationProvide
sb.append("<b>").append(extensionPoint.getEffectiveQualifiedName()).append("</b>");
sb.append("<br>").append(DomUtil.getFile(extensionPoint).getName());
if (DomUtil.hasXml(extensionPoint.getBeanClass())) {
generateClassDoc(sb, extensionPoint.getBeanClass().getValue());
final PsiClass beanClass = extensionPoint.getBeanClass().getValue();
if (beanClass != null) {
generateClassDoc(sb, beanClass);
StringBuilder bindingText = new StringBuilder();
new ExtensionPointBinding(beanClass).visit(new ExtensionPointBinding.BindingVisitor() {
@Override
public void visitAttribute(@NotNull PsiField field, @NotNull String attributeName, boolean required) {
appendFieldBindingText(field, attributeName, required);
}
List<With> withElements = extensionPoint.getWithElements();
if (!withElements.isEmpty()) {
@Override
public void visitTagOrProperty(@NotNull PsiField field, @NotNull String tagName, boolean required) {
visitAttribute(field, "&lt;" + tagName + ">", required);
}
@Override
public void visitXCollection(@NotNull PsiField field,
@Nullable String tagName,
@NotNull PsiAnnotation collectionAnnotation,
boolean required) {
visitAttribute(field, "&lt;" + tagName + ">...", required);
}
private void appendFieldBindingText(@NotNull PsiField field, @NotNull String displayName, boolean required) {
StringBuilder hyperLink = new StringBuilder();
DocumentationManagerUtil.createHyperlink(hyperLink, field,
JavaDocUtil.getReferenceText(field.getProject(), field), displayName, false);
final String typeText = field.getType().getPresentableText();
final String initializer = field.getInitializer() != null ? " = " + field.getInitializer().getText() : "";
appendSection(bindingText, hyperLink.toString(), typeText + (required ? " (required)" : "") + initializer);
}
});
if (bindingText.length() > 0) {
sb.append(DocumentationMarkup.SECTIONS_START);
for (With withElement : withElements) {
String name = StringUtil.notNullize(DomUtil.hasXml(withElement.getAttribute())
? withElement.getAttribute().getStringValue()
: "<" + withElement.getTag().getStringValue() + ">");
StringBuilder classLinkSb = new StringBuilder();
generateClassLink(classLinkSb, withElement.getImplements().getValue());
appendSection(sb, XmlUtil.escape(name), classLinkSb.toString());
}
sb.append(bindingText);
sb.append("<br/>");
sb.append(DocumentationMarkup.SECTIONS_END);
}
}
sb.append(DocumentationMarkup.DEFINITION_END);
@@ -120,7 +139,7 @@ public class ExtensionPointDocumentationProvider implements DocumentationProvide
}
private static void appendSection(StringBuilder sb, String sectionName, String sectionContent) {
sb.append(DocumentationMarkup.SECTION_HEADER_START).append(sectionName).append(":")
sb.append(DocumentationMarkup.SECTION_HEADER_START).append(sectionName)
.append(DocumentationMarkup.SECTION_SEPARATOR);
sb.append(sectionContent);
sb.append(DocumentationMarkup.SECTION_END);

View File

@@ -1,7 +1,18 @@
package bar;
import com.intellij.openapi.extensions.RequiredElement;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
/**
* MyExtensionPoint JavaDoc.
*/
public interface MyExtensionPoint {
public class MyExtensionPoint {
@RequiredElement
@Attribute
public String implementationClass;
@Tag
public Integer intValue;
}

View File

@@ -5,7 +5,6 @@
<extensionPoints>
<extensionPoint name="bar" beanClass="bar.MyExtensionPoint">
<with attribute="implementationClass" implements="bar.MyExtension"/>
<with tag="tagName" implements="java.lang.Integer"/>
</extensionPoint>
</extensionPoints>

View File

@@ -5,7 +5,6 @@
<extensionPoints>
<extensionPoint qualifiedName="foo.bar" beanClass="bar.MyExtensionPoint">
<with attribute="implementationClass" implements="bar.MyExtension"/>
<with tag="tagName" implements="java.lang.Integer"/>
</extensionPoint>
</extensionPoints>

View File

@@ -30,6 +30,9 @@ public class ExtensionPointDocumentationProviderTest extends LightJavaCodeInsigh
private void doBeanClassExtensionPointTest(String pluginXml) {
myFixture.configureByFiles(pluginXml,
"bar/MyExtensionPoint.java", "bar/MyExtension.java");
myFixture.addClass("package com.intellij.openapi.extensions; public @interface RequiredElement {}");
myFixture.addClass("package com.intellij.util.xmlb.annotations; public @interface Attribute {}");
myFixture.addClass("package com.intellij.util.xmlb.annotations; public @interface Tag {}");
final PsiElement docElement =
DocumentationManager.getInstance(getProject()).findTargetElement(myFixture.getEditor(),
@@ -44,9 +47,12 @@ public class ExtensionPointDocumentationProviderTest extends LightJavaCodeInsigh
provider.getQuickNavigateInfo(docElement, getOriginalElement()));
assertEquals(
"<div class='definition'><pre><b>foo.bar</b><br>" + pluginXml +"<div class='definition'><pre>bar<br>public interface <b>MyExtensionPoint</b></pre></div><div class='content'>\n" +
"<div class='definition'><pre><b>foo.bar</b><br>" +
pluginXml +
"<div class='definition'><pre>bar<br>public class <b>MyExtensionPoint</b>\n" +
"extends <a href=\"psi_element://java.lang.Object\"><code>Object</code></a></pre></div><div class='content'>\n" +
" MyExtensionPoint JavaDoc.\n" +
" </div><table class='sections'><p></table><table class='sections'><tr><td valign='top' class='section'><p>implementationClass:</td><td valign='top'><a href=\"psi_element://bar.MyExtension\"><code>MyExtension</code></a></td><tr><td valign='top' class='section'><p>&lt;tagName&gt;:</td><td valign='top'><a href=\"psi_element://java.lang.Integer\"><code>Integer</code></a></td></table></pre></div><div class='content'><h2>Extension Point Implementation</h2><div class='definition'><pre>bar<br>public interface <b>MyExtension</b></pre></div><div class='content'>\n" +
" </div><table class='sections'><p></table><table class='sections'><tr><td valign='top' class='section'><p><a href=\"psi_element://bar.MyExtensionPoint#implementationClass\"><code>implementationClass</code></a></td><td valign='top'>String (required)</td><tr><td valign='top' class='section'><p><a href=\"psi_element://bar.MyExtensionPoint#intValue\"><code>&lt;intValue></code></a></td><td valign='top'>Integer</td><br/></table></pre></div><div class='content'><h2>Extension Point Implementation</h2><div class='definition'><pre>bar<br>public interface <b>MyExtension</b></pre></div><div class='content'>\n" +
" My Extension Javadoc.\n" +
" </div><table class='sections'><p></table></div>",
provider.generateDoc(docElement, getOriginalElement()));