mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[devkit] goto declaration in plugin.xml for Action/ActionGroup (IDEA-129958)
GitOrigin-RevId: 16d2dd5bac02c211e33168f6e334247526491911
This commit is contained in:
committed by
intellij-monorepo-bot
parent
72102f2de6
commit
9a78cb32e7
@@ -359,6 +359,8 @@ implemented.at.runtime.jamElement=JAM Element implemented at runtime
|
||||
line.marker.tooltip.extension.declaration=<a href="#navigation/{0}:{1}">{2}</a> declaration in {3}
|
||||
line.marker.tooltip.extension.point.declaration=<a href="#navigation/{0}:{1}">{2}</a> extension point declaration in {3}
|
||||
line.marker.tooltip.listener.declaration=<a href="#navigation/{0}:{1}">{2}</a> listener in {3}
|
||||
line.marker.tooltip.action.declaration=<a href="#navigation/{0}:{1}">{2}</a> action in {3}
|
||||
line.marker.tooltip.action.group.declaration=<a href="#navigation/{0}:{1}">{2}</a> action group in {3}
|
||||
|
||||
inspections.usage.uelement.as.psi=Usage of UElement as PsiElement is not recommended
|
||||
|
||||
@@ -487,6 +489,8 @@ gutter.related.navigation.popup.description.tooltip=Description
|
||||
gutter.related.navigation.choose.extension=Choose Extension
|
||||
gutter.related.navigation.choose.extension.point=Choose Extension Point
|
||||
gutter.related.navigation.choose.listener=Choose Listener
|
||||
gutter.related.navigation.choose.action=Choose Action
|
||||
gutter.related.navigation.choose.action.group=Choose Action Group
|
||||
|
||||
# plugin.xml resolving
|
||||
plugin.xml.convert.action.or.group.cannot.resolve=Cannot resolve {0} ''{1}''
|
||||
|
||||
@@ -23,6 +23,7 @@ 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.annotations.Nullable;
|
||||
import org.jetbrains.idea.devkit.dom.*;
|
||||
import org.jetbrains.idea.devkit.dom.index.RegistrationEntry.RegistrationType;
|
||||
|
||||
@@ -95,20 +96,24 @@ public class IdeaPluginRegistrationIndex extends PluginXmlIndexBase<String, List
|
||||
return INDEX_VERSION;
|
||||
}
|
||||
|
||||
public static boolean isRegisteredClass(PsiClass psiClass, GlobalSearchScope scope) {
|
||||
return isRegisteredClass(psiClass, scope, null);
|
||||
}
|
||||
|
||||
public static boolean isRegisteredApplicationComponent(PsiClass psiClass, GlobalSearchScope scope) {
|
||||
return isRegistered(psiClass, scope, RegistrationType.APPLICATION_COMPONENT);
|
||||
return isRegisteredClass(psiClass, scope, RegistrationType.APPLICATION_COMPONENT);
|
||||
}
|
||||
|
||||
public static boolean isRegisteredProjectComponent(PsiClass psiClass, GlobalSearchScope scope) {
|
||||
return isRegistered(psiClass, scope, RegistrationType.PROJECT_COMPONENT);
|
||||
return isRegisteredClass(psiClass, scope, RegistrationType.PROJECT_COMPONENT);
|
||||
}
|
||||
|
||||
public static boolean isRegisteredModuleComponent(PsiClass psiClass, GlobalSearchScope scope) {
|
||||
return isRegistered(psiClass, scope, RegistrationType.MODULE_COMPONENT);
|
||||
return isRegisteredClass(psiClass, scope, RegistrationType.MODULE_COMPONENT);
|
||||
}
|
||||
|
||||
public static boolean isRegisteredAction(PsiClass psiClass, GlobalSearchScope scope) {
|
||||
return isRegistered(psiClass, scope, RegistrationType.ACTION);
|
||||
public static boolean isRegisteredActionOrGroup(PsiClass psiClass, GlobalSearchScope scope) {
|
||||
return isRegisteredClass(psiClass, scope, RegistrationType.ACTION);
|
||||
}
|
||||
|
||||
public static boolean processListener(@NotNull Project project,
|
||||
@@ -129,7 +134,10 @@ public class IdeaPluginRegistrationIndex extends PluginXmlIndexBase<String, List
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isRegistered(PsiClass psiClass, GlobalSearchScope scope, RegistrationType type) {
|
||||
/**
|
||||
* @param type {@code null} for any
|
||||
*/
|
||||
private static boolean isRegisteredClass(PsiClass psiClass, GlobalSearchScope scope, @Nullable RegistrationType type) {
|
||||
final String qualifiedName = psiClass.getQualifiedName();
|
||||
if (qualifiedName == null) {
|
||||
return false;
|
||||
@@ -137,7 +145,14 @@ public class IdeaPluginRegistrationIndex extends PluginXmlIndexBase<String, List
|
||||
|
||||
return !FileBasedIndex.getInstance()
|
||||
.processValues(NAME, qualifiedName, null,
|
||||
(file, value) -> ContainerUtil.process(value, entry -> !(entry.getRegistrationType() == type)),
|
||||
(file, value) -> ContainerUtil.process(value, entry -> {
|
||||
RegistrationType registrationType = entry.getRegistrationType();
|
||||
if (type == null) {
|
||||
return !(registrationType.isClass());
|
||||
}
|
||||
|
||||
return !(registrationType == type);
|
||||
}),
|
||||
scope);
|
||||
}
|
||||
|
||||
@@ -149,6 +164,18 @@ public class IdeaPluginRegistrationIndex extends PluginXmlIndexBase<String, List
|
||||
return ContainerUtil.process(keys, s -> processActionOrGroup(project, s, scope, processor));
|
||||
}
|
||||
|
||||
public static boolean processActionOrGroupClass(@NotNull Project project,
|
||||
PsiClass actionOrGroupClass,
|
||||
GlobalSearchScope scope,
|
||||
Processor<? super ActionOrGroup> processor) {
|
||||
String fqn = actionOrGroupClass.getQualifiedName();
|
||||
if (fqn == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return doProcessActionOrGroup(project, fqn, scope, EnumSet.of(RegistrationType.ACTION), processor);
|
||||
}
|
||||
|
||||
public static boolean processActionOrGroup(@NotNull Project project,
|
||||
@NotNull String actionOrGroupId,
|
||||
GlobalSearchScope scope,
|
||||
@@ -173,11 +200,11 @@ public class IdeaPluginRegistrationIndex extends PluginXmlIndexBase<String, List
|
||||
}
|
||||
|
||||
private static boolean doProcessActionOrGroup(@NotNull Project project,
|
||||
@NotNull String actionOrGroupId,
|
||||
@NotNull String key,
|
||||
GlobalSearchScope scope,
|
||||
EnumSet<RegistrationType> types,
|
||||
Processor<? super ActionOrGroup> processor) {
|
||||
List<XmlTag> tags = collectTags(project, actionOrGroupId, scope, types);
|
||||
List<XmlTag> tags = collectTags(project, key, scope, types);
|
||||
|
||||
return ContainerUtil.process(tags, tag -> {
|
||||
final DomElement domElement = DomManager.getDomManager(project).getDomElement(tag);
|
||||
|
||||
@@ -41,16 +41,26 @@ class RegistrationEntry {
|
||||
|
||||
// do not change order
|
||||
enum RegistrationType {
|
||||
ACTION,
|
||||
ACTION(true),
|
||||
|
||||
APPLICATION_COMPONENT,
|
||||
PROJECT_COMPONENT,
|
||||
MODULE_COMPONENT,
|
||||
APPLICATION_COMPONENT(true),
|
||||
PROJECT_COMPONENT(true),
|
||||
MODULE_COMPONENT(true),
|
||||
|
||||
ACTION_ID,
|
||||
ACTION_GROUP_ID,
|
||||
ACTION_ID(false),
|
||||
ACTION_GROUP_ID(false),
|
||||
|
||||
APPLICATION_LISTENER,
|
||||
PROJECT_LISTENER
|
||||
APPLICATION_LISTENER(true),
|
||||
PROJECT_LISTENER(true);
|
||||
|
||||
private final boolean myIsClass;
|
||||
|
||||
RegistrationType(boolean isClass) {
|
||||
myIsClass = isClass;
|
||||
}
|
||||
|
||||
boolean isClass() {
|
||||
return myIsClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 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.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.inspections;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -177,8 +177,8 @@ final class RegistrationCheckerUtil {
|
||||
}
|
||||
|
||||
if (findAll || myRegistrationType == RegistrationType.ACTION) {
|
||||
if (IdeaPluginRegistrationIndex.isRegisteredAction(myPsiClass,
|
||||
scope)) {
|
||||
if (IdeaPluginRegistrationIndex.isRegisteredActionOrGroup(myPsiClass,
|
||||
scope)) {
|
||||
addType(ActionType.ACTION.myClassName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
package org.jetbrains.idea.devkit.navigation;
|
||||
|
||||
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
|
||||
import com.intellij.codeInsight.navigation.DomGotoRelatedItem;
|
||||
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
|
||||
import com.intellij.navigation.GotoRelatedItem;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.text.HtmlBuilder;
|
||||
import com.intellij.openapi.util.text.HtmlChunk;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -25,13 +27,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.PropertyKey;
|
||||
import org.jetbrains.idea.devkit.DevKitBundle;
|
||||
import org.jetbrains.idea.devkit.DevKitIcons;
|
||||
import org.jetbrains.idea.devkit.dom.ActionOrGroup;
|
||||
import org.jetbrains.idea.devkit.dom.Extension;
|
||||
import org.jetbrains.idea.devkit.dom.ExtensionPoint;
|
||||
import org.jetbrains.idea.devkit.dom.Listeners;
|
||||
import org.jetbrains.idea.devkit.util.ActionCandidate;
|
||||
import org.jetbrains.idea.devkit.util.ListenerCandidate;
|
||||
import org.jetbrains.idea.devkit.util.PointableCandidate;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
final class LineMarkerInfoHelper {
|
||||
@@ -39,7 +44,7 @@ final class LineMarkerInfoHelper {
|
||||
private static final NotNullFunction<PointableCandidate, Collection<? extends PsiElement>> CONVERTER =
|
||||
candidate -> ContainerUtil.createMaybeSingletonList(candidate.pointer.getElement());
|
||||
private static final NotNullFunction<PointableCandidate, Collection<? extends GotoRelatedItem>> RELATED_ITEM_PROVIDER =
|
||||
candidate -> GotoRelatedItem.createItems(ContainerUtil.createMaybeSingletonList(candidate.pointer.getElement()), "DevKit");
|
||||
candidate -> Collections.singleton(new DomGotoRelatedItem(DomUtil.getDomElement(candidate.pointer.getElement()), "DevKit"));
|
||||
|
||||
private static final NullableFunction<PointableCandidate, String> EXTENSION_NAMER =
|
||||
createNamer("line.marker.tooltip.extension.declaration", tag -> {
|
||||
@@ -65,6 +70,18 @@ final class LineMarkerInfoHelper {
|
||||
return StringUtil.notNullize(((Listeners.Listener)element).getTopicClassName().getStringValue(), "?");
|
||||
});
|
||||
|
||||
private static final NotNullFunction<XmlTag, @NlsContexts.ListItem String> ACTION_OR_GROUP_NAME_FUNCTION = tag -> {
|
||||
final DomElement element = DomUtil.getDomElement(tag);
|
||||
if (!(element instanceof ActionOrGroup)) return "?";
|
||||
return StringUtil.notNullize(((ActionOrGroup)element).getId().getStringValue(), "?");
|
||||
};
|
||||
|
||||
private static final NullableFunction<PointableCandidate, String> ACTION_NAMER =
|
||||
createNamer("line.marker.tooltip.action.declaration", ACTION_OR_GROUP_NAME_FUNCTION);
|
||||
|
||||
private static final NullableFunction<PointableCandidate, String> ACTION_GROUP_NAMER =
|
||||
createNamer("line.marker.tooltip.action.group.declaration", ACTION_OR_GROUP_NAME_FUNCTION);
|
||||
|
||||
private LineMarkerInfoHelper() {
|
||||
}
|
||||
|
||||
@@ -89,6 +106,18 @@ final class LineMarkerInfoHelper {
|
||||
LISTENER_NAMER);
|
||||
}
|
||||
|
||||
static RelatedItemLineMarkerInfo<?> createActionLineMarkerInfo(List<? extends ActionCandidate> targets, PsiElement element) {
|
||||
return createPluginLineMarkerInfo(targets, element,
|
||||
DevKitBundle.message("gutter.related.navigation.choose.action"),
|
||||
ACTION_NAMER);
|
||||
}
|
||||
|
||||
static RelatedItemLineMarkerInfo<?> createActionGroupLineMarkerInfo(List<? extends ActionCandidate> targets, PsiElement element) {
|
||||
return createPluginLineMarkerInfo(targets, element,
|
||||
DevKitBundle.message("gutter.related.navigation.choose.action.group"),
|
||||
ACTION_GROUP_NAMER);
|
||||
}
|
||||
|
||||
private static @NotNull RelatedItemLineMarkerInfo<PsiElement> createPluginLineMarkerInfo(@NotNull List<? extends PointableCandidate> targets,
|
||||
@NotNull PsiElement element,
|
||||
@Nls(capitalization = Nls.Capitalization.Title) String popup,
|
||||
|
||||
+29
-7
@@ -2,10 +2,12 @@
|
||||
package org.jetbrains.idea.devkit.navigation;
|
||||
|
||||
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.devkit.DevKitBundle;
|
||||
@@ -20,6 +22,7 @@ import java.util.List;
|
||||
/**
|
||||
* Related declaration(s) in {@code plugin.xml} for class registered as:
|
||||
* <ul>
|
||||
* <li>Action/ActionGroup</li>
|
||||
* <li>Listener</li>
|
||||
* <li>Extension</li>
|
||||
* </ul>
|
||||
@@ -48,6 +51,32 @@ public final class PluginDescriptorDeclarationRelatedItemLineMarkerProvider exte
|
||||
Project project = psiClass.getProject();
|
||||
GlobalSearchScope candidatesScope = PluginRelatedLocatorsUtils.getCandidatesScope(project);
|
||||
|
||||
// only EPs are not indexed via IdeaPluginRegistrationIndex
|
||||
if (!IdeaPluginRegistrationIndex.isRegisteredClass(psiClass, candidatesScope)) {
|
||||
List<ExtensionCandidate> epTargets = ExtensionLocatorKt.locateExtensionsByPsiClass(psiClass);
|
||||
if (!epTargets.isEmpty()) {
|
||||
result.add(LineMarkerInfoHelper.createExtensionLineMarkerInfo(epTargets, identifier));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Action/ActionGroup (most likely)
|
||||
// search all candidates, e.g. EmptyAction/NonTrivialActionGroup is registered multiple times
|
||||
if (IdeaPluginRegistrationIndex.isRegisteredActionOrGroup(psiClass, candidatesScope)) {
|
||||
List<ActionCandidate> targets = new SmartList<>();
|
||||
IdeaPluginRegistrationIndex.processActionOrGroupClass(project, psiClass, candidatesScope, actionOrGroup -> {
|
||||
targets.add(new ActionCandidate(actionOrGroup));
|
||||
return true;
|
||||
});
|
||||
if (InheritanceUtil.isInheritor(psiClass, ActionGroup.class.getName())) {
|
||||
result.add(LineMarkerInfoHelper.createActionGroupLineMarkerInfo(targets, identifier));
|
||||
}
|
||||
else {
|
||||
result.add(LineMarkerInfoHelper.createActionLineMarkerInfo(targets, identifier));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Listeners: search for _all_ candidates as
|
||||
// - some listeners are registered on both application- and project-level, e.g. com.intellij.notification.Notifications
|
||||
// - some classes implement multiple listeners, e.g. com.intellij.notification.impl.widget.NotificationWidgetListener
|
||||
@@ -58,13 +87,6 @@ public final class PluginDescriptorDeclarationRelatedItemLineMarkerProvider exte
|
||||
});
|
||||
if (!listenerTargets.isEmpty()) {
|
||||
result.add(LineMarkerInfoHelper.createListenerLineMarkerInfo(listenerTargets, identifier));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
List<ExtensionCandidate> epTargets = ExtensionLocatorKt.locateExtensionsByPsiClass(psiClass);
|
||||
if (!epTargets.isEmpty()) {
|
||||
result.add(LineMarkerInfoHelper.createExtensionLineMarkerInfo(epTargets, identifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.util;
|
||||
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import org.jetbrains.idea.devkit.dom.ActionOrGroup;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ActionCandidate extends PointableCandidate {
|
||||
public ActionCandidate(ActionOrGroup actionOrGroup) {
|
||||
super(SmartPointerManager.createPointer(Objects.requireNonNull(actionOrGroup.getXmlTag())));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
public class My<caret>Action extends com.intellij.openapi.actionSystem.AnAction {}
|
||||
+1
@@ -0,0 +1 @@
|
||||
public class My<caret>ActionGroup extends com.intellij.openapi.actionSystem.ActionGroup {}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<idea-plugin>
|
||||
<actions>
|
||||
<group class="MyActionGroup" id="firstDeclaration"/>
|
||||
</actions>
|
||||
<actions>
|
||||
<group class="MyActionGroup" id="secondDeclaration"/>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<idea-plugin>
|
||||
<actions>
|
||||
<action class="MyAction" id="firstDeclaration" icon="AllIcons.Actions.AddFile"/>
|
||||
</actions>
|
||||
<actions>
|
||||
<action class="MyAction" id="secondDeclaration"/>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<idea-plugin>
|
||||
<actions>
|
||||
<action class="MyAction" id="singleDeclaration"/>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.navigation;
|
||||
|
||||
import com.intellij.codeInsight.daemon.GutterMark;
|
||||
import com.intellij.codeInsight.navigation.DomGotoRelatedItem;
|
||||
import com.intellij.codeInsight.navigation.NavigationUtil;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.navigation.GotoRelatedItem;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.idea.devkit.DevKitIcons;
|
||||
import org.jetbrains.idea.devkit.DevkitJavaTestsUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@TestDataPath("$CONTENT_ROOT/testData/navigation/actionDeclaration")
|
||||
public class ActionDeclarationRelatedItemLineMarkerProviderTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return DevkitJavaTestsUtil.TESTDATA_PATH + "navigation/actionDeclaration";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) {
|
||||
String platformEditorJar = PathUtil.getJarPathForClass(AnAction.class);
|
||||
moduleBuilder.addLibrary("platform-editor", platformEditorJar);
|
||||
String platformIdeJar = PathUtil.getJarPathForClass(JBList.class);
|
||||
moduleBuilder.addLibrary("platform-ide", platformIdeJar);
|
||||
String platformUtilJar = PathUtil.getJarPathForClass(AllIcons.class);
|
||||
moduleBuilder.addLibrary("platform-util", platformUtilJar);
|
||||
}
|
||||
|
||||
public void testActionSingleDeclaration() {
|
||||
VirtualFile pluginXmlFile = myFixture.copyFileToProject("pluginActionSingleDeclaration.xml");
|
||||
|
||||
GutterMark gutter = myFixture.findGutter("MyAction.java");
|
||||
DevKitGutterTargetsChecker.checkGutterTargets(gutter,
|
||||
"<html><body>" +
|
||||
buildTooltipText(pluginXmlFile, 30, "singleDeclaration", "action") +
|
||||
"</body></html>",
|
||||
DevKitIcons.Gutter.Plugin, "action");
|
||||
}
|
||||
|
||||
public void testActionMultipleDeclarations() {
|
||||
VirtualFile pluginXmlFile = myFixture.copyFileToProject("pluginActionMultipleDeclarations.xml");
|
||||
|
||||
GutterMark gutter = myFixture.findGutter("MyAction.java");
|
||||
DevKitGutterTargetsChecker.checkGutterTargets(gutter,
|
||||
"<html><body>" +
|
||||
buildTooltipText(pluginXmlFile, 140, "secondDeclaration", "action") +
|
||||
buildTooltipText(pluginXmlFile, 30, "firstDeclaration", "action") +
|
||||
"</body></html>",
|
||||
DevKitIcons.Gutter.Plugin, "action");
|
||||
|
||||
List<GotoRelatedItem> relatedItems = NavigationUtil.collectRelatedItems(myFixture.findClass("MyAction"), null);
|
||||
assertSize(2, relatedItems);
|
||||
DomGotoRelatedItem first = assertInstanceOf(relatedItems.get(0), DomGotoRelatedItem.class);
|
||||
assertEquals("DevKit", first.getGroup());
|
||||
assertEquals("firstDeclaration", first.getCustomName());
|
||||
assertEquals(AllIcons.Actions.AddFile, first.getCustomIcon());
|
||||
}
|
||||
|
||||
public void testActionGroupMultipleDeclarations() {
|
||||
VirtualFile pluginXmlFile = myFixture.copyFileToProject("pluginActionGroupMultipleDeclarations.xml");
|
||||
|
||||
GutterMark gutter = myFixture.findGutter("MyActionGroup.java");
|
||||
DevKitGutterTargetsChecker.checkGutterTargets(gutter,
|
||||
"<html><body>" +
|
||||
buildTooltipText(pluginXmlFile, 112, "secondDeclaration", "action group") +
|
||||
buildTooltipText(pluginXmlFile, 30, "firstDeclaration", "action group") +
|
||||
"</body></html>",
|
||||
DevKitIcons.Gutter.Plugin, "group");
|
||||
}
|
||||
|
||||
private String buildTooltipText(VirtualFile pluginXmlFile, int expectedTagPosition, String actionId, String actionType) {
|
||||
String pluginXmlPath = pluginXmlFile.getPath();
|
||||
|
||||
String color = ColorUtil.toHex(UIUtil.getInactiveTextColor());
|
||||
return " <a href=\"#navigation/" + pluginXmlPath
|
||||
+ ":" + expectedTagPosition + "\">" + actionId + "</a> " + actionType + " in " + pluginXmlFile.getName() +
|
||||
" <font color=\"" + color + "\">[" + getModule().getName() + "]</font><br>";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user