@Override
  @NotNull
  public AnnotationPlace chooseAnnotationsPlace(@NotNull final PsiElement element) {
    if (!element.isPhysical()) return AnnotationPlace.IN_CODE; // element just created
    if (!element.getManager().isInProject(element)) return AnnotationPlace.EXTERNAL;
    final Project project = myPsiManager.getProject();
    final PsiFile containingFile = element.getContainingFile();
    final VirtualFile virtualFile = containingFile.getVirtualFile();
    LOG.assertTrue(virtualFile != null);
    final List<OrderEntry> entries =
        ProjectRootManager.getInstance(project).getFileIndex().getOrderEntriesForFile(virtualFile);
    if (!entries.isEmpty()) {
      for (OrderEntry entry : entries) {
        if (!(entry instanceof ModuleOrderEntry)) {
          if (AnnotationOrderRootType.getUrls(entry).length > 0) {
            return AnnotationPlace.EXTERNAL;
          }
          break;
        }
      }
    }
    final MyExternalPromptDialog dialog =
        ApplicationManager.getApplication().isUnitTestMode()
                || ApplicationManager.getApplication().isHeadlessEnvironment()
            ? null
            : new MyExternalPromptDialog(project);
    if (dialog != null && dialog.isToBeShown()) {
      final PsiElement highlightElement =
          element instanceof PsiNameIdentifierOwner
              ? ((PsiNameIdentifierOwner) element).getNameIdentifier()
              : element.getNavigationElement();
      LOG.assertTrue(highlightElement != null);
      final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
      final List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
      final boolean highlight =
          editor != null
              && editor.getDocument()
                  == PsiDocumentManager.getInstance(project).getDocument(containingFile);
      try {
        if (highlight) { // do not highlight for batch inspections
          final EditorColorsManager colorsManager = EditorColorsManager.getInstance();
          final TextAttributes attributes =
              colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
          final TextRange textRange = highlightElement.getTextRange();
          HighlightManager.getInstance(project)
              .addRangeHighlight(
                  editor,
                  textRange.getStartOffset(),
                  textRange.getEndOffset(),
                  attributes,
                  true,
                  highlighters);
          final LogicalPosition logicalPosition =
              editor.offsetToLogicalPosition(textRange.getStartOffset());
          editor.getScrollingModel().scrollTo(logicalPosition, ScrollType.CENTER);
        }

        dialog.show();
        if (dialog.getExitCode() == 2) {
          return AnnotationPlace.EXTERNAL;
        } else if (dialog.getExitCode() == 1) {
          return AnnotationPlace.NOWHERE;
        }

      } finally {
        if (highlight) {
          HighlightManager.getInstance(project)
              .removeSegmentHighlighter(editor, highlighters.get(0));
        }
      }
    } else if (dialog != null) {
      dialog.close(DialogWrapper.OK_EXIT_CODE);
    }
    return AnnotationPlace.IN_CODE;
  }
Ejemplo n.º 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;
  }