public static void doRename(
      final PsiElement element,
      String newName,
      UsageInfo[] usages,
      final Project project,
      @Nullable final RefactoringElementListener listener)
      throws IncorrectOperationException {
    final RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(element);
    final String fqn =
        element instanceof PsiFile
            ? ((PsiFile) element).getVirtualFile().getPath()
            : CopyReferenceAction.elementToFqn(element);
    if (fqn != null) {
      UndoableAction action =
          new BasicUndoableAction() {
            public void undo() throws UnexpectedUndoException {
              if (listener instanceof UndoRefactoringElementListener) {
                ((UndoRefactoringElementListener) listener).undoElementMovedOrRenamed(element, fqn);
              }
            }

            @Override
            public void redo() throws UnexpectedUndoException {}
          };
      UndoManager.getInstance(project).undoableActionPerformed(action);
    }
    processor.renameElement(element, newName, usages, listener);
  }
Пример #2
0
 public void prepareRenaming(
     @NotNull final PsiElement element,
     final String newName,
     final LinkedHashMap<PsiElement, String> allRenames) {
   final List<RenamePsiElementProcessor> processors =
       RenamePsiElementProcessor.allForElement(element);
   myForceShowPreview = false;
   for (RenamePsiElementProcessor processor : processors) {
     if (processor.canProcessElement(element)) {
       processor.prepareRenaming(element, newName, allRenames);
       myForceShowPreview |= processor.forcesShowPreview();
     }
   }
 }
  private static String getStringToReplace(
      PsiElement element,
      String newName,
      boolean nonJava,
      final RenamePsiElementProcessor theProcessor) {
    if (element instanceof PsiMetaOwner) {
      final PsiMetaOwner psiMetaOwner = (PsiMetaOwner) element;
      final PsiMetaData metaData = psiMetaOwner.getMetaData();
      if (metaData != null) {
        return metaData.getName();
      }
    }

    if (theProcessor != null) {
      String result = theProcessor.getQualifiedNameAfterRename(element, newName, nonJava);
      if (result != null) {
        return result;
      }
    }

    if (element instanceof PsiNamedElement) {
      return newName;
    } else {
      LOG.error("Unknown element type");
      return null;
    }
  }
Пример #4
0
  public void performRefactoring(UsageInfo[] usages) {
    final int[] choice = myAllRenames.size() > 1 ? new int[] {-1} : null;
    String message = null;
    try {
      for (Iterator<Map.Entry<PsiElement, String>> iterator = myAllRenames.entrySet().iterator();
          iterator.hasNext(); ) {
        Map.Entry<PsiElement, String> entry = iterator.next();
        if (entry.getKey() instanceof PsiFile) {
          final PsiFile file = (PsiFile) entry.getKey();
          final PsiDirectory containingDirectory = file.getContainingDirectory();
          if (CopyFilesOrDirectoriesHandler.checkFileExist(
              containingDirectory, choice, file, entry.getValue(), "Rename")) {
            iterator.remove();
            continue;
          }
        }
        RenameUtil.checkRename(entry.getKey(), entry.getValue());
      }
    } catch (IncorrectOperationException e) {
      message = e.getMessage();
    }

    if (message != null) {
      CommonRefactoringUtil.showErrorMessage(
          RefactoringBundle.message("rename.title"), message, getHelpID(), myProject);
      return;
    }

    List<Runnable> postRenameCallbacks = new ArrayList<Runnable>();

    final MultiMap<PsiElement, UsageInfo> classified =
        classifyUsages(myAllRenames.keySet(), usages);
    for (final PsiElement element : myAllRenames.keySet()) {
      String newName = myAllRenames.get(element);

      final RefactoringElementListener elementListener =
          getTransaction().getElementListener(element);
      final RenamePsiElementProcessor renamePsiElementProcessor =
          RenamePsiElementProcessor.forElement(element);
      Runnable postRenameCallback =
          renamePsiElementProcessor.getPostRenameCallback(element, newName, elementListener);
      final Collection<UsageInfo> infos = classified.get(element);
      try {
        RenameUtil.doRename(
            element,
            newName,
            infos.toArray(new UsageInfo[infos.size()]),
            myProject,
            elementListener);
      } catch (final IncorrectOperationException e) {
        RenameUtil.showErrorMessage(e, element, myProject);
        return;
      }
      if (postRenameCallback != null) {
        postRenameCallbacks.add(postRenameCallback);
      }
    }

    for (Runnable runnable : postRenameCallbacks) {
      runnable.run();
    }

    List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<NonCodeUsageInfo>();
    for (UsageInfo usage : usages) {
      if (usage instanceof NonCodeUsageInfo) {
        nonCodeUsages.add((NonCodeUsageInfo) usage);
      }
    }
    myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
    if (!mySkippedUsages.isEmpty()) {
      if (!ApplicationManager.getApplication().isUnitTestMode()
          && !ApplicationManager.getApplication().isHeadlessEnvironment()) {
        ApplicationManager.getApplication()
            .invokeLater(
                new Runnable() {
                  public void run() {
                    final IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(myProject);
                    if (ideFrame != null) {

                      StatusBarEx statusBar = (StatusBarEx) ideFrame.getStatusBar();
                      HyperlinkListener listener =
                          new HyperlinkListener() {
                            public void hyperlinkUpdate(HyperlinkEvent e) {
                              if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) return;
                              Messages.showMessageDialog(
                                  "<html>"
                                      + StringUtil.join(
                                          mySkippedUsages,
                                          new Function<UnresolvableCollisionUsageInfo, String>() {
                                            public String fun(
                                                UnresolvableCollisionUsageInfo
                                                    unresolvableCollisionUsageInfo) {
                                              return unresolvableCollisionUsageInfo
                                                  .getDescription();
                                            }
                                          },
                                          "<br>")
                                      + "</html>",
                                  "Don't panic! They are safe to skip",
                                  null);
                            }
                          };
                      statusBar.notifyProgressByBalloon(
                          MessageType.WARNING,
                          "<html><body>Unable to rename certain usages. <a href=\"\">Browse</a></body></html>",
                          null,
                          listener);
                    }
                  }
                },
                ModalityState.NON_MODAL);
      }
    }
  }
Пример #5
0
  public boolean preprocessUsages(final Ref<UsageInfo[]> refUsages) {
    UsageInfo[] usagesIn = refUsages.get();
    MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();

    RenameUtil.addConflictDescriptions(usagesIn, conflicts);
    RenamePsiElementProcessor.forElement(myPrimaryElement)
        .findExistingNameConflicts(myPrimaryElement, myNewName, conflicts);
    if (!conflicts.isEmpty()) {
      if (ApplicationManager.getApplication().isUnitTestMode()) {
        throw new ConflictsInTestsException(conflicts.values());
      }
      ConflictsDialog conflictsDialog = prepareConflictsDialog(conflicts, refUsages.get());
      conflictsDialog.show();
      if (!conflictsDialog.isOK()) {
        if (conflictsDialog.isShowConflicts()) prepareSuccessful();
        return false;
      }
    }

    final List<UsageInfo> variableUsages = new ArrayList<UsageInfo>();
    if (!myRenamers.isEmpty()) {
      if (!findRenamedVariables(variableUsages)) return false;
      final LinkedHashMap<PsiElement, String> renames = new LinkedHashMap<PsiElement, String>();
      for (final AutomaticRenamer renamer : myRenamers) {
        final List<? extends PsiNamedElement> variables = renamer.getElements();
        for (final PsiNamedElement variable : variables) {
          final String newName = renamer.getNewName(variable);
          if (newName != null) {
            addElement(variable, newName);
            prepareRenaming(variable, newName, renames);
          }
        }
      }
      if (!renames.isEmpty()) {
        myAllRenames.putAll(renames);
        final Runnable runnable =
            new Runnable() {
              public void run() {
                for (Map.Entry<PsiElement, String> entry : renames.entrySet()) {
                  final UsageInfo[] usages =
                      RenameUtil.findUsages(
                          entry.getKey(),
                          entry.getValue(),
                          mySearchInComments,
                          mySearchTextOccurrences,
                          myAllRenames);
                  Collections.addAll(variableUsages, usages);
                }
              }
            };
        if (!ProgressManager.getInstance()
            .runProcessWithProgressSynchronously(
                runnable, RefactoringBundle.message("searching.for.variables"), true, myProject)) {
          return false;
        }
      }
    }

    final Set<UsageInfo> usagesSet = new HashSet<UsageInfo>(Arrays.asList(usagesIn));
    usagesSet.addAll(variableUsages);
    final List<UnresolvableCollisionUsageInfo> conflictUsages =
        RenameUtil.removeConflictUsages(usagesSet);
    if (conflictUsages != null) {
      mySkippedUsages.addAll(conflictUsages);
    }
    refUsages.set(usagesSet.toArray(new UsageInfo[usagesSet.size()]));

    prepareSuccessful();
    return true;
  }
Пример #6
0
 @Nullable
 private String getHelpID() {
   return RenamePsiElementProcessor.forElement(myPrimaryElement).getHelpID(myPrimaryElement);
 }
  @NotNull
  public static UsageInfo[] findUsages(
      final PsiElement element,
      final String newName,
      boolean searchInStringsAndComments,
      boolean searchForTextOccurrences,
      Map<? extends PsiElement, String> allRenames) {
    final List<UsageInfo> result = Collections.synchronizedList(new ArrayList<UsageInfo>());

    PsiManager manager = element.getManager();
    GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject());
    RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(element);

    Collection<PsiReference> refs = processor.findReferences(element, searchInStringsAndComments);
    for (final PsiReference ref : refs) {
      if (ref == null) {
        LOG.error("null reference from processor " + processor);
        continue;
      }
      PsiElement referenceElement = ref.getElement();
      result.add(
          new MoveRenameUsageInfo(
              referenceElement,
              ref,
              ref.getRangeInElement().getStartOffset(),
              ref.getRangeInElement().getEndOffset(),
              element,
              ref.resolve() == null));
    }

    processor.findCollisions(element, newName, allRenames, result);

    final PsiElement searchForInComments =
        processor.getElementToSearchInStringsAndComments(element);

    if (searchInStringsAndComments && searchForInComments != null) {
      String stringToSearch =
          ElementDescriptionUtil.getElementDescription(
              searchForInComments, NonCodeSearchDescriptionLocation.STRINGS_AND_COMMENTS);
      if (stringToSearch.length() > 0) {
        final String stringToReplace = getStringToReplace(element, newName, false, processor);
        TextOccurrencesUtil.UsageInfoFactory factory =
            new NonCodeUsageInfoFactory(searchForInComments, stringToReplace);
        TextOccurrencesUtil.addUsagesInStringsAndComments(
            searchForInComments, stringToSearch, result, factory);
      }
    }

    if (searchForTextOccurrences && searchForInComments != null) {
      String stringToSearch =
          ElementDescriptionUtil.getElementDescription(
              searchForInComments, NonCodeSearchDescriptionLocation.NON_JAVA);
      if (stringToSearch.length() > 0) {
        final String stringToReplace = getStringToReplace(element, newName, true, processor);
        addTextOccurrence(
            searchForInComments, result, projectScope, stringToSearch, stringToReplace);
      }

      final Pair<String, String> additionalStringToSearch =
          processor.getTextOccurrenceSearchStrings(searchForInComments, newName);
      if (additionalStringToSearch != null && additionalStringToSearch.first.length() > 0) {
        addTextOccurrence(
            searchForInComments,
            result,
            projectScope,
            additionalStringToSearch.first,
            additionalStringToSearch.second);
      }
    }

    return result.toArray(new UsageInfo[result.size()]);
  }