diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiExpressionTrimRenderer.java b/java/java-psi-api/src/com/intellij/psi/util/PsiExpressionTrimRenderer.java index 964b5fb67ed3..b6e2f6eb6d64 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiExpressionTrimRenderer.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiExpressionTrimRenderer.java @@ -150,6 +150,15 @@ public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisito expr.getArgumentList().accept(this); } + @Override + public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { + final PsiElement qualifier = expression.getQualifier(); + if (qualifier != null) { + qualifier.accept(this); + } + myBuf.append("::"); + myBuf.append(expression.getReferenceName()); + } @Override public void visitArrayInitializerExpression(final PsiArrayInitializerExpression expression) { diff --git a/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java b/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java index 5fbe67f56f1c..753ed4b59dec 100644 --- a/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java +++ b/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java @@ -179,9 +179,11 @@ public class AddImportHelper { * @param file where to operate * @param name which to import (qualified is OK) * @param asName optional name for 'as' clause + * @param anchor place where the imported name was used * @return whether import statement was actually added */ - public static boolean addImportStatement(PsiFile file, String name, @Nullable String asName, ImportPriority priority) { + public static boolean addImportStatement(PsiFile file, String name, @Nullable String asName, ImportPriority priority, + @Nullable PsiElement anchor) { if (!(file instanceof PyFile)) { return false; } @@ -198,8 +200,11 @@ public class AddImportHelper { final PyElementGenerator generator = PyElementGenerator.getInstance(file.getProject()); final LanguageLevel languageLevel = LanguageLevel.forElement(file); final PyImportStatement importNodeToInsert = generator.createImportStatement(languageLevel, name, asName); + final PyImportStatementBase importStatement = PsiTreeUtil.getParentOfType(anchor, PyImportStatementBase.class, false); + final PsiElement insertParent = importStatement != null && importStatement.getContainingFile() == file ? + importStatement.getParent() : file; try { - file.addBefore(importNodeToInsert, getInsertPosition(file, name, priority)); + insertParent.addBefore(importNodeToInsert, getInsertPosition(insertParent, name, priority)); } catch (IncorrectOperationException e) { LOG.error(e); @@ -283,12 +288,12 @@ public class AddImportHelper { if (qName == null) return; String path = qName.toString(); if (target instanceof PsiFileSystemItem && qName.getComponentCount() == 1) { - addImportStatement(file, path, null, priority); + addImportStatement(file, path, null, priority, element); } else { final QualifiedName toImportQName = QualifiedNameFinder.findCanonicalImportPath(toImport, element); if (useQualified) { - addImportStatement(file, path, null, priority); + addImportStatement(file, path, null, priority, element); final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(file.getProject()); final String targetName = PyUtil.getElementNameWithoutExtension(target); element.replace(elementGenerator.createExpressionFromText(LanguageLevel.forElement(target), toImportQName + "." + targetName)); diff --git a/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java b/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java index 09eb355e57a3..2a70fd643bb9 100644 --- a/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java +++ b/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java @@ -158,7 +158,7 @@ public class ImportFromExistingAction implements QuestionAction { if (myImportLocally) { AddImportHelper.addLocalImportStatement(myTarget, myName); } else { - AddImportHelper.addImportStatement(file, myName, null, priority); + AddImportHelper.addImportStatement(file, myName, null, priority, null); } } else { @@ -172,7 +172,7 @@ public class ImportFromExistingAction implements QuestionAction { AddImportHelper.addLocalImportStatement(myTarget, nameToImport); } else { - AddImportHelper.addImportStatement(file, nameToImport, null, priority); + AddImportHelper.addImportStatement(file, nameToImport, null, priority, null); } myTarget.replace(gen.createExpressionFromText(LanguageLevel.forElement(myTarget), qualifiedName + "." + myName)); } diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java index 0a07ffaac98d..e8c3da7fc5b3 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java @@ -321,7 +321,7 @@ public final class PyClassRefactoringUtil { return AddImportHelper.addImportFrom(file, null, containingQName.toString(), importedName, asName, priority, anchor); } else { - return AddImportHelper.addImportStatement(file, containingQName.append(importedName).toString(), asName, priority); + return AddImportHelper.addImportStatement(file, containingQName.append(importedName).toString(), asName, priority, anchor); } } diff --git a/python/testData/refactoring/move/conditionalImportFromPackage/after/src/mod1.py b/python/testData/refactoring/move/conditionalImportFromPackage/after/src/mod1.py new file mode 100644 index 000000000000..08f91c02004c --- /dev/null +++ b/python/testData/refactoring/move/conditionalImportFromPackage/after/src/mod1.py @@ -0,0 +1,6 @@ +if True: + import pkgutil +else: + import mod2 as pkgutil + +print(pkgutil) diff --git a/python/testData/refactoring/move/conditionalImportFromPackage/after/src/mod2.py b/python/testData/refactoring/move/conditionalImportFromPackage/after/src/mod2.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/conditionalImportFromPackage/after/src/pkg1/__init__.py b/python/testData/refactoring/move/conditionalImportFromPackage/after/src/pkg1/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/conditionalImportFromPackage/before/src/mod1.py b/python/testData/refactoring/move/conditionalImportFromPackage/before/src/mod1.py new file mode 100644 index 000000000000..16b31152f96e --- /dev/null +++ b/python/testData/refactoring/move/conditionalImportFromPackage/before/src/mod1.py @@ -0,0 +1,6 @@ +if True: + import pkgutil +else: + from pkg1 import mod2 as pkgutil + +print(pkgutil) diff --git a/python/testData/refactoring/move/conditionalImportFromPackage/before/src/pkg1/__init__.py b/python/testData/refactoring/move/conditionalImportFromPackage/before/src/pkg1/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/conditionalImportFromPackage/before/src/pkg1/mod2.py b/python/testData/refactoring/move/conditionalImportFromPackage/before/src/pkg1/mod2.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testSrc/com/jetbrains/python/PyAddImportTest.java b/python/testSrc/com/jetbrains/python/PyAddImportTest.java index 2b64e00064e1..5cedd4af2045 100644 --- a/python/testSrc/com/jetbrains/python/PyAddImportTest.java +++ b/python/testSrc/com/jetbrains/python/PyAddImportTest.java @@ -34,7 +34,7 @@ public class PyAddImportTest extends PyTestCase { new WriteCommandAction(myFixture.getProject(), myFixture.getFile()) { @Override protected void run(Result result) throws Throwable { - AddImportHelper.addImportStatement(myFixture.getFile(), "re", null, AddImportHelper.ImportPriority.BUILTIN); + AddImportHelper.addImportStatement(myFixture.getFile(), "re", null, AddImportHelper.ImportPriority.BUILTIN, null); } }.execute(); myFixture.checkResultByFile("addImport/addBuiltin.after.py"); diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java index e74c06260bc8..0e1a673b3e7f 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java @@ -139,6 +139,11 @@ public class PyMoveTest extends PyTestCase { doMoveFileTest("mod2.py", "pkg1"); } + // PY-13870 + public void testConditionalImportFromPackage() { + doMoveFileTest("pkg1/mod2.py", ""); + } + // PY-7378 public void testMoveNamespacePackage1() { runWithLanguageLevel(LanguageLevel.PYTHON33, new Runnable() {