From 9015f21a2973f41b1882636fce165d938ed942c1 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 24 May 2012 16:14:31 +0200 Subject: [PATCH] down arrows for Kotlin classes --- .../highlighter/JetLineMarkerProvider.java | 60 +++++++++++++++++++ .../KotlinDirectInheritorsSearcher.java | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java index f559f098e1c..ba9cf70b2d3 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java @@ -21,24 +21,31 @@ import com.intellij.codeHighlighting.Pass; import com.intellij.codeInsight.daemon.GutterIconNavigationHandler; import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProvider; +import com.intellij.codeInsight.daemon.impl.MarkerType; import com.intellij.codeInsight.hint.HintUtil; import com.intellij.codeInsight.navigation.NavigationUtil; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Function; import com.intellij.util.PsiNavigateUtil; +import org.jetbrains.jet.asJava.JetLightClass; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.Modality; +import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.codeInsight.JetFunctionPsiElementCellRenderer; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.resolve.DescriptorRenderer; @@ -55,6 +62,38 @@ import java.util.Set; public class JetLineMarkerProvider implements LineMarkerProvider { public static final Icon OVERRIDING_MARK = IconLoader.getIcon("/gutter/overridingMethod.png"); public static final Icon IMPLEMENTING_MARK = IconLoader.getIcon("/gutter/implementingMethod.png"); + protected static final Icon OVERRIDDEN_MARK = IconLoader.getIcon("/gutter/overridenMethod.png"); + + private static final Function SUBCLASSED_CLASS_TOOLTIP_ADAPTER = new Function() { + @Override + public String fun(PsiElement element) { + PsiElement child = getPsiClassFirstChild(element); + // Java puts its marker on a child of the PsiClass, so we must find a child of our own class too + return child != null ? MarkerType.SUBCLASSED_CLASS.getTooltip().fun(child) : null; + } + }; + + private static PsiElement getPsiClassFirstChild(PsiElement element) { + if (!(element instanceof JetClass)) { + element = element.getParent(); + if (!(element instanceof JetClass)) { + return null; + } + } + final PsiClass lightClass = JetLightClass.wrapDelegate((JetClass) element).getDelegate(); + final PsiElement[] children = lightClass.getChildren(); + return children.length > 0 ? children[0] : null; + } + + private static final GutterIconNavigationHandler SUBCLASSED_CLASS_NAVIGATION_HANDLER = new GutterIconNavigationHandler() { + @Override + public void navigate(MouseEvent e, PsiElement elt) { + PsiElement child = getPsiClassFirstChild(elt); + if (child != null) { + MarkerType.SUBCLASSED_CLASS.getNavigationHandler().navigate(e, child); + } + } + }; @Override public LineMarkerInfo getLineMarkerInfo(final PsiElement element) { @@ -141,5 +180,26 @@ public class JetLineMarkerProvider implements LineMarkerProvider { @Override public void collectSlowLineMarkers(List elements, Collection result) { + if (elements.isEmpty() || DumbService.getInstance(elements.get(0).getProject()).isDumb()) { + return; + } + for (PsiElement element : elements) { + if (element instanceof JetClass) { + collectInheritingClasses((JetClass)element, result); + } + } + } + + private static void collectInheritingClasses(JetClass element, Collection result) { + if (!element.hasModifier(JetTokens.OPEN_KEYWORD)) { + return; + } + PsiClass inheritor = ClassInheritorsSearch.search(JetLightClass.wrapDelegate(element), false).findFirst(); + if (inheritor != null) { + final PsiElement nameIdentifier = element.getNameIdentifier(); + PsiElement anchor = nameIdentifier != null ? nameIdentifier : element; + result.add(new LineMarkerInfo(anchor, anchor.getTextOffset(), OVERRIDDEN_MARK, Pass.UPDATE_OVERRIDEN_MARKERS, + SUBCLASSED_CLASS_TOOLTIP_ADAPTER, SUBCLASSED_CLASS_NAVIGATION_HANDLER)); + } } } diff --git a/idea/src/org/jetbrains/jet/plugin/references/KotlinDirectInheritorsSearcher.java b/idea/src/org/jetbrains/jet/plugin/references/KotlinDirectInheritorsSearcher.java index bf2dda9ba17..cc505252f36 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/KotlinDirectInheritorsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/references/KotlinDirectInheritorsSearcher.java @@ -56,7 +56,7 @@ public class KotlinDirectInheritorsSearcher extends QueryExecutorBase