private void doMoveClass(PsiSubstitutor substitutor, MemberInfo info) { PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); PsiClass aClass = (PsiClass) info.getMember(); if (Boolean.FALSE.equals(info.getOverrides())) { final PsiReferenceList sourceReferenceList = info.getSourceReferenceList(); LOG.assertTrue(sourceReferenceList != null); PsiJavaCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ? RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass) : RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass); if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) { RefactoringUtil.replaceMovedMemberTypeParameters( ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final PsiReferenceList referenceList = myIsTargetInterface ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList(); assert referenceList != null; referenceList.add(ref); } } else { RefactoringUtil.replaceMovedMemberTypeParameters( aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); fixReferencesToStatic(aClass); final PsiMember movedElement = (PsiMember) myTargetSuperClass.add( convertClassToLanguage(aClass, myTargetSuperClass.getLanguage())); myMembersAfterMove.add(movedElement); aClass.delete(); } }
protected void performRefactoring(final UsageInfo[] usages) { new PushDownProcessor( mySuperClass.getProject(), myMemberInfos, mySuperClass, new DocCommentPolicy(DocCommentPolicy.ASIS)) { // push down conflicts are already collected @Override protected boolean showConflicts(MultiMap<PsiElement, String> conflicts, UsageInfo[] usages) { return true; } }.run(); RefactoringUtil.sortDepthFirstRightLeftOrder(usages); for (UsageInfo usageInfo : usages) { if (!(usageInfo instanceof ReplaceExtendsListUsageInfo)) { try { ((FixableUsageInfo) usageInfo).fixUsage(); } catch (IncorrectOperationException e) { LOG.info(e); } } } replaceInnerTypeUsages(); // postpone broken hierarchy for (UsageInfo usage : usages) { if (usage instanceof ReplaceExtendsListUsageInfo) { ((ReplaceExtendsListUsageInfo) usage).fixUsage(); } } try { mySuperClass.delete(); } catch (IncorrectOperationException e) { LOG.error(e); } }
@Nullable public static PsiElement doCopyClasses( final Map<PsiFile, PsiClass[]> fileToClasses, @Nullable HashMap<PsiFile, String> map, final String copyClassName, final PsiDirectory targetDirectory, final Project project) throws IncorrectOperationException { PsiElement newElement = null; final Map<PsiClass, PsiElement> oldToNewMap = new HashMap<PsiClass, PsiElement>(); for (final PsiClass[] psiClasses : fileToClasses.values()) { if (psiClasses != null) { for (PsiClass aClass : psiClasses) { if (aClass instanceof SyntheticElement) { continue; } oldToNewMap.put(aClass, null); } } } final List<PsiFile> createdFiles = new ArrayList<PsiFile>(fileToClasses.size()); int[] choice = fileToClasses.size() > 1 ? new int[] {-1} : null; List<PsiFile> files = new ArrayList<PsiFile>(); for (final Map.Entry<PsiFile, PsiClass[]> entry : fileToClasses.entrySet()) { final PsiFile psiFile = entry.getKey(); final PsiClass[] sources = entry.getValue(); if (psiFile instanceof PsiClassOwner && sources != null) { final PsiFile createdFile = copy( psiFile, targetDirectory, copyClassName, map == null ? null : map.get(psiFile), choice); if (createdFile == null) return null; for (final PsiClass destination : ((PsiClassOwner) createdFile).getClasses()) { if (destination instanceof SyntheticElement) { continue; } PsiClass source = findByName(sources, destination.getName()); if (source != null) { final PsiClass copy = copy(source, copyClassName); newElement = destination.replace(copy); oldToNewMap.put(source, newElement); } else { destination.delete(); } } createdFiles.add(createdFile); } else { files.add(psiFile); } } for (PsiFile file : files) { try { PsiDirectory finalTarget = targetDirectory; final String relativePath = map != null ? map.get(file) : null; if (relativePath != null && !relativePath.isEmpty()) { finalTarget = buildRelativeDir(targetDirectory, relativePath).findOrCreateTargetDirectory(); } final PsiFile fileCopy = CopyFilesOrDirectoriesHandler.copyToDirectory( file, getNewFileName(file, copyClassName), finalTarget, choice); if (fileCopy != null) { createdFiles.add(fileCopy); } } catch (IOException e) { throw new IncorrectOperationException(e.getMessage()); } } final Set<PsiElement> rebindExpressions = new HashSet<PsiElement>(); for (PsiElement element : oldToNewMap.values()) { if (element == null) { LOG.error(oldToNewMap.keySet()); continue; } decodeRefs(element, oldToNewMap, rebindExpressions); } final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); for (PsiFile psiFile : createdFiles) { if (psiFile instanceof PsiJavaFile) { codeStyleManager.removeRedundantImports((PsiJavaFile) psiFile); } } for (PsiElement expression : rebindExpressions) { codeStyleManager.shortenClassReferences(expression); } new OptimizeImportsProcessor( project, createdFiles.toArray(new PsiFile[createdFiles.size()]), null) .run(); return newElement != null ? newElement : createdFiles.size() > 0 ? createdFiles.get(0) : null; }