Skip to content
Open
Show file tree
Hide file tree
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 @@ -7,6 +7,7 @@
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.listeners.RefactoringEventData;
import com.intellij.refactoring.ui.UsageViewDescriptorAdapter;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.usageView.UsageInfo;
Expand All @@ -26,6 +27,7 @@
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -83,7 +85,7 @@ protected void performRefactoring(final UsageInfo @NotNull [] usages) {
usagesByElement.putValue(((MyUsageInfo)usage).myMovedElement, usage);
}
boolean isNamespace = ContainerUtil.all(mySourceFiles, PyNamespacePackageUtil::isInNamespacePackage);
CommandProcessor.getInstance().executeCommand(myProject, () -> ApplicationManager.getApplication().runWriteAction(() -> {
CommandProcessor.getInstance().executeCommand(myProject, () -> {
final PyFile destination = PyClassRefactoringUtil.getOrCreateFile(myDestination, myProject, isNamespace);
CommonRefactoringUtil.checkReadOnlyStatus(myProject, destination);
final LinkedHashSet<PsiFile> optimizeImportsTargets = Sets.newLinkedHashSet(mySourceFiles);
Expand Down Expand Up @@ -126,14 +128,33 @@ protected void performRefactoring(final UsageInfo @NotNull [] usages) {
for (PsiFile file : optimizeImportsTargets) {
PyClassRefactoringUtil.optimizeImports(file);
}
}), getRefactoringName(), null);
}, getRefactoringName(), null);
}

@Override
protected @NotNull String getCommandName() {
return getRefactoringName();
}

@Override
protected @Nullable String getRefactoringId() {
return "refactoring.python.move.module.members";
}

@Override
protected @Nullable RefactoringEventData getBeforeData() {
final RefactoringEventData data = new RefactoringEventData();
data.addElements(ContainerUtil.mapNotNull(myElements, SmartPsiElementPointer::getElement));
return data;
}

@Override
protected @Nullable RefactoringEventData getAfterData(UsageInfo @NotNull [] usages) {
final RefactoringEventData data = new RefactoringEventData();
data.addElements(ContainerUtil.mapNotNull(myElements, SmartPsiElementPointer::getElement));
return data;
}

private static class MyUsageInfo extends UsageInfo {
private final PsiElement myMovedElement;
MyUsageInfo(@NotNull UsageInfo usageInfo, @NotNull PsiElement element) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.refactoring;

import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.listeners.RefactoringEventData;
import com.intellij.refactoring.listeners.RefactoringEventListener;
import com.intellij.util.messages.MessageBusConnection;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.refactoring.move.moduleMembers.PyMoveModuleMembersProcessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public class PyMoveModuleMembersEventsTest extends PyTestCase {
private final List<String> myEvents = new ArrayList<>();

@Override
protected void setUp() throws Exception {
super.setUp();
MessageBusConnection connection = myFixture.getProject().getMessageBus().connect(getTestRootDisposable());
connection.subscribe(RefactoringEventListener.REFACTORING_EVENT_TOPIC, new RefactoringEventListener() {
@Override
public void refactoringStarted(@NotNull String refactoringId, @Nullable RefactoringEventData beforeData) {
myEvents.add("started: " + refactoringId);
}

@Override
public void refactoringDone(@NotNull String refactoringId, @Nullable RefactoringEventData afterData) {
myEvents.add("done: " + refactoringId);
}

@Override
public void conflictsDetected(@NotNull String refactoringId, @NotNull RefactoringEventData conflictsData) {
myEvents.add("conflicts: " + refactoringId);
}

@Override
public void undoRefactoring(@NotNull String refactoringId) {
myEvents.add("undo: " + refactoringId);
}
});
}

public void testMoveEvents() {
myFixture.configureByText("a.py", "class C:\n pass\n");
PsiFile fileA = myFixture.getFile();
myFixture.configureByText("b.py", "");
PyClass pyClass = PsiTreeUtil.findChildOfType(fileA, PyClass.class);
assertNotNull(pyClass);
String destination = myFixture.getFile().getVirtualFile().getParent().getPath() + "/b.py";

new PyMoveModuleMembersProcessor(new PsiNamedElement[]{pyClass}, destination).run();

assertContainsElements(myEvents, "started: refactoring.python.move.module.members", "done: refactoring.python.move.module.members");
}
}