[devkit] IJPL-216103: Render plugin ID if the file name is plugin.xml

GitOrigin-RevId: d212d259efd0baf8fdbb7c17fed50a909484f5d4
This commit is contained in:
Karol Lewandowski
2025-11-19 13:29:31 +00:00
committed by intellij-monorepo-bot
parent 5dc3ee5eda
commit 7eacec658f
3 changed files with 53 additions and 7 deletions
@@ -5,6 +5,7 @@ import com.intellij.codeInsight.documentation.DocumentationManager;
import com.intellij.codeInsight.documentation.DocumentationManagerProtocol;
import com.intellij.codeInsight.javadoc.JavaDocUtil;
import com.intellij.icons.AllIcons;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.lang.documentation.DocumentationMarkup;
import com.intellij.lang.documentation.DocumentationProvider;
import com.intellij.openapi.module.Module;
@@ -17,12 +18,16 @@ import com.intellij.pom.PomTargetPsiElement;
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.DomFileElement;
import com.intellij.util.xml.DomUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.DevKitBundle;
import org.jetbrains.idea.devkit.dom.ExtensionPoint;
import org.jetbrains.idea.devkit.dom.IdeaPlugin;
import org.jetbrains.idea.devkit.util.DescriptorUtil;
import static com.intellij.lang.documentation.DocumentationMarkup.DEFINITION_ELEMENT;
@@ -92,10 +97,28 @@ final class ExtensionPointDocumentationProvider implements DocumentationProvider
HtmlChunk.text(extensionPoint.getEffectiveQualifiedName()).bold().wrapWith(PRE_ELEMENT),
HtmlChunk.icon("AllIcons.Nodes.Plugin", AllIcons.Nodes.Plugin),
HtmlChunk.nbsp(),
HtmlChunk.text(DomUtil.getFile(extensionPoint).getName())
HtmlChunk.text(getNameAndOptionalPluginId(extensionPoint))
).wrapWith(DEFINITION_ELEMENT);
}
private static @Nls @NotNull String getNameAndOptionalPluginId(ExtensionPoint extensionPoint) {
XmlFile file = DomUtil.getFile(extensionPoint);
String fileName = file.getName();
if (!PluginManagerCore.PLUGIN_XML.equals(fileName)) {
return fileName;
}
DomFileElement<DomElement> element = DomUtil.getFileElement(extensionPoint);
if (element == null) return fileName;
DomElement rootElement = element.getRootElement();
if (rootElement instanceof IdeaPlugin ideaPlugin) {
String pluginId = ideaPlugin.getId().getStringValue();
if (StringUtil.isNotEmpty(pluginId)) {
return fileName + " (" + pluginId + ")";
}
}
return fileName;
}
private static @NotNull HtmlChunk epBeanDocAndFields(ExtensionPoint extensionPoint) {
final PsiClass beanClass = extensionPoint.getBeanClass().getValue();
if (beanClass != null) {
@@ -0,0 +1,16 @@
<idea-plugin>
<id>foo.bar</id>
<extensionPoints>
<extensionPoint qualifiedName="foo.bar" beanClass="bar.MyExtensionPoint">
<with attribute="implementationClass" implements="bar.MyExtension"/>
</extensionPoint>
</extensionPoints>
<extensions defaultExtensionNs="foo">
<b<caret>ar/>
</extensions>
</idea-plugin>
@@ -21,15 +21,22 @@ public class ExtensionPointDocumentationProviderTest extends LightJavaCodeInsigh
}
public void testBeanClassExtensionPointDocumentation() {
doBeanClassExtensionPointTest("beanClassExtensionPointDocumentation.xml");
doBeanClassExtensionPointTest("beanClassExtensionPointDocumentation.xml",
"beanClassExtensionPointDocumentation.xml");
}
public void testBeanClassExtensionPointQualifiedNameDocumentation() {
doBeanClassExtensionPointTest("beanClassExtensionPointQualifiedNameDocumentation.xml");
doBeanClassExtensionPointTest("beanClassExtensionPointQualifiedNameDocumentation.xml",
"beanClassExtensionPointQualifiedNameDocumentation.xml");
}
private void doBeanClassExtensionPointTest(String pluginXml) {
myFixture.configureByFiles(pluginXml,
public void testBeanClassExtensionPointDocumentationWhenFileNameIsPluginXml() {
doBeanClassExtensionPointTest("plugin.xml",
"plugin.xml (foo.bar)");
}
private void doBeanClassExtensionPointTest(String pluginXmlFileName, String expectedEpLocationString) {
myFixture.configureByFiles(pluginXmlFileName,
"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 {}");
@@ -41,14 +48,14 @@ public class ExtensionPointDocumentationProviderTest extends LightJavaCodeInsigh
DocumentationProvider provider = DocumentationManager.getProviderFromElement(docElement);
String epDefinition = "[" + getModule().getName() + "]" +
"<br/><b>foo.bar</b> (" + pluginXml + ")<br/>" +
"<br/><b>foo.bar</b> (" + pluginXmlFileName + ")<br/>" +
"<a href=\"psi_element://bar.MyExtensionPoint\"><code>MyExtensionPoint</code></a><br/>" +
"<a href=\"psi_element://bar.MyExtension\"><code>MyExtension</code></a>";
assertEquals(epDefinition,
provider.getQuickNavigateInfo(docElement, getOriginalElement()));
assertEquals(
"<div class=\"definition\"><pre><b>foo.bar</b></pre><icon src=\"AllIcons.Nodes.Plugin\"/>&nbsp;" + pluginXml + "</div><div class=\"definition\"><pre>" +
"<div class=\"definition\"><pre><b>foo.bar</b></pre><icon src=\"AllIcons.Nodes.Plugin\"/>&nbsp;" + expectedEpLocationString + "</div><div class=\"definition\"><pre>" +
"<div class=\"bottom\"><icon src=\"AllIcons.Nodes.Package\">&nbsp;<a href=\"psi_element://bar\"><code><span style=\"color:#000000;\">bar</span></code></a></div><div class='definition'><pre><span style=\"color:#000080;font-weight:bold;\">public</span> <span style=\"color:#000080;font-weight:bold;\">class</span> <span style=\"color:#000000;\">MyExtensionPoint</span></pre></div><div class='content'>\n" +
" MyExtensionPoint JavaDoc.\n" +
" </div><table class='sections'><p></table><table class=\"sections\"><tr><td class=\"section\" valign=\"top\"><p><a href=\"psi_element://bar.MyExtensionPoint#implementationClass\"><code>implementationClass</code></a></p></td><td valign=\"top\">String (required)</td></tr><tr><td class=\"section\" valign=\"top\"><p><a href=\"psi_element://bar.MyExtensionPoint#stringCanBeEmpty\"><code>stringCanBeEmpty</code></a></p></td><td valign=\"top\">String (required, empty allowed)</td></tr><tr><td class=\"section\" valign=\"top\"><p><a href=\"psi_element://bar.MyExtensionPoint#intValue\"><code>&lt;intValue&gt;</code></a></p></td><td valign=\"top\">Integer</td></tr><br/></table></pre></div><div class=\"content\"><a href=\"https://jb.gg/ipe?extensions=foo.bar\">Show Usages in IntelliJ Platform Explorer</a></div><div class=\"content\"><h2>Extension Point Implementation</h2><div class=\"bottom\"><icon src=\"AllIcons.Nodes.Package\">&nbsp;<a href=\"psi_element://bar\"><code><span style=\"color:#000000;\">bar</span></code></a></div><div class='definition'><pre><span style=\"color:#000080;font-weight:bold;\">public</span> <span style=\"color:#000080;font-weight:bold;\">interface</span> <span style=\"color:#000000;\">MyExtension</span></pre></div><div class='content'>\n" +