diff --git a/python/src/com/jetbrains/python/refactoring/PyRefactoringUtil.java b/python/src/com/jetbrains/python/refactoring/PyRefactoringUtil.java index d392eb8adb91..44bda58e9990 100644 --- a/python/src/com/jetbrains/python/refactoring/PyRefactoringUtil.java +++ b/python/src/com/jetbrains/python/refactoring/PyRefactoringUtil.java @@ -75,10 +75,10 @@ public class PyRefactoringUtil { // Check if selection breaks AST node in binary expression if (parent instanceof PyBinaryExpression) { final String selection = file.getText().substring(element1.getTextOffset(), element2.getTextOffset() + element2.getTextLength()); - final PyExpression expression = - PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyAssignmentStatement.class, "z=" + selection) - .getAssignedValue(); - if (PsiUtilBase.hasErrorElementChild(expression)) { + final PyElementGenerator generator = PyElementGenerator.getInstance(project); + final LanguageLevel langLevel = LanguageLevel.forElement(element1); + final PyExpression expression = generator.createFromText(langLevel, PyAssignmentStatement.class, "z=" + selection).getAssignedValue(); + if (PsiUtilBase.hasErrorElementChild(expression) || !(expression instanceof PyBinaryExpression)) { return null; } final String parentText = parent.getText(); @@ -91,13 +91,11 @@ public class PyRefactoringUtil { final String prefix = parentText.substring(0, startOffset); final String suffix = parentText.substring(endOffset, parentText.length()); final TextRange textRange = TextRange.from(startOffset, endOffset - startOffset); - final PsiElement fakeExpression = - PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), parent.getClass(), prefix + "python" + suffix); + final PsiElement fakeExpression = generator.createFromText(langLevel, parent.getClass(), prefix + "python" + suffix); if (PsiUtilBase.hasErrorElementChild(fakeExpression)) { return null; } - assert expression != null; expression.putUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE, Pair.create(parent, textRange)); return expression; } diff --git a/python/testData/refactoring/introduceVariable/oneSidedSelection.py b/python/testData/refactoring/introduceVariable/oneSidedSelection.py new file mode 100644 index 000000000000..a1c6d2b0a315 --- /dev/null +++ b/python/testData/refactoring/introduceVariable/oneSidedSelection.py @@ -0,0 +1 @@ +a = b + func() \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceVariableTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceVariableTest.java index c866b98a6cfb..d73eab1ab2ac 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceVariableTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceVariableTest.java @@ -45,6 +45,14 @@ public class PyIntroduceVariableTest extends PyIntroduceTestCase { } public void testIncorrectSelection() { // PY-4455 + doTestCannotPerform(); + } + + public void testOneSidedSelection() { // PY-4456 + doTestCannotPerform(); + } + + private void doTestCannotPerform() { boolean thrownExpectedException = false; try { doTest();