diff --git a/plugins/devkit/devkit-core/src/dom/index/IdeaPluginRegistrationIndex.java b/plugins/devkit/devkit-core/src/dom/index/IdeaPluginRegistrationIndex.java index 4b33c22269fa..767d5876c4aa 100644 --- a/plugins/devkit/devkit-core/src/dom/index/IdeaPluginRegistrationIndex.java +++ b/plugins/devkit/devkit-core/src/dom/index/IdeaPluginRegistrationIndex.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2019 JetBrains s.r.o. + * Copyright 2000-2020 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,18 @@ package org.jetbrains.idea.devkit.dom.index; import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.DataInputOutputUtilRt; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.DefaultFileTypeSpecificInputFilter; import com.intellij.util.indexing.FileBasedIndex; @@ -28,19 +36,23 @@ import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.DataInputOutputUtil; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; +import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomManager; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.ActionOrGroup; import org.jetbrains.idea.devkit.dom.IdeaPlugin; import org.jetbrains.idea.devkit.dom.index.RegistrationEntry.RegistrationType; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import java.util.EnumSet; import java.util.List; import java.util.Map; public class IdeaPluginRegistrationIndex extends PluginXmlIndexBase> { - private static final int INDEX_VERSION = 1; + private static final int INDEX_VERSION = 2; private static final ID> NAME = ID.create("IdeaPluginRegistrationIndex"); @@ -130,4 +142,57 @@ public class IdeaPluginRegistrationIndex extends PluginXmlIndexBase ContainerUtil.process(value, entry -> !(entry.getRegistrationType() == type)), scope); } + + public static boolean processAllActionOrGroup(@NotNull Project project, + GlobalSearchScope scope, + Processor processor) { + return FileBasedIndex.getInstance().processAllKeys(NAME, s -> processActionOrGroup(project, s, scope, processor), scope, null); + } + + public static boolean processActionOrGroup(@NotNull Project project, + @NotNull String actionOrGroupId, + GlobalSearchScope scope, + Processor processor) { + return doProcessActionOrGroup(project, actionOrGroupId, scope, + EnumSet.of(RegistrationType.ACTION_ID, RegistrationType.ACTION_GROUP_ID), + processor); + } + + public static boolean processAction(@NotNull Project project, + @NotNull String actionId, + GlobalSearchScope scope, + Processor processor) { + return doProcessActionOrGroup(project, actionId, scope, EnumSet.of(RegistrationType.ACTION_ID), processor); + } + + public static boolean processGroup(@NotNull Project project, + @NotNull String actionGroupId, + GlobalSearchScope scope, + Processor processor) { + return doProcessActionOrGroup(project, actionGroupId, scope, EnumSet.of(RegistrationType.ACTION_GROUP_ID), processor); + } + + private static boolean doProcessActionOrGroup(@NotNull Project project, + @NotNull String actionOrGroupId, + GlobalSearchScope scope, + EnumSet types, + Processor processor) { + return FileBasedIndex.getInstance().processValues(NAME, actionOrGroupId, null, (file, value) -> { + return ContainerUtil.process(value, entry -> { + if (!types.contains(entry.getRegistrationType())) { + return true; + } + + final PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + if (!(psiFile instanceof XmlFile)) return true; + + PsiElement psiElement = psiFile.findElementAt(entry.getOffset()); + XmlTag xmlTag = PsiTreeUtil.getParentOfType(psiElement, XmlTag.class, false); + final DomElement domElement = DomManager.getDomManager(project).getDomElement(xmlTag); + + if (!(domElement instanceof ActionOrGroup)) return true; + return processor.process((ActionOrGroup)domElement); + }); + }, scope); + } } diff --git a/plugins/devkit/devkit-core/src/dom/index/RegistrationEntry.java b/plugins/devkit/devkit-core/src/dom/index/RegistrationEntry.java index daefcdb166be..be1b246ab14a 100644 --- a/plugins/devkit/devkit-core/src/dom/index/RegistrationEntry.java +++ b/plugins/devkit/devkit-core/src/dom/index/RegistrationEntry.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. + * Copyright 2000-2020 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,6 +57,9 @@ class RegistrationEntry { ACTION, APPLICATION_COMPONENT, PROJECT_COMPONENT, - MODULE_COMPONENT + MODULE_COMPONENT, + + ACTION_ID, + ACTION_GROUP_ID } } diff --git a/plugins/devkit/devkit-core/src/dom/index/RegistrationIndexer.java b/plugins/devkit/devkit-core/src/dom/index/RegistrationIndexer.java index a98dc33a98a4..2d0f24f1c225 100644 --- a/plugins/devkit/devkit-core/src/dom/index/RegistrationIndexer.java +++ b/plugins/devkit/devkit-core/src/dom/index/RegistrationIndexer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2019 JetBrains s.r.o. + * Copyright 2000-2020 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.devkit.dom.index; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiClass; import com.intellij.psi.xml.XmlElement; import com.intellij.util.Function; @@ -22,6 +23,7 @@ import com.intellij.util.SmartList; import com.intellij.util.containers.FactoryMap; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomUtil; +import com.intellij.util.xml.GenericAttributeValue; import com.intellij.util.xml.GenericDomValue; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.devkit.dom.*; @@ -80,6 +82,7 @@ class RegistrationIndexer { private void processGroup(Group group) { addEntry(group, group.getClazz(), RegistrationEntry.RegistrationType.ACTION); + addIdEntry(group, group.getId(), RegistrationEntry.RegistrationType.ACTION_GROUP_ID); for (Action action : group.getActions()) { processAction(action); @@ -91,6 +94,17 @@ class RegistrationIndexer { private void processAction(Action action) { addEntry(action, action.getClazz(), RegistrationEntry.RegistrationType.ACTION); + addIdEntry(action, action.getId(), RegistrationEntry.RegistrationType.ACTION_ID); + } + + private void addIdEntry(DomElement domElement, + GenericAttributeValue idValue, + RegistrationEntry.RegistrationType type) { + if (!DomUtil.hasXml(domElement)) return; + String id = idValue.getStringValue(); + if (StringUtil.isEmpty(id)) return; + + storeEntry(id, domElement, type); } private void addEntry(DomElement domElement, @@ -102,14 +116,15 @@ class RegistrationIndexer { final String className = clazz.replace('$', '.'); - List entries = myValueMap.get(className); - RegistrationEntry entry = new RegistrationEntry(type, getOffset(domElement)); - entries.add(entry); + storeEntry(className, domElement, type); } - private static int getOffset(DomElement element) { - final XmlElement xmlElement = element.getXmlElement(); - assert xmlElement != null : element; - return xmlElement.getTextOffset(); + private void storeEntry(String key, DomElement domElement, RegistrationEntry.RegistrationType type) { + List entries = myValueMap.get(key); + + final XmlElement xmlElement = domElement.getXmlElement(); + assert xmlElement != null : domElement; + RegistrationEntry entry = new RegistrationEntry(type, xmlElement.getTextOffset()); + entries.add(entry); } }