@Nullable private String verifyInnerClassDestination() { PsiClass targetClass = findTargetClass(); if (targetClass == null) return null; for (PsiElement element : myElementsToMove) { if (PsiTreeUtil.isAncestor(element, targetClass, false)) { return RefactoringBundle.message("move.class.to.inner.move.to.self.error"); } final Language targetClassLanguage = targetClass.getLanguage(); if (!element.getLanguage().equals(targetClassLanguage)) { return RefactoringBundle.message( "move.to.different.language", UsageViewUtil.getType(element), ((PsiClass) element).getQualifiedName(), targetClass.getQualifiedName()); } if (element.getLanguage().equals(Language.findLanguageByID("Groovy"))) { return RefactoringBundle.message("dont.support.inner.classes", "Groovy"); } } while (targetClass != null) { if (targetClass.getContainingClass() != null && !targetClass.hasModifierProperty(PsiModifier.STATIC)) { return RefactoringBundle.message("move.class.to.inner.nonstatic.error"); } targetClass = targetClass.getContainingClass(); } return null; }
@Nullable private MoveDestination selectDestination() { final String packageName = getTargetPackage().trim(); if (packageName.length() > 0 && !JavaPsiFacade.getInstance(myManager.getProject()) .getNameHelper() .isQualifiedName(packageName)) { Messages.showErrorDialog( myProject, RefactoringBundle.message("please.enter.a.valid.target.package.name"), RefactoringBundle.message("move.title")); return null; } RecentsManager.getInstance(myProject).registerRecentEntry(RECENTS_KEY, packageName); PackageWrapper targetPackage = new PackageWrapper(myManager, packageName); if (!targetPackage.exists()) { final int ret = Messages.showYesNoDialog( myProject, RefactoringBundle.message("package.does.not.exist", packageName), RefactoringBundle.message("move.title"), Messages.getQuestionIcon()); if (ret != 0) return null; } return ((DestinationFolderComboBox) myDestinationFolderCB).selectDirectory(targetPackage, true); }
private void invokeMoveToPackage() { final MoveDestination destination = selectDestination(); if (destination == null) return; saveRefactoringSettings(); for (final PsiElement element : myElementsToMove) { String message = verifyDestinationForElement(element, destination); if (message != null) { String helpId = HelpID.getMoveHelpID(myElementsToMove[0]); CommonRefactoringUtil.showErrorMessage( RefactoringBundle.message("error.title"), message, helpId, getProject()); return; } } try { for (PsiElement element : myElementsToMove) { if (element instanceof PsiClass) { final PsiClass aClass = (PsiClass) element; LOG.assertTrue(aClass.isPhysical(), aClass); /*PsiElement toAdd; if (aClass.getContainingFile() instanceof PsiJavaFile && ((PsiJavaFile)aClass.getContainingFile()).getClasses().length > 1) { toAdd = aClass; } else { toAdd = aClass.getContainingFile(); }*/ final PsiDirectory targetDirectory = destination.getTargetIfExists(element.getContainingFile()); if (targetDirectory != null) { MoveFilesOrDirectoriesUtil.checkMove(aClass, targetDirectory); } } } MoveClassesOrPackagesProcessor processor = createMoveToPackageProcessor(destination, myElementsToMove, myMoveCallback); if (processor.verifyValidPackageName()) { processor.setOpenInEditor(isOpenInEditor()); invokeRefactoring(processor); } } catch (IncorrectOperationException e) { String helpId = HelpID.getMoveHelpID(myElementsToMove[0]); CommonRefactoringUtil.showErrorMessage( RefactoringBundle.message("error.title"), e.getMessage(), helpId, getProject()); } }
private void addDoRefactoringAction( @NotNull UsageView usageView, @NotNull Runnable refactoringRunnable, @NotNull String canNotMakeString) { usageView.addPerformOperationAction( refactoringRunnable, getCommandName(), canNotMakeString, RefactoringBundle.message("usageView.doAction"), false); }
private ReferenceEditorComboWithBrowseButton createPackageChooser() { final ReferenceEditorComboWithBrowseButton packageChooser = new PackageNameReferenceEditorCombo( "", myProject, RECENTS_KEY, RefactoringBundle.message("choose.destination.package")); final Document document = packageChooser.getChildComponent().getDocument(); document.addDocumentListener( new DocumentAdapter() { public void documentChanged(DocumentEvent e) { validateButtons(); } }); return packageChooser; }
protected void customizeUsagesView( @NotNull final UsageViewDescriptor viewDescriptor, @NotNull final UsageView usageView) { final Runnable refactoringRunnable = new Runnable() { @Override public void run() { Set<UsageInfo> usagesToRefactor = UsageViewUtil.getNotExcludedUsageInfos(usageView); final UsageInfo[] infos = usagesToRefactor.toArray(new UsageInfo[usagesToRefactor.size()]); if (ensureElementsWritable(infos, viewDescriptor)) { execute(infos); } } }; String canNotMakeString = RefactoringBundle.message("usageView.need.reRun"); addDoRefactoringAction(usageView, refactoringRunnable, canNotMakeString); }
public void setData( PsiElement[] psiElements, String targetPackageName, final PsiDirectory initialTargetDirectory, boolean isTargetDirectoryFixed, boolean searchInComments, boolean searchForTextOccurences, String helpID) { myInitialTargetDirectory = initialTargetDirectory; myTargetDirectoryFixed = isTargetDirectoryFixed; if (targetPackageName.length() != 0) { myWithBrowseButtonReference.prependItem(targetPackageName); myClassPackageChooser.prependItem(targetPackageName); } String nameFromCallback = myMoveCallback instanceof MoveClassesOrPackagesCallback ? ((MoveClassesOrPackagesCallback) myMoveCallback).getElementsToMoveName() : null; if (nameFromCallback != null) { myNameLabel.setText(nameFromCallback); } else if (psiElements.length == 1) { PsiElement firstElement = psiElements[0]; if (firstElement instanceof PsiClass) { LOG.assertTrue(!MoveClassesOrPackagesImpl.isClassInnerOrLocal((PsiClass) firstElement)); } else { PsiElement parent = firstElement.getParent(); LOG.assertTrue(parent != null); } myNameLabel.setText( RefactoringBundle.message( "move.single.class.or.package.name.label", UsageViewUtil.getType(firstElement), UsageViewUtil.getLongName(firstElement))); } else if (psiElements.length > 1) { myNameLabel.setText( psiElements[0] instanceof PsiClass ? RefactoringBundle.message("move.specified.classes") : RefactoringBundle.message("move.specified.packages")); } selectInitialCard(); myCbSearchInComments.setSelected(searchInComments); myCbSearchTextOccurences.setSelected(searchForTextOccurences); ((DestinationFolderComboBox) myDestinationFolderCB) .setData( myProject, myInitialTargetDirectory, new Pass<String>() { @Override public void pass(String s) { setErrorText(s); } }, myClassPackageChooser.getChildComponent()); UIUtil.setEnabled( myTargetPanel, getSourceRoots().length > 0 && isMoveToPackage() && !isTargetDirectoryFixed, true); validateButtons(); myHelpID = helpID; }
private void doRefactoring(@NotNull final Collection<UsageInfo> usageInfoSet) { for (Iterator<UsageInfo> iterator = usageInfoSet.iterator(); iterator.hasNext(); ) { UsageInfo usageInfo = iterator.next(); final PsiElement element = usageInfo.getElement(); if (element == null || !isToBeChanged(usageInfo)) { iterator.remove(); } } LocalHistoryAction action = LocalHistory.getInstance().startAction(getCommandName()); final UsageInfo[] writableUsageInfos = usageInfoSet.toArray(new UsageInfo[usageInfoSet.size()]); try { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); RefactoringListenerManagerImpl listenerManager = (RefactoringListenerManagerImpl) RefactoringListenerManager.getInstance(myProject); myTransaction = listenerManager.startTransaction(); final Map<RefactoringHelper, Object> preparedData = new LinkedHashMap<>(); final Runnable prepareHelpersRunnable = new Runnable() { @Override public void run() { for (final RefactoringHelper helper : Extensions.getExtensions(RefactoringHelper.EP_NAME)) { Object operation = ApplicationManager.getApplication() .runReadAction( new Computable<Object>() { @Override public Object compute() { return helper.prepareOperation(writableUsageInfos); } }); preparedData.put(helper, operation); } } }; ProgressManager.getInstance() .runProcessWithProgressSynchronously( prepareHelpersRunnable, "Prepare ...", false, myProject); ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { final String refactoringId = getRefactoringId(); if (refactoringId != null) { RefactoringEventData data = getBeforeData(); if (data != null) { data.addUsages(usageInfoSet); } myProject .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .refactoringStarted(refactoringId, data); } try { if (refactoringId != null) { UndoableAction action = new UndoRefactoringAction(myProject, refactoringId); UndoManager.getInstance(myProject).undoableActionPerformed(action); } performRefactoring(writableUsageInfos); } finally { if (refactoringId != null) { myProject .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .refactoringDone(refactoringId, getAfterData(writableUsageInfos)); } } } }); DumbService.getInstance(myProject).completeJustSubmittedTasks(); for (Map.Entry<RefactoringHelper, Object> e : preparedData.entrySet()) { //noinspection unchecked e.getKey().performOperation(myProject, e.getValue()); } myTransaction.commit(); ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { performPsiSpoilingRefactoring(); } }); } finally { action.finish(); } int count = writableUsageInfos.length; if (count > 0) { StatusBarUtil.setStatusBarInfo( myProject, RefactoringBundle.message("statusBar.refactoring.result", count)); } else { if (!isPreviewUsages(writableUsageInfos)) { StatusBarUtil.setStatusBarInfo(myProject, RefactoringBundle.message("statusBar.noUsages")); } } }
@NotNull private static UsageViewPresentation createPresentation( @NotNull UsageViewDescriptor descriptor, @NotNull Usage[] usages) { UsageViewPresentation presentation = new UsageViewPresentation(); presentation.setTabText(RefactoringBundle.message("usageView.tabText")); presentation.setTargetsNodeText(descriptor.getProcessedElementsHeader()); presentation.setShowReadOnlyStatusAsRed(true); presentation.setShowCancelButton(true); presentation.setUsagesString(RefactoringBundle.message("usageView.usagesText")); int codeUsageCount = 0; int nonCodeUsageCount = 0; int dynamicUsagesCount = 0; Set<PsiFile> codeFiles = new HashSet<>(); Set<PsiFile> nonCodeFiles = new HashSet<>(); Set<PsiFile> dynamicUsagesCodeFiles = new HashSet<>(); for (Usage usage : usages) { if (usage instanceof PsiElementUsage) { final PsiElementUsage elementUsage = (PsiElementUsage) usage; final PsiElement element = elementUsage.getElement(); if (element == null) continue; final PsiFile containingFile = element.getContainingFile(); if (elementUsage.isNonCodeUsage()) { nonCodeUsageCount++; nonCodeFiles.add(containingFile); } else { codeUsageCount++; codeFiles.add(containingFile); } if (usage instanceof UsageInfo2UsageAdapter) { final UsageInfo usageInfo = ((UsageInfo2UsageAdapter) usage).getUsageInfo(); if (usageInfo instanceof MoveRenameUsageInfo && usageInfo.isDynamicUsage()) { dynamicUsagesCount++; dynamicUsagesCodeFiles.add(containingFile); } } } } codeFiles.remove(null); nonCodeFiles.remove(null); dynamicUsagesCodeFiles.remove(null); String codeReferencesText = descriptor.getCodeReferencesText(codeUsageCount, codeFiles.size()); presentation.setCodeUsagesString(codeReferencesText); final String commentReferencesText = descriptor.getCommentReferencesText(nonCodeUsageCount, nonCodeFiles.size()); if (commentReferencesText != null) { presentation.setNonCodeUsagesString(commentReferencesText); } presentation.setDynamicUsagesString( "Dynamic " + StringUtil.decapitalize( descriptor.getCodeReferencesText( dynamicUsagesCount, dynamicUsagesCodeFiles.size()))); String generatedCodeString; if (codeReferencesText.contains("in code")) { generatedCodeString = StringUtil.replace(codeReferencesText, "in code", "in generated code"); } else { generatedCodeString = codeReferencesText + " in generated code"; } presentation.setUsagesInGeneratedCodeString(generatedCodeString); return presentation; }
protected void doRun() { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); final Ref<UsageInfo[]> refUsages = new Ref<>(); final Ref<Language> refErrorLanguage = new Ref<>(); final Ref<Boolean> refProcessCanceled = new Ref<>(); final Ref<Boolean> anyException = new Ref<>(); final Runnable findUsagesRunnable = new Runnable() { @Override public void run() { try { refUsages.set( DumbService.getInstance(myProject) .runReadActionInSmartMode( new Computable<UsageInfo[]>() { @Override public UsageInfo[] compute() { return findUsages(); } })); } catch (UnknownReferenceTypeException e) { refErrorLanguage.set(e.getElementLanguage()); } catch (ProcessCanceledException e) { refProcessCanceled.set(Boolean.TRUE); } catch (Throwable e) { anyException.set(Boolean.TRUE); LOG.error(e); } } }; if (!ProgressManager.getInstance() .runProcessWithProgressSynchronously( findUsagesRunnable, RefactoringBundle.message("progress.text"), true, myProject)) { return; } if (!refErrorLanguage.isNull()) { Messages.showErrorDialog( myProject, RefactoringBundle.message( "unsupported.refs.found", refErrorLanguage.get().getDisplayName()), RefactoringBundle.message("error.title")); return; } if (DumbService.isDumb(myProject)) { DumbService.getInstance(myProject) .showDumbModeNotification("Refactoring is not available until indices are ready"); return; } if (!refProcessCanceled.isNull()) { Messages.showErrorDialog( myProject, "Index corruption detected. Please retry the refactoring - indexes will be rebuilt automatically", RefactoringBundle.message("error.title")); return; } if (!anyException.isNull()) { // do not proceed if find usages fails return; } assert !refUsages.isNull() : "Null usages from processor " + this; if (!preprocessUsages(refUsages)) return; final UsageInfo[] usages = refUsages.get(); assert usages != null; UsageViewDescriptor descriptor = createUsageViewDescriptor(usages); boolean isPreview = isPreviewUsages(usages); if (!isPreview) { isPreview = !ensureElementsWritable(usages, descriptor) || UsageViewUtil.hasReadOnlyUsages(usages); if (isPreview) { StatusBarUtil.setStatusBarInfo( myProject, RefactoringBundle.message("readonly.occurences.found")); } } if (isPreview) { for (UsageInfo usage : usages) { LOG.assertTrue(usage != null, getClass()); } previewRefactoring(usages); } else { execute(usages); } }
public void setData( PsiElement[] psiElements, String targetPackageName, PsiDirectory initialTargetDirectory, boolean isTargetDirectoryFixed, boolean suggestToMoveToAnotherRoot, boolean searchInComments, boolean searchForTextOccurences, String helpID) { myTargetDirectoryFixed = isTargetDirectoryFixed; mySuggestToMoveToAnotherRoot = suggestToMoveToAnotherRoot; if (targetPackageName.length() != 0) { myWithBrowseButtonReference.prependItem(targetPackageName); myClassPackageChooser.prependItem(targetPackageName); } String nameFromCallback = myMoveCallback instanceof MoveClassesOrPackagesCallback ? ((MoveClassesOrPackagesCallback) myMoveCallback).getElementsToMoveName() : null; if (nameFromCallback != null) { myNameLabel.setText(nameFromCallback); } else if (psiElements.length == 1) { PsiElement firstElement = psiElements[0]; if (firstElement instanceof PsiClass) { LOG.assertTrue(!MoveClassesOrPackagesImpl.isClassInnerOrLocal((PsiClass) firstElement)); } else { PsiElement parent = firstElement.getParent(); LOG.assertTrue(parent != null); } myNameLabel.setText( RefactoringBundle.message( "move.single.class.or.package.name.label", UsageViewUtil.getType(firstElement), UsageViewUtil.getLongName(firstElement))); } else if (psiElements.length > 1) { myNameLabel.setText( psiElements[0] instanceof PsiClass ? RefactoringBundle.message("move.specified.classes") : RefactoringBundle.message("move.specified.packages")); } selectInitialCard(); myCbSearchInComments.setSelected(searchInComments); myCbSearchTextOccurences.setSelected(searchForTextOccurences); if (initialTargetDirectory != null && JavaMoveClassesOrPackagesHandler.packageHasMultipleDirectoriesInModule( myProject, initialTargetDirectory)) { final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); final Set<VirtualFile> initialRoots = new HashSet<VirtualFile>(); collectSourceRoots(psiElements, fileIndex, initialRoots); if (initialRoots.size() > 1) { initialTargetDirectory = null; } } ((DestinationFolderComboBox) myDestinationFolderCB) .setData( myProject, initialTargetDirectory, new Pass<String>() { @Override public void pass(String s) { setErrorText(s); } }, myHavePackages ? myWithBrowseButtonReference.getChildComponent() : myClassPackageChooser.getChildComponent()); UIUtil.setEnabled( myTargetPanel, !getSourceRoots().isEmpty() && isMoveToPackage() && !isTargetDirectoryFixed, true); validateButtons(); myHelpID = helpID; }