@Override
public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
final PsiElement at = file.findElementAt(editor.getCaretModel().getOffset());
final DartComponent component = PsiTreeUtil.getParentOfType(at, DartComponent.class);
final DartClass dartClass = PsiTreeUtil.getParentOfType(at, DartClass.class);
if (at == null || dartClass == null || component == null) return;
final List<DartClass> supers = new ArrayList<DartClass>();
final DartType superClass = dartClass.getSuperClass();
// looks like there's no sense in jumping to Object class
if (superClass != null && !DartResolveUtil.OBJECT.equals(superClass.getReferenceExpression().getText())) {
final DartClassResolveResult dartClassResolveResult = DartResolveUtil.resolveClassByType(superClass);
if (dartClassResolveResult.getDartClass() != null) {
supers.add(dartClassResolveResult.getDartClass());
}
}
List<DartClassResolveResult> implementsAndMixinsList =
DartResolveUtil.resolveClassesByTypes(DartResolveUtil.getImplementsAndMixinsList(dartClass));
for (DartClassResolveResult resolveResult : implementsAndMixinsList) {
final DartClass resolveResultDartClass = resolveResult.getDartClass();
if (resolveResultDartClass != null) {
supers.add(resolveResultDartClass);
}
}
final List<DartComponent> superItems = DartResolveUtil.findNamedSubComponents(false, supers.toArray(new DartClass[supers.size()]));
final DartComponentType type = DartComponentType.typeOf(component);
if (type == DartComponentType.METHOD) {
tryNavigateToSuperMethod(editor, component, superItems);
}
else if (!supers.isEmpty() && component instanceof DartClass) {
PsiElementListNavigator.openTargets(
editor,
DartResolveUtil.getComponentNames(supers).toArray(new NavigatablePsiElement[supers.size()]),
DaemonBundle.message("navigation.title.subclass", component.getName(), supers.size()),
"Subclasses of " + component.getName(),
new DefaultPsiElementCellRenderer()
);
}
}