Package org.twodividedbyzero.idea.findbugs.gui.editor

Source Code of org.twodividedbyzero.idea.findbugs.gui.editor.BugAnnotator

/*
* Copyright 2008-2013 Andre Pfeiler
*
* This file is part of FindBugs-IDEA.
*
* FindBugs-IDEA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FindBugs-IDEA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FindBugs-IDEA.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.twodividedbyzero.idea.findbugs.gui.editor;

import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiAnonymousClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.JBColor;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.Detector;
import org.jetbrains.annotations.NotNull;
import org.twodividedbyzero.idea.findbugs.common.ExtendedProblemDescriptor;
import org.twodividedbyzero.idea.findbugs.common.event.EventListener;
import org.twodividedbyzero.idea.findbugs.common.event.EventManagerImpl;
import org.twodividedbyzero.idea.findbugs.common.event.filters.BugReporterEventFilter;
import org.twodividedbyzero.idea.findbugs.common.event.types.BugReporterEvent;
import org.twodividedbyzero.idea.findbugs.common.util.BugInstanceUtil;
import org.twodividedbyzero.idea.findbugs.common.util.IdeaUtilImpl;
import org.twodividedbyzero.idea.findbugs.common.util.StringUtil;
import org.twodividedbyzero.idea.findbugs.intentions.ClearAndSuppressBugIntentionAction;
import org.twodividedbyzero.idea.findbugs.intentions.ClearBugIntentionAction;
import org.twodividedbyzero.idea.findbugs.intentions.SuppressReportBugForClassIntentionAction;
import org.twodividedbyzero.idea.findbugs.intentions.SuppressReportBugIntentionAction;
import org.twodividedbyzero.idea.findbugs.preferences.FindBugsPreferences;
import org.twodividedbyzero.idea.findbugs.resources.ResourcesLoader;

import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
* $Date: 2013-12-05 08:09:56 -0600 (Thu, 05 Dec 2013) $
*
* @author Andre Pfeiler<andrepdo@dev.java.net>
* @version $Revision: 257 $
* @since 0.9.94
*/
public class BugAnnotator implements Annotator, EventListener<BugReporterEvent> {

  private boolean _analysisRunning;
  private boolean _isRegistered;
  private FindBugsPreferences _preferences;


  public BugAnnotator() {
    _analysisRunning = false;
    _isRegistered = false;
  }


  private FindBugsPreferences getPreferences(final PsiElement psiElement) {
    if (_preferences == null) {
      _preferences = IdeaUtilImpl.getPluginComponent(psiElement.getProject()).getPreferences();
    }
    return _preferences;
  }


  public void annotate(@NotNull final PsiElement psiElement, @NotNull final AnnotationHolder annotationHolder) {
    if (! getPreferences(psiElement).isAnnotationTextRangeMarkupEnabled()) {
      return;
    }
    if (_analysisRunning) {
      return;
    }
    if (!_isRegistered) {
      EventManagerImpl.getInstance().addEventListener(new BugReporterEventFilter(psiElement.getProject().getName()), this);
      _isRegistered = true;
    }
    final Project project = psiElement.getProject();
    final Map<PsiFile, List<ExtendedProblemDescriptor>> problems = IdeaUtilImpl.getPluginComponent(project).getProblems();

    final PsiFile psiFile = psiElement.getContainingFile();
    if (problems.containsKey(psiFile)) {
      addAnnotation(psiElement, new ArrayList<ExtendedProblemDescriptor>(problems.get(psiFile)), annotationHolder);
    }
  }


  private static void addAnnotation(@NotNull final PsiElement psiElement, final Iterable<ExtendedProblemDescriptor> problemDescriptors, @NotNull final AnnotationHolder annotationHolder) {
    final List<ExtendedProblemDescriptor> matchingDescriptors = new ArrayList<ExtendedProblemDescriptor>();
    for (final ExtendedProblemDescriptor descriptor : problemDescriptors) {
      final PsiElement problemPsiElement = descriptor.getPsiElement();

      final PsiAnonymousClass psiAnonymousClass = PsiTreeUtil.getParentOfType(psiElement, PsiAnonymousClass.class);
      if (psiElement.equals(problemPsiElement)) {
        matchingDescriptors.add(descriptor);
        addAnnotation(descriptor, matchingDescriptors, psiElement, annotationHolder);
      } else if (psiAnonymousClass != null && psiAnonymousClass.equals(problemPsiElement)) {
        matchingDescriptors.add(descriptor);
        addAnnotation(descriptor, matchingDescriptors, psiAnonymousClass, annotationHolder);
      }
    }
  }


  private static void addAnnotation(final ExtendedProblemDescriptor problemDescriptor, final List<ExtendedProblemDescriptor> matchingDescriptors, final PsiElement psiElement, @NotNull final AnnotationHolder annotationHolder) {
    final BugInstance bugInstance = problemDescriptor.getBugInstance();
    final int priority = bugInstance.getPriority();
    final Annotation annotation;
    final PsiElement problemElement = problemDescriptor.getPsiElement();
    final TextRange textRange = problemElement.getTextRange();


    switch (priority) {
      case Detector.HIGH_PRIORITY:

        if (psiElement instanceof PsiAnonymousClass) {
          final PsiElement firstChild = psiElement.getFirstChild();
          annotation = annotationHolder.createWarningAnnotation(firstChild == null ? psiElement : firstChild, getAnnotationText(matchingDescriptors));
          // todo: use color from annotation configuration
          annotation.setEnforcedTextAttributes(new TextAttributes(null, null, JBColor.RED.brighter(), EffectType.BOXED, Font.PLAIN));
        } else {
          annotation = annotationHolder.createWarningAnnotation(textRange, getAnnotationText(matchingDescriptors));
          // todo: use color from annotation configuration
          annotation.setEnforcedTextAttributes(new TextAttributes(null, null, JBColor.RED, EffectType.WAVE_UNDERSCORE, Font.PLAIN));
        }

        annotation.registerFix(new SuppressReportBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new SuppressReportBugForClassIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearAndSuppressBugIntentionAction(problemDescriptor), textRange);

        break;

      case Detector.NORMAL_PRIORITY:

        if (psiElement instanceof PsiAnonymousClass) {
          final PsiElement firstChild = psiElement.getFirstChild();
          annotation = annotationHolder.createWarningAnnotation(firstChild == null ? psiElement : firstChild, getAnnotationText(matchingDescriptors));
        } else {
          annotation = annotationHolder.createWarningAnnotation(textRange, getAnnotationText(matchingDescriptors));
        }

        // todo: use color from annotation configuration
        annotation.setEnforcedTextAttributes(new TextAttributes(null, null, JBColor.YELLOW.darker(), EffectType.WAVE_UNDERSCORE, Font.PLAIN));

        annotation.registerFix(new SuppressReportBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new SuppressReportBugForClassIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearAndSuppressBugIntentionAction(problemDescriptor), textRange);

        break;

      case Detector.EXP_PRIORITY:

        if (problemElement instanceof PsiAnonymousClass) {
          final PsiElement firstChild = psiElement.getFirstChild();
          annotation = annotationHolder.createWarningAnnotation(firstChild == null ? psiElement : firstChild, getAnnotationText(matchingDescriptors));
        } else {
          annotation = annotationHolder.createWarningAnnotation(textRange, getAnnotationText(matchingDescriptors));
        }

        // todo: use color from annotation configuration
        annotation.setEnforcedTextAttributes(new TextAttributes(null, null, JBColor.GRAY, EffectType.WAVE_UNDERSCORE, Font.PLAIN));

        annotation.registerFix(new SuppressReportBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new SuppressReportBugForClassIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearAndSuppressBugIntentionAction(problemDescriptor), textRange);

        break;
      case Detector.LOW_PRIORITY:

        if (psiElement instanceof PsiAnonymousClass) {
          final PsiElement firstChild = psiElement.getFirstChild();
          annotation = annotationHolder.createInfoAnnotation(firstChild == null ? psiElement : firstChild, getAnnotationText(matchingDescriptors));
        } else {
          annotation = annotationHolder.createInfoAnnotation(textRange, getAnnotationText(matchingDescriptors));
        }

        // todo: use color from annotation configuration
        annotation.setEnforcedTextAttributes(new TextAttributes(null, null, JBColor.GREEN, EffectType.WAVE_UNDERSCORE, Font.PLAIN));

        annotation.registerFix(new SuppressReportBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new SuppressReportBugForClassIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearAndSuppressBugIntentionAction(problemDescriptor), textRange);

        break;
      case Detector.IGNORE_PRIORITY:
        if (problemElement instanceof PsiAnonymousClass) {
          final PsiElement firstChild = psiElement.getFirstChild();
          annotation = annotationHolder.createWarningAnnotation(firstChild == null ? psiElement : firstChild, getAnnotationText(matchingDescriptors));
          annotation.setEnforcedTextAttributes(new TextAttributes(null, null, JBColor.MAGENTA.brighter(), EffectType.WAVE_UNDERSCORE, Font.PLAIN));
        } else {
          annotation = annotationHolder.createWarningAnnotation(textRange, getAnnotationText(matchingDescriptors));
        }

        // todo: use color from annotation configuration
        annotation.setEnforcedTextAttributes(new TextAttributes(null, null, JBColor.MAGENTA, EffectType.WAVE_UNDERSCORE, Font.PLAIN));

        annotation.registerFix(new SuppressReportBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new SuppressReportBugForClassIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearBugIntentionAction(problemDescriptor), textRange);
        annotation.registerFix(new ClearAndSuppressBugIntentionAction(problemDescriptor), textRange);

        break;
      default:
        throw new IllegalArgumentException("Unknown bugInstance.getPriority() == " + priority);
    }
  }
 

  private static String getAnnotationText(final List<ExtendedProblemDescriptor> problemDescriptors) {
    final StringBuilder buffer = new StringBuilder();
    for (//noinspection LocalCanBeFinal
        int i = 0, problemDescriptorsSize = problemDescriptors.size(); i < problemDescriptorsSize; i++) {
      final ExtendedProblemDescriptor problemDescriptor = problemDescriptors.get(i);
      buffer.append(ResourcesLoader.getString("findbugs.name")).append(": ").append(StringUtil.html2text(BugInstanceUtil.getBugPatternShortDescription(problemDescriptor.getBugInstance()))).append('\n');
      buffer.append(StringUtil.html2text(BugInstanceUtil.getDetailText(problemDescriptor.getBugInstance())));
      if (i < problemDescriptors.size() - 1) {
        //noinspection HardcodedLineSeparator
        buffer.append("\n\n");
      }
    }

    return StringUtil.addLineSeparatorAt(buffer, 250).toString();
  }


  public void onEvent(@NotNull final BugReporterEvent event) {
    switch (event.getOperation()) {

      case ANALYSIS_STARTED:
        _analysisRunning = true;
        break;
      case ANALYSIS_ABORTED:
      case ANALYSIS_FINISHED:
        _analysisRunning = false;
        break;
      case NEW_BUG_INSTANCE:
        break;
      default:
    }
  }


  /*private static class AnonymousInnerClassMayBeStaticVisitor extends BaseInspectionVisitor {

    @Override
    public void visitClass(@NotNull PsiClass aClass) {
      if (!(aClass instanceof PsiAnonymousClass)) {
        return;
      }
      if (aClass instanceof PsiEnumConstantInitializer) {
        return;
      }
      final PsiMember containingMember = PsiTreeUtil.getParentOfType(aClass, PsiMember.class);
      if (containingMember == null || containingMember.hasModifierProperty(PsiModifier.STATIC)) {
        return;
      }
      final PsiAnonymousClass anAnonymousClass = (PsiAnonymousClass) aClass;
      final InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(anAnonymousClass);
      anAnonymousClass.accept(visitor);
      if (!visitor.canInnerClassBeStatic()) {
        return;
      }
      registerClassError(aClass);
    }
  }*/
TOP

Related Classes of org.twodividedbyzero.idea.findbugs.gui.editor.BugAnnotator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.