private List<? extends PsiNamedElement> getNamedChildren(final PsiElement psiElement) { List<PsiNamedElement> children = Arrays.stream(psiElement.getChildren()) .filter(child -> child instanceof PsiNamedElement) .map(child -> (PsiNamedElement) child) .collect(Collectors.toList()); if (children.isEmpty()) { Optional<PsiElement> navigatablePsiElement = Arrays.stream(psiElement.getChildren()) .filter(child -> child instanceof NavigatablePsiElement) .filter(child -> !(child instanceof JsonStringLiteral)) .findFirst(); return navigatablePsiElement.isPresent() ? getNamedChildren(navigatablePsiElement.get()) : new ArrayList<>(); } return new ArrayList<>(children); }
private Optional<? extends PsiElement> getChildByName(final PsiElement psiElement, final String name) { if (ROOT_PATH.equals(name)) { return Optional.of(psiElement); } List<PsiNamedElement> children = Arrays.stream(psiElement.getChildren()) .filter(child -> child instanceof PsiNamedElement) .map(child -> (PsiNamedElement) child) .collect(Collectors.toList()); if (children.isEmpty()) { Optional<PsiElement> navigatablePsiElement = Arrays.stream(psiElement.getChildren()) .filter(child -> child instanceof NavigatablePsiElement) .filter(child -> !(child instanceof JsonStringLiteral)) .findFirst(); return navigatablePsiElement.isPresent() ? getChildByName(navigatablePsiElement.get(), name) : Optional.empty(); } return children.stream() .filter(child -> name.equals(child.getName())) .findFirst(); }
@Nullable private static JBPopup navigateOrCreatePopup(final NavigatablePsiElement[] targets, final String title, final String findUsagesTitle, final ListCellRenderer listRenderer, @Nullable final ListBackgroundUpdaterTask listUpdaterTask) { return navigateOrCreatePopup(targets, title, findUsagesTitle, listRenderer, listUpdaterTask, new Consumer<Object[]>() { @Override public void consume(Object[] selectedElements) { for (Object element : selectedElements) { PsiElement selected = (PsiElement)element; LOG.assertTrue(selected.isValid()); ((NavigatablePsiElement)selected).navigate(true); } } }); }
@Nullable private static JBPopup navigateOrCreatePopup(final NavigatablePsiElement[] targets, final String title, final String findUsagesTitle, final ListCellRenderer listRenderer, final @Nullable ListBackgroundUpdaterTask listUpdaterTask) { return navigateOrCreatePopup(targets, title, findUsagesTitle, listRenderer, listUpdaterTask, new Consumer<Object[]>() { @Override public void consume(Object[] selectedElements) { for (Object element : selectedElements) { PsiElement selected = (PsiElement)element; LOG.assertTrue(selected.isValid()); ((NavigatablePsiElement)selected).navigate(true); } } }); }
@RequiredReadAction public static void openTargets(@NotNull Collection<? extends PsiElement> members, @NotNull MouseEvent mouseEvent, @NotNull String text, @NotNull final Function<PsiElement, PsiElement> map) { NavigatablePsiElement[] navigatablePsiElements = members.toArray(new NavigatablePsiElement[members.size()]); ContainerUtil.sort(navigatablePsiElements, (o1, o2) -> { PsiElement map1 = map.fun(o1); PsiElement map2 = map.fun(o2); if(map1 instanceof PsiNamedElement && map2 instanceof PsiNamedElement) { return Comparing.compare(((PsiNamedElement) map1).getName(), ((PsiNamedElement) map2).getName()); } return 0; }); PsiElementListNavigator.openTargets(mouseEvent, navigatablePsiElements, text, text, new PsiMappedElementListCellRender(map)); }
private static void tryNavigateToSuperMethod(Editor editor, HaxeMethod methodDeclaration, List<HaxeNamedComponent> superItems) { final String methodName = methodDeclaration.getName(); if (methodName == null) { return; } final List<HaxeNamedComponent> filteredSuperItems = ContainerUtil.filter(superItems, new Condition<HaxeNamedComponent>() { @Override public boolean value(HaxeNamedComponent component) { return methodName.equals(component.getName()); } }); if (!filteredSuperItems.isEmpty()) { PsiElementListNavigator.openTargets(editor, HaxeResolveUtil.getComponentNames(filteredSuperItems) .toArray(new NavigatablePsiElement[filteredSuperItems.size()]), DaemonBundle.message("navigation.title.super.method", methodName), null, new DefaultPsiElementCellRenderer()); } }
private static void tryNavigateToSuperMethod(Editor editor, HaxeComponentWithDeclarationList methodDeclaration, List<HaxeNamedComponent> superItems) { final String methodName = methodDeclaration.getName(); if (methodName == null) { return; } final List<HaxeNamedComponent> filteredSuperItems = ContainerUtil.filter(superItems, new Condition<HaxeNamedComponent>() { @Override public boolean value(HaxeNamedComponent component) { return methodName.equals(component.getName()); } }); if (!filteredSuperItems.isEmpty()) { PsiElementListNavigator.openTargets(editor, HaxeResolveUtil.getComponentNames(filteredSuperItems) .toArray(new NavigatablePsiElement[filteredSuperItems.size()]), DaemonBundle.message("navigation.title.super.method", methodName), null, new DefaultPsiElementCellRenderer()); } }
public static void openTargets(MouseEvent e, NavigatablePsiElement[] targets, String title, final String findUsagesTitle, ListCellRenderer listRenderer, @Nullable ListBackgroundUpdaterTask listUpdaterTask) { JBPopup popup = navigateOrCreatePopup(targets, title, findUsagesTitle, listRenderer, listUpdaterTask); if (popup != null) { if (listUpdaterTask != null) { Alarm alarm = new Alarm(popup); alarm.addRequest(() -> popup.show(new RelativePoint(e)), 300); ProgressManager.getInstance().run(listUpdaterTask); } else { popup.show(new RelativePoint(e)); } } }
@Override public void navigate(final MouseEvent e, final T elt) { final List<NavigatablePsiElement> navElements = new ArrayList<NavigatablePsiElement>(); Query<T> elementQuery = search(elt); if(elementQuery == null) { return; } elementQuery.forEach(new Processor<T>() { @Override public boolean process(final T psiElement) { if(psiElement instanceof NavigatablePsiElement) { navElements.add((NavigatablePsiElement) psiElement); } return true; } }); final NavigatablePsiElement[] methods = navElements.toArray(new NavigatablePsiElement[navElements.size()]); PsiElementListNavigator.openTargets(e, methods, getTitle(elt), "", new DefaultPsiElementCellRenderer()); }
@Nullable @Override public String getPresentableText() { final NavigatablePsiElement element = getElement(); final ItemPresentation presentation = element == null ? null : element.getPresentation(); return presentation == null ? null : presentation.getPresentableText(); }
public static void openTargets(MouseEvent e, NavigatablePsiElement[] targets, String title, final String findUsagesTitle, ListCellRenderer listRenderer, @Nullable ListBackgroundUpdaterTask listUpdaterTask) { JBPopup popup = navigateOrCreatePopup(targets, title, findUsagesTitle, listRenderer, listUpdaterTask); if (popup != null) popup.show(new RelativePoint(e)); }
private Navigatable getNavigatable(HierarchyNodeDescriptor descriptor) { if (descriptor instanceof Navigatable && descriptor.isValid()) { return (Navigatable)descriptor; } PsiElement element = getElementFromDescriptor(descriptor); if (element instanceof NavigatablePsiElement && element.isValid()) { return (NavigatablePsiElement)element; } return null; }
public void navigate(final MouseEvent e, final T elt) { final List<NavigatablePsiElement> navElements = new ArrayList<NavigatablePsiElement>(); Query<T> elementQuery = search(elt); if (elementQuery == null) return; elementQuery.forEach(new Processor<T>() { public boolean process(final T psiElement) { if (psiElement instanceof NavigatablePsiElement) { navElements.add((NavigatablePsiElement)psiElement); } return true; } }); final NavigatablePsiElement[] methods = navElements.toArray(new NavigatablePsiElement[navElements.size()]); PsiElementListNavigator.openTargets(e, methods, getTitle(elt), null, new DefaultPsiElementCellRenderer()); }
private static void navigateOrChoose(Editor editor, Collection<? extends NavigatablePsiElement> superElements, final String title) { if (!superElements.isEmpty()) { NavigatablePsiElement[] superElementArray = superElements.toArray(new NavigatablePsiElement[superElements.size()]); if (superElementArray.length == 1) { superElementArray[0].navigate(true); } else { NavigationUtil.getPsiElementPopup(superElementArray, title).showInBestPositionFor(editor); } } }
/** Returns true if a target or BUILD file could be found and navigated to. */ private static void navigateToTargetOrFile(Project project, VirtualFile vf) { // First, find the parent BUILD file. We don't want to navigate to labels in other packages BlazePackage parentPackage = getBuildFile(project, vf); if (parentPackage == null) { return; } // first, look for a specific target which includes this source file PsiElement target = findBuildTarget(project, parentPackage, new File(vf.getPath())); if (target instanceof NavigatablePsiElement) { ((NavigatablePsiElement) target).navigate(true); return; } OpenFileAction.openFile(parentPackage.buildFile.getFile().getPath(), project); }
@Nullable @Override public Result applyFilter(String line, int entireLength) { Matcher matcher = TARGET_PATTERN.matcher(line); List<ResultItem> results = new ArrayList<>(); while (matcher.find()) { String labelString = matcher.group(); String prefix = matcher.group(1); if (prefix != null) { labelString = labelString.substring(prefix.length()); } Label label = LabelUtils.createLabelFromString(null, labelString); if (label == null) { continue; } PsiElement psi = BuildReferenceManager.getInstance(project).resolveLabel(label); if (!(psi instanceof NavigatablePsiElement)) { continue; } HyperlinkInfo link = project -> ((NavigatablePsiElement) psi).navigate(true); int offset = entireLength - line.length(); results.add( new ResultItem( matcher.start() + offset, matcher.end() + offset, link, highlightAttributes)); } return results.isEmpty() ? null : new Result(results); }
@Override public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { final PsiElement at = file.findElementAt(editor.getCaretModel().getOffset()); final HaxeComponentName componentName = PsiTreeUtil.getParentOfType(at, HaxeComponentName.class); final HaxeClass haxeClass = PsiTreeUtil.getParentOfType(at, HaxeClass.class); final HaxeNamedComponent namedComponent = componentName == null ? haxeClass : (HaxeNamedComponent)componentName.getParent(); if (at == null || haxeClass == null || namedComponent == null) return; final List<HaxeClass> supers = HaxeResolveUtil.tyrResolveClassesByQName(haxeClass.getHaxeExtendsList()); supers.addAll(HaxeResolveUtil.tyrResolveClassesByQName(haxeClass.getHaxeImplementsList())); final List<HaxeNamedComponent> superItems = HaxeResolveUtil.findNamedSubComponents(false, supers.toArray(new HaxeClass[supers.size()])); final HaxeComponentType type = HaxeComponentType.typeOf(namedComponent); if (type == HaxeComponentType.METHOD) { final HaxeMethod methodDeclaration = (HaxeMethod)namedComponent; tryNavigateToSuperMethod(editor, methodDeclaration, superItems); } else if (!supers.isEmpty() && namedComponent instanceof HaxeClass) { PsiElementListNavigator.openTargets( editor, HaxeResolveUtil.getComponentNames(supers).toArray(new NavigatablePsiElement[supers.size()]), DaemonBundle.message("navigation.title.subclass", namedComponent.getName(), supers.size()), "Subclasses of " + namedComponent.getName(), new DefaultPsiElementCellRenderer() ); } }
@Nullable private static LineMarkerInfo createImplementationMarker(final HaxeClass componentWithDeclarationList, final List<HaxeClass> items) { final HaxeComponentName componentName = componentWithDeclarationList.getComponentName(); if (componentName == null) { return null; } final PsiElement element = componentName.getIdentifier().getFirstChild(); return new LineMarkerInfo<>( element, element.getTextRange(), componentWithDeclarationList instanceof HaxeInterfaceDeclaration ? AllIcons.Gutter.ImplementedMethod : AllIcons.Gutter.OverridenMethod, Pass.UPDATE_ALL, item -> DaemonBundle.message("method.is.implemented.too.many"), new GutterIconNavigationHandler<PsiElement>() { @Override public void navigate(MouseEvent e, PsiElement elt) { PsiElementListNavigator.openTargets( e, HaxeResolveUtil.getComponentNames(items).toArray(new NavigatablePsiElement[items.size()]), DaemonBundle.message("navigation.title.subclass", componentWithDeclarationList.getName(), items.size()), "Subclasses of " + componentWithDeclarationList.getName(), new DefaultPsiElementCellRenderer() ); } }, GutterIconRenderer.Alignment.RIGHT ); }
@Override public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { final PsiElement at = file.findElementAt(editor.getCaretModel().getOffset()); final HaxeComponentName componentName = PsiTreeUtil.getParentOfType(at, HaxeComponentName.class); final HaxeClass haxeClass = PsiTreeUtil.getParentOfType(at, HaxeClass.class); final HaxeNamedComponent namedComponent = componentName == null ? haxeClass : (HaxeNamedComponent)componentName.getParent(); if (at == null || haxeClass == null || namedComponent == null) return; final List<HaxeClass> supers = HaxeResolveUtil.tyrResolveClassesByQName(haxeClass.getExtendsList()); supers.addAll(HaxeResolveUtil.tyrResolveClassesByQName(haxeClass.getImplementsList())); final List<HaxeNamedComponent> superItems = HaxeResolveUtil.findNamedSubComponents(false, supers.toArray(new HaxeClass[supers.size()])); final HaxeComponentType type = HaxeComponentType.typeOf(namedComponent); if (type == HaxeComponentType.METHOD) { final HaxeComponentWithDeclarationList methodDeclaration = (HaxeComponentWithDeclarationList)namedComponent; tryNavigateToSuperMethod(editor, methodDeclaration, superItems); } else if (!supers.isEmpty() && namedComponent instanceof HaxeClass) { PsiElementListNavigator.openTargets( editor, HaxeResolveUtil.getComponentNames(supers).toArray(new NavigatablePsiElement[supers.size()]), DaemonBundle.message("navigation.title.subclass", namedComponent.getName(), supers.size()), "Subclasses of " + namedComponent.getName(), new DefaultPsiElementCellRenderer() ); } }
@Nullable private static LineMarkerInfo createImplementationMarker(final HaxeClass componentWithDeclarationList, final List<HaxeClass> items) { final HaxeComponentName componentName = componentWithDeclarationList.getComponentName(); if (componentName == null) { return null; } return new LineMarkerInfo<PsiElement>( componentName, componentName.getTextRange(), componentWithDeclarationList instanceof HaxeInterfaceDeclaration ? AllIcons.Gutter.ImplementedMethod : AllIcons.Gutter.OverridenMethod, Pass.UPDATE_ALL, new Function<PsiElement, String>() { @Override public String fun(PsiElement element) { return DaemonBundle.message("method.is.implemented.too.many"); } }, new GutterIconNavigationHandler<PsiElement>() { @Override public void navigate(MouseEvent e, PsiElement elt) { PsiElementListNavigator.openTargets( e, HaxeResolveUtil.getComponentNames(items).toArray(new NavigatablePsiElement[items.size()]), DaemonBundle.message("navigation.title.subclass", componentWithDeclarationList.getName(), items.size()), "Subclasses of " + componentWithDeclarationList.getName(), new DefaultPsiElementCellRenderer() ); } }, GutterIconRenderer.Alignment.RIGHT ); }
@NotNull public static List<NavigatablePsiElement> findImplementations(ThriftDefinitionName definitionName) { final List<NavigatablePsiElement> implementations = new ArrayList<NavigatablePsiElement>(); processImplementations(definitionName, new Processor<NavigatablePsiElement>() { @Override public boolean process(NavigatablePsiElement element) { implementations.add(element); return true; } }); return implementations; }
public static void processImplementations(ThriftDefinitionName definitionName, @NotNull Processor<NavigatablePsiElement> processor) { String name = definitionName.getText(); for (ChooseByNameContributor contributor : ChooseByNameRegistry.getInstance().getClassModelContributors()) { if (!(contributor instanceof ThriftClassContributor)) { for (NavigationItem navigationItem : contributor.getItemsByName(name, name, definitionName.getProject(), false)) { if (navigationItem instanceof NavigatablePsiElement && !processor.process((NavigatablePsiElement)navigationItem)) { return; } } } } }
@Nullable private LineMarkerInfo findImplementationsAndCreateMarker(final ThriftDefinitionName definitionName) { final List<NavigatablePsiElement> implementations = ThriftPsiUtil.findImplementations(definitionName); if (implementations.isEmpty()) { return null; } return new LineMarkerInfo<PsiElement>( definitionName, definitionName.getTextRange(), AllIcons.Gutter.ImplementedMethod, Pass.UPDATE_ALL, new Function<PsiElement, String>() { @Override public String fun(PsiElement element) { return DaemonBundle.message("interface.is.implemented.too.many"); } }, new GutterIconNavigationHandler<PsiElement>() { @Override public void navigate(MouseEvent e, PsiElement elt) { PsiElementListNavigator.openTargets( e, implementations.toArray(new NavigatablePsiElement[implementations.size()]), DaemonBundle.message("navigation.title.implementation.method", definitionName.getText(), implementations.size()), "Implementations of " + definitionName.getText(), new DefaultPsiElementCellRenderer() ); } }, GutterIconRenderer.Alignment.RIGHT ); }
@RequiredDispatchThread @Override public void navigate(MouseEvent e, T elt) { PsiElementListNavigator.openTargets(e, myReferences.toArray(new NavigatablePsiElement[myReferences.size()]), myTitle, null, createListCellRenderer()); }
@Nullable private static JBPopup navigateOrCreatePopup(final NavigatablePsiElement[] targets, final String title, final String findUsagesTitle, final ListCellRenderer listRenderer, @Nullable final ListBackgroundUpdaterTask listUpdaterTask) { return navigateOrCreatePopup(targets, title, findUsagesTitle, listRenderer, listUpdaterTask, selectedElements -> { for (Object element : selectedElements) { PsiElement selected = (PsiElement)element; LOG.assertTrue(selected.isValid()); ((NavigatablePsiElement)selected).navigate(true); } }); }
@Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { NavigatablePsiElement e = myPointer.getElement(); if(e != null && e.isValid()) { e.navigate(true); } }
private static void navigateToSiblingOverridingMethod(MouseEvent e, @NotNull PsiMethod method) { PsiMethod superMethod = FindSuperElementsHelper.getSiblingInheritedViaSubClass(method); if(superMethod == null) { return; } PsiElementListNavigator.openTargets(e, new NavigatablePsiElement[]{superMethod}, DaemonBundle.message("navigation.title.super.method", method.getName()), DaemonBundle.message("navigation" + ".findUsages.title.super.method", method.getName()), new MethodCellRenderer(false)); }
public static void navigateToSubclassedClass(MouseEvent e, @NotNull final PsiClass aClass) { if(DumbService.isDumb(aClass.getProject())) { DumbService.getInstance(aClass.getProject()).showDumbModeNotification("Navigation to overriding methods is not possible during index update"); return; } final PsiElementProcessor.FindElement<PsiClass> collectProcessor = new PsiElementProcessor.FindElement<>(); final PsiElementProcessor.FindElement<PsiFunctionalExpression> collectExprProcessor = new PsiElementProcessor.FindElement<>(); if(!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> { ClassInheritorsSearch.search(aClass).forEach(new PsiElementProcessorAdapter<>(collectProcessor)); if(collectProcessor.getFoundElement() == null) { FunctionalExpressionSearch.search(aClass).forEach(new PsiElementProcessorAdapter<>(collectExprProcessor)); } }, SEARCHING_FOR_OVERRIDDEN_METHODS, true, aClass.getProject(), (JComponent) e.getComponent())) { return; } final List<NavigatablePsiElement> inheritors = new ArrayList<>(); ContainerUtil.addIfNotNull(inheritors, collectProcessor.getFoundElement()); ContainerUtil.addIfNotNull(inheritors, collectExprProcessor.getFoundElement()); if(inheritors.isEmpty()) { return; } final PsiClassOrFunctionalExpressionListCellRenderer renderer = new PsiClassOrFunctionalExpressionListCellRenderer(); final SubclassUpdater subclassUpdater = new SubclassUpdater(aClass, renderer); Collections.sort(inheritors, renderer.getComparator()); PsiElementListNavigator.openTargets(e, inheritors.toArray(new NavigatablePsiElement[inheritors.size()]), subclassUpdater.getCaption(inheritors.size()), CodeInsightBundle.message("goto" + ".implementation.findUsages.title", aClass.getName()), renderer, subclassUpdater); }
@Override public void onFinished() { super.onFinished(); PsiElement oneElement = getTheOnlyOneElement(); if(oneElement instanceof NavigatablePsiElement) { ((NavigatablePsiElement) oneElement).navigate(true); myPopup.cancel(); } }
AppleScriptStructureViewElement(@NotNull final NavigatablePsiElement element) { super(element); isRoot = false; }
private AppleScriptStructureViewElement(NavigatablePsiElement element, boolean isRootElement) { super(element); this.isRoot = isRootElement; }
@NotNull @Override public Collection<StructureViewTreeElement> getChildrenBase() { final NavigatablePsiElement element = getElement(); final List<StructureViewTreeElement> result = new ArrayList<>(); THashSet<AppleScriptComponent> myComponents = new THashSet<>(); if (element != null && element instanceof AppleScriptFile) { if (!isRoot) { result.add(new AppleScriptStructureViewElement(element, true)); } AppleScriptPsiElementImpl .processDeclarationsImpl(element, new AppleScriptComponentScopeProcessor(myComponents), ResolveState.initial(), null, null); } else if (element instanceof AppleScriptScriptObject) { List<AppleScriptComponent> myScriptComponents = AppleScriptResolveUtil.getNamedSubComponentsFor((AppleScriptScriptObject) element); myComponents.addAll(myScriptComponents); } for (AppleScriptComponent component : myComponents) { if (component instanceof AppleScriptHandlerPositionalParametersDefinition) { result.add(new AppleScriptStructureViewElement(component)); } else if (component instanceof AppleScriptScriptPropertyDeclaration) { result.add(new AppleScriptStructureViewElement(component)); } else if (component instanceof AppleScriptVarAccessDeclaration || component instanceof AppleScriptVarDeclarationListPart) { result.add(new AppleScriptStructureViewElement(component)); } else if (component instanceof AppleScriptScriptObject && component != element) { result.add(new AppleScriptStructureViewElement(component, true)); } else if (component instanceof AppleScriptHandler) { result.add(new AppleScriptStructureViewElement(component)); } else if (component.getName() != null && !(component instanceof AppleScriptHandlerInterleavedParametersSelectorPart)//todo remove && component != element) { result.add(new AppleScriptStructureViewElement(component)); } } result.sort((o1, o2) -> { PsiElement element1, element2; if (o1 instanceof AppleScriptStructureViewElement && o2 instanceof AppleScriptStructureViewElement) { element1 = ((AppleScriptStructureViewElement) o1).getElement(); element2 = ((AppleScriptStructureViewElement) o2).getElement(); if (element1 != null && element2 != null) { return element1.getTextOffset() - element2.getTextOffset(); } } return 0; }); return result; }
public void visitNavigatablePsiElement(@NotNull NavigatablePsiElement o) { visitElement(o); }
@Override public String getElementText(NavigatablePsiElement element) { return element instanceof PsiClass ? ClassPresentationUtil.getNameForClass((PsiClass)element, false) : PsiExpressionTrimRenderer.render((PsiExpression)element); }
@Override protected String getContainerText(NavigatablePsiElement element, final String name) { return PsiClassListCellRenderer.getContainerTextStatic(element); }