Code Hierarchy
Code hierarchy views allow developers to explore structural relationships in their code. Consulo supports three hierarchy views: Type Hierarchy (supertypes and subtypes of a class), Method Hierarchy (overriding and implementing methods across a class hierarchy), and Call Hierarchy (callers and callees of a method). Each view is provided by implementing a dedicated provider interface.
HierarchyProvider
HierarchyProvider is the base interface for all hierarchy providers. It implements LanguageExtension and defines three methods that every hierarchy provider must implement:
| Method | Description |
|---|---|
getTarget(DataContext dataContext) |
Returns the PSI element for which the hierarchy should be displayed, based on the current action context. Returns null if the action is not applicable. |
createHierarchyBrowser(PsiElement target) |
Creates a HierarchyBrowser instance for viewing the hierarchy of the specified element. |
browserActivated(HierarchyBrowser hierarchyBrowser) |
Called when the hierarchy tool window is shown and the given browser is currently displayed. |
HierarchyBrowser
HierarchyBrowser represents the UI component displayed in the Hierarchy tool window. It defines:
| Method | Description |
|---|---|
getComponent() |
Returns the JComponent to be displayed in the tool window. |
setContent(Content content) |
Notifies the browser that it is being displayed in the specified Content tab. |
TypeHierarchyProvider
TypeHierarchyProvider is annotated with @ExtensionAPI(ComponentScope.APPLICATION) and extends HierarchyProvider. It provides the Type Hierarchy view, which shows supertypes and subtypes of a selected class or type.
Registration
import consulo.annotation.component.ExtensionImpl;
import consulo.dataContext.DataContext;
import consulo.language.Language;
import consulo.language.editor.hierarchy.HierarchyBrowser;
import consulo.language.editor.hierarchy.TypeHierarchyProvider;
import consulo.language.psi.PsiElement;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
@ExtensionImpl
public class MyTypeHierarchyProvider implements TypeHierarchyProvider {
@Nonnull
@Override
public Language getLanguage() {
return MyLanguage.INSTANCE;
}
@Nullable
@Override
public PsiElement getTarget(@Nonnull DataContext dataContext) {
// Extract the class element from the data context
// Return null if the caret is not on a class declaration
return findTargetClass(dataContext);
}
@Nonnull
@Override
public HierarchyBrowser createHierarchyBrowser(PsiElement target) {
// Create and return a browser component showing the type hierarchy
return new MyTypeHierarchyBrowser(target);
}
@Override
public void browserActivated(@Nonnull HierarchyBrowser hierarchyBrowser) {
// Perform any setup needed when the browser is displayed
}
// ... helper methods omitted for brevity
}
MethodHierarchyProvider
MethodHierarchyProvider is annotated with @ExtensionAPI(ComponentScope.APPLICATION) and extends HierarchyProvider. It provides the Method Hierarchy view, which shows how a method is overridden or implemented across the type hierarchy.
Registration
import consulo.annotation.component.ExtensionImpl;
import consulo.dataContext.DataContext;
import consulo.language.Language;
import consulo.language.editor.hierarchy.HierarchyBrowser;
import consulo.language.editor.hierarchy.MethodHierarchyProvider;
import consulo.language.psi.PsiElement;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
@ExtensionImpl
public class MyMethodHierarchyProvider implements MethodHierarchyProvider {
@Nonnull
@Override
public Language getLanguage() {
return MyLanguage.INSTANCE;
}
@Nullable
@Override
public PsiElement getTarget(@Nonnull DataContext dataContext) {
// Extract the method element from the data context
return findTargetMethod(dataContext);
}
@Nonnull
@Override
public HierarchyBrowser createHierarchyBrowser(PsiElement target) {
return new MyMethodHierarchyBrowser(target);
}
@Override
public void browserActivated(@Nonnull HierarchyBrowser hierarchyBrowser) {
// Perform any setup needed when the browser is displayed
}
}
CallHierarchyProvider
CallHierarchyProvider is annotated with @ExtensionAPI(ComponentScope.APPLICATION) and extends HierarchyProvider. It provides the Call Hierarchy view, which shows the callers (and optionally callees) of a selected method.
Registration
import consulo.annotation.component.ExtensionImpl;
import consulo.dataContext.DataContext;
import consulo.language.Language;
import consulo.language.editor.hierarchy.CallHierarchyProvider;
import consulo.language.editor.hierarchy.HierarchyBrowser;
import consulo.language.psi.PsiElement;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
@ExtensionImpl
public class MyCallHierarchyProvider implements CallHierarchyProvider {
@Nonnull
@Override
public Language getLanguage() {
return MyLanguage.INSTANCE;
}
@Nullable
@Override
public PsiElement getTarget(@Nonnull DataContext dataContext) {
// Extract the method/function element from the data context
return findTargetCallable(dataContext);
}
@Nonnull
@Override
public HierarchyBrowser createHierarchyBrowser(PsiElement target) {
return new MyCallHierarchyBrowser(target);
}
@Override
public void browserActivated(@Nonnull HierarchyBrowser hierarchyBrowser) {
// Perform any setup needed when the browser is displayed
}
}
Implementation Notes
All three hierarchy provider interfaces -- TypeHierarchyProvider, MethodHierarchyProvider, and CallHierarchyProvider -- inherit the same three methods from HierarchyProvider. The only difference is the semantic contract: each interface is registered as its own extension point so the platform knows which provider to invoke for which hierarchy action.
The typical implementation pattern is:
- In
getTarget(), use theDataContextto locate the relevant PSI element (class, method, or callable) at the current caret position. Returnnullif the context is not applicable. - In
createHierarchyBrowser(), construct aHierarchyBrowserthat builds and displays the tree structure for the target element. - In
browserActivated(), perform any additional initialization after the hierarchy tool window becomes visible (for example, selecting the initial view or expanding nodes).