private PsiCodeBlock getCodeBlock() throws IncorrectOperationException {
   if (codeBlock == null) {
     codeBlock =
         (PsiCodeBlock)
             MatcherImplUtil
                 .createTreeFromText(
                     myContext.getOptions().getMatchOptions().getSearchPattern(),
                     PatternTreeContext.Block,
                     myContext.getOptions().getMatchOptions().getFileType(),
                     myContext.getProject())[0]
                 .getParent();
   }
   return codeBlock;
 }
  public void replace(final ReplacementInfo info, ReplaceOptions options) {
    PsiElement elementToReplace = info.getMatch(0);
    PsiElement elementParent = elementToReplace.getParent();
    String replacementToMake = info.getReplacement();
    Project project = myContext.getProject();
    PsiElement el = findRealSubstitutionElement(elementToReplace);
    boolean listContext = isListContext(el);

    if (el instanceof PsiAnnotation && !StringUtil.startsWithChar(replacementToMake, '@')) {
      replacementToMake = "@" + replacementToMake;
    }

    PsiElement[] statements =
        ReplacerUtil.createTreeForReplacement(
            replacementToMake,
            el instanceof PsiMember && !isSymbolReplacement(el)
                ? PatternTreeContext.Class
                : PatternTreeContext.Block,
            myContext);

    if (listContext) {
      if (statements.length > 1) {
        elementParent.addRangeBefore(
            statements[0], statements[statements.length - 1], elementToReplace);
      } else if (statements.length == 1) {
        PsiElement replacement = getMatchExpr(statements[0], elementToReplace);

        handleModifierList(el, replacement);
        replacement = handleSymbolReplacement(replacement, el);

        if (replacement instanceof PsiTryStatement) {
          final List<PsiCatchSection> unmatchedCatchSections =
              el.getUserData(JavaMatchingVisitor.UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY);
          final PsiCatchSection[] catches = ((PsiTryStatement) replacement).getCatchSections();

          if (unmatchedCatchSections != null) {
            for (int i = unmatchedCatchSections.size() - 1; i >= 0; --i) {
              final PsiParameter parameter = unmatchedCatchSections.get(i).getParameter();
              final PsiElementFactory elementFactory =
                  JavaPsiFacade.getInstance(project).getElementFactory();
              final PsiCatchSection catchSection =
                  elementFactory.createCatchSection(parameter.getType(), parameter.getName(), null);

              catchSection.getCatchBlock().replace(unmatchedCatchSections.get(i).getCatchBlock());
              replacement.addAfter(catchSection, catches[catches.length - 1]);
              replacement.addBefore(createWhiteSpace(replacement), replacement.getLastChild());
            }
          }
        }

        try {
          final PsiElement inserted = elementParent.addBefore(replacement, elementToReplace);

          if (replacement instanceof PsiComment
              && (elementParent instanceof PsiIfStatement
                  || elementParent instanceof PsiLoopStatement)) {
            elementParent.addAfter(createSemicolon(replacement), inserted);
          }
        } catch (IncorrectOperationException e) {
          elementToReplace.replace(replacement);
        }
      }
    } else if (statements.length > 0) {
      PsiElement replacement =
          ReplacerUtil.copySpacesAndCommentsBefore(
              elementToReplace, statements, replacementToMake, elementParent);

      replacement = getMatchExpr(replacement, elementToReplace);

      if (replacement instanceof PsiStatement
          && !(replacement.getLastChild() instanceof PsiJavaToken)
          && !(replacement.getLastChild() instanceof PsiComment)) {
        // assert w/o ;
        final PsiElement prevLastChildInParent = replacement.getLastChild().getPrevSibling();

        if (prevLastChildInParent != null) {
          elementParent.addRangeBefore(replacement.getFirstChild(), prevLastChildInParent, el);
        } else {
          elementParent.addBefore(replacement.getFirstChild(), el);
        }

        el.getNode().getTreeParent().removeChild(el.getNode());
      } else {
        // preserve comments
        handleModifierList(el, replacement);

        if (replacement instanceof PsiClass) {
          // modifier list
          final PsiStatement[] searchStatements = getCodeBlock().getStatements();
          if (searchStatements.length > 0
              && searchStatements[0] instanceof PsiDeclarationStatement
              && ((PsiDeclarationStatement) searchStatements[0]).getDeclaredElements()[0]
                  instanceof PsiClass) {
            final PsiClass replaceClazz = (PsiClass) replacement;
            final PsiClass queryClazz =
                (PsiClass) ((PsiDeclarationStatement) searchStatements[0]).getDeclaredElements()[0];
            final PsiClass clazz = (PsiClass) el;

            if (replaceClazz.getExtendsList().getTextLength() == 0
                && queryClazz.getExtendsList().getTextLength() == 0
                && clazz.getExtendsList().getTextLength() != 0) {
              replaceClazz.addBefore(
                  clazz.getExtendsList().getPrevSibling(),
                  replaceClazz.getExtendsList()); // whitespace
              replaceClazz
                  .getExtendsList()
                  .addRange(
                      clazz.getExtendsList().getFirstChild(),
                      clazz.getExtendsList().getLastChild());
            }

            if (replaceClazz.getImplementsList().getTextLength() == 0
                && queryClazz.getImplementsList().getTextLength() == 0
                && clazz.getImplementsList().getTextLength() != 0) {
              replaceClazz.addBefore(
                  clazz.getImplementsList().getPrevSibling(),
                  replaceClazz.getImplementsList()); // whitespace
              replaceClazz
                  .getImplementsList()
                  .addRange(
                      clazz.getImplementsList().getFirstChild(),
                      clazz.getImplementsList().getLastChild());
            }

            if (replaceClazz.getTypeParameterList().getTextLength() == 0
                && queryClazz.getTypeParameterList().getTextLength() == 0
                && clazz.getTypeParameterList().getTextLength() != 0) {
              // skip < and >
              replaceClazz.getTypeParameterList().replace(clazz.getTypeParameterList());
            }
          }
        }

        replacement = handleSymbolReplacement(replacement, el);

        el.replace(replacement);
      }
    } else {
      final PsiElement nextSibling = el.getNextSibling();
      el.delete();
      if (nextSibling instanceof PsiWhiteSpace && nextSibling.isValid()) {
        nextSibling.delete();
      }
    }

    if (listContext) {
      final int matchSize = info.getMatchesCount();

      for (int i = 0; i < matchSize; ++i) {
        PsiElement matchElement = info.getMatch(i);
        PsiElement element = findRealSubstitutionElement(matchElement);

        if (element == null) continue;
        PsiElement firstToDelete = element;
        PsiElement lastToDelete = element;
        PsiElement prevSibling = element.getPrevSibling();
        PsiElement nextSibling = element.getNextSibling();

        if (prevSibling instanceof PsiWhiteSpace) {
          firstToDelete = prevSibling;
          prevSibling = prevSibling != null ? prevSibling.getPrevSibling() : null;
        } else if (prevSibling == null && nextSibling instanceof PsiWhiteSpace) {
          lastToDelete = nextSibling;
        }

        if (nextSibling instanceof XmlText && i + 1 < matchSize) {
          final PsiElement next = info.getMatch(i + 1);
          if (next != null && next == nextSibling.getNextSibling()) {
            lastToDelete = nextSibling;
          }
        }

        if (element instanceof PsiExpression) {
          final PsiElement parent = element.getParent().getParent();
          if ((parent instanceof PsiCall || parent instanceof PsiAnonymousClass)
              && prevSibling instanceof PsiJavaToken
              && ((PsiJavaToken) prevSibling).getTokenType() == JavaTokenType.COMMA) {
            firstToDelete = prevSibling;
          }
        } else if (element instanceof PsiParameter
            && prevSibling instanceof PsiJavaToken
            && ((PsiJavaToken) prevSibling).getTokenType() == JavaTokenType.COMMA) {
          firstToDelete = prevSibling;
        }

        element.getParent().deleteChildRange(firstToDelete, lastToDelete);
      }
    }
  }
Пример #3
0
 @Override
 public StructuralReplaceHandler getReplaceHandler(@NotNull ReplacementContext context) {
   return new DocumentBasedReplaceHandler(context.getProject());
 }