private void reportNullableReturns(
      DataFlowInstructionVisitor visitor,
      ProblemsHolder holder,
      Set<PsiElement> reportedAnchors,
      @NotNull PsiElement block) {
    final PsiMethod method = getScopeMethod(block);
    if (method == null || NullableStuffInspectionBase.isNullableNotInferred(method, true)) return;

    boolean notNullRequired = NullableNotNullManager.isNotNull(method);
    if (!notNullRequired && !SUGGEST_NULLABLE_ANNOTATIONS) return;

    PsiType returnType = method.getReturnType();
    // no warnings in void lambdas, where the expression is not returned anyway
    if (block instanceof PsiExpression
        && block.getParent() instanceof PsiLambdaExpression
        && returnType == PsiType.VOID) return;

    // no warnings for Void methods, where only null can be possibly returned
    if (returnType == null || returnType.equalsToText(CommonClassNames.JAVA_LANG_VOID)) return;

    for (PsiElement statement : visitor.getProblems(NullabilityProblem.nullableReturn)) {
      assert statement instanceof PsiExpression;
      final PsiExpression expr = (PsiExpression) statement;
      if (!reportedAnchors.add(expr)) continue;

      if (notNullRequired) {
        final String text =
            isNullLiteralExpression(expr)
                ? InspectionsBundle.message("dataflow.message.return.null.from.notnull")
                : InspectionsBundle.message("dataflow.message.return.nullable.from.notnull");
        holder.registerProblem(expr, text);
      } else if (AnnotationUtil.isAnnotatingApplicable(statement)) {
        final NullableNotNullManager manager =
            NullableNotNullManager.getInstance(expr.getProject());
        final String defaultNullable = manager.getDefaultNullable();
        final String presentableNullable = StringUtil.getShortName(defaultNullable);
        final String text =
            isNullLiteralExpression(expr)
                ? InspectionsBundle.message(
                    "dataflow.message.return.null.from.notnullable", presentableNullable)
                : InspectionsBundle.message(
                    "dataflow.message.return.nullable.from.notnullable", presentableNullable);
        final LocalQuickFix[] fixes =
            PsiTreeUtil.getParentOfType(expr, PsiMethod.class, PsiLambdaExpression.class)
                    instanceof PsiLambdaExpression
                ? LocalQuickFix.EMPTY_ARRAY
                : new LocalQuickFix[] {
                  new AnnotateMethodFix(
                      defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())) {
                    @Override
                    public int shouldAnnotateBaseMethod(
                        PsiMethod method, PsiMethod superMethod, Project project) {
                      return 1;
                    }
                  }
                };
        holder.registerProblem(expr, text, fixes);
      }
    }
  }
Esempio n. 2
0
  public void showDescription(InspectionTool tool) {
    if (tool.getShortName().length() == 0) {
      showEmpty();
      return;
    }
    @NonNls StringBuffer page = new StringBuffer();
    page.append("<table border='0' cellspacing='0' cellpadding='0' width='100%'>");
    page.append("<tr><td colspan='2'>");
    HTMLComposer.appendHeading(
        page, InspectionsBundle.message("inspection.tool.in.browser.id.title"));
    page.append("</td></tr>");
    page.append("<tr><td width='37'></td>" + "<td>");
    page.append(tool.getShortName());
    page.append("</td></tr>");
    page.append("<tr height='10'></tr>");
    page.append("<tr><td colspan='2'>");
    HTMLComposer.appendHeading(
        page, InspectionsBundle.message("inspection.tool.in.browser.description.title"));
    page.append("</td></tr>");
    page.append("<tr><td width='37'></td>" + "<td>");
    @NonNls final String underConstruction = "<b>" + UNDER_CONSTRUCTION + "</b></html>";
    try {
      @NonNls String description = tool.loadDescription();
      if (description == null) {
        description = underConstruction;
      }
      page.append(UIUtil.getHtmlBody(description));

      page.append("</td></tr></table>");
      myHTMLViewer.setText(XmlStringUtil.wrapInHtml(page));
      setupStyle();
    } finally {
      myCurrentEntity = null;
    }
  }
 public RerunAction(JComponent comp) {
   super(
       InspectionsBundle.message("inspection.action.rerun"),
       InspectionsBundle.message("inspection.action.rerun"),
       AllIcons.Actions.Rerun);
   registerCustomShortcutSet(CommonShortcuts.getRerun(), comp);
 }
 private void handleBranchingInstruction(
     ProblemsHolder holder,
     StandardInstructionVisitor visitor,
     Set<Instruction> trueSet,
     Set<Instruction> falseSet,
     HashSet<PsiElement> reportedAnchors,
     BranchingInstruction instruction,
     final boolean onTheFly) {
   PsiElement psiAnchor = instruction.getPsiAnchor();
   boolean underBinary = isAtRHSOfBooleanAnd(psiAnchor);
   if (instruction instanceof InstanceofInstruction
       && visitor.isInstanceofRedundant((InstanceofInstruction) instruction)) {
     if (visitor.canBeNull((BinopInstruction) instruction)) {
       holder.registerProblem(
           psiAnchor,
           InspectionsBundle.message("dataflow.message.redundant.instanceof"),
           new RedundantInstanceofFix());
     } else {
       final LocalQuickFix localQuickFix = createSimplifyBooleanExpressionFix(psiAnchor, true);
       holder.registerProblem(
           psiAnchor,
           InspectionsBundle.message(
               underBinary
                   ? "dataflow.message.constant.condition.when.reached"
                   : "dataflow.message.constant.condition",
               Boolean.toString(true)),
           localQuickFix == null ? null : new LocalQuickFix[] {localQuickFix});
     }
   } else if (psiAnchor instanceof PsiSwitchLabelStatement) {
     if (falseSet.contains(instruction)) {
       holder.registerProblem(
           psiAnchor, InspectionsBundle.message("dataflow.message.unreachable.switch.label"));
     }
   } else if (psiAnchor != null
       && !reportedAnchors.contains(psiAnchor)
       && !isFlagCheck(psiAnchor)) {
     boolean evaluatesToTrue = trueSet.contains(instruction);
     final PsiElement parent = psiAnchor.getParent();
     if (parent instanceof PsiAssignmentExpression
         && ((PsiAssignmentExpression) parent).getLExpression() == psiAnchor) {
       holder.registerProblem(
           psiAnchor,
           InspectionsBundle.message(
               "dataflow.message.pointless.assignment.expression",
               Boolean.toString(evaluatesToTrue)),
           createConditionalAssignmentFixes(
               evaluatesToTrue, (PsiAssignmentExpression) parent, onTheFly));
     } else if (!skipReportingConstantCondition(visitor, psiAnchor, evaluatesToTrue)) {
       final LocalQuickFix fix = createSimplifyBooleanExpressionFix(psiAnchor, evaluatesToTrue);
       String message =
           InspectionsBundle.message(
               underBinary
                   ? "dataflow.message.constant.condition.when.reached"
                   : "dataflow.message.constant.condition",
               Boolean.toString(evaluatesToTrue));
       holder.registerProblem(psiAnchor, message, fix == null ? null : new LocalQuickFix[] {fix});
     }
     reportedAnchors.add(psiAnchor);
   }
 }
    private OptionsPanel() {
      super(new GridBagLayout());

      GridBagConstraints gc = new GridBagConstraints();
      gc.fill = GridBagConstraints.HORIZONTAL;
      gc.weightx = 1;
      gc.weighty = 0;
      gc.anchor = GridBagConstraints.NORTHWEST;

      myPackageLocalForMembersCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.visibility.option"));
      myPackageLocalForMembersCheckbox.setSelected(SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS);
      myPackageLocalForMembersCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS = myPackageLocalForMembersCheckbox.isSelected();
                }
              });

      gc.gridy = 0;
      add(myPackageLocalForMembersCheckbox, gc);

      myPackageLocalForTopClassesCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.visibility.option1"));
      myPackageLocalForTopClassesCheckbox.setSelected(SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES);
      myPackageLocalForTopClassesCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES =
                      myPackageLocalForTopClassesCheckbox.isSelected();
                }
              });

      gc.gridy = 1;
      add(myPackageLocalForTopClassesCheckbox, gc);

      myPrivateForInnersCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.visibility.option2"));
      myPrivateForInnersCheckbox.setSelected(SUGGEST_PRIVATE_FOR_INNERS);
      myPrivateForInnersCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  SUGGEST_PRIVATE_FOR_INNERS = myPrivateForInnersCheckbox.isSelected();
                }
              });

      gc.gridy = 2;
      gc.weighty = 1;
      add(myPrivateForInnersCheckbox, gc);
    }
Esempio n. 6
0
    private OptionsPanel() {
      super(new GridBagLayout());

      GridBagConstraints gc = new GridBagConstraints();
      gc.weighty = 0;
      gc.weightx = 1;
      gc.fill = GridBagConstraints.HORIZONTAL;
      gc.anchor = GridBagConstraints.NORTHWEST;

      myReportClassesCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option"));
      myReportClassesCheckbox.setSelected(REPORT_CLASSES);
      myReportClassesCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  REPORT_CLASSES = myReportClassesCheckbox.isSelected();
                }
              });
      gc.gridy = 0;
      add(myReportClassesCheckbox, gc);

      myReportMethodsCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option1"));
      myReportMethodsCheckbox.setSelected(REPORT_METHODS);
      myReportMethodsCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  REPORT_METHODS = myReportMethodsCheckbox.isSelected();
                }
              });
      gc.gridy++;
      add(myReportMethodsCheckbox, gc);

      myReportFieldsCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option2"));
      myReportFieldsCheckbox.setSelected(REPORT_FIELDS);
      myReportFieldsCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  REPORT_FIELDS = myReportFieldsCheckbox.isSelected();
                }
              });

      gc.weighty = 1;
      gc.gridy++;
      add(myReportFieldsCheckbox, gc);
    }
  private static void reportNullableAssignments(
      DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
    for (PsiElement expr : visitor.getProblems(NullabilityProblem.assigningToNotNull)) {
      if (!reportedAnchors.add(expr)) continue;

      final String text =
          isNullLiteralExpression(expr)
              ? InspectionsBundle.message("dataflow.message.assigning.null")
              : InspectionsBundle.message("dataflow.message.assigning.nullable");
      holder.registerProblem(expr, text);
    }
  }
  private void reportNullableArguments(
      DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
    for (PsiElement expr :
        visitor.getProblems(NullabilityProblem.passingNullableToNotNullParameter)) {
      if (!reportedAnchors.add(expr)) continue;

      final String text =
          isNullLiteralExpression(expr)
              ? InspectionsBundle.message("dataflow.message.passing.null.argument")
              : InspectionsBundle.message("dataflow.message.passing.nullable.argument");
      LocalQuickFix[] fixes =
          createNPEFixes((PsiExpression) expr, (PsiExpression) expr, holder.isOnTheFly());
      holder.registerProblem(expr, text, fixes);
    }
  }
 private void reportFieldAccessMayProduceNpe(
     ProblemsHolder holder, PsiElement elementToAssert, PsiExpression expression) {
   if (expression instanceof PsiArrayAccessExpression) {
     LocalQuickFix[] fix =
         createNPEFixes((PsiExpression) elementToAssert, expression, holder.isOnTheFly());
     holder.registerProblem(
         expression, InspectionsBundle.message("dataflow.message.npe.array.access"), fix);
   } else {
     LocalQuickFix[] fix =
         createNPEFixes((PsiExpression) elementToAssert, expression, holder.isOnTheFly());
     assert elementToAssert != null;
     holder.registerProblem(
         elementToAssert, InspectionsBundle.message("dataflow.message.npe.field.access"), fix);
   }
 }
  private void analyzeDfaWithNestedClosures(
      PsiElement scope,
      ProblemsHolder holder,
      StandardDataFlowRunner dfaRunner,
      Collection<DfaMemoryState> initialStates) {
    final DataFlowInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
    final RunnerResult rc =
        dfaRunner.analyzeMethod(scope, visitor, IGNORE_ASSERT_STATEMENTS, initialStates);
    if (rc == RunnerResult.OK) {
      createDescription(dfaRunner, holder, visitor);

      MultiMap<PsiElement, DfaMemoryState> nestedClosures = dfaRunner.getNestedClosures();
      for (PsiElement closure : nestedClosures.keySet()) {
        analyzeDfaWithNestedClosures(closure, holder, dfaRunner, nestedClosures.get(closure));
      }
    } else if (rc == RunnerResult.TOO_COMPLEX) {
      if (scope.getParent() instanceof PsiMethod) {
        PsiMethod method = (PsiMethod) scope.getParent();
        final PsiIdentifier name = method.getNameIdentifier();
        if (name != null) { // Might be null for synthetic methods like JSP page.
          holder.registerProblem(
              name,
              InspectionsBundle.message("dataflow.too.complex"),
              ProblemHighlightType.WEAK_WARNING);
        }
      }
    }
  }
 private static void reportUnboxedNullables(
     DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
   for (PsiElement expr : visitor.getProblems(NullabilityProblem.unboxingNullable)) {
     if (!reportedAnchors.add(expr)) continue;
     holder.registerProblem(expr, InspectionsBundle.message("dataflow.message.unboxing"));
   }
 }
 @Nullable
 @Override
 public JComponent createOptionsPanel() {
   return new SingleCheckboxOptionsPanel(
       InspectionsBundle.message("inspection.duplicate.throws.ignore.subclassing.option"),
       this,
       "ignoreSubclassing");
 }
 private static void reportCastMayFail(ProblemsHolder holder, TypeCastInstruction instruction) {
   PsiTypeCastExpression typeCast = instruction.getCastExpression();
   PsiExpression operand = typeCast.getOperand();
   PsiTypeElement castType = typeCast.getCastType();
   assert castType != null;
   assert operand != null;
   holder.registerProblem(
       castType, InspectionsBundle.message("dataflow.message.cce", operand.getText()));
 }
  private void reportCallMayProduceNpe(
      ProblemsHolder holder, PsiMethodCallExpression callExpression, boolean onTheFly) {
    LocalQuickFix[] fix =
        createNPEFixes(
            callExpression.getMethodExpression().getQualifierExpression(),
            callExpression,
            onTheFly);

    holder.registerProblem(
        callExpression, InspectionsBundle.message("dataflow.message.npe.method.invocation"), fix);
  }
  @Nullable
  private ProblemDescriptor createDescription(
      @NotNull PsiTypeCastExpression cast, @NotNull InspectionManager manager, boolean onTheFly) {
    PsiExpression operand = cast.getOperand();
    PsiTypeElement castType = cast.getCastType();
    if (operand == null || castType == null) return null;
    PsiElement parent = cast.getParent();
    while (parent instanceof PsiParenthesizedExpression) {
      parent = parent.getParent();
    }
    if (parent instanceof PsiReferenceExpression) {
      if (IGNORE_ANNOTATED_METHODS) {
        final PsiElement gParent = parent.getParent();
        if (gParent instanceof PsiMethodCallExpression) {
          final PsiMethod psiMethod = ((PsiMethodCallExpression) gParent).resolveMethod();
          if (psiMethod != null && NullableNotNullManager.isNotNull(psiMethod)) {
            final PsiClass superClass = PsiUtil.resolveClassInType(operand.getType());
            final PsiClass containingClass = psiMethod.getContainingClass();
            if (containingClass != null
                && superClass != null
                && containingClass.isInheritor(superClass, true)) {
              for (PsiMethod method : psiMethod.findSuperMethods(superClass)) {
                if (NullableNotNullManager.isNullable(method)) {
                  return null;
                }
              }
            }
          }
        }
      }
    } else if (parent instanceof PsiExpressionList) {
      final PsiElement gParent = parent.getParent();
      if (gParent instanceof PsiMethodCallExpression && IGNORE_SUSPICIOUS_METHOD_CALLS) {
        final String message =
            SuspiciousCollectionsMethodCallsInspection.getSuspiciousMethodCallMessage(
                (PsiMethodCallExpression) gParent,
                operand.getType(),
                true,
                new ArrayList<PsiMethod>(),
                new IntArrayList());
        if (message != null) {
          return null;
        }
      }
    }

    String message =
        InspectionsBundle.message(
            "inspection.redundant.cast.problem.descriptor",
            "<code>" + operand.getText() + "</code>",
            "<code>#ref</code> #loc");
    return manager.createProblemDescriptor(
        castType, message, myQuickFixAction, ProblemHighlightType.LIKE_UNUSED_SYMBOL, onTheFly);
  }
  private static void reportNullableReturns(
      StandardDataFlowRunner runner,
      DataFlowInstructionVisitor visitor,
      ProblemsHolder holder,
      Set<PsiElement> reportedAnchors) {
    for (PsiElement statement : visitor.getProblems(NullabilityProblem.nullableReturn)) {
      assert statement instanceof PsiExpression;
      final PsiExpression expr = (PsiExpression) statement;
      if (!reportedAnchors.add(expr)) continue;

      if (runner.isInNotNullMethod()) {
        final String text =
            isNullLiteralExpression(expr)
                ? InspectionsBundle.message("dataflow.message.return.null.from.notnull")
                : InspectionsBundle.message("dataflow.message.return.nullable.from.notnull");
        holder.registerProblem(expr, text);
      } else if (AnnotationUtil.isAnnotatingApplicable(statement)) {
        final NullableNotNullManager manager =
            NullableNotNullManager.getInstance(expr.getProject());
        final String defaultNullable = manager.getDefaultNullable();
        final String presentableNullable = StringUtil.getShortName(defaultNullable);
        final String text =
            isNullLiteralExpression(expr)
                ? InspectionsBundle.message(
                    "dataflow.message.return.null.from.notnullable", presentableNullable)
                : InspectionsBundle.message(
                    "dataflow.message.return.nullable.from.notnullable", presentableNullable);
        holder.registerProblem(
            expr,
            text,
            new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())) {
              @Override
              public int shouldAnnotateBaseMethod(
                  PsiMethod method, PsiMethod superMethod, Project project) {
                return 1;
              }
            });
      }
    }
  }
Esempio n. 17
0
  @Override
  @Nullable
  public CommonProblemDescriptor[] checkElement(
      @NotNull final RefEntity refEntity,
      @NotNull final AnalysisScope scope,
      @NotNull final InspectionManager manager,
      @NotNull final GlobalInspectionContext globalContext,
      @NotNull final ProblemDescriptionsProcessor processor) {
    if (refEntity instanceof RefJavaElement) {
      final RefJavaElement refElement = (RefJavaElement) refEntity;
      if (refElement instanceof RefParameter) return null;
      if (!refElement.isReferenced()) return null;
      if (refElement.isSyntheticJSP()) return null;
      if (refElement.isFinal()) return null;
      if (!((RefElementImpl) refElement).checkFlag(CanBeFinalAnnotator.CAN_BE_FINAL_MASK))
        return null;

      final PsiMember psiMember = (PsiMember) refElement.getElement();
      if (psiMember == null || !CanBeFinalHandler.allowToBeFinal(psiMember)) return null;

      PsiIdentifier psiIdentifier = null;
      if (refElement instanceof RefClass) {
        RefClass refClass = (RefClass) refElement;
        if (refClass.isInterface() || refClass.isAnonymous() || refClass.isAbstract()) return null;
        if (!isReportClasses()) return null;
        psiIdentifier = ((PsiClass) psiMember).getNameIdentifier();
      } else if (refElement instanceof RefMethod) {
        RefMethod refMethod = (RefMethod) refElement;
        if (refMethod.getOwnerClass().isFinal()) return null;
        if (!isReportMethods()) return null;
        psiIdentifier = ((PsiMethod) psiMember).getNameIdentifier();
      } else if (refElement instanceof RefField) {
        if (!isReportFields()) return null;
        psiIdentifier = ((PsiField) psiMember).getNameIdentifier();
      }

      if (psiIdentifier != null) {
        return new ProblemDescriptor[] {
          manager.createProblemDescriptor(
              psiIdentifier,
              InspectionsBundle.message("inspection.export.results.can.be.final.description"),
              new AcceptSuggested(globalContext.getRefManager()),
              ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
              false)
        };
      }
    }
    return null;
  }
Esempio n. 18
0
 private void appendSuppressSection(final StringBuffer buf) {
   final InspectionTool tool = getTool();
   if (tool != null) {
     final HighlightDisplayKey key = HighlightDisplayKey.find(tool.getShortName());
     if (key != null) { // dummy entry points
       final SuppressActionWrapper.SuppressTreeAction[] suppressActions =
           new SuppressActionWrapper(
                   myView.getProject(), tool, myView.getTree().getSelectionPaths())
               .getChildren(null);
       if (suppressActions.length > 0) {
         final List<AnAction> activeSuppressActions = new ArrayList<AnAction>();
         for (SuppressActionWrapper.SuppressTreeAction suppressAction : suppressActions) {
           if (suppressAction.isAvailable()) {
             activeSuppressActions.add(suppressAction);
           }
         }
         if (!activeSuppressActions.isEmpty()) {
           int idx = 0;
           @NonNls final String br = "<br>";
           buf.append(br);
           HTMLComposerImpl.appendHeading(
               buf, InspectionsBundle.message("inspection.export.results.suppress"));
           for (AnAction suppressAction : activeSuppressActions) {
             buf.append(br);
             if (idx == activeSuppressActions.size() - 1) {
               buf.append(br);
             }
             HTMLComposer.appendAfterHeaderIndention(buf);
             @NonNls
             final String href =
                 "<a HREF=\"file://bred.txt#suppress:"
                     + idx
                     + "\">"
                     + suppressAction.getTemplatePresentation().getText()
                     + "</a>";
             buf.append(href);
             idx++;
           }
         }
       }
     }
   }
 }
 private static String cannotResolveSymbolMessage(String params) {
   return InspectionsBundle.message("inspection.javadoc.problem.cannot.resolve", params);
 }
Esempio n. 20
0
public class CanBeFinalInspection extends GlobalJavaBatchInspectionTool {
  private static final Logger LOG =
      Logger.getInstance("#com.intellij.codeInspection.canBeFinal.CanBeFinalInspection");

  public boolean REPORT_CLASSES;
  public boolean REPORT_METHODS;
  public boolean REPORT_FIELDS = true;
  public static final String DISPLAY_NAME =
      InspectionsBundle.message("inspection.can.be.final.display.name");
  @NonNls public static final String SHORT_NAME = "CanBeFinal";

  @NonNls
  private static final String QUICK_FIX_NAME =
      InspectionsBundle.message("inspection.can.be.final.accept.quickfix");

  private class OptionsPanel extends JPanel {
    private final JCheckBox myReportClassesCheckbox;
    private final JCheckBox myReportMethodsCheckbox;
    private final JCheckBox myReportFieldsCheckbox;

    private OptionsPanel() {
      super(new GridBagLayout());

      GridBagConstraints gc = new GridBagConstraints();
      gc.weighty = 0;
      gc.weightx = 1;
      gc.fill = GridBagConstraints.HORIZONTAL;
      gc.anchor = GridBagConstraints.NORTHWEST;

      myReportClassesCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option"));
      myReportClassesCheckbox.setSelected(REPORT_CLASSES);
      myReportClassesCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  REPORT_CLASSES = myReportClassesCheckbox.isSelected();
                }
              });
      gc.gridy = 0;
      add(myReportClassesCheckbox, gc);

      myReportMethodsCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option1"));
      myReportMethodsCheckbox.setSelected(REPORT_METHODS);
      myReportMethodsCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  REPORT_METHODS = myReportMethodsCheckbox.isSelected();
                }
              });
      gc.gridy++;
      add(myReportMethodsCheckbox, gc);

      myReportFieldsCheckbox =
          new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option2"));
      myReportFieldsCheckbox.setSelected(REPORT_FIELDS);
      myReportFieldsCheckbox
          .getModel()
          .addChangeListener(
              new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                  REPORT_FIELDS = myReportFieldsCheckbox.isSelected();
                }
              });

      gc.weighty = 1;
      gc.gridy++;
      add(myReportFieldsCheckbox, gc);
    }
  }

  public boolean isReportClasses() {
    return REPORT_CLASSES;
  }

  public boolean isReportMethods() {
    return REPORT_METHODS;
  }

  public boolean isReportFields() {
    return REPORT_FIELDS;
  }

  @Override
  public JComponent createOptionsPanel() {
    return new OptionsPanel();
  }

  @Override
  @Nullable
  public RefGraphAnnotator getAnnotator(@NotNull final RefManager refManager) {
    return new CanBeFinalAnnotator(refManager);
  }

  @Override
  @Nullable
  public CommonProblemDescriptor[] checkElement(
      @NotNull final RefEntity refEntity,
      @NotNull final AnalysisScope scope,
      @NotNull final InspectionManager manager,
      @NotNull final GlobalInspectionContext globalContext,
      @NotNull final ProblemDescriptionsProcessor processor) {
    if (refEntity instanceof RefJavaElement) {
      final RefJavaElement refElement = (RefJavaElement) refEntity;
      if (refElement instanceof RefParameter) return null;
      if (!refElement.isReferenced()) return null;
      if (refElement.isSyntheticJSP()) return null;
      if (refElement.isFinal()) return null;
      if (!((RefElementImpl) refElement).checkFlag(CanBeFinalAnnotator.CAN_BE_FINAL_MASK))
        return null;

      final PsiMember psiMember = (PsiMember) refElement.getElement();
      if (psiMember == null || !CanBeFinalHandler.allowToBeFinal(psiMember)) return null;

      PsiIdentifier psiIdentifier = null;
      if (refElement instanceof RefClass) {
        RefClass refClass = (RefClass) refElement;
        if (refClass.isInterface() || refClass.isAnonymous() || refClass.isAbstract()) return null;
        if (!isReportClasses()) return null;
        psiIdentifier = ((PsiClass) psiMember).getNameIdentifier();
      } else if (refElement instanceof RefMethod) {
        RefMethod refMethod = (RefMethod) refElement;
        if (refMethod.getOwnerClass().isFinal()) return null;
        if (!isReportMethods()) return null;
        psiIdentifier = ((PsiMethod) psiMember).getNameIdentifier();
      } else if (refElement instanceof RefField) {
        if (!isReportFields()) return null;
        psiIdentifier = ((PsiField) psiMember).getNameIdentifier();
      }

      if (psiIdentifier != null) {
        return new ProblemDescriptor[] {
          manager.createProblemDescriptor(
              psiIdentifier,
              InspectionsBundle.message("inspection.export.results.can.be.final.description"),
              new AcceptSuggested(globalContext.getRefManager()),
              ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
              false)
        };
      }
    }
    return null;
  }

  @Override
  protected boolean queryExternalUsagesRequests(
      @NotNull final RefManager manager,
      @NotNull final GlobalJavaInspectionContext globalContext,
      @NotNull final ProblemDescriptionsProcessor problemsProcessor) {
    for (RefElement entryPoint : globalContext.getEntryPointsManager(manager).getEntryPoints()) {
      problemsProcessor.ignoreElement(entryPoint);
    }

    manager.iterate(
        new RefJavaVisitor() {
          @Override
          public void visitElement(@NotNull RefEntity refEntity) {
            if (problemsProcessor.getDescriptions(refEntity) == null) return;
            refEntity.accept(
                new RefJavaVisitor() {
                  @Override
                  public void visitMethod(@NotNull final RefMethod refMethod) {
                    if (!refMethod.isStatic()
                        && !PsiModifier.PRIVATE.equals(refMethod.getAccessModifier())
                        && !(refMethod instanceof RefImplicitConstructor)) {
                      globalContext.enqueueDerivedMethodsProcessor(
                          refMethod,
                          new GlobalJavaInspectionContext.DerivedMethodsProcessor() {
                            @Override
                            public boolean process(PsiMethod derivedMethod) {
                              ((RefElementImpl) refMethod)
                                  .setFlag(false, CanBeFinalAnnotator.CAN_BE_FINAL_MASK);
                              problemsProcessor.ignoreElement(refMethod);
                              return false;
                            }
                          });
                    }
                  }

                  @Override
                  public void visitClass(@NotNull final RefClass refClass) {
                    if (!refClass.isAnonymous()) {
                      globalContext.enqueueDerivedClassesProcessor(
                          refClass,
                          new GlobalJavaInspectionContext.DerivedClassesProcessor() {
                            @Override
                            public boolean process(PsiClass inheritor) {
                              ((RefClassImpl) refClass)
                                  .setFlag(false, CanBeFinalAnnotator.CAN_BE_FINAL_MASK);
                              problemsProcessor.ignoreElement(refClass);
                              return false;
                            }
                          });
                    }
                  }

                  @Override
                  public void visitField(@NotNull final RefField refField) {
                    globalContext.enqueueFieldUsagesProcessor(
                        refField,
                        new GlobalJavaInspectionContext.UsagesProcessor() {
                          @Override
                          public boolean process(PsiReference psiReference) {
                            PsiElement expression = psiReference.getElement();
                            if (expression instanceof PsiReferenceExpression
                                && PsiUtil.isAccessedForWriting((PsiExpression) expression)) {
                              ((RefFieldImpl) refField)
                                  .setFlag(false, CanBeFinalAnnotator.CAN_BE_FINAL_MASK);
                              problemsProcessor.ignoreElement(refField);
                              return false;
                            }
                            return true;
                          }
                        });
                  }
                });
          }
        });

    return false;
  }

  @Override
  @Nullable
  public QuickFix getQuickFix(final String hint) {
    return new AcceptSuggested(null);
  }

  @Override
  @NotNull
  public String getDisplayName() {
    return DISPLAY_NAME;
  }

  @Override
  @NotNull
  public String getGroupDisplayName() {
    return GroupNames.DECLARATION_REDUNDANCY;
  }

  @Override
  @NotNull
  public String getShortName() {
    return SHORT_NAME;
  }

  private static class AcceptSuggested implements LocalQuickFix {
    private final RefManager myManager;

    public AcceptSuggested(final RefManager manager) {
      myManager = manager;
    }

    @Override
    @NotNull
    public String getFamilyName() {
      return QUICK_FIX_NAME;
    }

    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      final PsiElement element = descriptor.getPsiElement();
      final PsiModifierListOwner psiElement =
          PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class);
      if (psiElement != null) {
        RefJavaElement refElement =
            (RefJavaElement) (myManager != null ? myManager.getReference(psiElement) : null);
        try {
          if (psiElement instanceof PsiVariable) {
            ((PsiVariable) psiElement).normalizeDeclaration();
          }
          final PsiModifierList modifierList = psiElement.getModifierList();
          LOG.assertTrue(modifierList != null);
          modifierList.setModifierProperty(PsiModifier.FINAL, true);
          modifierList.setModifierProperty(PsiModifier.VOLATILE, false);
        } catch (IncorrectOperationException e) {
          LOG.error(e);
        }

        if (refElement != null) {
          RefJavaUtil.getInstance().setIsFinal(refElement, true);
        }
      }
    }
  }
}
 private EditSettingsAction() {
   super(
       InspectionsBundle.message("inspection.action.edit.settings"),
       InspectionsBundle.message("inspection.action.edit.settings"),
       AllIcons.General.Settings);
 }
  @SuppressWarnings({"NonStaticInitializer"})
  private JComponent createRightActionsToolbar() {
    myIncludeAction =
        new AnAction(InspectionsBundle.message("inspections.result.view.include.action.text")) {
          {
            registerCustomShortcutSet(CommonShortcuts.INSERT, myTree);
          }

          @Override
          public void actionPerformed(AnActionEvent e) {
            final TreePath[] paths = myTree.getSelectionPaths();
            if (paths != null) {
              for (TreePath path : paths) {
                ((InspectionTreeNode) path.getLastPathComponent()).amnesty();
              }
            }
            updateView(false);
          }

          @Override
          public void update(final AnActionEvent e) {
            final TreePath[] paths = myTree.getSelectionPaths();
            e.getPresentation()
                .setEnabled(
                    paths != null
                        && paths.length > 0
                        && !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS);
          }
        };

    myExcludeAction =
        new AnAction(InspectionsBundle.message("inspections.result.view.exclude.action.text")) {
          {
            registerCustomShortcutSet(CommonShortcuts.getDelete(), myTree);
          }

          @Override
          public void actionPerformed(final AnActionEvent e) {
            final TreePath[] paths = myTree.getSelectionPaths();
            if (paths != null) {
              for (TreePath path : paths) {
                ((InspectionTreeNode) path.getLastPathComponent()).ignoreElement();
              }
            }
            updateView(false);
          }

          @Override
          public void update(final AnActionEvent e) {
            final TreePath[] path = myTree.getSelectionPaths();
            e.getPresentation().setEnabled(path != null && path.length > 0);
          }
        };

    DefaultActionGroup specialGroup = new DefaultActionGroup();
    specialGroup.add(myGlobalInspectionContext.getUIOptions().createGroupBySeverityAction(this));
    specialGroup.add(myGlobalInspectionContext.getUIOptions().createGroupByDirectoryAction(this));
    specialGroup.add(
        myGlobalInspectionContext.getUIOptions().createFilterResolvedItemsAction(this));
    specialGroup.add(
        myGlobalInspectionContext.getUIOptions().createShowOutdatedProblemsAction(this));
    specialGroup.add(myGlobalInspectionContext.getUIOptions().createShowDiffOnlyAction(this));
    specialGroup.add(new EditSettingsAction());
    specialGroup.add(new InvokeQuickFixAction(this));
    specialGroup.add(new InspectionsOptionsToolbarAction(this));
    return createToolbar(specialGroup);
  }
Esempio n. 23
0
class Browser extends JPanel {
  private static final String UNDER_CONSTRUCTION =
      InspectionsBundle.message("inspection.tool.description.under.construction.text");
  private final List<ClickListener> myClickListeners =
      ContainerUtil.createLockFreeCopyOnWriteList();
  private RefEntity myCurrentEntity;
  private JEditorPane myHTMLViewer;
  private final InspectionResultsView myView;
  private final HyperlinkListener myHyperLinkListener;
  private CommonProblemDescriptor myCurrentDescriptor;

  public static class ClickEvent {
    public static final int REF_ELEMENT = 1;
    public static final int FILE_OFFSET = 2;
    private final VirtualFile myFile;
    private final int myStartPosition;
    private final int myEndPosition;
    private final RefElement refElement;
    private final int myEventType;

    public ClickEvent(VirtualFile myFile, int myStartPosition, int myEndPosition) {
      this.myFile = myFile;
      this.myStartPosition = myStartPosition;
      this.myEndPosition = myEndPosition;
      myEventType = FILE_OFFSET;
      refElement = null;
    }

    public int getEventType() {
      return myEventType;
    }

    public VirtualFile getFile() {
      return myFile;
    }

    public int getStartOffset() {
      return myStartPosition;
    }

    public int getEndOffset() {
      return myEndPosition;
    }

    public RefElement getClickedElement() {
      return refElement;
    }
  }

  public void dispose() {
    removeAll();
    if (myHTMLViewer != null) {
      myHTMLViewer.removeHyperlinkListener(myHyperLinkListener);
      myHTMLViewer = null;
    }
    myClickListeners.clear();
  }

  public interface ClickListener {
    void referenceClicked(ClickEvent e);
  }

  private void showPageFromHistory(RefEntity newEntity) {
    InspectionTool tool = getTool(newEntity);
    try {
      if (tool instanceof DescriptorProviderInspection
          && !(tool instanceof CommonInspectionToolWrapper)) {
        showEmpty();
      } else {
        try {
          String html = generateHTML(newEntity, tool);
          myHTMLViewer.read(new StringReader(html), null);
          setupStyle();
          myHTMLViewer.setCaretPosition(0);
        } catch (Exception e) {
          showEmpty();
        }
      }
    } finally {
      myCurrentEntity = newEntity;
      myCurrentDescriptor = null;
    }
  }

  public void showPageFor(RefEntity refEntity, CommonProblemDescriptor descriptor) {
    try {
      String html = generateHTML(refEntity, descriptor);
      myHTMLViewer.read(new StringReader(html), null);
      setupStyle();
      myHTMLViewer.setCaretPosition(0);
    } catch (Exception e) {
      showEmpty();
    } finally {
      myCurrentEntity = refEntity;
      myCurrentDescriptor = descriptor;
    }
  }

  public void showPageFor(RefEntity newEntity) {
    if (newEntity == null) {
      showEmpty();
      return;
    }
    // multiple problems for one entity -> refresh browser
    showPageFromHistory(newEntity.getRefManager().getRefinedElement(newEntity));
  }

  public Browser(InspectionResultsView view) {
    super(new BorderLayout());
    myView = view;

    myCurrentEntity = null;
    myCurrentDescriptor = null;

    myHTMLViewer =
        new JEditorPane(
            UIUtil.HTML_MIME,
            InspectionsBundle.message("inspection.offline.view.empty.browser.text"));
    myHTMLViewer.setEditable(false);
    myHyperLinkListener =
        new HyperlinkListener() {
          @Override
          public void hyperlinkUpdate(HyperlinkEvent e) {
            if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
              JEditorPane pane = (JEditorPane) e.getSource();
              if (e instanceof HTMLFrameHyperlinkEvent) {
                HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e;
                HTMLDocument doc = (HTMLDocument) pane.getDocument();
                doc.processHTMLFrameHyperlinkEvent(evt);
              } else {
                try {
                  URL url = e.getURL();
                  @NonNls String ref = url.getRef();
                  if (ref.startsWith("pos:")) {
                    int delimeterPos = ref.indexOf(':', "pos:".length() + 1);
                    String startPosition = ref.substring("pos:".length(), delimeterPos);
                    String endPosition = ref.substring(delimeterPos + 1);
                    Integer textStartOffset = new Integer(startPosition);
                    Integer textEndOffset = new Integer(endPosition);
                    String fileURL = url.toExternalForm();
                    fileURL = fileURL.substring(0, fileURL.indexOf('#'));
                    VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
                    if (vFile != null) {
                      fireClickEvent(vFile, textStartOffset.intValue(), textEndOffset.intValue());
                    }
                  } else if (ref.startsWith("descr:")) {
                    if (myCurrentDescriptor instanceof ProblemDescriptor) {
                      PsiElement psiElement =
                          ((ProblemDescriptor) myCurrentDescriptor).getPsiElement();
                      if (psiElement == null) return;
                      VirtualFile vFile = psiElement.getContainingFile().getVirtualFile();
                      if (vFile != null) {
                        TextRange range =
                            ((ProblemDescriptorBase) myCurrentDescriptor).getTextRange();
                        fireClickEvent(vFile, range.getStartOffset(), range.getEndOffset());
                      }
                    }
                  } else if (ref.startsWith("invoke:")) {
                    int actionNumber = Integer.parseInt(ref.substring("invoke:".length()));
                    getTool()
                        .getQuickFixes(new RefElement[] {(RefElement) myCurrentEntity})[
                        actionNumber]
                        .doApplyFix(new RefElement[] {(RefElement) myCurrentEntity}, myView);
                  } else if (ref.startsWith("invokelocal:")) {
                    int actionNumber = Integer.parseInt(ref.substring("invokelocal:".length()));
                    if (actionNumber > -1) {
                      invokeLocalFix(actionNumber);
                    }
                  } else if (ref.startsWith("suppress:")) {
                    final SuppressActionWrapper.SuppressTreeAction[] suppressTreeActions =
                        new SuppressActionWrapper(
                                myView.getProject(),
                                getTool(),
                                myView.getTree().getSelectionPaths())
                            .getChildren(null);
                    final List<AnAction> activeActions = new ArrayList<AnAction>();
                    for (SuppressActionWrapper.SuppressTreeAction suppressTreeAction :
                        suppressTreeActions) {
                      if (suppressTreeAction.isAvailable()) activeActions.add(suppressTreeAction);
                    }
                    if (!activeActions.isEmpty()) {
                      int actionNumber = Integer.parseInt(ref.substring("suppress:".length()));
                      if (actionNumber > -1 && activeActions.size() > actionNumber) {
                        activeActions.get(actionNumber).actionPerformed(null);
                      }
                    }
                  } else {
                    int offset = Integer.parseInt(ref);
                    String fileURL = url.toExternalForm();
                    fileURL = fileURL.substring(0, fileURL.indexOf('#'));
                    VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
                    if (vFile == null) {
                      vFile = VfsUtil.findFileByURL(url);
                    }
                    if (vFile != null) {
                      fireClickEvent(vFile, offset, offset);
                    }
                  }
                } catch (Throwable t) {
                  // ???
                }
              }
            }
          }
        };
    myHTMLViewer.addHyperlinkListener(myHyperLinkListener);

    final JScrollPane pane = ScrollPaneFactory.createScrollPane(myHTMLViewer);
    pane.setBorder(null);
    add(pane, BorderLayout.CENTER);
    setupStyle();
  }

  private void setupStyle() {
    Document document = myHTMLViewer.getDocument();
    if (!(document instanceof StyledDocument)) {
      return;
    }

    StyledDocument styledDocument = (StyledDocument) document;

    EditorColorsManager colorsManager = EditorColorsManager.getInstance();
    EditorColorsScheme scheme = colorsManager.getGlobalScheme();

    Style style = styledDocument.addStyle("active", null);
    StyleConstants.setFontFamily(style, scheme.getEditorFontName());
    StyleConstants.setFontSize(style, scheme.getEditorFontSize());
    styledDocument.setCharacterAttributes(0, document.getLength(), style, false);
  }

  public void addClickListener(ClickListener listener) {
    myClickListeners.add(listener);
  }

  private void fireClickEvent(VirtualFile file, int startPosition, int endPosition) {
    ClickEvent e = new ClickEvent(file, startPosition, endPosition);

    for (ClickListener listener : myClickListeners) {
      listener.referenceClicked(e);
    }
  }

  private String generateHTML(final RefEntity refEntity, final InspectionTool tool) {
    final StringBuffer buf = new StringBuffer();
    if (refEntity instanceof RefElement) {
      final Runnable action =
          new Runnable() {
            @Override
            public void run() {
              tool.getComposer().compose(buf, refEntity);
            }
          };
      ApplicationManager.getApplication().runReadAction(action);
    } else {
      tool.getComposer().compose(buf, refEntity);
    }

    uppercaseFirstLetter(buf);

    if (refEntity instanceof RefElement) {
      appendSuppressSection(buf);
    }

    insertHeaderFooter(buf);

    return buf.toString();
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  private static void insertHeaderFooter(final StringBuffer buf) {
    buf.insert(0, "<HTML><BODY>");
    buf.append("</BODY></HTML>");
  }

  private String generateHTML(final RefEntity refEntity, final CommonProblemDescriptor descriptor) {
    final StringBuffer buf = new StringBuffer();
    final Runnable action =
        new Runnable() {
          @Override
          public void run() {
            InspectionTool tool = getTool(refEntity);
            tool.getComposer().compose(buf, refEntity, descriptor);
          }
        };
    ApplicationManager.getApplication().runReadAction(action);

    uppercaseFirstLetter(buf);

    if (refEntity instanceof RefElement) {
      appendSuppressSection(buf);
    }

    insertHeaderFooter(buf);
    return buf.toString();
  }

  private InspectionTool getTool(final RefEntity refEntity) {
    InspectionTool tool = getTool();
    assert tool != null;
    final GlobalInspectionContextImpl manager = tool.getContext();
    if (manager == null) return tool;
    if (refEntity instanceof RefElement) {
      PsiElement element = ((RefElement) refEntity).getElement();
      if (element == null) return tool;
      final InspectionProfileWrapper profileWrapper =
          InspectionProjectProfileManagerImpl.getInstanceImpl(manager.getProject())
              .getProfileWrapper();
      if (profileWrapper == null) return tool;
      tool = profileWrapper.getInspectionTool(tool.getShortName(), element);
    }
    return tool;
  }

  private void appendSuppressSection(final StringBuffer buf) {
    final InspectionTool tool = getTool();
    if (tool != null) {
      final HighlightDisplayKey key = HighlightDisplayKey.find(tool.getShortName());
      if (key != null) { // dummy entry points
        final SuppressActionWrapper.SuppressTreeAction[] suppressActions =
            new SuppressActionWrapper(
                    myView.getProject(), tool, myView.getTree().getSelectionPaths())
                .getChildren(null);
        if (suppressActions.length > 0) {
          final List<AnAction> activeSuppressActions = new ArrayList<AnAction>();
          for (SuppressActionWrapper.SuppressTreeAction suppressAction : suppressActions) {
            if (suppressAction.isAvailable()) {
              activeSuppressActions.add(suppressAction);
            }
          }
          if (!activeSuppressActions.isEmpty()) {
            int idx = 0;
            @NonNls final String br = "<br>";
            buf.append(br);
            HTMLComposerImpl.appendHeading(
                buf, InspectionsBundle.message("inspection.export.results.suppress"));
            for (AnAction suppressAction : activeSuppressActions) {
              buf.append(br);
              if (idx == activeSuppressActions.size() - 1) {
                buf.append(br);
              }
              HTMLComposer.appendAfterHeaderIndention(buf);
              @NonNls
              final String href =
                  "<a HREF=\"file://bred.txt#suppress:"
                      + idx
                      + "\">"
                      + suppressAction.getTemplatePresentation().getText()
                      + "</a>";
              buf.append(href);
              idx++;
            }
          }
        }
      }
    }
  }

  private static void uppercaseFirstLetter(final StringBuffer buf) {
    if (buf.length() > 1) {
      char[] firstLetter = new char[1];
      buf.getChars(0, 1, firstLetter, 0);
      buf.setCharAt(0, Character.toUpperCase(firstLetter[0]));
    }
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  public void showEmpty() {
    myCurrentEntity = null;
    try {
      myHTMLViewer.read(new StringReader("<html><body></body></html>"), null);
    } catch (IOException e) {
      // can't be
    }
  }

  public void showDescription(InspectionTool tool) {
    if (tool.getShortName().length() == 0) {
      showEmpty();
      return;
    }
    @NonNls StringBuffer page = new StringBuffer();
    page.append("<table border='0' cellspacing='0' cellpadding='0' width='100%'>");
    page.append("<tr><td colspan='2'>");
    HTMLComposer.appendHeading(
        page, InspectionsBundle.message("inspection.tool.in.browser.id.title"));
    page.append("</td></tr>");
    page.append("<tr><td width='37'></td>" + "<td>");
    page.append(tool.getShortName());
    page.append("</td></tr>");
    page.append("<tr height='10'></tr>");
    page.append("<tr><td colspan='2'>");
    HTMLComposer.appendHeading(
        page, InspectionsBundle.message("inspection.tool.in.browser.description.title"));
    page.append("</td></tr>");
    page.append("<tr><td width='37'></td>" + "<td>");
    @NonNls final String underConstruction = "<b>" + UNDER_CONSTRUCTION + "</b></html>";
    try {
      @NonNls String description = tool.loadDescription();
      if (description == null) {
        description = underConstruction;
      }
      page.append(UIUtil.getHtmlBody(description));

      page.append("</td></tr></table>");
      myHTMLViewer.setText(XmlStringUtil.wrapInHtml(page));
      setupStyle();
    } finally {
      myCurrentEntity = null;
    }
  }

  @Nullable
  private InspectionTool getTool() {
    if (myView != null) {
      return myView.getTree().getSelectedTool();
    }
    return null;
  }

  public void invokeLocalFix(int idx) {
    if (myView.getTree().getSelectionCount() != 1) return;
    final InspectionTreeNode node =
        (InspectionTreeNode) myView.getTree().getSelectionPath().getLastPathComponent();
    if (node instanceof ProblemDescriptionNode) {
      final ProblemDescriptionNode problemNode = (ProblemDescriptionNode) node;
      final CommonProblemDescriptor descriptor = problemNode.getDescriptor();
      final RefEntity element = problemNode.getElement();
      invokeFix(element, descriptor, idx);
    } else if (node instanceof RefElementNode) {
      RefElementNode elementNode = (RefElementNode) node;
      RefEntity element = elementNode.getElement();
      CommonProblemDescriptor descriptor = elementNode.getProblem();
      if (descriptor != null) {
        invokeFix(element, descriptor, idx);
      }
    }
  }

  private void invokeFix(
      final RefEntity element, final CommonProblemDescriptor descriptor, final int idx) {
    final QuickFix[] fixes = descriptor.getFixes();
    if (fixes != null && fixes.length > idx && fixes[idx] != null) {
      if (element instanceof RefElement) {
        PsiElement psiElement = ((RefElement) element).getElement();
        if (psiElement != null && psiElement.isValid()) {
          if (!FileModificationService.getInstance().preparePsiElementForWrite(psiElement)) return;
          performFix(element, descriptor, idx, fixes[idx]);
        }
      } else {
        performFix(element, descriptor, idx, fixes[idx]);
      }
    }
  }

  private void performFix(
      final RefEntity element,
      final CommonProblemDescriptor descriptor,
      final int idx,
      final QuickFix fix) {
    final Runnable command =
        new Runnable() {
          @Override
          public void run() {
            ApplicationManager.getApplication()
                .runWriteAction(
                    new Runnable() {
                      @Override
                      public void run() {
                        final PsiModificationTracker tracker =
                            PsiManager.getInstance(myView.getProject()).getModificationTracker();
                        final long startCount = tracker.getModificationCount();
                        CommandProcessor.getInstance()
                            .markCurrentCommandAsGlobal(myView.getProject());
                        // CCE here means QuickFix was incorrectly inherited
                        fix.applyFix(myView.getProject(), descriptor);
                        if (startCount != tracker.getModificationCount()) {
                          final DescriptorProviderInspection tool =
                              ((DescriptorProviderInspection) myView.getTree().getSelectedTool());
                          if (tool != null) {
                            tool.ignoreProblem(element, descriptor, idx);
                          }
                          myView.updateView(false);
                        }
                      }
                    });
          }
        };
    CommandProcessor.getInstance()
        .executeCommand(myView.getProject(), command, fix.getName(), null);
  }
}
Esempio n. 24
0
  public Browser(InspectionResultsView view) {
    super(new BorderLayout());
    myView = view;

    myCurrentEntity = null;
    myCurrentDescriptor = null;

    myHTMLViewer =
        new JEditorPane(
            UIUtil.HTML_MIME,
            InspectionsBundle.message("inspection.offline.view.empty.browser.text"));
    myHTMLViewer.setEditable(false);
    myHyperLinkListener =
        new HyperlinkListener() {
          @Override
          public void hyperlinkUpdate(HyperlinkEvent e) {
            if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
              JEditorPane pane = (JEditorPane) e.getSource();
              if (e instanceof HTMLFrameHyperlinkEvent) {
                HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e;
                HTMLDocument doc = (HTMLDocument) pane.getDocument();
                doc.processHTMLFrameHyperlinkEvent(evt);
              } else {
                try {
                  URL url = e.getURL();
                  @NonNls String ref = url.getRef();
                  if (ref.startsWith("pos:")) {
                    int delimeterPos = ref.indexOf(':', "pos:".length() + 1);
                    String startPosition = ref.substring("pos:".length(), delimeterPos);
                    String endPosition = ref.substring(delimeterPos + 1);
                    Integer textStartOffset = new Integer(startPosition);
                    Integer textEndOffset = new Integer(endPosition);
                    String fileURL = url.toExternalForm();
                    fileURL = fileURL.substring(0, fileURL.indexOf('#'));
                    VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
                    if (vFile != null) {
                      fireClickEvent(vFile, textStartOffset.intValue(), textEndOffset.intValue());
                    }
                  } else if (ref.startsWith("descr:")) {
                    if (myCurrentDescriptor instanceof ProblemDescriptor) {
                      PsiElement psiElement =
                          ((ProblemDescriptor) myCurrentDescriptor).getPsiElement();
                      if (psiElement == null) return;
                      VirtualFile vFile = psiElement.getContainingFile().getVirtualFile();
                      if (vFile != null) {
                        TextRange range =
                            ((ProblemDescriptorBase) myCurrentDescriptor).getTextRange();
                        fireClickEvent(vFile, range.getStartOffset(), range.getEndOffset());
                      }
                    }
                  } else if (ref.startsWith("invoke:")) {
                    int actionNumber = Integer.parseInt(ref.substring("invoke:".length()));
                    getTool()
                        .getQuickFixes(new RefElement[] {(RefElement) myCurrentEntity})[
                        actionNumber]
                        .doApplyFix(new RefElement[] {(RefElement) myCurrentEntity}, myView);
                  } else if (ref.startsWith("invokelocal:")) {
                    int actionNumber = Integer.parseInt(ref.substring("invokelocal:".length()));
                    if (actionNumber > -1) {
                      invokeLocalFix(actionNumber);
                    }
                  } else if (ref.startsWith("suppress:")) {
                    final SuppressActionWrapper.SuppressTreeAction[] suppressTreeActions =
                        new SuppressActionWrapper(
                                myView.getProject(),
                                getTool(),
                                myView.getTree().getSelectionPaths())
                            .getChildren(null);
                    final List<AnAction> activeActions = new ArrayList<AnAction>();
                    for (SuppressActionWrapper.SuppressTreeAction suppressTreeAction :
                        suppressTreeActions) {
                      if (suppressTreeAction.isAvailable()) activeActions.add(suppressTreeAction);
                    }
                    if (!activeActions.isEmpty()) {
                      int actionNumber = Integer.parseInt(ref.substring("suppress:".length()));
                      if (actionNumber > -1 && activeActions.size() > actionNumber) {
                        activeActions.get(actionNumber).actionPerformed(null);
                      }
                    }
                  } else {
                    int offset = Integer.parseInt(ref);
                    String fileURL = url.toExternalForm();
                    fileURL = fileURL.substring(0, fileURL.indexOf('#'));
                    VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
                    if (vFile == null) {
                      vFile = VfsUtil.findFileByURL(url);
                    }
                    if (vFile != null) {
                      fireClickEvent(vFile, offset, offset);
                    }
                  }
                } catch (Throwable t) {
                  // ???
                }
              }
            }
          }
        };
    myHTMLViewer.addHyperlinkListener(myHyperLinkListener);

    final JScrollPane pane = ScrollPaneFactory.createScrollPane(myHTMLViewer);
    pane.setBorder(null);
    add(pane, BorderLayout.CENTER);
    setupStyle();
  }
 @Override
 @NotNull
 public String getDisplayName() {
   return InspectionsBundle.message("inspection.data.flow.display.name");
 }
 @Override
 @NotNull
 public String getDisplayName() {
   return InspectionsBundle.message("inspection.duplicate.throws.display.name");
 }
 @NotNull
 public String getDisplayName() {
   return InspectionsBundle.message("inspection.javadoc.ref.display.name");
 }
/** @author max Date: Dec 24, 2001 */
public class RedundantCastInspection extends GenericsInspectionToolBase {
  private static final Logger LOG =
      Logger.getInstance("#com.intellij.codeInspection.redundantCast.RedundantCastInspection");
  private final LocalQuickFix myQuickFixAction;
  private static final String DISPLAY_NAME =
      InspectionsBundle.message("inspection.redundant.cast.display.name");
  @NonNls private static final String SHORT_NAME = "RedundantCast";

  public boolean IGNORE_ANNOTATED_METHODS = false;
  public boolean IGNORE_SUSPICIOUS_METHOD_CALLS = false;

  public RedundantCastInspection() {
    myQuickFixAction = new AcceptSuggested();
  }

  @Override
  @Nullable
  public ProblemDescriptor[] getDescriptions(
      PsiElement where, InspectionManager manager, boolean isOnTheFly) {
    List<PsiTypeCastExpression> redundantCasts = RedundantCastUtil.getRedundantCastsInside(where);
    if (redundantCasts.isEmpty()) return null;
    List<ProblemDescriptor> descriptions = new ArrayList<ProblemDescriptor>(redundantCasts.size());
    for (PsiTypeCastExpression redundantCast : redundantCasts) {
      ProblemDescriptor descriptor = createDescription(redundantCast, manager, isOnTheFly);
      if (descriptor != null) {
        descriptions.add(descriptor);
      }
    }
    if (descriptions.isEmpty()) return null;
    return descriptions.toArray(new ProblemDescriptor[descriptions.size()]);
  }

  @Override
  public void writeSettings(@NotNull Element node) throws WriteExternalException {
    if (IGNORE_ANNOTATED_METHODS || IGNORE_SUSPICIOUS_METHOD_CALLS) {
      super.writeSettings(node);
    }
  }

  @Override
  public JComponent createOptionsPanel() {
    final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this);
    optionsPanel.addCheckbox(
        "Ignore casts in suspicious collections method calls", "IGNORE_SUSPICIOUS_METHOD_CALLS");
    optionsPanel.addCheckbox(
        "Ignore casts to invoke @NotNull method which overrides @Nullable",
        "IGNORE_ANNOTATED_METHODS");
    return optionsPanel;
  }

  @Nullable
  private ProblemDescriptor createDescription(
      @NotNull PsiTypeCastExpression cast, @NotNull InspectionManager manager, boolean onTheFly) {
    PsiExpression operand = cast.getOperand();
    PsiTypeElement castType = cast.getCastType();
    if (operand == null || castType == null) return null;
    PsiElement parent = cast.getParent();
    while (parent instanceof PsiParenthesizedExpression) {
      parent = parent.getParent();
    }
    if (parent instanceof PsiReferenceExpression) {
      if (IGNORE_ANNOTATED_METHODS) {
        final PsiElement gParent = parent.getParent();
        if (gParent instanceof PsiMethodCallExpression) {
          final PsiMethod psiMethod = ((PsiMethodCallExpression) gParent).resolveMethod();
          if (psiMethod != null && NullableNotNullManager.isNotNull(psiMethod)) {
            final PsiClass superClass = PsiUtil.resolveClassInType(operand.getType());
            final PsiClass containingClass = psiMethod.getContainingClass();
            if (containingClass != null
                && superClass != null
                && containingClass.isInheritor(superClass, true)) {
              for (PsiMethod method : psiMethod.findSuperMethods(superClass)) {
                if (NullableNotNullManager.isNullable(method)) {
                  return null;
                }
              }
            }
          }
        }
      }
    } else if (parent instanceof PsiExpressionList) {
      final PsiElement gParent = parent.getParent();
      if (gParent instanceof PsiMethodCallExpression && IGNORE_SUSPICIOUS_METHOD_CALLS) {
        final String message =
            SuspiciousCollectionsMethodCallsInspection.getSuspiciousMethodCallMessage(
                (PsiMethodCallExpression) gParent,
                operand.getType(),
                true,
                new ArrayList<PsiMethod>(),
                new IntArrayList());
        if (message != null) {
          return null;
        }
      }
    }

    String message =
        InspectionsBundle.message(
            "inspection.redundant.cast.problem.descriptor",
            "<code>" + operand.getText() + "</code>",
            "<code>#ref</code> #loc");
    return manager.createProblemDescriptor(
        castType, message, myQuickFixAction, ProblemHighlightType.LIKE_UNUSED_SYMBOL, onTheFly);
  }

  private static class AcceptSuggested implements LocalQuickFix {
    @Override
    @NotNull
    public String getName() {
      return InspectionsBundle.message("inspection.redundant.cast.remove.quickfix");
    }

    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      if (!FileModificationService.getInstance()
          .preparePsiElementForWrite(descriptor.getPsiElement())) return;
      PsiElement castTypeElement = descriptor.getPsiElement();
      PsiTypeCastExpression cast =
          castTypeElement == null ? null : (PsiTypeCastExpression) castTypeElement.getParent();
      if (cast != null) {
        RedundantCastUtil.removeCast(cast);
      }
    }

    @Override
    @NotNull
    public String getFamilyName() {
      return getName();
    }
  }

  @Override
  @NotNull
  public String getDisplayName() {
    return DISPLAY_NAME;
  }

  @Override
  @NotNull
  public String getGroupDisplayName() {
    return GroupNames.VERBOSE_GROUP_NAME;
  }

  @Override
  @NotNull
  public String getShortName() {
    return SHORT_NAME;
  }
}
 @NotNull
 public String getGroupDisplayName() {
   return InspectionsBundle.message("group.names.javadoc.issues");
 }
 @Override
 @NotNull
 public String getName() {
   return InspectionsBundle.message("inspection.data.flow.redundant.instanceof.quickfix");
 }