update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInsight / daemon / impl / MarkerType.java
blobfdffd64eead2a83f758029119e8c0a6f916f0fd3
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @author max
20 package com.intellij.codeInsight.daemon.impl;
22 import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
23 import com.intellij.codeInsight.daemon.DaemonBundle;
24 import com.intellij.codeInsight.CodeInsightBundle;
25 import com.intellij.psi.*;
26 import com.intellij.psi.util.PsiUtil;
27 import com.intellij.psi.search.PsiElementProcessor;
28 import com.intellij.psi.search.PsiElementProcessorAdapter;
29 import com.intellij.psi.search.searches.OverridingMethodsSearch;
30 import com.intellij.psi.search.searches.ClassInheritorsSearch;
31 import com.intellij.util.Function;
32 import com.intellij.util.NullableFunction;
33 import com.intellij.util.CommonProcessors;
34 import com.intellij.ide.util.MethodCellRenderer;
35 import com.intellij.ide.util.PsiClassListCellRenderer;
36 import com.intellij.openapi.progress.ProgressManager;
37 import org.jetbrains.annotations.NonNls;
39 import javax.swing.*;
40 import java.util.Comparator;
41 import java.util.Arrays;
42 import java.awt.event.MouseEvent;
44 public enum MarkerType {
45 OVERRIDING_METHOD(new NullableFunction<PsiElement, String>() {
46 public String fun(PsiElement element) {
47 PsiElement parent = element.getParent();
48 if (!(parent instanceof PsiMethod)) return null;
49 PsiMethod method = (PsiMethod)parent;
51 PsiMethod[] superMethods = method.findSuperMethods(false);
52 if (superMethods.length == 0) return null;
54 PsiMethod superMethod = superMethods[0];
55 boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
56 boolean isSuperAbstract = superMethod.hasModifierProperty(PsiModifier.ABSTRACT);
58 final boolean sameSignature = superMethod.getSignature(PsiSubstitutor.EMPTY).equals(method.getSignature(PsiSubstitutor.EMPTY));
59 @NonNls final String key;
60 if (isSuperAbstract && !isAbstract){
61 key = sameSignature ? "method.implements" : "method.implements.in";
63 else{
64 key = sameSignature ? "method.overrides" : "method.overrides.in";
66 return GutterIconTooltipHelper.composeText(superMethods, "", DaemonBundle.message(key));
68 }, new LineMarkerNavigator(){
69 public void browse(MouseEvent e, PsiElement element) {
70 PsiElement parent = element.getParent();
71 if (!(parent instanceof PsiMethod)) return;
72 PsiMethod method = (PsiMethod)parent;
73 PsiMethod[] superMethods = method.findSuperMethods(false);
74 if (superMethods.length == 0) return;
75 boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(superMethods);
76 PsiElementListNavigator.openTargets(e, superMethods,
77 DaemonBundle.message("navigation.title.super.method", method.getName()),
78 new MethodCellRenderer(showMethodNames));
81 }),
82 OVERRIDEN_METHOD(new NullableFunction<PsiElement, String>() {
83 public String fun(PsiElement element) {
84 PsiElement parent = element.getParent();
85 if (!(parent instanceof PsiMethod)) return null;
86 PsiMethod method = (PsiMethod)parent;
88 PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5);
89 OverridingMethodsSearch.search(method, method.getUseScope(), true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor));
91 boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
93 if (processor.isOverflow()){
94 return isAbstract ? DaemonBundle.message("method.is.implemented.too.many") : DaemonBundle.message("method.is.overridden.too.many");
97 PsiMethod[] overridings = processor.toArray(new PsiMethod[processor.getCollection().size()]);
98 if (overridings.length == 0) return null;
100 Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator();
101 Arrays.sort(overridings, comparator);
103 String start = isAbstract ? DaemonBundle.message("method.is.implemented.header") : DaemonBundle.message("method.is.overriden.header");
104 @NonNls String pattern = "&nbsp;&nbsp;&nbsp;&nbsp;{1}";
105 return GutterIconTooltipHelper.composeText(overridings, start, pattern);
107 }, new LineMarkerNavigator(){
108 public void browse(MouseEvent e, PsiElement element) {
109 PsiElement parent = element.getParent();
110 if (!(parent instanceof PsiMethod)) return;
112 final PsiMethod method = (PsiMethod)parent;
113 final CommonProcessors.CollectProcessor<PsiMethod> collectProcessor = new CommonProcessors.CollectProcessor<PsiMethod>();
114 if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
115 public void run() {
116 OverridingMethodsSearch.search(method, method.getUseScope(), true).forEach(collectProcessor);
118 }, "Searching for overridding methods", true, method.getProject(), (JComponent)e.getComponent())) {
119 return;
122 PsiMethod[] overridings = collectProcessor.toArray(PsiMethod.EMPTY_ARRAY);
123 if (overridings.length == 0) return;
124 String title = method.hasModifierProperty(PsiModifier.ABSTRACT) ?
125 DaemonBundle .message("navigation.title.implementation.method", method.getName(), overridings.length) :
126 DaemonBundle.message("navigation.title.overrider.method", method.getName(), overridings.length);
127 boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(overridings);
128 MethodCellRenderer renderer = new MethodCellRenderer(showMethodNames);
129 Arrays.sort(overridings, renderer.getComparator());
130 PsiElementListNavigator.openTargets(e, overridings, title, renderer);
134 SUBCLASSED_CLASS(new NullableFunction<PsiElement, String>() {
135 public String fun(PsiElement element) {
136 PsiElement parent = element.getParent();
137 if (!(parent instanceof PsiClass)) return null;
138 PsiClass aClass = (PsiClass)parent;
139 PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiClass>(5);
140 ClassInheritorsSearch.search(aClass, aClass.getUseScope(), true).forEach(new PsiElementProcessorAdapter<PsiClass>(processor));
142 if (processor.isOverflow()) {
143 return aClass.isInterface()
144 ? DaemonBundle.message("interface.is.implemented.too.many")
145 : DaemonBundle.message("class.is.subclassed.too.many");
148 PsiClass[] subclasses = processor.toArray(new PsiClass[processor.getCollection().size()]);
149 if (subclasses.length == 0) return null;
151 Comparator<PsiClass> comparator = new PsiClassListCellRenderer().getComparator();
152 Arrays.sort(subclasses, comparator);
154 String start = aClass.isInterface()
155 ? DaemonBundle.message("interface.is.implemented.by.header")
156 : DaemonBundle.message("class.is.subclassed.by.header");
157 @NonNls String pattern = "&nbsp;&nbsp;&nbsp;&nbsp;{0}";
158 return GutterIconTooltipHelper.composeText(subclasses, start, pattern);
160 }, new LineMarkerNavigator(){
161 public void browse(MouseEvent e, PsiElement element) {
162 PsiElement parent = element.getParent();
163 if (!(parent instanceof PsiClass)) return;
165 final PsiClass aClass = (PsiClass)parent;
166 final CommonProcessors.CollectProcessor<PsiClass> collectProcessor = new CommonProcessors.CollectProcessor<PsiClass>();
167 if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
168 public void run() {
169 ClassInheritorsSearch.search(aClass, aClass.getUseScope(), true).forEach(collectProcessor);
171 }, "Searching for overridden methods", true, aClass.getProject(), (JComponent)e.getComponent())) {
172 return;
175 PsiClass[] inheritors = collectProcessor.toArray(PsiClass.EMPTY_ARRAY);
176 if (inheritors.length == 0) return;
177 String title = aClass.isInterface()
178 ? CodeInsightBundle.message("goto.implementation.chooser.title", aClass.getName(), inheritors.length)
179 : DaemonBundle.message("navigation.title.subclass", aClass.getName(), inheritors.length);
180 PsiClassListCellRenderer renderer = new PsiClassListCellRenderer();
181 Arrays.sort(inheritors, renderer.getComparator());
182 PsiElementListNavigator.openTargets(e, inheritors, title, renderer);
186 private final GutterIconNavigationHandler handler;
187 private final Function<? super PsiElement, String> myTooltip;
189 MarkerType(Function<? super PsiElement, String> tooltip, final LineMarkerNavigator navigator) {
190 myTooltip = tooltip;
191 handler = new GutterIconNavigationHandler() {
192 public void navigate(MouseEvent e, PsiElement elt) {
193 navigator.browse(e, elt);
198 public <T extends PsiElement> GutterIconNavigationHandler<T> getNavigationHandler() {
199 return handler;
202 public <T extends PsiElement> Function<T, String> getTooltip() {
203 return (Function<T, String>)myTooltip;