Fixed rename of elements that are imported via alias (PY-8857)

This commit is contained in:
Andrey Vlasovskikh
2013-02-13 22:03:46 +04:00
parent e484284d3a
commit 0ee5725481
12 changed files with 102 additions and 5 deletions

View File

@@ -3,17 +3,22 @@ package com.jetbrains.python.refactoring.rename;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.rename.RenamePsiFileProcessor;
import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyImportElement;
import com.jetbrains.python.psi.PyImportStatementBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -35,6 +40,18 @@ public class RenamePyFileProcessor extends RenamePsiFileProcessor {
return element;
}
@NotNull
@Override
public Collection<PsiReference> findReferences(PsiElement element) {
final List<PsiReference> results = new ArrayList<PsiReference>();
for (PsiReference reference : super.findReferences(element)) {
if (isNotAliasedInImportElement(reference)) {
results.add(reference);
}
}
return results;
}
@Override
public void findCollisions(PsiElement element,
final String newName,
@@ -57,4 +74,21 @@ public class RenamePyFileProcessor extends RenamePsiFileProcessor {
}
}
}
private static boolean isNotAliasedInImportElement(@NotNull PsiReference reference) {
boolean include = true;
if (reference instanceof PsiPolyVariantReference) {
final ResolveResult[] results = ((PsiPolyVariantReference)reference).multiResolve(false);
for (ResolveResult result : results) {
final PsiElement resolved = result.getElement();
if (resolved instanceof PyImportElement) {
if (((PyImportElement)resolved).getAsName() != null) {
include = false;
break;
}
}
}
}
return include;
}
}

View File

@@ -0,0 +1,3 @@
import bar as foo
foo.f()

View File

@@ -0,0 +1,2 @@
def f():
pass

View File

@@ -0,0 +1,3 @@
import f<caret>oo as foo
foo.f()

View File

@@ -0,0 +1,2 @@
def f():
pass

View File

@@ -0,0 +1,3 @@
import p1.bar as foo
foo.f()

View File

@@ -0,0 +1 @@
__author__ = 'user'

View File

@@ -0,0 +1,2 @@
def f():
pass

View File

@@ -0,0 +1,3 @@
import p1.f<caret>oo as foo
foo.f()

View File

@@ -0,0 +1 @@
__author__ = 'user'

View File

@@ -0,0 +1,2 @@
def f():
pass

View File

@@ -1,26 +1,37 @@
package com.jetbrains.python.refactoring;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.testFramework.PlatformTestUtil;
import com.jetbrains.python.PythonTestUtil;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.LanguageLevel;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* @author yole
*/
public class PyRenameTest extends PyTestCase {
public static final String RENAME_DATA_PATH = "refactoring/rename/";
public void testRenameField() { // PY-457
doTest("qu");
}
public void testSearchInStrings() { // PY-670
myFixture.configureByFile("refactoring/rename/" + getTestName(true) + ".py");
myFixture.configureByFile(RENAME_DATA_PATH + getTestName(true) + ".py");
final PsiElement element = TargetElementUtilBase.findTargetElement(myFixture.getEditor(), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED |
TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
assertNotNull(element);
myFixture.renameElement(element, "bar", true, false);
myFixture.checkResultByFile("refactoring/rename/" + getTestName(true) + "_after.py");
myFixture.checkResultByFile(RENAME_DATA_PATH + getTestName(true) + "_after.py");
}
public void testRenameParameter() { // PY-385
@@ -147,8 +158,18 @@ public class PyRenameTest extends PyTestCase {
doTest("bar");
}
// PY-8857
public void testRenameImportSubModuleAs() {
doMultiFileTest("bar.py");
}
// PY-8857
public void testRenameImportModuleAs() {
doMultiFileTest("bar.py");
}
private void doRenameConflictTest(String newName, String expectedConflict) {
myFixture.configureByFile("refactoring/rename/" + getTestName(true) + ".py");
myFixture.configureByFile(RENAME_DATA_PATH + getTestName(true) + ".py");
try {
myFixture.renameElementAtCaret(newName);
}
@@ -160,8 +181,28 @@ public class PyRenameTest extends PyTestCase {
}
private void doTest(final String newName) {
myFixture.configureByFile("refactoring/rename/" + getTestName(true) + ".py");
myFixture.configureByFile(RENAME_DATA_PATH + getTestName(true) + ".py");
myFixture.renameElementAtCaret(newName);
myFixture.checkResultByFile("refactoring/rename/" + getTestName(true) + "_after.py");
myFixture.checkResultByFile(RENAME_DATA_PATH + getTestName(true) + "_after.py");
}
private void doMultiFileTest(String newName) {
final String testName = getTestName(true);
final VirtualFile dir1 = myFixture.copyDirectoryToProject(RENAME_DATA_PATH + testName + "/before", "");
PsiDocumentManager.getInstance(myFixture.getProject()).commitAllDocuments();
myFixture.configureFromTempProjectFile("a.py");
myFixture.renameElementAtCaret(newName);
VirtualFile dir2 = getVirtualFileByName(PythonTestUtil.getTestDataPath() + "/" + RENAME_DATA_PATH + testName + "/after");
try {
PlatformTestUtil.assertDirectoriesEqual(dir2, dir1, null);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
@Nullable
private static VirtualFile getVirtualFileByName(String fileName) {
return LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/'));
}
}