diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java index c9e0464afd22..003761e3a728 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java @@ -27,7 +27,9 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.FunctionUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -81,6 +83,12 @@ public class RecursiveCallLineMarkerProvider extends LineMarkerProviderDescripto return "Recursive call"; } + @Nullable + @Override + public Icon getIcon() { + return AllIcons.Gutter.RecursiveMethod; + } + private static class RecursiveMethodCallMarkerInfo extends LineMarkerInfo { private RecursiveMethodCallMarkerInfo(@NotNull PsiMethodCallExpression methodCall) { super(methodCall, diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java index 2efa191e2d2c..dce57dab7024 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java @@ -16,30 +16,30 @@ package com.intellij.application.options.editor; import com.intellij.codeInsight.daemon.*; -import com.intellij.codeInsight.daemon.LineMarkerSettings; +import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.lang.LanguageExtensionPoint; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.ui.CheckBoxList; +import com.intellij.ui.SeparatorWithText; import com.intellij.util.Function; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.EmptyIcon; -import gnu.trove.THashSet; -import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; +import java.util.*; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; /** * @author Dmitry Avdeev @@ -48,6 +48,7 @@ public class GutterIconsConfigurable implements Configurable { private JPanel myPanel; private CheckBoxList myList; private List myDescriptors; + private Map myFirstDescriptors = new HashMap(); @Nls @Override @@ -65,33 +66,40 @@ public class GutterIconsConfigurable implements Configurable { @Override public JComponent createComponent() { ExtensionPoint point = Extensions.getRootArea().getExtensionPoint(LineMarkerProviders.EP_NAME); + @SuppressWarnings("unchecked") LanguageExtensionPoint[] extensions = (LanguageExtensionPoint[])point.getExtensions(); - List descriptors = ContainerUtil - .mapNotNull(extensions, new NullableFunction, LineMarkerProviderDescriptor>() { + NullableFunction, PluginDescriptor> function = + new NullableFunction, PluginDescriptor>() { @Nullable @Override - public LineMarkerProviderDescriptor fun(LanguageExtensionPoint point) { + public PluginDescriptor fun(LanguageExtensionPoint point) { LineMarkerProvider instance = point.getInstance(); - if (instance instanceof LineMarkerProviderDescriptor) { - LineMarkerProviderDescriptor descriptor = (LineMarkerProviderDescriptor)instance; - return descriptor.getName() == null ? null : descriptor; - } - return null; + return instance instanceof LineMarkerProviderDescriptor && ((LineMarkerProviderDescriptor)instance).getName() != null ? point.getPluginDescriptor() : null; } - }); - myDescriptors = new ArrayList(new THashSet(descriptors, - new TObjectHashingStrategy() { - @Override - public int computeHashCode(LineMarkerProviderDescriptor object) { - return object.getClass().hashCode(); - } - - @Override - public boolean equals(LineMarkerProviderDescriptor o1, - LineMarkerProviderDescriptor o2) { - return o1.getClass().equals(o2.getClass()); - } - })); + }; + MultiMap> map = ContainerUtil.groupBy(Arrays.asList(extensions), function); + myDescriptors = new ArrayList(); + for (final PluginDescriptor descriptor : map.keySet()) { + Collection> points = map.get(descriptor); + final AtomicBoolean first = new AtomicBoolean(true); + for (LanguageExtensionPoint extensionPoint : points) { + GutterIconDescriptor instance = (GutterIconDescriptor)extensionPoint.getInstance(); + if (instance.getOptions().length > 0) { + for (GutterIconDescriptor option : instance.getOptions()) { + if (first.getAndSet(false)) { + myFirstDescriptors.put(instance, descriptor); + } + myDescriptors.add(option); + } + } + else { + if (first.getAndSet(false)) { + myFirstDescriptors.put(instance, descriptor); + } + myDescriptors.add(instance); + } + } + } List options = new ArrayList(); for (Iterator iterator = myDescriptors.iterator(); iterator.hasNext(); ) { GutterIconDescriptor descriptor = iterator.next(); @@ -156,6 +164,15 @@ public class GutterIconsConfigurable implements Configurable { panel.add(checkBox, BorderLayout.CENTER); panel.setBackground(rootComponent.getBackground()); checkBox.setBorder(null); + + PluginDescriptor pluginDescriptor = myFirstDescriptors.get(descriptor); + if (pluginDescriptor instanceof IdeaPluginDescriptor) { + SeparatorWithText separator = new SeparatorWithText(); + String name = ((IdeaPluginDescriptor)pluginDescriptor).getName(); + separator.setCaption("IDEA CORE".equals(name) ? "Platform" : name); + panel.add(separator, BorderLayout.NORTH); + } + return panel; } };