From 566faf4602c4f7725bb6e096a6f411b6682b20db Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Tue, 16 Jun 2015 17:45:26 +0300 Subject: [PATCH] PY-14617 Update references to modules imported via relative imports inside the moved module Current solution is very crude, because we can't use standard IDE facilities to find usages of the import element in the a file, once that file was moved. And exactly that API MoveFileHandler offers to us. --- .../psi/resolve/RatedResolveResult.java | 2 +- .../refactoring/move/PyMoveFileHandler.java | 21 +++++++++++++++++++ .../after/src/m1.py | 5 +++++ .../after/src/pkg/__init__.py | 0 .../after/src/pkg/m2.py | 1 + .../after/src/pkg/subpkg/__init__.py | 0 .../after/src/pkg/subpkg/m3.py | 0 .../before/src/pkg/__init__.py | 0 .../before/src/pkg/m1.py | 5 +++++ .../before/src/pkg/m2.py | 1 + .../before/src/pkg/subpkg/__init__.py | 0 .../before/src/pkg/subpkg/m3.py | 0 .../python/refactoring/PyMoveTest.java | 5 +++++ 13 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/m1.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/__init__.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/m2.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/subpkg/__init__.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/subpkg/m3.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/__init__.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/m1.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/m2.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/subpkg/__init__.py create mode 100644 python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/subpkg/m3.py diff --git a/python/psi-api/src/com/jetbrains/python/psi/resolve/RatedResolveResult.java b/python/psi-api/src/com/jetbrains/python/psi/resolve/RatedResolveResult.java index 47a28f8f6b34..8485d2f45cb1 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/resolve/RatedResolveResult.java +++ b/python/psi-api/src/com/jetbrains/python/psi/resolve/RatedResolveResult.java @@ -61,7 +61,7 @@ public class RatedResolveResult implements ResolveResult { @Override public String toString() { - return myWhat.toString() + "@" + myRate; + return String.valueOf(myWhat) + "@" + myRate; } /** diff --git a/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java b/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java index bf6c8b5b78e9..2a84ab0cbc1d 100644 --- a/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java +++ b/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java @@ -16,6 +16,7 @@ package com.jetbrains.python.refactoring.move; import com.intellij.lang.injection.InjectedLanguageManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; @@ -33,6 +34,8 @@ import com.jetbrains.python.PyNames; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.PythonFileType; import com.jetbrains.python.actions.CreatePackageAction; +import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; +import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.codeInsight.imports.PyImportOptimizer; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.resolve.PyResolveContext; @@ -117,6 +120,24 @@ public class PyMoveFileHandler extends MoveFileHandler { } final QualifiedName newName = QualifiedNameFinder.findShortestImportableQName(resolved); replaceWithQualifiedExpression(referenceExpr, newName); + final QualifiedName oldQualifiedName = referenceExpr.asQualifiedName(); + if (!Comparing.equal(oldQualifiedName, newName)) { + final ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(importElement); + if (scopeOwner == null) { + continue; + } + scopeOwner.accept(new PyRecursiveElementVisitor() { + @Override + public void visitPyReferenceExpression(PyReferenceExpression node) { + if (Comparing.equal(node.asQualifiedName(), oldQualifiedName)) { + replaceWithQualifiedExpression(node, newName); + } + else { + super.visitPyReferenceExpression(node); + } + } + }); + } } } diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/m1.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/m1.py new file mode 100644 index 000000000000..39023e306dfa --- /dev/null +++ b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/m1.py @@ -0,0 +1,5 @@ +import pkg.m2 +import pkg.subpkg.m3 + + +print(pkg.m2, pkg.subpkg.m3.VAR) diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/__init__.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/m2.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/m2.py new file mode 100644 index 000000000000..fe5433bef744 --- /dev/null +++ b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/m2.py @@ -0,0 +1 @@ +VAR = 42 \ No newline at end of file diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/subpkg/__init__.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/subpkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/subpkg/m3.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/after/src/pkg/subpkg/m3.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/__init__.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/m1.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/m1.py new file mode 100644 index 000000000000..73a72c8c26cb --- /dev/null +++ b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/m1.py @@ -0,0 +1,5 @@ +import m2 +import subpkg.m3 + + +print(m2, subpkg.m3.VAR) diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/m2.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/m2.py new file mode 100644 index 000000000000..fe5433bef744 --- /dev/null +++ b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/m2.py @@ -0,0 +1 @@ +VAR = 42 \ No newline at end of file diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/subpkg/__init__.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/subpkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/subpkg/m3.py b/python/testData/refactoring/move/usagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule/before/src/pkg/subpkg/m3.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java index 86ac0e56da3a..91db92b20a1b 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java @@ -329,6 +329,11 @@ public class PyMoveTest extends PyTestCase { doMoveFileTest("pkg/subpkg", ""); } + // PY-14617 + public void testUsagesOfUnqualifiedOldStyleRelativeImportsInsideMovedModule() { + doMoveFileTest("pkg/m1.py", ""); + } + // PY-15324 public void testInterdependentSymbols() { doMoveSymbolsTest("b.py", "f", "A");