private static void gotoTargetElement(
      @NotNull PsiElement element, @NotNull Editor currentEditor, @NotNull PsiFile currentFile) {
    if (navigateInCurrentEditor(element, currentFile, currentEditor)) return;

    Navigatable navigatable =
        element instanceof Navigatable
            ? (Navigatable) element
            : EditSourceUtil.getDescriptor(element);
    if (navigatable != null && navigatable.canNavigate()) {
      navigatable.navigate(true);
    }
  }
예제 #2
0
  @Nullable
  private Info getInfoAt(@NotNull Editor editor, PsiFile file, int offset, BrowseMode browseMode) {
    PsiElement targetElement = null;

    if (browseMode == BrowseMode.TypeDeclaration) {
      try {
        targetElement = GotoTypeDeclarationAction.findSymbolType(editor, offset);
      } catch (IndexNotReadyException e) {
        showDumbModeNotification(myProject);
      }
    } else if (browseMode == BrowseMode.Declaration) {
      final PsiReference ref = TargetElementUtilBase.findReference(editor, offset);
      final List<PsiElement> resolvedElements =
          ref != null ? resolve(ref) : Collections.<PsiElement>emptyList();
      final PsiElement resolvedElement =
          resolvedElements.size() == 1 ? resolvedElements.get(0) : null;

      final PsiElement[] targetElements =
          GotoDeclarationAction.findTargetElementsNoVS(myProject, editor, offset, false);
      final PsiElement elementAtPointer =
          file.findElementAt(
              TargetElementUtilBase.adjustOffset(file, editor.getDocument(), offset));

      if (targetElements != null) {
        if (targetElements.length == 0) {
          return null;
        } else if (targetElements.length == 1) {
          if (targetElements[0] != resolvedElement
              && elementAtPointer != null
              && targetElements[0].isPhysical()) {
            return ref != null
                ? new InfoSingle(ref, targetElements[0])
                : new InfoSingle(elementAtPointer, targetElements[0]);
          }
        } else {
          return elementAtPointer != null ? new InfoMultiple(elementAtPointer) : null;
        }
      }

      if (resolvedElements.size() == 1) {
        return new InfoSingle(ref, resolvedElements.get(0));
      } else if (resolvedElements.size() > 1) {
        return elementAtPointer != null ? new InfoMultiple(elementAtPointer, ref) : null;
      }
    } else if (browseMode == BrowseMode.Implementation) {
      final PsiElement element =
          TargetElementUtilBase.getInstance()
              .findTargetElement(editor, ImplementationSearcher.getFlags(), offset);
      PsiElement[] targetElements =
          new ImplementationSearcher() {
            @Override
            @NotNull
            protected PsiElement[] searchDefinitions(final PsiElement element, Editor editor) {
              final List<PsiElement> found = new ArrayList<PsiElement>(2);
              DefinitionsScopedSearch.search(element, getSearchScope(element, editor))
                  .forEach(
                      new Processor<PsiElement>() {
                        @Override
                        public boolean process(final PsiElement psiElement) {
                          found.add(psiElement);
                          return found.size() != 2;
                        }
                      });
              return PsiUtilCore.toPsiElementArray(found);
            }
          }.searchImplementations(editor, element, offset);
      if (targetElements.length > 1) {
        PsiElement elementAtPointer = file.findElementAt(offset);
        if (elementAtPointer != null) {
          return new InfoMultiple(elementAtPointer);
        }
        return null;
      }
      if (targetElements.length == 1) {
        Navigatable descriptor = EditSourceUtil.getDescriptor(targetElements[0]);
        if (descriptor == null || !descriptor.canNavigate()) {
          return null;
        }
        targetElement = targetElements[0];
      }
    }

    if (targetElement != null && targetElement.isPhysical()) {
      PsiElement elementAtPointer = file.findElementAt(offset);
      if (elementAtPointer != null) {
        return new InfoSingle(elementAtPointer, targetElement);
      }
    }

    return null;
  }
  private void show(
      @NotNull final Project project,
      @NotNull Editor editor,
      @NotNull PsiFile file,
      @NotNull final GotoData gotoData) {
    final PsiElement[] targets = gotoData.targets;
    final List<AdditionalAction> additionalActions = gotoData.additionalActions;

    if (targets.length == 0 && additionalActions.isEmpty()) {
      HintManager.getInstance().showErrorHint(editor, getNotFoundMessage(project, editor, file));
      return;
    }

    if (targets.length == 1 && additionalActions.isEmpty()) {
      Navigatable descriptor =
          targets[0] instanceof Navigatable
              ? (Navigatable) targets[0]
              : EditSourceUtil.getDescriptor(targets[0]);
      if (descriptor != null && descriptor.canNavigate()) {
        navigateToElement(descriptor);
      }
      return;
    }

    for (PsiElement eachTarget : targets) {
      gotoData.renderers.put(eachTarget, createRenderer(gotoData, eachTarget));
    }

    final String name = ((PsiNamedElement) gotoData.source).getName();
    boolean finished = gotoData.listUpdaterTask == null || gotoData.listUpdaterTask.isFinished();
    final String title = getChooserTitle(gotoData.source, name, targets.length, finished);

    if (shouldSortTargets()) {
      Arrays.sort(targets, createComparator(gotoData.renderers, gotoData));
    }

    List<Object> allElements = new ArrayList<Object>(targets.length + additionalActions.size());
    Collections.addAll(allElements, targets);
    allElements.addAll(additionalActions);

    final JBListWithHintProvider list =
        new JBListWithHintProvider(new CollectionListModel<Object>(allElements)) {
          @Override
          protected PsiElement getPsiElementForHint(final Object selectedValue) {
            return selectedValue instanceof PsiElement ? (PsiElement) selectedValue : null;
          }
        };

    list.setFont(EditorUtil.getEditorFont());

    list.setCellRenderer(
        new DefaultListCellRenderer() {
          @Override
          public Component getListCellRendererComponent(
              JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            if (value == null)
              return super.getListCellRendererComponent(
                  list, value, index, isSelected, cellHasFocus);
            if (value instanceof AdditionalAction) {
              return myActionElementRenderer.getListCellRendererComponent(
                  list, value, index, isSelected, cellHasFocus);
            }
            PsiElementListCellRenderer renderer = getRenderer(value, gotoData.renderers, gotoData);
            return renderer.getListCellRendererComponent(
                list, value, index, isSelected, cellHasFocus);
          }
        });

    final Runnable runnable =
        () -> {
          int[] ids = list.getSelectedIndices();
          if (ids == null || ids.length == 0) return;
          Object[] selectedElements = list.getSelectedValues();
          for (Object element : selectedElements) {
            if (element instanceof AdditionalAction) {
              ((AdditionalAction) element).execute();
            } else {
              Navigatable nav =
                  element instanceof Navigatable
                      ? (Navigatable) element
                      : EditSourceUtil.getDescriptor((PsiElement) element);
              try {
                if (nav != null && nav.canNavigate()) {
                  navigateToElement(nav);
                }
              } catch (IndexNotReadyException e) {
                DumbService.getInstance(project)
                    .showDumbModeNotification("Navigation is not available while indexing");
              }
            }
          }
        };

    final PopupChooserBuilder builder = new PopupChooserBuilder(list);
    builder.setFilteringEnabled(
        o -> {
          if (o instanceof AdditionalAction) {
            return ((AdditionalAction) o).getText();
          }
          return getRenderer(o, gotoData.renderers, gotoData).getElementText((PsiElement) o);
        });

    final Ref<UsageView> usageView = new Ref<UsageView>();
    final JBPopup popup =
        builder
            .setTitle(title)
            .setItemChoosenCallback(runnable)
            .setMovable(true)
            .setCancelCallback(
                () -> {
                  HintUpdateSupply.hideHint(list);
                  final ListBackgroundUpdaterTask task = gotoData.listUpdaterTask;
                  if (task != null) {
                    task.cancelTask();
                  }
                  return true;
                })
            .setCouldPin(
                popup1 -> {
                  usageView.set(
                      FindUtil.showInUsageView(
                          gotoData.source,
                          gotoData.targets,
                          getFindUsagesTitle(gotoData.source, name, gotoData.targets.length),
                          project));
                  popup1.cancel();
                  return false;
                })
            .setAdText(getAdText(gotoData.source, targets.length))
            .createPopup();

    builder.getScrollPane().setBorder(null);
    builder.getScrollPane().setViewportBorder(null);

    if (gotoData.listUpdaterTask != null) {
      gotoData.listUpdaterTask.init((AbstractPopup) popup, list, usageView);
      ProgressManager.getInstance().run(gotoData.listUpdaterTask);
    }
    popup.showInBestPositionFor(editor);
  }
  private void show(Project project, Editor editor, PsiFile file, final GotoData gotoData) {
    final PsiElement[] targets = gotoData.targets;
    final List<AdditionalAction> additionalActions = gotoData.additionalActions;

    if (targets.length == 0 && additionalActions.isEmpty()) {
      HintManager.getInstance().showErrorHint(editor, getNotFoundMessage(project, editor, file));
      return;
    }

    if (targets.length == 1 && additionalActions.isEmpty()) {
      Navigatable descriptor =
          targets[0] instanceof Navigatable
              ? (Navigatable) targets[0]
              : EditSourceUtil.getDescriptor(targets[0]);
      if (descriptor != null && descriptor.canNavigate()) {
        navigateToElement(descriptor);
      }
      return;
    }

    for (PsiElement eachTarget : targets) {
      gotoData.renderers.put(eachTarget, createRenderer(gotoData, eachTarget));
    }

    String name = ((PsiNamedElement) gotoData.source).getName();
    String title = getChooserTitle(gotoData.source, name, targets.length);

    if (shouldSortTargets()) {
      Arrays.sort(targets, createComparator(gotoData.renderers, gotoData));
    }

    List<Object> allElements = new ArrayList<Object>(targets.length + additionalActions.size());
    Collections.addAll(allElements, targets);
    allElements.addAll(additionalActions);

    final JBListWithHintProvider list =
        new JBListWithHintProvider(new CollectionListModel<Object>(allElements)) {
          @Override
          protected PsiElement getPsiElementForHint(final Object selectedValue) {
            return selectedValue instanceof PsiElement ? (PsiElement) selectedValue : null;
          }
        };

    list.setCellRenderer(
        new DefaultListCellRenderer() {
          @Override
          public Component getListCellRendererComponent(
              JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            if (value == null)
              return super.getListCellRendererComponent(
                  list, value, index, isSelected, cellHasFocus);
            if (value instanceof AdditionalAction) {
              return myActionElementRenderer.getListCellRendererComponent(
                  list, value, index, isSelected, cellHasFocus);
            }
            PsiElementListCellRenderer renderer = getRenderer(value, gotoData.renderers, gotoData);
            return renderer.getListCellRendererComponent(
                list, value, index, isSelected, cellHasFocus);
          }
        });

    final Runnable runnable =
        new Runnable() {
          @Override
          public void run() {
            int[] ids = list.getSelectedIndices();
            if (ids == null || ids.length == 0) return;
            Object[] selectedElements = list.getSelectedValues();
            for (Object element : selectedElements) {
              if (element instanceof AdditionalAction) {
                ((AdditionalAction) element).execute();
              } else {
                Navigatable nav =
                    element instanceof Navigatable
                        ? (Navigatable) element
                        : EditSourceUtil.getDescriptor((PsiElement) element);
                if (nav != null && nav.canNavigate()) {
                  navigateToElement(nav);
                }
              }
            }
          }
        };

    final PopupChooserBuilder builder = new PopupChooserBuilder(list);
    builder.setFilteringEnabled(
        new Function<Object, String>() {
          @Override
          public String fun(Object o) {
            if (o instanceof AdditionalAction) {
              return ((AdditionalAction) o).getText();
            }
            return getRenderer(o, gotoData.renderers, gotoData).getElementText((PsiElement) o);
          }
        });

    final JBPopup popup =
        builder
            .setTitle(title)
            .setItemChoosenCallback(runnable)
            .setMovable(true)
            .setCancelCallback(
                new Computable<Boolean>() {
                  @Override
                  public Boolean compute() {
                    list.hideHint();
                    return true;
                  }
                })
            .setAdText(getAdText(gotoData.source, targets.length))
            .createPopup();
    if (gotoData.listUpdaterTask != null) {
      gotoData.listUpdaterTask.init((AbstractPopup) popup, list);
      ProgressManager.getInstance().run(gotoData.listUpdaterTask);
    }
    popup.showInBestPositionFor(editor);
  }