mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-221095 Devkit: resolve EPs when used via xinclude or <depends>
GitOrigin-RevId: 52cc521f09a847e043ac1eaba5b5a62bf358d809
This commit is contained in:
committed by
intellij-monorepo-bot
parent
600e43c052
commit
dfac135468
@@ -63,6 +63,7 @@
|
||||
|
||||
<fileBasedIndex implementation="org.jetbrains.idea.devkit.dom.index.IdeaPluginRegistrationIndex"/>
|
||||
<fileBasedIndex implementation="org.jetbrains.idea.devkit.dom.index.PluginIdModuleIndex"/>
|
||||
<fileBasedIndex implementation="org.jetbrains.idea.devkit.dom.index.PluginIdDependenciesIndex"/>
|
||||
|
||||
<editorTabTitleProvider implementation="org.jetbrains.idea.devkit.dom.ide.PluginDescriptorEditorTabTitleProvider"/>
|
||||
<useScopeEnlarger implementation="org.jetbrains.idea.devkit.dom.ide.PluginDescriptorUseScopeEnlarger"/>
|
||||
|
||||
@@ -3,12 +3,14 @@ package org.jetbrains.idea.devkit.dom.impl;
|
||||
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.impl.include.FileIncludeManager;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomUtil;
|
||||
import com.intellij.util.xml.XmlName;
|
||||
@@ -19,8 +21,9 @@ import com.intellij.util.xml.reflect.DomExtender;
|
||||
import com.intellij.util.xml.reflect.DomExtensionsRegistrar;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.devkit.dom.*;
|
||||
import org.jetbrains.idea.devkit.dom.index.PluginIdDependenciesIndex;
|
||||
import org.jetbrains.idea.devkit.dom.index.PluginIdModuleIndex;
|
||||
import org.jetbrains.idea.devkit.util.DescriptorUtil;
|
||||
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -89,36 +92,42 @@ public class ExtensionsDomExtender extends DomExtender<Extensions> {
|
||||
|
||||
static Collection<String> getDependencies(IdeaPlugin ideaPlugin) {
|
||||
Set<String> result = new HashSet<>();
|
||||
|
||||
result.add(PluginManagerCore.CORE_PLUGIN_ID);
|
||||
|
||||
for (Dependency dependency : ideaPlugin.getDependencies()) {
|
||||
ContainerUtil.addIfNotNull(result, dependency.getStringValue());
|
||||
}
|
||||
|
||||
if (ideaPlugin.getPluginId() == null) {
|
||||
final VirtualFile file = DomUtil.getFile(ideaPlugin).getOriginalFile().getVirtualFile();
|
||||
if (file != null) {
|
||||
final String fileName = file.getName();
|
||||
if (!PluginManagerCore.PLUGIN_XML.equals(fileName)) {
|
||||
final VirtualFile mainPluginXml = file.findFileByRelativePath("../" + PluginManagerCore.PLUGIN_XML);
|
||||
if (mainPluginXml != null) {
|
||||
final PsiFile psiFile = PsiManager.getInstance(ideaPlugin.getManager().getProject()).findFile(mainPluginXml);
|
||||
if (psiFile instanceof XmlFile) {
|
||||
final XmlFile xmlFile = (XmlFile)psiFile;
|
||||
final IdeaPlugin mainPlugin = DescriptorUtil.getIdeaPlugin(xmlFile);
|
||||
if (mainPlugin != null) {
|
||||
ContainerUtil.addIfNotNull(result, mainPlugin.getPluginId());
|
||||
for (Dependency dependency : mainPlugin.getDependencies()) {
|
||||
ContainerUtil.addIfNotNull(result, dependency.getStringValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ideaPlugin.getPluginId() != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
final VirtualFile currentFile = DomUtil.getFile(ideaPlugin).getOriginalFile().getVirtualFile();
|
||||
if (currentFile == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
final Project project = ideaPlugin.getManager().getProject();
|
||||
final VirtualFile[] includingFiles = FileIncludeManager.getManager(project).getIncludingFiles(currentFile, false);
|
||||
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
Set<VirtualFile> includingAndDependsFiles = new SmartHashSet<>();
|
||||
for (VirtualFile virtualFile : includingFiles) {
|
||||
if (!fileIndex.isUnderSourceRootOfType(virtualFile, JavaModuleSourceRootTypes.PRODUCTION)) {
|
||||
continue;
|
||||
}
|
||||
includingAndDependsFiles.add(virtualFile);
|
||||
}
|
||||
|
||||
final Collection<VirtualFile> dependsToFiles = PluginIdDependenciesIndex.findDependsTo(project, currentFile);
|
||||
includingAndDependsFiles.addAll(dependsToFiles);
|
||||
|
||||
if (includingAndDependsFiles.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
final Set<String> ids = PluginIdDependenciesIndex.getPluginAndDependsIds(project, includingAndDependsFiles);
|
||||
result.addAll(ids);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright 2000-2019 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 org.jetbrains.idea.devkit.dom.index;
|
||||
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.search.GlobalSearchScopesCore;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.intellij.util.indexing.*;
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.devkit.dom.Dependency;
|
||||
import org.jetbrains.idea.devkit.dom.IdeaPlugin;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PluginIdDependenciesIndex extends ScalarIndexExtension<String> {
|
||||
|
||||
private static final ID<String, Void> NAME = ID.create("PluginIdDependenciesIndex");
|
||||
|
||||
@NonNls
|
||||
private static final String FILENAME_KEY_PREFIX = "___FILENAME___";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KeyDescriptor<String> getKeyDescriptor() {
|
||||
return EnumeratorStringDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ID<String, Void> getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DataIndexer<String, Void, FileContent> getIndexer() {
|
||||
return inputData -> {
|
||||
IdeaPlugin plugin = RegistrationIndexer.obtainIdeaPlugin(inputData);
|
||||
if (plugin == null) return Collections.emptyMap();
|
||||
|
||||
List<String> ids = new SmartList<>();
|
||||
ContainerUtil.addIfNotNull(ids, plugin.getPluginId());
|
||||
for (Dependency dependency : plugin.getDependencies()) {
|
||||
ContainerUtil.addIfNotNull(ids, dependency.getStringValue());
|
||||
|
||||
final String configFile = dependency.getConfigFile().getStringValue();
|
||||
if (configFile != null) {
|
||||
final String filename = PathUtil.getFileName(configFile);
|
||||
ids.add(getDependsIndexingKey(filename));
|
||||
}
|
||||
}
|
||||
|
||||
return ContainerUtil.newHashMap(ids, Collections.nCopies(ids.size(), null));
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FileBasedIndex.InputFilter getInputFilter() {
|
||||
return new DefaultFileTypeSpecificInputFilter(StdFileTypes.XML);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dependsOnFileContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Set<String> getPluginAndDependsIds(Project project, Set<VirtualFile> files) {
|
||||
Set<String> ids = new SmartHashSet<>();
|
||||
for (VirtualFile file : files) {
|
||||
final Map<String, Void> data = FileBasedIndex.getInstance().getFileData(NAME, file, project);
|
||||
ids.addAll(ContainerUtil.filter(data.keySet(), s -> !StringUtil.startsWith(s, FILENAME_KEY_PREFIX)));
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
public static Collection<VirtualFile> findDependsTo(Project project, VirtualFile file) {
|
||||
return FileBasedIndex.getInstance().getContainingFiles(NAME, getDependsIndexingKey(file.getName()),
|
||||
GlobalSearchScopesCore.projectProductionScope(project));
|
||||
}
|
||||
|
||||
private static String getDependsIndexingKey(String filename) {
|
||||
return FILENAME_KEY_PREFIX + filename;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<!-- included from ExtensionsHighlighting.xml can access all its EPs -->
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<myPlugin.foo.bar implementation="java.util.ArrayList" os="<error descr="Unknown enum value 'INVALID_VALUE'">INVALID_VALUE</error>"/>
|
||||
|
||||
<completion.contributor/>
|
||||
<custom.custom/>
|
||||
<indirect.indirect/>
|
||||
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<!-- via <depends> from ExtensionsHighlighting.xml can access all its EPs -->
|
||||
<idea-plugin>
|
||||
<module value="com.myplugin.depends"/>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<myPlugin.foo.bar implementation="java.util.ArrayList" os="<error descr="Unknown enum value 'INVALID_VALUE'">INVALID_VALUE</error>"/>
|
||||
|
||||
<completion.contributor/>
|
||||
<custom.custom/>
|
||||
<indirect.indirect/>
|
||||
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -1,4 +1,4 @@
|
||||
<idea-plugin>
|
||||
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<id>com.intellij.myPlugin</id>
|
||||
<vendor>JetBrains</vendor>
|
||||
<version>1.0</version>
|
||||
@@ -12,6 +12,10 @@
|
||||
</extensionPoints>
|
||||
|
||||
<depends>com.intellij.custom</depends>
|
||||
<depends config-file="../ExtensionsHighlighting-via-depends.xml">com.myplugin.depends</depends>
|
||||
|
||||
<xi:include href="ExtensionsHighlighting-included.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<<error descr="'implementation' attribute should be defined">myPlugin.ext</error>/>
|
||||
|
||||
+5
@@ -159,7 +159,12 @@ class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase {
|
||||
"public class MyServiceDescriptor { @Attribute public String serviceImplementation; }")
|
||||
|
||||
configureByFile()
|
||||
myFixture.copyFileToProject("ExtensionsHighlighting-included.xml")
|
||||
myFixture.copyFileToProject("ExtensionsHighlighting-via-depends.xml",)
|
||||
myFixture.checkHighlighting(true, false, false)
|
||||
|
||||
myFixture.testHighlighting("ExtensionsHighlighting-included.xml")
|
||||
myFixture.testHighlighting("ExtensionsHighlighting-via-depends.xml")
|
||||
}
|
||||
|
||||
void testDependsHighlighting() {
|
||||
|
||||
Reference in New Issue
Block a user