コード例 #1
0
  public void hideCoverageData() {
    if (myEditor == null) return;
    final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
    final List<RangeHighlighter> highlighters = myEditor.getUserData(COVERAGE_HIGHLIGHTERS);
    if (highlighters != null) {
      for (final RangeHighlighter highlighter : highlighters) {
        ApplicationManager.getApplication().invokeLater(() -> highlighter.dispose());
      }
      myEditor.putUserData(COVERAGE_HIGHLIGHTERS, null);
    }

    final Map<FileEditor, EditorNotificationPanel> map =
        myFile.getCopyableUserData(NOTIFICATION_PANELS);
    if (map != null) {
      final VirtualFile vFile = myFile.getVirtualFile();
      LOG.assertTrue(vFile != null);
      boolean freeAll = !fileEditorManager.isFileOpen(vFile);
      myFile.putCopyableUserData(NOTIFICATION_PANELS, null);
      for (FileEditor fileEditor : map.keySet()) {
        if (!freeAll && !isCurrentEditor(fileEditor)) {
          continue;
        }
        fileEditorManager.removeTopComponent(fileEditor, map.get(fileEditor));
      }
    }

    final DocumentListener documentListener = myEditor.getUserData(COVERAGE_DOCUMENT_LISTENER);
    if (documentListener != null) {
      myDocument.removeDocumentListener(documentListener);
      myEditor.putUserData(COVERAGE_DOCUMENT_LISTENER, null);
    }
  }
コード例 #2
0
 private static List<ParameterInfoController> getAllControllers(@NotNull Editor editor) {
   List<ParameterInfoController> array = editor.getUserData(ALL_CONTROLLERS_KEY);
   if (array == null) {
     array = new ArrayList<>();
     editor.putUserData(ALL_CONTROLLERS_KEY, array);
   }
   return array;
 }
コード例 #3
0
  private static CompletionState getCompletionState(Editor editor) {
    CompletionState state = editor.getUserData(KEY_STATE);
    if (state == null) {
      state = new CompletionState();
      editor.putUserData(KEY_STATE, state);
    }

    return state;
  }
コード例 #4
0
  public boolean isSelected(AnActionEvent e) {
    VcsContext context = VcsContextFactory.SERVICE.getInstance().createContextOn(e);
    Editor editor = context.getEditor();
    if (editor == null) {
      return false;
    }

    Collection annotations = editor.getUserData(KEY_IN_EDITOR);
    return annotations != null && !annotations.isEmpty();
  }
コード例 #5
0
 @Nullable
 public Map<RangeHighlighter, HighlightInfo> getHighlightInfoMap(
     @NotNull Editor editor, boolean toCreate) {
   if (editor instanceof EditorWindow)
     return getHighlightInfoMap(((EditorWindow) editor).getDelegate(), toCreate);
   Map<RangeHighlighter, HighlightInfo> map = editor.getUserData(HIGHLIGHT_INFO_MAP_KEY);
   if (map == null && toCreate) {
     map =
         ((UserDataHolderEx) editor)
             .putUserDataIfAbsent(
                 HIGHLIGHT_INFO_MAP_KEY, new HashMap<RangeHighlighter, HighlightInfo>());
   }
   return map;
 }
コード例 #6
0
  private static void clearLineMarkers(Editor editor) {
    final List<RangeHighlighter> oldHighlighters =
        editor.getUserData(TAG_TREE_HIGHLIGHTERS_IN_EDITOR_KEY);

    if (oldHighlighters != null) {
      final MarkupModelEx markupModel = (MarkupModelEx) editor.getMarkupModel();

      for (RangeHighlighter highlighter : oldHighlighters) {
        if (markupModel.containsHighlighter(highlighter)) {
          highlighter.dispose();
        }
      }
      editor.putUserData(TAG_TREE_HIGHLIGHTERS_IN_EDITOR_KEY, null);
    }
  }
コード例 #7
0
  @Nullable
  private static Point getVisibleBestPopupLocation(@NotNull Editor editor) {
    VisualPosition visualPosition = editor.getUserData(ANCHOR_POPUP_POSITION);

    if (visualPosition == null) {
      CaretModel caretModel = editor.getCaretModel();
      if (caretModel.isUpToDate()) {
        visualPosition = caretModel.getVisualPosition();
      } else {
        visualPosition = editor.offsetToVisualPosition(caretModel.getOffset());
      }
    }

    Point p =
        editor.visualPositionToXY(
            new VisualPosition(visualPosition.line + 1, visualPosition.column));

    final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
    return visibleArea.contains(p) ? p : null;
  }
コード例 #8
0
  public static void doAnnotate(
      final Editor editor, final Project project, final FileAnnotation fileAnnotation) {
    final UpToDateLineNumberProvider getUpToDateLineNumber =
        new UpToDateLineNumberProviderImpl(editor.getDocument(), project);

    editor.getGutter().closeAllAnnotations();

    // be careful, not proxies but original items are put there (since only their presence not
    // behaviour is important)
    Collection<ActiveAnnotationGutter> annotations = editor.getUserData(KEY_IN_EDITOR);
    if (annotations == null) {
      annotations = new HashSet<ActiveAnnotationGutter>();
      editor.putUserData(KEY_IN_EDITOR, annotations);
    }

    final RevuAnnotationFieldGutter gutter = new RevuAnnotationFieldGutter(fileAnnotation, editor);
    final AnnotationGutterLineConvertorProxy proxy =
        new AnnotationGutterLineConvertorProxy(getUpToDateLineNumber, gutter);
    editor.getGutter().registerTextAnnotation(proxy, proxy);
    annotations.add(gutter);
  }
コード例 #9
0
 protected static boolean isModified(@NotNull final Editor editor) {
   final Long timestamp = editor.getUserData(SMART_ENTER_TIMESTAMP);
   assert timestamp != null;
   return editor.getDocument().getModificationStamp() != timestamp.longValue();
 }
コード例 #10
0
  @Override
  public void invoke(
      @NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
    PsiDocumentManager.getInstance(project).commitAllDocuments();

    PsiElement container = null;
    WeakReference<LightweightHint> ref = editor.getUserData(MY_LAST_HINT_KEY);
    if (ref != null) {
      LightweightHint hint = ref.get();
      if (hint != null && hint.isVisible()) {
        hint.hide();
        container = hint.getUserData(CONTAINER_KEY);
        if (container != null && !container.isValid()) {
          container = null;
        }
      }
    }

    StructureViewBuilder builder =
        LanguageStructureViewBuilder.INSTANCE.getStructureViewBuilder(file);
    if (builder instanceof TreeBasedStructureViewBuilder) {
      StructureViewModel model =
          ((TreeBasedStructureViewBuilder) builder).createStructureViewModel();
      boolean goOneLevelUp = true;
      if (container == null) {
        goOneLevelUp = false;
        Object element = model.getCurrentEditorElement();
        if (element instanceof PsiElement) {
          container = (PsiElement) element;
        }
      }
      while (true) {
        if (container == null || container instanceof PsiFile) {
          return;
        }
        if (goOneLevelUp) {
          goOneLevelUp = false;
        } else {
          if (!isDeclarationVisible(container, editor)) {
            break;
          }
        }

        container = container.getParent();
        while (container != null
            && DeclarationRangeUtil.getPossibleDeclarationAtRange(container) == null) {
          container = container.getParent();
          if (container instanceof PsiFile) return;
        }
      }
    }
    if (container == null) {
      return;
    }

    final TextRange range = DeclarationRangeUtil.getPossibleDeclarationAtRange(container);
    if (range == null) {
      return;
    }
    final PsiElement _container = container;
    ApplicationManager.getApplication()
        .invokeLater(
            new Runnable() {
              @Override
              public void run() {
                LightweightHint hint =
                    EditorFragmentComponent.showEditorFragmentHint(editor, range, true, true);
                if (hint != null) {
                  hint.putUserData(CONTAINER_KEY, _container);
                  editor.putUserData(MY_LAST_HINT_KEY, new WeakReference<LightweightHint>(hint));
                }
              }
            });
  }
コード例 #11
0
    @Nullable
    public List<IntentionAction> getOptions(@NotNull PsiElement element, @Nullable Editor editor) {
      if (editor != null
          && Boolean.FALSE.equals(
              editor.getUserData(IntentionManager.SHOW_INTENTION_OPTIONS_KEY))) {
        return null;
      }
      List<IntentionAction> options = myOptions;
      HighlightDisplayKey key = myKey;
      if (myProblemGroup != null) {
        String problemName = myProblemGroup.getProblemName();
        HighlightDisplayKey problemGroupKey =
            problemName != null ? HighlightDisplayKey.findById(problemName) : null;
        if (problemGroupKey != null) {
          key = problemGroupKey;
        }
      }
      if (options != null || key == null) {
        return options;
      }
      IntentionManager intentionManager = IntentionManager.getInstance();
      List<IntentionAction> newOptions = intentionManager.getStandardIntentionOptions(key, element);
      InspectionProfile profile =
          InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();
      InspectionToolWrapper toolWrapper = profile.getInspectionTool(key.toString(), element);
      if (!(toolWrapper instanceof LocalInspectionToolWrapper)) {
        HighlightDisplayKey idkey = HighlightDisplayKey.findById(key.toString());
        if (idkey != null) {
          toolWrapper = profile.getInspectionTool(idkey.toString(), element);
        }
      }
      if (toolWrapper != null) {

        myCanCleanup = toolWrapper.isCleanupTool();

        ContainerUtil.addIfNotNull(
            newOptions, intentionManager.createFixAllIntention(toolWrapper, myAction));
        InspectionProfileEntry wrappedTool =
            toolWrapper instanceof LocalInspectionToolWrapper
                ? ((LocalInspectionToolWrapper) toolWrapper).getTool()
                : ((GlobalInspectionToolWrapper) toolWrapper).getTool();
        if (wrappedTool instanceof CustomSuppressableInspectionTool) {
          final IntentionAction[] suppressActions =
              ((CustomSuppressableInspectionTool) wrappedTool).getSuppressActions(element);
          if (suppressActions != null) {
            ContainerUtil.addAll(newOptions, suppressActions);
          }
        } else {
          SuppressQuickFix[] suppressFixes = wrappedTool.getBatchSuppressActions(element);
          if (suppressFixes.length > 0) {
            ContainerUtil.addAll(
                newOptions,
                ContainerUtil.map(
                    suppressFixes,
                    new Function<SuppressQuickFix, IntentionAction>() {
                      @Override
                      public IntentionAction fun(SuppressQuickFix fix) {
                        return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction(
                            fix);
                      }
                    }));
          }
        }
      }
      if (myProblemGroup instanceof SuppressableProblemGroup) {
        final IntentionAction[] suppressActions =
            ((SuppressableProblemGroup) myProblemGroup).getSuppressActions(element);
        ContainerUtil.addAll(newOptions, suppressActions);
      }

      synchronized (this) {
        options = myOptions;
        if (options == null) {
          myOptions = options = newOptions;
        }
        myKey = null;
      }
      return options;
    }
コード例 #12
0
 @Nullable
 public static TemplateState getTemplateState(@NotNull Editor editor) {
   return editor.getUserData(TEMPLATE_STATE_KEY);
 }
コード例 #13
0
    @Nullable
    public List<IntentionAction> getOptions(@NotNull PsiElement element, @Nullable Editor editor) {
      if (editor != null
          && Boolean.FALSE.equals(
              editor.getUserData(IntentionManager.SHOW_INTENTION_OPTIONS_KEY))) {
        return null;
      }
      List<IntentionAction> options = myOptions;
      HighlightDisplayKey key = myKey;
      if (options != null || key == null) {
        return options;
      }
      List<IntentionAction> newOptions =
          IntentionManager.getInstance().getStandardIntentionOptions(key, element);
      InspectionProfile profile =
          InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();
      InspectionProfileEntry tool = profile.getInspectionTool(key.toString(), element);
      if (!(tool instanceof LocalInspectionToolWrapper)) {
        HighlightDisplayKey idkey = HighlightDisplayKey.findById(key.toString());
        if (idkey != null) {
          tool = profile.getInspectionTool(idkey.toString(), element);
        }
      }
      InspectionProfileEntry wrappedTool = tool;
      if (tool instanceof LocalInspectionToolWrapper) {
        wrappedTool = ((LocalInspectionToolWrapper) tool).getTool();
        Class aClass = myAction.getClass();
        if (myAction instanceof QuickFixWrapper) {
          aClass = ((QuickFixWrapper) myAction).getFix().getClass();
        }
        newOptions.add(new CleanupInspectionIntention((LocalInspectionToolWrapper) tool, aClass));
      } else if (tool instanceof GlobalInspectionToolWrapper) {
        wrappedTool = ((GlobalInspectionToolWrapper) tool).getTool();
        if (wrappedTool instanceof GlobalSimpleInspectionTool
            && (myAction instanceof LocalQuickFix || myAction instanceof QuickFixWrapper)) {
          Class aClass = myAction.getClass();
          if (myAction instanceof QuickFixWrapper) {
            aClass = ((QuickFixWrapper) myAction).getFix().getClass();
          }
          newOptions.add(
              new CleanupInspectionIntention((GlobalInspectionToolWrapper) tool, aClass));
        }
      }

      if (wrappedTool instanceof CustomSuppressableInspectionTool) {
        final IntentionAction[] suppressActions =
            ((CustomSuppressableInspectionTool) wrappedTool).getSuppressActions(element);
        if (suppressActions != null) {
          ContainerUtil.addAll(newOptions, suppressActions);
        }
      }
      if (wrappedTool instanceof BatchSuppressableTool) {
        final SuppressQuickFix[] suppressActions =
            ((BatchSuppressableTool) wrappedTool).getBatchSuppressActions(element);
        ContainerUtil.addAll(
            newOptions,
            ContainerUtil.map(
                suppressActions,
                new Function<SuppressQuickFix, IntentionAction>() {
                  @Override
                  public IntentionAction fun(SuppressQuickFix fix) {
                    return InspectionManagerEx.convertBatchToSuppressIntentionAction(fix);
                  }
                }));
      }

      synchronized (this) {
        options = myOptions;
        if (options == null) {
          myOptions = options = newOptions;
        }
        myKey = null;
      }
      return options;
    }
コード例 #14
0
  public void showCoverageInformation(final CoverageSuitesBundle suite) {
    // Store the values of myFile and myEditor in local variables to avoid an NPE after dispose()
    // has been called in the EDT.
    final PsiFile psiFile = myFile;
    final Editor editor = myEditor;
    final Document document = myDocument;
    if (editor == null || psiFile == null || document == null) return;
    final MarkupModel markupModel = DocumentMarkupModel.forDocument(document, myProject, true);
    final List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
    final ProjectData data = suite.getCoverageData();
    if (data == null) {
      coverageDataNotFound(suite);
      return;
    }
    final CoverageEngine engine = suite.getCoverageEngine();
    final Set<String> qualifiedNames = engine.getQualifiedNames(psiFile);

    // let's find old content in local history and build mapping from old lines to new one
    // local history doesn't index libraries, so let's distinguish libraries content with other one
    final ProjectFileIndex projectFileIndex =
        ProjectRootManager.getInstance(myProject).getFileIndex();
    final VirtualFile file = psiFile.getVirtualFile();
    LOG.assertTrue(file != null);

    final long fileTimeStamp = file.getTimeStamp();
    final long coverageTimeStamp = suite.getLastCoverageTimeStamp();
    final TIntIntHashMap oldToNewLineMapping;

    // do not show coverage info over cls
    if (engine.isInLibraryClasses(myProject, file)) {
      return;
    }
    // if in libraries content
    if (projectFileIndex.isInLibrarySource(file)) {
      // compare file and coverage timestamps
      if (fileTimeStamp > coverageTimeStamp) {
        showEditorWarningMessage(CodeInsightBundle.message("coverage.data.outdated"));
        return;
      }
      oldToNewLineMapping = null;
    } else {
      // check local history
      oldToNewLineMapping = getOldToNewLineMapping(coverageTimeStamp);
      if (oldToNewLineMapping == null) {

        // if history for file isn't available let's check timestamps
        if (fileTimeStamp > coverageTimeStamp
            && classesArePresentInCoverageData(data, qualifiedNames)) {
          showEditorWarningMessage(CodeInsightBundle.message("coverage.data.outdated"));
          return;
        }
      }
    }

    if (editor.getUserData(COVERAGE_HIGHLIGHTERS) != null) {
      // highlighters already collected - no need to do it twice
      return;
    }

    final Module module =
        ApplicationManager.getApplication()
            .runReadAction(
                new Computable<Module>() {
                  @Nullable
                  @Override
                  public Module compute() {
                    return ModuleUtilCore.findModuleForPsiElement(psiFile);
                  }
                });
    if (module != null) {
      if (engine.recompileProjectAndRerunAction(
          module,
          suite,
          () -> CoverageDataManager.getInstance(myProject).chooseSuitesBundle(suite))) {
        return;
      }
    }

    // now if oldToNewLineMapping is null we should use f(x)=id(x) mapping

    // E.g. all *.class files for java source file with several classes
    final Set<File> outputFiles = engine.getCorrespondingOutputFiles(psiFile, module, suite);

    final boolean subCoverageActive =
        CoverageDataManager.getInstance(myProject).isSubCoverageActive();
    final boolean coverageByTestApplicable =
        suite.isCoverageByTestApplicable()
            && !(subCoverageActive && suite.isCoverageByTestEnabled());
    final TreeMap<Integer, LineData> executableLines = new TreeMap<Integer, LineData>();
    final TreeMap<Integer, Object[]> classLines = new TreeMap<Integer, Object[]>();
    final TreeMap<Integer, String> classNames = new TreeMap<Integer, String>();
    class HighlightersCollector {
      private void collect(File outputFile, final String qualifiedName) {
        final ClassData fileData = data.getClassData(qualifiedName);
        if (fileData != null) {
          final Object[] lines = fileData.getLines();
          if (lines != null) {
            final Object[] postProcessedLines =
                suite.getCoverageEngine().postProcessExecutableLines(lines, editor);
            for (Object lineData : postProcessedLines) {
              if (lineData instanceof LineData) {
                final int line = ((LineData) lineData).getLineNumber() - 1;
                final int lineNumberInCurrent;
                if (oldToNewLineMapping != null) {
                  // use mapping based on local history
                  if (!oldToNewLineMapping.contains(line)) {
                    continue;
                  }
                  lineNumberInCurrent = oldToNewLineMapping.get(line);
                } else {
                  // use id mapping
                  lineNumberInCurrent = line;
                }
                LOG.assertTrue(lineNumberInCurrent < document.getLineCount());
                executableLines.put(line, (LineData) lineData);

                classLines.put(line, postProcessedLines);
                classNames.put(line, qualifiedName);

                ApplicationManager.getApplication()
                    .invokeLater(
                        () -> {
                          if (lineNumberInCurrent >= document.getLineCount()) return;
                          final RangeHighlighter highlighter =
                              createRangeHighlighter(
                                  suite.getLastCoverageTimeStamp(),
                                  markupModel,
                                  coverageByTestApplicable,
                                  executableLines,
                                  qualifiedName,
                                  line,
                                  lineNumberInCurrent,
                                  suite,
                                  postProcessedLines);
                          highlighters.add(highlighter);
                        });
              }
            }
          }
        } else if (outputFile != null
            && !subCoverageActive
            && engine.includeUntouchedFileInCoverage(qualifiedName, outputFile, psiFile, suite)) {
          collectNonCoveredFileInfo(
              outputFile, highlighters, markupModel, executableLines, coverageByTestApplicable);
        }
      }
    }

    final HighlightersCollector collector = new HighlightersCollector();
    if (!outputFiles.isEmpty()) {
      for (File outputFile : outputFiles) {
        final String qualifiedName = engine.getQualifiedName(outputFile, psiFile);
        if (qualifiedName != null) {
          collector.collect(outputFile, qualifiedName);
        }
      }
    } else { // check non-compilable classes which present in ProjectData
      for (String qName : qualifiedNames) {
        collector.collect(null, qName);
      }
    }
    ApplicationManager.getApplication()
        .invokeLater(
            () -> {
              if (myEditor != null && highlighters.size() > 0) {
                editor.putUserData(COVERAGE_HIGHLIGHTERS, highlighters);
              }
            });

    final DocumentListener documentListener =
        new DocumentAdapter() {
          @Override
          public void documentChanged(final DocumentEvent e) {
            myNewToOldLines = null;
            myOldToNewLines = null;
            List<RangeHighlighter> rangeHighlighters = editor.getUserData(COVERAGE_HIGHLIGHTERS);
            if (rangeHighlighters == null) rangeHighlighters = new ArrayList<RangeHighlighter>();
            int offset = e.getOffset();
            final int lineNumber = document.getLineNumber(offset);
            final int lastLineNumber = document.getLineNumber(offset + e.getNewLength());
            final TextRange changeRange =
                new TextRange(
                    document.getLineStartOffset(lineNumber),
                    document.getLineEndOffset(lastLineNumber));
            for (Iterator<RangeHighlighter> it = rangeHighlighters.iterator(); it.hasNext(); ) {
              final RangeHighlighter highlighter = it.next();
              if (!highlighter.isValid() || TextRange.create(highlighter).intersects(changeRange)) {
                highlighter.dispose();
                it.remove();
              }
            }
            final List<RangeHighlighter> highlighters = rangeHighlighters;
            myUpdateAlarm.cancelAllRequests();
            if (!myUpdateAlarm.isDisposed()) {
              myUpdateAlarm.addRequest(
                  () -> {
                    final TIntIntHashMap newToOldLineMapping =
                        getNewToOldLineMapping(suite.getLastCoverageTimeStamp());
                    if (newToOldLineMapping != null) {
                      ApplicationManager.getApplication()
                          .invokeLater(
                              () -> {
                                if (editor.isDisposed()) return;
                                for (int line = lineNumber; line <= lastLineNumber; line++) {
                                  final int oldLineNumber = newToOldLineMapping.get(line);
                                  final LineData lineData = executableLines.get(oldLineNumber);
                                  if (lineData != null) {
                                    RangeHighlighter rangeHighlighter =
                                        createRangeHighlighter(
                                            suite.getLastCoverageTimeStamp(),
                                            markupModel,
                                            coverageByTestApplicable,
                                            executableLines,
                                            classNames.get(oldLineNumber),
                                            oldLineNumber,
                                            line,
                                            suite,
                                            classLines.get(oldLineNumber));
                                    highlighters.add(rangeHighlighter);
                                  }
                                }
                                editor.putUserData(
                                    COVERAGE_HIGHLIGHTERS,
                                    highlighters.size() > 0 ? highlighters : null);
                              });
                    }
                  },
                  100);
            }
          }
        };
    document.addDocumentListener(documentListener);
    editor.putUserData(COVERAGE_DOCUMENT_LISTENER, documentListener);
  }
コード例 #15
0
 @Nullable
 public static AbstractInplaceIntroducer getActiveIntroducer(@Nullable Editor editor) {
   if (editor == null) return null;
   return editor.getUserData(ACTIVE_INTRODUCE);
 }