mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
plugin.xml:
correctly determine extension short name don't red-highlight hacky non-existing vcs plugin reference
This commit is contained in:
@@ -161,3 +161,5 @@ project.title=Plugin Project
|
||||
no.java.sdk.for.idea.sdk.found=No Java SDK of appropriate version found. In addition to the IDEA JDK, you need to define a JSDK with the same Java version ({0}).
|
||||
no.idea.sdk.version.found=Failed to detect JDK version required for IDEA JDK.
|
||||
group.PluginDeployActions.text=Plugin Deployment Actions
|
||||
|
||||
error.cannot.resolve.plugin=Cannot resolve plugin {0}
|
||||
@@ -13,10 +13,10 @@ import org.jetbrains.idea.devkit.dom.impl.ExtensionNsConverter;
|
||||
public interface Extensions extends DomElement {
|
||||
@NotNull
|
||||
@Attribute("defaultExtensionNs")
|
||||
@Convert(ExtensionNsConverter.class)
|
||||
@Convert(value=ExtensionNsConverter.class, soft=true)
|
||||
GenericAttributeValue<IdeaPlugin> getDefaultExtensionNs();
|
||||
|
||||
@NotNull
|
||||
@Convert(ExtensionNsConverter.class)
|
||||
@Convert(value=ExtensionNsConverter.class, soft=true)
|
||||
GenericAttributeValue<IdeaPlugin> getXmlns();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.jetbrains.idea.devkit.dom.impl;
|
||||
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.xml.*;
|
||||
import com.intellij.util.xml.reflect.DomExtender;
|
||||
import com.intellij.util.xml.reflect.DomExtension;
|
||||
@@ -11,9 +13,12 @@ import com.intellij.util.xml.reflect.DomExtensionsRegistrar;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.devkit.dom.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
@@ -31,56 +36,71 @@ public class ExtensionDomExtender extends DomExtender<Extensions> {
|
||||
|
||||
if (ideaPlugin == null) return;
|
||||
|
||||
registerExtensions(extensions, ideaPlugin, registrar, psiManager);
|
||||
|
||||
IdeaPlugin plugin = extensions.getDefaultExtensionNs().getValue();
|
||||
if (plugin == null) plugin = extensions.getXmlns().getValue();
|
||||
if (plugin != null) {
|
||||
registerExtensions(extensions, plugin, registrar, psiManager);
|
||||
String prefix = extensions.getDefaultExtensionNs().getStringValue();
|
||||
if (prefix == null) prefix = extensions.getXmlns().getStringValue();
|
||||
if (prefix != null) {
|
||||
prefix += ".";
|
||||
} else {
|
||||
prefix = "";
|
||||
}
|
||||
|
||||
final Collection<String> dependencies = getDependencies(ideaPlugin);
|
||||
ContainerUtil.addIfNotNull(ideaPlugin.getPluginId(), dependencies);
|
||||
for (IdeaPlugin plugin : IdeaPluginConverter.collectAllVisiblePlugins(extensions.getRoot().getFile())) {
|
||||
final String value = plugin.getPluginId();
|
||||
if (value != null && dependencies.contains(value)) {
|
||||
registerExtensions(prefix, plugin, registrar, psiManager);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void registerExtensions(final Extensions extensions, final IdeaPlugin plugin, final DomExtensionsRegistrar registrar,
|
||||
private static void registerExtensions(final String prefix, final IdeaPlugin plugin, final DomExtensionsRegistrar registrar,
|
||||
final PsiManager psiManager) {
|
||||
final String pluginId = plugin.getPluginId();
|
||||
for (ExtensionPoints points : plugin.getExtensionPoints()) {
|
||||
for (ExtensionPoint point : points.getExtensionPoints()) {
|
||||
registerExtensionPoint(registrar, point, psiManager);
|
||||
registerExtensionPoint(registrar, point, psiManager, prefix, pluginId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerExtensionPoint(final DomExtensionsRegistrar registrar, final ExtensionPoint extensionPoint, final PsiManager manager) {
|
||||
final String epName = extensionPoint.getName().getStringValue();
|
||||
if (epName != null) {
|
||||
final DomExtension domExtension = registrar.registerCollectionChildrenExtension(new XmlName(epName), Extension.class);
|
||||
domExtension.putUserData(DomExtension.KEY_DECLARATION, extensionPoint);
|
||||
domExtension.addExtender(new DomExtender() {
|
||||
public void registerExtensions(@NotNull final DomElement domElement, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
final String interfaceName = extensionPoint.getInterface().getStringValue();
|
||||
if (interfaceName != null) {
|
||||
registrar.registerGenericAttributeValueChildExtension(new XmlName("implementation"), PsiClass.class).setConverter(
|
||||
CLASS_CONVERTER);
|
||||
private static void registerExtensionPoint(final DomExtensionsRegistrar registrar, final ExtensionPoint extensionPoint, final PsiManager manager, String prefix, @Nullable String pluginId) {
|
||||
String epName = extensionPoint.getName().getStringValue();
|
||||
if (epName == null) epName = extensionPoint.getQualifiedName().getStringValue();
|
||||
if (epName == null) return;
|
||||
|
||||
final PsiClass implClass =
|
||||
JavaPsiFacade.getInstance(manager.getProject()).findClass(interfaceName, GlobalSearchScope.allScope(manager.getProject()));
|
||||
if (implClass != null) {
|
||||
registerXmlb(registrar, implClass);
|
||||
}
|
||||
if (StringUtil.isNotEmpty(pluginId)) epName = pluginId + "." + epName;
|
||||
if (!epName.startsWith(prefix)) return;
|
||||
|
||||
final DomExtension domExtension = registrar.registerCollectionChildrenExtension(new XmlName(epName.substring(prefix.length())), Extension.class);
|
||||
domExtension.putUserData(DomExtension.KEY_DECLARATION, extensionPoint);
|
||||
domExtension.addExtender(new DomExtender() {
|
||||
public void registerExtensions(@NotNull final DomElement domElement, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
final String interfaceName = extensionPoint.getInterface().getStringValue();
|
||||
if (interfaceName != null) {
|
||||
registrar.registerGenericAttributeValueChildExtension(new XmlName("implementation"), PsiClass.class).setConverter(
|
||||
CLASS_CONVERTER);
|
||||
|
||||
final PsiClass implClass =
|
||||
JavaPsiFacade.getInstance(manager.getProject()).findClass(interfaceName, GlobalSearchScope.allScope(manager.getProject()));
|
||||
if (implClass != null) {
|
||||
registerXmlb(registrar, implClass);
|
||||
}
|
||||
else {
|
||||
final String beanClassName = extensionPoint.getBeanClass().getStringValue();
|
||||
if (beanClassName != null) {
|
||||
final PsiClass beanClass =
|
||||
JavaPsiFacade.getInstance(manager.getProject()).findClass(beanClassName, GlobalSearchScope.allScope(manager.getProject()));
|
||||
}
|
||||
else {
|
||||
final String beanClassName = extensionPoint.getBeanClass().getStringValue();
|
||||
if (beanClassName != null) {
|
||||
final PsiClass beanClass =
|
||||
JavaPsiFacade.getInstance(manager.getProject()).findClass(beanClassName, GlobalSearchScope.allScope(manager.getProject()));
|
||||
|
||||
if (beanClass != null) {
|
||||
registerXmlb(registrar, beanClass);
|
||||
}
|
||||
if (beanClass != null) {
|
||||
registerXmlb(registrar, beanClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void registerXmlb(final DomExtensionsRegistrar registrar, final PsiClass beanClass) {
|
||||
|
||||
@@ -19,13 +19,12 @@ import com.intellij.util.xml.ResolvingConverter;
|
||||
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.IdeaPlugin;
|
||||
import org.jetbrains.idea.devkit.module.PluginModuleType;
|
||||
import org.jetbrains.idea.devkit.projectRoots.IdeaJdk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
@@ -33,9 +32,18 @@ import java.util.List;
|
||||
public class IdeaPluginConverter extends ResolvingConverter<IdeaPlugin> {
|
||||
@NotNull
|
||||
public Collection<? extends IdeaPlugin> getVariants(final ConvertContext context) {
|
||||
final XmlFile xmlFile = context.getFile();
|
||||
return collectAllVisiblePlugins(context.getFile());
|
||||
}
|
||||
|
||||
return collectAllVisiblePlugins(xmlFile);
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getAdditionalVariants(@NotNull final ConvertContext context) {
|
||||
return Collections.singleton("com.intellij.modules.vcs"); //todo this is a hack
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage(@Nullable final String s, final ConvertContext context) {
|
||||
return DevKitBundle.message("error.cannot.resolve.plugin", s);
|
||||
}
|
||||
|
||||
public static Collection<IdeaPlugin> collectAllVisiblePlugins(final XmlFile xmlFile) {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<idea-plugin>
|
||||
<id>com.intellij.myPlugin</id>
|
||||
|
||||
<depends>com.intellij</depends>
|
||||
<depends>com.intellij.modules.vcs</depends> <!-- a hack -->
|
||||
<depends>com.intellij.custom</depends>
|
||||
<depends><error descr="Cannot resolve plugin com.intellij.xxx">com.intellij.xxx</error></depends>
|
||||
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,15 @@
|
||||
<idea-plugin>
|
||||
<id>com.intellij.myPlugin</id>
|
||||
<extensionPoints>
|
||||
<extensionPoint name="foo.bar"/>
|
||||
</extensionPoints>
|
||||
|
||||
<depends>com.intellij.custom</depends>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<myPlugin.foo.bar/>
|
||||
<completion.contributor/>
|
||||
<custom.custom/>
|
||||
<<error descr="Element custom.error is not allowed here">custom.error</error>/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
package org.jetbrains.idea.devkit.codeInsight;
|
||||
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
|
||||
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
|
||||
import com.intellij.testFramework.fixtures.TempDirTestFixture;
|
||||
import org.jetbrains.idea.devkit.DevKitInspectionToolProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PluginXmlFunctionalTest extends CodeInsightFixtureTestCase {
|
||||
private TempDirTestFixture myTempDirFixture;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myTempDirFixture = IdeaTestFixtureFactory.getFixtureFactory().createTempDirTestFixture();
|
||||
myFixture.enableInspections(new DevKitInspectionToolProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/svnPlugins/devkit/testData/codeInsight";
|
||||
}
|
||||
|
||||
public void testExtensionsHighlighting() throws Throwable {
|
||||
final String root = "idea_core";
|
||||
addPluginXml(root, "<idea-plugin>\n" +
|
||||
" <id>com.intellij</id>\n" +
|
||||
" <extensionPoints>\n" +
|
||||
" <extensionPoint name=\"completion.contributor\"/>\n" +
|
||||
" </extensionPoints>\n" +
|
||||
"</idea-plugin>");
|
||||
addPluginXml("custom", "<idea-plugin>\n" +
|
||||
" <id>com.intellij.custom</id>\n" +
|
||||
" <extensionPoints>\n" +
|
||||
" <extensionPoint name=\"custom\"/>\n" +
|
||||
" </extensionPoints>\n" +
|
||||
"</idea-plugin>");
|
||||
|
||||
myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject(getTestName(false) + ".xml", "META-INF/plugin.xml"));
|
||||
myFixture.checkHighlighting(false, false, false);
|
||||
}
|
||||
|
||||
public void testDependsHighlighting() throws Throwable {
|
||||
final String root = "idea_core";
|
||||
addPluginXml(root, "<idea-plugin>\n" +
|
||||
" <id>com.intellij</id>\n" +
|
||||
"</idea-plugin>");
|
||||
addPluginXml("custom", "<idea-plugin>\n" +
|
||||
" <id>com.intellij.custom</id>\n" +
|
||||
"</idea-plugin>");
|
||||
|
||||
myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject(getTestName(false) + ".xml", "META-INF/plugin.xml"));
|
||||
myFixture.checkHighlighting(false, false, false);
|
||||
}
|
||||
|
||||
private void addPluginXml(final String root, final String text) throws IOException {
|
||||
myTempDirFixture.createFile(root +
|
||||
"/META-INF/plugin.xml", text);
|
||||
new WriteCommandAction(getProject()) {
|
||||
protected void run(Result result) throws Throwable {
|
||||
PsiTestUtil.addSourceContentToRoots(myModule, myTempDirFixture.getFile(root));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user