Esempio n. 1
0
  public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
    PsiElement element = descriptor.getPsiElement();
    PsiStatement anchorStatement = PsiTreeUtil.getParentOfType(element, PsiStatement.class);
    LOG.assertTrue(anchorStatement != null);
    Editor editor = getEditor(project, element);
    if (editor == null) return;
    PsiFile file = element.getContainingFile();
    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    Document document = documentManager.getDocument(file);
    if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
    PsiElement[] elements = {anchorStatement};
    PsiElement prev = PsiTreeUtil.skipSiblingsBackward(anchorStatement, PsiWhiteSpace.class);
    if (prev instanceof PsiComment
        && SuppressManager.getInstance().getSuppressedInspectionIdsIn(prev) != null) {
      elements = new PsiElement[] {prev, anchorStatement};
    }
    try {
      TextRange textRange = new JavaWithIfSurrounder().surroundElements(project, editor, elements);
      if (textRange == null) return;

      @NonNls String newText = myText + " != null";
      document.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), newText);
      editor.getCaretModel().moveToOffset(textRange.getEndOffset() + newText.length());
      editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);

    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  public CommonProblemDescriptor[] checkElement(
      @NotNull final PsiElement psiElement, InspectionManager manager, Project project) {
    final Map<PsiElement, Collection<String>> suppressedScopes =
        new THashMap<PsiElement, Collection<String>>();
    psiElement.accept(
        new JavaRecursiveElementWalkingVisitor() {
          @Override
          public void visitModifierList(PsiModifierList list) {
            super.visitModifierList(list);
            final PsiElement parent = list.getParent();
            if (parent instanceof PsiModifierListOwner && !(parent instanceof PsiClass)) {
              checkElement(parent);
            }
          }

          @Override
          public void visitComment(PsiComment comment) {
            checkElement(comment);
          }

          @Override
          public void visitClass(PsiClass aClass) {
            if (aClass == psiElement) {
              super.visitClass(aClass);
              checkElement(aClass);
            }
          }

          private void checkElement(final PsiElement owner) {
            String idsString = SuppressManager.getInstance().getSuppressedInspectionIdsIn(owner);
            if (idsString != null && idsString.length() != 0) {
              List<String> ids = StringUtil.split(idsString, ",");
              if (IGNORE_ALL
                  && (ids.contains(SuppressionUtil.ALL)
                      || ids.contains(SuppressionUtil.ALL.toLowerCase()))) return;
              Collection<String> suppressed = suppressedScopes.get(owner);
              if (suppressed == null) {
                suppressed = ids;
              } else {
                for (String id : ids) {
                  if (!suppressed.contains(id)) {
                    suppressed.add(id);
                  }
                }
              }
              suppressedScopes.put(owner, suppressed);
            }
          }
        });

    if (suppressedScopes.values().isEmpty()) return null;
    // have to visit all file from scratch since inspections can be written in any perversive way
    // including checkFile() overriding
    Collection<InspectionTool> suppressedTools = new THashSet<InspectionTool>();
    InspectionTool[] tools = getInspectionTools(psiElement, manager);
    for (Collection<String> ids : suppressedScopes.values()) {
      for (Iterator<String> iterator = ids.iterator(); iterator.hasNext(); ) {
        final String shortName = iterator.next().trim();
        for (InspectionTool tool : tools) {
          if (tool instanceof LocalInspectionToolWrapper
              && ((LocalInspectionToolWrapper) tool).getTool().getID().equals(shortName)) {
            if (!((LocalInspectionToolWrapper) tool).isUnfair()) {
              suppressedTools.add(tool);
            } else {
              iterator.remove();
              break;
            }
          } else if (tool.getShortName().equals(shortName)) {
            // ignore global unused as it won't be checked anyway
            if (!(tool instanceof LocalInspectionToolWrapper)
                && !(tool instanceof GlobalInspectionToolWrapper)) {
              iterator.remove();
              break;
            } else {
              suppressedTools.add(tool);
            }
          }
        }
      }
    }

    final AnalysisScope scope = new AnalysisScope(psiElement.getContainingFile());
    final InspectionManagerEx inspectionManagerEx =
        ((InspectionManagerEx) InspectionManager.getInstance(project));
    GlobalInspectionContextImpl globalContext = inspectionManagerEx.createNewGlobalContext(false);
    globalContext.setCurrentScope(scope);
    final RefManagerImpl refManager = ((RefManagerImpl) globalContext.getRefManager());
    refManager.inspectionReadActionStarted();
    final List<ProblemDescriptor> result;
    try {
      result = new ArrayList<ProblemDescriptor>();
      for (InspectionTool tool : suppressedTools) {
        String toolId =
            tool instanceof LocalInspectionToolWrapper
                ? ((LocalInspectionToolWrapper) tool).getTool().getID()
                : tool.getShortName();
        tool.initialize(globalContext);
        Collection<CommonProblemDescriptor> descriptors;
        if (tool instanceof LocalInspectionToolWrapper) {
          LocalInspectionToolWrapper local = (LocalInspectionToolWrapper) tool;
          if (local.isUnfair()) continue; // cant't work with passes other than LocalInspectionPass
          local.processFile(psiElement.getContainingFile(), false, manager);
          descriptors = local.getProblemDescriptors();
        } else if (tool instanceof GlobalInspectionToolWrapper) {
          GlobalInspectionToolWrapper global = (GlobalInspectionToolWrapper) tool;
          if (global.getTool().isGraphNeeded()) {
            refManager.findAllDeclarations();
          }
          global.processFile(scope, manager, globalContext, false);
          descriptors = global.getProblemDescriptors();
        } else {
          continue;
        }
        for (PsiElement suppressedScope : suppressedScopes.keySet()) {
          Collection<String> suppressedIds = suppressedScopes.get(suppressedScope);
          if (!suppressedIds.contains(toolId)) continue;
          for (CommonProblemDescriptor descriptor : descriptors) {
            if (!(descriptor instanceof ProblemDescriptor)) continue;
            PsiElement element = ((ProblemDescriptor) descriptor).getPsiElement();
            if (element == null) continue;
            PsiElement annotation =
                SuppressManager.getInstance().getElementToolSuppressedIn(element, toolId);
            if (annotation != null && PsiTreeUtil.isAncestor(suppressedScope, annotation, false)
                || annotation == null && !PsiTreeUtil.isAncestor(suppressedScope, element, false)) {
              suppressedIds.remove(toolId);
              break;
            }
          }
        }
      }
      for (PsiElement suppressedScope : suppressedScopes.keySet()) {
        Collection<String> suppressedIds = suppressedScopes.get(suppressedScope);
        for (String toolId : suppressedIds) {
          PsiMember psiMember;
          String problemLine = null;
          if (suppressedScope instanceof PsiMember) {
            psiMember = (PsiMember) suppressedScope;
          } else {
            psiMember = PsiTreeUtil.getParentOfType(suppressedScope, PsiDocCommentOwner.class);
            final PsiStatement statement =
                PsiTreeUtil.getNextSiblingOfType(suppressedScope, PsiStatement.class);
            problemLine = statement != null ? statement.getText() : null;
          }
          if (psiMember != null && psiMember.isValid()) {
            String description =
                InspectionsBundle.message("inspection.redundant.suppression.description");
            if (myQuickFixes == null) myQuickFixes = new BidirectionalMap<String, QuickFix>();
            final String key = toolId + (problemLine != null ? ";" + problemLine : "");
            QuickFix fix = myQuickFixes.get(key);
            if (fix == null) {
              fix = new RemoveSuppressWarningAction(toolId, problemLine);
              myQuickFixes.put(key, fix);
            }
            PsiElement identifier = null;
            if (psiMember instanceof PsiMethod) {
              identifier = ((PsiMethod) psiMember).getNameIdentifier();
            } else if (psiMember instanceof PsiField) {
              identifier = ((PsiField) psiMember).getNameIdentifier();
            } else if (psiMember instanceof PsiClass) {
              identifier = ((PsiClass) psiMember).getNameIdentifier();
            }
            if (identifier == null) {
              identifier = psiMember;
            }
            result.add(
                manager.createProblemDescriptor(
                    identifier,
                    description,
                    (LocalQuickFix) fix,
                    ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
                    false));
          }
        }
      }
    } finally {
      refManager.inspectionReadActionFinished();
      globalContext.close(true);
    }
    return result.toArray(new ProblemDescriptor[result.size()]);
  }