PY-13599 Moving a function fails with "Cannot bind to element"

This commit is contained in:
Ilya.Kazakevich
2014-10-16 00:47:24 +04:00
parent 27284e3dd9
commit 04aee9310a
4 changed files with 59 additions and 10 deletions
@@ -68,7 +68,7 @@ public class PyMoveClassOrFunctionDelegate extends MoveHandlerDelegate {
initialDestination = FileUtil.toSystemDependentName(virtualFile.getPath());
}
}
final PyMoveClassOrFunctionDialog dialog = new PyMoveClassOrFunctionDialog(project, elementsToMove, initialDestination);
final PyMoveClassOrFunctionDialog dialog = PyMoveClassOrFunctionDialog.getInstance(project, elementsToMove, initialDestination);
dialog.show();
if (!dialog.isOK()) {
return;
@@ -29,6 +29,7 @@ import com.jetbrains.python.PyBundle;
import com.jetbrains.python.psi.PyClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
@@ -36,9 +37,46 @@ import javax.swing.*;
* @author vlan
*/
public class PyMoveClassOrFunctionDialog extends RefactoringDialog {
/**
* Instance to be injected to mimic this class in tests
*/
private static PyMoveClassOrFunctionDialog ourInstanceToReplace = null;
private PyMoveClassOrFunctionPanel myPanel;
public PyMoveClassOrFunctionDialog(@NotNull Project project, @NotNull PsiNamedElement[] elements, @Nullable String destination) {
/**
* Creates dialog
*
* @param project dialog project
* @param elements elements to move
* @param destination destination where elements have to be moved
* @return dialog
*/
public static PyMoveClassOrFunctionDialog getInstance(@NotNull final Project project,
@NotNull final PsiNamedElement[] elements,
@Nullable final String destination) {
return ((ourInstanceToReplace != null) ?
ourInstanceToReplace :
new PyMoveClassOrFunctionDialog(project, elements, destination));
}
/**
* Injects instance to be used in tests
*
* @param instanceToReplace instance to be used in tests
*/
@TestOnly
public static void setInstanceToReplace(@NotNull final PyMoveClassOrFunctionDialog instanceToReplace) {
ourInstanceToReplace = instanceToReplace;
}
/**
*
* @param project dialog project
* @param elements elements to move
* @param destination destination where elements have to be moved
* @return dialog
*/
protected PyMoveClassOrFunctionDialog(@NotNull Project project, @NotNull PsiNamedElement[] elements, @Nullable String destination) {
super(project, true);
assert elements.length > 0;
final String moveText;
@@ -67,9 +105,10 @@ public class PyMoveClassOrFunctionDialog extends RefactoringDialog {
descriptor.setRoots(ProjectRootManager.getInstance(project).getContentRoots());
descriptor.withTreeRootVisible(true);
myPanel.getBrowseTargetFileButton().addBrowseFolderListener(PyBundle.message("refactoring.move.class.or.function.choose.destination.file.title"),
null, project, descriptor,
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
myPanel.getBrowseTargetFileButton()
.addBrowseFolderListener(PyBundle.message("refactoring.move.class.or.function.choose.destination.file.title"),
null, project, descriptor,
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
init();
}
@@ -31,6 +31,8 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
@@ -44,6 +46,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.TestDataPath;
@@ -289,6 +292,17 @@ public abstract class PyTestCase extends UsefulTestCase {
}, null, null);
}
/**
* Runs refactoring using special handler
*
* @param handler handler to be used
*/
protected void refactorUsingHandler(@NotNull final RefactoringActionHandler handler) {
final Editor editor = myFixture.getEditor();
assertInstanceOf(editor, EditorEx.class);
handler.invoke(myFixture.getProject(), editor, myFixture.getFile(), ((EditorEx)editor).getDataContext());
}
protected static class PyLightProjectDescriptor implements LightProjectDescriptor {
private final String myPythonVersion;
@@ -17,8 +17,6 @@ package com.jetbrains.python.refactoring;
import com.intellij.lang.LanguageRefactoringSupport;
import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.refactoring.RefactoringActionHandler;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.fixtures.LightMarkedTestCase;
@@ -50,11 +48,9 @@ public class PyExtractMethodTest extends LightMarkedTestCase {
assertNotNull(provider);
final RefactoringActionHandler handler = provider.getExtractMethodHandler();
assertNotNull(handler);
final Editor editor = myFixture.getEditor();
assertInstanceOf(editor, EditorEx.class);
System.setProperty(PyExtractMethodUtil.NAME, newName);
try {
handler.invoke(myFixture.getProject(), editor, myFixture.getFile(), ((EditorEx)editor).getDataContext());
refactorUsingHandler(handler);
}
finally {
System.clearProperty(PyExtractMethodUtil.NAME);