Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package consulo.csharp.impl.ide.refactoring.move;

import consulo.annotation.access.RequiredReadAction;
Expand All @@ -36,6 +35,7 @@
import consulo.language.psi.PsiFileSystemItem;
import consulo.language.psi.scope.GlobalSearchScope;
import consulo.language.util.IncorrectOperationException;
import consulo.localize.LocalizeValue;
import consulo.logging.Logger;
import consulo.project.Project;
import consulo.ui.annotation.RequiredUIAccess;
Expand All @@ -45,180 +45,166 @@
import consulo.util.lang.Couple;

import jakarta.annotation.Nonnull;

import java.util.*;
import java.util.function.Function;

/**
* @author VISTALL
* @since 2019-07-20
*/
public class CSharpMoveClassesUtil
{
private static final Logger LOG = Logger.getInstance(CSharpMoveClassesUtil.class);

@RequiredUIAccess
public static void doMove(
final Project project,
final PsiElement[] elements,
final PsiElement[] targetElement,
final MoveCallback moveCallback
)
{
doMove(
project,
elements,
targetElement,
moveCallback,
oldElements -> {
PsiElement[] newElements = new PsiElement[oldElements.length];

for (int i = 0; i < oldElements.length; i++)
{
PsiElement oldElement = oldElements[i];
if (oldElement instanceof CSharpTypeDeclaration)
{
newElements[i] = oldElement.getContainingFile();
}
else
{
newElements[i] = oldElement;
}
}

return newElements;
}
);
}

@RequiredUIAccess
public static void doMove(
final Project project,
final PsiElement[] elements,
final PsiElement[] targetElement,
final MoveCallback moveCallback,
final Function<PsiElement[], PsiElement[]> adjustElements
)
{
final PsiDirectory targetDirectory = MoveFilesOrDirectoriesUtil.resolveToDirectory(project, targetElement[0]);
if (targetElement[0] != null && targetDirectory == null)
{
return;
}

final PsiElement[] newElements = adjustElements != null ? adjustElements.apply(elements) : elements;

final PsiDirectory initialTargetDirectory = MoveFilesOrDirectoriesUtil.getInitialTargetDirectory(targetDirectory, elements);

final MoveFilesOrDirectoriesDialog.Callback doRun = moveDialog -> CommandProcessor.getInstance().executeCommand(
project,
() -> {
final PsiDirectory targetDirectory1 = moveDialog != null ? moveDialog.getTargetDirectory() : initialTargetDirectory;
if (targetDirectory1 == null)
{
LOG.error("ItemPresentationImpl is null! The target directory, it is null!");
return;
}

Collection<PsiElement> toCheck = ContainerUtil.newArrayList((PsiElement) targetDirectory1);
for (PsiElement e : newElements)
{
toCheck.add(e instanceof PsiFileSystemItem && e.getParent() != null ? e.getParent() : e);
}
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, toCheck, false))
{
return;
}

targetElement[0] = targetDirectory1;

try
{
final int[] choice = elements.length > 1 || elements[0] instanceof PsiDirectory ? new int[]{-1} : null;
final List<PsiElement> els = new ArrayList<>();
for (final PsiElement psiElement : newElements)
{
if (psiElement instanceof PsiFile)
{
final PsiFile file = (PsiFile) psiElement;

if (CommonRefactoringUtil.checkFileExist(targetDirectory1, choice, file, file.getName(), "Move"))
{
continue;
}
}
MoveFilesOrDirectoriesUtil.checkMove(psiElement, targetDirectory1);
els.add(psiElement);
}
final Runnable callback = () -> {
if (moveDialog != null)
{
moveDialog.close(DialogWrapper.CANCEL_EXIT_CODE);
}
};
if (els.isEmpty())
{
callback.run();
return;
}
new CSharpClassesMoveProcessor(project,
els.toArray(new PsiElement[els.size()]),
targetDirectory1,
RefactoringSettings.getInstance().MOVE_SEARCH_FOR_REFERENCES_FOR_FILE,
false,
false,
moveCallback,
callback
).run();
}
catch (IncorrectOperationException e)
{
CommonRefactoringUtil.showErrorMessage(RefactoringLocalize.errorTitle().get(), e.getMessage(), "refactoring.moveFile", project);
}
},
MoveHandler.REFACTORING_NAME.get(),
null
);

final MoveFilesOrDirectoriesDialog moveDialog = new MoveFilesOrDirectoriesDialog(project, doRun);
moveDialog.setData(newElements, initialTargetDirectory, "refactoring.moveFile");
moveDialog.show();
}


/**
* Return couple of elements.
*
* If first element is type - second will be same element
*
* if first element is namespace declaration - second will namespace as element (global namespace object not c# file declaration)
*/
@Nonnull
public static Set<Couple<DotNetNamedElement>> findTypesAndNamespaces(@Nonnull PsiElement element)
{
Set<Couple<DotNetNamedElement>> result = new LinkedHashSet<>();
element.accept(new CSharpRecursiveElementVisitor()
{
@Override
public void visitTypeDeclaration(CSharpTypeDeclaration declaration)
{
super.visitTypeDeclaration(declaration);

result.add(Couple.of(declaration, declaration));
}

@Override
@RequiredReadAction
public void visitNamespaceDeclaration(CSharpNamespaceDeclaration declaration)
{
super.visitNamespaceDeclaration(declaration);

DotNetPsiSearcher searcher = DotNetPsiSearcher.getInstance(declaration.getProject());
DotNetNamespaceAsElement namespace =
searcher.findNamespace(declaration.getPresentableQName(), GlobalSearchScope.projectScope(declaration.getProject()));

result.add(Couple.<DotNetNamedElement>of(declaration, namespace));
}
});
return result;
}
public class CSharpMoveClassesUtil {
private static final Logger LOG = Logger.getInstance(CSharpMoveClassesUtil.class);

@RequiredUIAccess
public static void doMove(Project project, PsiElement[] elements, PsiElement[] targetElement, MoveCallback moveCallback) {
doMove(
project,
elements,
targetElement,
moveCallback,
oldElements -> {
PsiElement[] newElements = new PsiElement[oldElements.length];

for (int i = 0; i < oldElements.length; i++) {
PsiElement oldElement = oldElements[i];
if (oldElement instanceof CSharpTypeDeclaration) {
newElements[i] = oldElement.getContainingFile();
}
else {
newElements[i] = oldElement;
}
}

return newElements;
}
);
}

@RequiredUIAccess
public static void doMove(
Project project,
PsiElement[] elements,
PsiElement[] targetElement,
MoveCallback moveCallback,
Function<PsiElement[], PsiElement[]> adjustElements
) {
PsiDirectory targetDirectory = MoveFilesOrDirectoriesUtil.resolveToDirectory(project, targetElement[0]);
if (targetElement[0] != null && targetDirectory == null) {
return;
}

PsiElement[] newElements = adjustElements != null ? adjustElements.apply(elements) : elements;

PsiDirectory initialTargetDirectory = MoveFilesOrDirectoriesUtil.getInitialTargetDirectory(targetDirectory, elements);

@RequiredUIAccess
MoveFilesOrDirectoriesDialog.Callback doRun = moveDialog -> {
CommandProcessor.getInstance().newCommand()
.project(project)
.name(MoveHandler.REFACTORING_NAME)
.run(() -> {
PsiDirectory targetDirectory1 = moveDialog != null ? moveDialog.getTargetDirectory() : initialTargetDirectory;
if (targetDirectory1 == null) {
LOG.error("ItemPresentationImpl is null! The target directory, it is null!");
return;
}

Collection<PsiElement> toCheck = ContainerUtil.newArrayList((PsiElement) targetDirectory1);
for (PsiElement e : newElements) {
toCheck.add(e instanceof PsiFileSystemItem && e.getParent() != null ? e.getParent() : e);
}
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, toCheck, false)) {
return;
}

targetElement[0] = targetDirectory1;

try {
int[] choice = elements.length > 1 || elements[0] instanceof PsiDirectory ? new int[]{-1} : null;
List<PsiElement> els = new ArrayList<>();
for (PsiElement psiElement : newElements) {
if (psiElement instanceof PsiFile file) {
if (CommonRefactoringUtil.checkFileExist(
targetDirectory1,
choice,
file,
file.getName(),
RefactoringLocalize.commandNameMove()
)) {
continue;
}
}
MoveFilesOrDirectoriesUtil.checkMove(psiElement, targetDirectory1);
els.add(psiElement);
}
Runnable callback = () -> {
if (moveDialog != null) {
moveDialog.close(DialogWrapper.CANCEL_EXIT_CODE);
}
};
if (els.isEmpty()) {
callback.run();
return;
}
new CSharpClassesMoveProcessor(
project,
els.toArray(new PsiElement[els.size()]),
targetDirectory1,
RefactoringSettings.getInstance().MOVE_SEARCH_FOR_REFERENCES_FOR_FILE,
false,
false,
moveCallback,
callback
).run();
}
catch (IncorrectOperationException e) {
CommonRefactoringUtil.showErrorMessage(
RefactoringLocalize.errorTitle(),
LocalizeValue.ofNullable(e.getMessage()),
"refactoring.moveFile",
project
);
}
});
};

MoveFilesOrDirectoriesDialog moveDialog = new MoveFilesOrDirectoriesDialog(project, doRun);
moveDialog.setData(newElements, initialTargetDirectory, "refactoring.moveFile");
moveDialog.show();
}


/**
* Return couple of elements.
* <p>
* If first element is type - second will be same element
* <p>
* if first element is namespace declaration - second will namespace as element (global namespace object not c# file declaration)
*/
@Nonnull
public static Set<Couple<DotNetNamedElement>> findTypesAndNamespaces(@Nonnull PsiElement element) {
Set<Couple<DotNetNamedElement>> result = new LinkedHashSet<>();
element.accept(new CSharpRecursiveElementVisitor() {
@Override
public void visitTypeDeclaration(CSharpTypeDeclaration declaration) {
super.visitTypeDeclaration(declaration);

result.add(Couple.of(declaration, declaration));
}

@Override
@RequiredReadAction
public void visitNamespaceDeclaration(CSharpNamespaceDeclaration declaration) {
super.visitNamespaceDeclaration(declaration);

DotNetPsiSearcher searcher = DotNetPsiSearcher.getInstance(declaration.getProject());
DotNetNamespaceAsElement namespace =
searcher.findNamespace(declaration.getPresentableQName(), GlobalSearchScope.projectScope(declaration.getProject()));

result.add(Couple.<DotNetNamedElement>of(declaration, namespace));
}
});
return result;
}
}
Loading