@NotNull public UsageInfo[] findUsages() { myRenamers.clear(); ArrayList<UsageInfo> result = new ArrayList<UsageInfo>(); List<PsiElement> elements = new ArrayList<PsiElement>(myAllRenames.keySet()); //noinspection ForLoopReplaceableByForEach for (int i = 0; i < elements.size(); i++) { PsiElement element = elements.get(i); final String newName = myAllRenames.get(element); final UsageInfo[] usages = RenameUtil.findUsages( element, newName, mySearchInComments, mySearchTextOccurrences, myAllRenames); final List<UsageInfo> usagesList = Arrays.asList(usages); result.addAll(usagesList); for (AutomaticRenamerFactory factory : myRenamerFactories) { if (factory.isApplicable(element)) { myRenamers.add(factory.createRenamer(element, newName, usagesList)); } } for (AutomaticRenamerFactory factory : Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME)) { if (factory.getOptionName() == null && factory.isApplicable(element)) { myRenamers.add(factory.createRenamer(element, newName, usagesList)); } } } UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); usageInfos = UsageViewUtil.removeDuplicatedUsages(usageInfos); return usageInfos; }
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); } } }
private void tryToMoveInitializers( PsiMethod constructor, HashSet<PsiMethod> subConstructors, LinkedHashSet<PsiField> movedFields) throws IncorrectOperationException { final LinkedHashMap<PsiField, Initializer> fieldsToInitializers = new LinkedHashMap<PsiField, Initializer>(); boolean anyFound = false; for (PsiField field : movedFields) { PsiStatement commonInitializer = null; final ArrayList<PsiElement> fieldInitializersToRemove = new ArrayList<PsiElement>(); for (PsiMethod subConstructor : subConstructors) { commonInitializer = hasCommonInitializer( commonInitializer, subConstructor, field, fieldInitializersToRemove); if (commonInitializer == null) break; } if (commonInitializer != null) { final ParametersAndMovedFieldsUsedCollector visitor = new ParametersAndMovedFieldsUsedCollector(movedFields); commonInitializer.accept(visitor); fieldsToInitializers.put( field, new Initializer( commonInitializer, visitor.getUsedFields(), visitor.getUsedParameters(), fieldInitializersToRemove)); anyFound = true; } } if (!anyFound) return; { final Set<PsiField> initializedFields = fieldsToInitializers.keySet(); Set<PsiField> unmovable = RefactoringUtil.transitiveClosure( new RefactoringUtil.Graph<PsiField>() { public Set<PsiField> getVertices() { return initializedFields; } public Set<PsiField> getTargets(PsiField source) { return fieldsToInitializers.get(source).movedFieldsUsed; } }, new Condition<PsiField>() { public boolean value(PsiField object) { return !initializedFields.contains(object); } }); for (PsiField psiField : unmovable) { fieldsToInitializers.remove(psiField); } } final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject); if (constructor == null) { constructor = (PsiMethod) myTargetSuperClass.add(factory.createConstructor()); final String visibilityModifier = VisibilityUtil.getVisibilityModifier(myTargetSuperClass.getModifierList()); PsiUtil.setModifierProperty(constructor, visibilityModifier, true); } ArrayList<PsiField> initializedFields = new ArrayList<PsiField>(fieldsToInitializers.keySet()); Collections.sort( initializedFields, new Comparator<PsiField>() { public int compare(PsiField field1, PsiField field2) { Initializer i1 = fieldsToInitializers.get(field1); Initializer i2 = fieldsToInitializers.get(field2); if (i1.movedFieldsUsed.contains(field2)) return 1; if (i2.movedFieldsUsed.contains(field1)) return -1; return 0; } }); for (final PsiField initializedField : initializedFields) { Initializer initializer = fieldsToInitializers.get(initializedField); // correct constructor parameters and subConstructors super calls final PsiParameterList parameterList = constructor.getParameterList(); for (final PsiParameter parameter : initializer.usedParameters) { parameterList.add(parameter); } for (final PsiMethod subConstructor : subConstructors) { modifySuperCall(subConstructor, initializer.usedParameters); } PsiStatement assignmentStatement = (PsiStatement) constructor.getBody().add(initializer.initializer); PsiManager manager = PsiManager.getInstance(myProject); ChangeContextUtil.decodeContextInfo( assignmentStatement, myTargetSuperClass, RefactoringChangeUtil.createThisExpression(manager, null)); for (PsiElement psiElement : initializer.statementsToRemove) { psiElement.delete(); } } }