PY-13599 Moving a function fails with "Cannot bind to element"
authorIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Wed, 15 Oct 2014 20:47:24 +0000 (00:47 +0400)
committerIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Wed, 15 Oct 2014 20:47:24 +0000 (00:47 +0400)
python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDelegate.java
python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDialog.java
python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java
python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java

index 8306a4faec2313b75f8c78a6cb6adcd072442a0d..04e2742dd3c97e72136287149522f238085a5da0 100644 (file)
@@ -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;
index 965145cc36f2a030b41383962899c64d6f8a7be7..c5dd570dca3be685be6ed8822562c7a4cdff452c 100644 (file)
@@ -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();
   }
 
index d6943dc45e0267f1e82fe6ae929774298b6e15ff..222a3109716a224803d7deaf4a7ec278f13e61d1 100644 (file)
@@ -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;
 
index 84769c32b13ed3a450d046630ad777ad075d6071..2a404c58cf83128efd7ec29b2bcd2402a705a2d4 100644 (file)
@@ -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);