From dfac135468712d6745f33438212faea7a1732379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Fri, 23 Aug 2019 15:46:38 +0200 Subject: [PATCH] IDEA-221095 Devkit: resolve EPs when used via xinclude or GitOrigin-RevId: 52cc521f09a847e043ac1eaba5b5a62bf358d809 --- .../devkit-core/resources/META-INF/plugin.xml | 1 + .../src/dom/impl/ExtensionsDomExtender.java | 61 +++++++----- .../dom/index/PluginIdDependenciesIndex.java | 98 +++++++++++++++++++ .../ExtensionsHighlighting-included.xml | 11 +++ .../ExtensionsHighlighting-via-depends.xml | 12 +++ .../codeInsight/ExtensionsHighlighting.xml | 6 +- .../PluginXmlFunctionalTest.groovy | 5 + 7 files changed, 167 insertions(+), 27 deletions(-) create mode 100644 plugins/devkit/devkit-core/src/dom/index/PluginIdDependenciesIndex.java create mode 100644 plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting-included.xml create mode 100644 plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting-via-depends.xml diff --git a/plugins/devkit/devkit-core/resources/META-INF/plugin.xml b/plugins/devkit/devkit-core/resources/META-INF/plugin.xml index 8f392f5d2933..22802b04d90c 100644 --- a/plugins/devkit/devkit-core/resources/META-INF/plugin.xml +++ b/plugins/devkit/devkit-core/resources/META-INF/plugin.xml @@ -63,6 +63,7 @@ + diff --git a/plugins/devkit/devkit-core/src/dom/impl/ExtensionsDomExtender.java b/plugins/devkit/devkit-core/src/dom/impl/ExtensionsDomExtender.java index 32f8bf1ad64a..6b0150618e2c 100644 --- a/plugins/devkit/devkit-core/src/dom/impl/ExtensionsDomExtender.java +++ b/plugins/devkit/devkit-core/src/dom/impl/ExtensionsDomExtender.java @@ -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 { static Collection getDependencies(IdeaPlugin ideaPlugin) { Set 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 includingAndDependsFiles = new SmartHashSet<>(); + for (VirtualFile virtualFile : includingFiles) { + if (!fileIndex.isUnderSourceRootOfType(virtualFile, JavaModuleSourceRootTypes.PRODUCTION)) { + continue; + } + includingAndDependsFiles.add(virtualFile); + } + + final Collection dependsToFiles = PluginIdDependenciesIndex.findDependsTo(project, currentFile); + includingAndDependsFiles.addAll(dependsToFiles); + + if (includingAndDependsFiles.isEmpty()) { + return result; + } + + final Set ids = PluginIdDependenciesIndex.getPluginAndDependsIds(project, includingAndDependsFiles); + result.addAll(ids); return result; } } diff --git a/plugins/devkit/devkit-core/src/dom/index/PluginIdDependenciesIndex.java b/plugins/devkit/devkit-core/src/dom/index/PluginIdDependenciesIndex.java new file mode 100644 index 000000000000..eead1f7e8f7a --- /dev/null +++ b/plugins/devkit/devkit-core/src/dom/index/PluginIdDependenciesIndex.java @@ -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 { + + private static final ID NAME = ID.create("PluginIdDependenciesIndex"); + + @NonNls + private static final String FILENAME_KEY_PREFIX = "___FILENAME___"; + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return EnumeratorStringDescriptor.INSTANCE; + } + + @NotNull + @Override + public ID getName() { + return NAME; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return inputData -> { + IdeaPlugin plugin = RegistrationIndexer.obtainIdeaPlugin(inputData); + if (plugin == null) return Collections.emptyMap(); + + List 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 getPluginAndDependsIds(Project project, Set files) { + Set ids = new SmartHashSet<>(); + for (VirtualFile file : files) { + final Map 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 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; + } +} diff --git a/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting-included.xml b/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting-included.xml new file mode 100644 index 000000000000..0607282fd6e9 --- /dev/null +++ b/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting-included.xml @@ -0,0 +1,11 @@ + + + + INVALID_VALUE"/> + + + + + + + \ No newline at end of file diff --git a/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting-via-depends.xml b/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting-via-depends.xml new file mode 100644 index 000000000000..46750c0705d1 --- /dev/null +++ b/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting-via-depends.xml @@ -0,0 +1,12 @@ + + + + + INVALID_VALUE"/> + + + + + + + \ No newline at end of file diff --git a/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting.xml b/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting.xml index ad86305e3591..111244128166 100644 --- a/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting.xml +++ b/plugins/devkit/devkit-java-tests/testData/codeInsight/ExtensionsHighlighting.xml @@ -1,4 +1,4 @@ - + com.intellij.myPlugin JetBrains 1.0 @@ -12,6 +12,10 @@ com.intellij.custom + com.myplugin.depends + + + <myPlugin.ext/> diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/codeInsight/PluginXmlFunctionalTest.groovy b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/codeInsight/PluginXmlFunctionalTest.groovy index 9c480d9c1807..4d110aba76e3 100644 --- a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/codeInsight/PluginXmlFunctionalTest.groovy +++ b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/codeInsight/PluginXmlFunctionalTest.groovy @@ -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() {