blob: 5a31ec09386768a2df1d0c259db488d09f5d2c90 [file] [log] [blame]
package com.intellij.refactoring.move.moveClassesOrPackages;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler;
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Function;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author ksafonov
*/
public abstract class MoveDirectoryWithClassesHelper {
private static final ExtensionPointName<MoveDirectoryWithClassesHelper> EP_NAME =
ExtensionPointName.create("com.intellij.refactoring.moveDirectoryWithClassesHelper");
public abstract void findUsages(Collection<PsiFile> filesToMove, PsiDirectory[] directoriesToMove, Collection<UsageInfo> result,
boolean searchInComments, boolean searchInNonJavaFiles, Project project);
public abstract boolean move(PsiFile file,
PsiDirectory moveDestination,
Map<PsiElement, PsiElement> oldToNewElementsMapping,
List<PsiFile> movedFiles,
RefactoringElementListener listener);
public abstract void postProcessUsages(UsageInfo[] usages, Function<PsiDirectory, PsiDirectory> newDirMapper);
public abstract void beforeMove(PsiFile psiFile);
public abstract void afterMove(PsiElement newElement);
public void preprocessUsages(Project project,
Set<PsiFile> files,
UsageInfo[] infos,
PsiDirectory directory,
MultiMap<PsiElement, String> conflicts) {}
public static MoveDirectoryWithClassesHelper[] findAll() {
return Extensions.getExtensions(EP_NAME);
}
public static class Default extends MoveDirectoryWithClassesHelper {
@Override
public void findUsages(Collection<PsiFile> filesToMove,
PsiDirectory[] directoriesToMove,
Collection<UsageInfo> result,
boolean searchInComments,
boolean searchInNonJavaFiles,
Project project) {
for (PsiFile file : filesToMove) {
for (PsiReference reference : ReferencesSearch.search(file)) {
result.add(new MyUsageInfo(reference, file));
}
}
for (PsiDirectory psiDirectory : directoriesToMove) {
for (PsiReference reference : ReferencesSearch.search(psiDirectory)) {
result.add(new MyUsageInfo(reference, psiDirectory));
}
}
}
@Override
public void postProcessUsages(UsageInfo[] usages, Function<PsiDirectory, PsiDirectory> newDirMapper) {
for (UsageInfo usage : usages) {
if (usage instanceof MyUsageInfo) {
PsiReference reference = usage.getReference();
if (reference != null) {
PsiFileSystemItem file = ((MyUsageInfo)usage).myFile;
if (file instanceof PsiDirectory) {
file = newDirMapper.fun((PsiDirectory)file);
}
reference.bindToElement(file);
}
}
}
}
@Override
public boolean move(PsiFile psiFile,
PsiDirectory moveDestination,
Map<PsiElement, PsiElement> oldToNewElementsMapping,
List<PsiFile> movedFiles,
RefactoringElementListener listener) {
if (moveDestination.equals(psiFile.getContainingDirectory())) {
return false;
}
MoveFileHandler.forElement(psiFile).prepareMovedFile(psiFile, moveDestination, oldToNewElementsMapping);
PsiFile moving = moveDestination.findFile(psiFile.getName());
if (moving == null) {
MoveFilesOrDirectoriesUtil.doMoveFile(psiFile, moveDestination);
}
moving = moveDestination.findFile(psiFile.getName());
movedFiles.add(moving);
listener.elementMoved(psiFile);
return true;
}
@Override
public void beforeMove(PsiFile psiFile) {
}
@Override
public void afterMove(PsiElement newElement) {
}
private static class MyUsageInfo extends UsageInfo {
private final PsiFileSystemItem myFile;
public MyUsageInfo(@NotNull PsiReference reference, PsiFileSystemItem file) {
super(reference);
myFile = file;
}
@Override
@Nullable
public PsiReference getReference() {
PsiElement element = getElement();
if (element == null) {
return null;
}
else {
final ProperTextRange rangeInElement = getRangeInElement();
return rangeInElement != null ? element.findReferenceAt(rangeInElement.getStartOffset()) : element.getReference();
}
}
}
}
}