From 286cc42881d324cb20b1499a7e194dc33663eaf5 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 12 Dec 2012 16:08:11 +0400 Subject: [PATCH] fixed PY-8200 Introduce parameter: do not allow refactoring when there is local variable in the selection --- .../PyIntroduceParameterHandler.java | 36 +++++++++---------- .../introduceParameter/localVariable.py | 3 ++ .../refactoring/PyIntroduceParameterTest.java | 4 +++ 3 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 python/testData/refactoring/introduceParameter/localVariable.py diff --git a/python/src/com/jetbrains/python/refactoring/introduce/parameter/PyIntroduceParameterHandler.java b/python/src/com/jetbrains/python/refactoring/introduce/parameter/PyIntroduceParameterHandler.java index 65d1114888da..5fb57aea831d 100644 --- a/python/src/com/jetbrains/python/refactoring/introduce/parameter/PyIntroduceParameterHandler.java +++ b/python/src/com/jetbrains/python/refactoring/introduce/parameter/PyIntroduceParameterHandler.java @@ -1,15 +1,14 @@ package com.jetbrains.python.refactoring.introduce.parameter; import com.intellij.codeInsight.CodeInsightUtilBase; -import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduce.inplace.InplaceVariableIntroducer; -import com.intellij.refactoring.util.CommonRefactoringUtil; import com.jetbrains.python.PyBundle; +import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; +import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; +import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.refactoring.introduce.IntroduceHandler; @@ -60,24 +59,25 @@ public class PyIntroduceParameterHandler extends IntroduceHandler { return PyPsiUtils.replaceExpression(expression, newExpression); } - @Override - protected boolean checkIntroduceContext(PsiFile file, Editor editor, PsiElement element) { + protected boolean isValidIntroduceContext(PsiElement element) { if (element != null) { final PyFunction function = PsiTreeUtil.getParentOfType(element, PyFunction.class); - if (function == null) { - CommonRefactoringUtil.showErrorHint(file.getProject(), editor, - "Introduce Parameter refactoring cannot be performed outside any function", - RefactoringBundle.message("introduce.parameter.title"), null); - return false; - } - if (isResolvedToParameter(element)) { - CommonRefactoringUtil.showErrorHint(file.getProject(), editor, - PyBundle.message("refactoring.introduce.selection.error"), - RefactoringBundle.message("introduce.parameter.title"), null); - return false; + final ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(element); + final boolean[] isValid = {true}; + if (scopeOwner != null) { + new PyRecursiveElementVisitor() { + @Override + public void visitPyReferenceExpression(PyReferenceExpression node) { + super.visitPyReferenceExpression(node); + if (ControlFlowCache.getScope(scopeOwner).containsDeclaration(node.getName())) { + isValid[0] = false; + } + } + }.visitElement(element); } + return function != null && !isResolvedToParameter(element) && isValid[0]; } - return super.checkIntroduceContext(file, editor, element); + return false; } private boolean isResolvedToParameter(PsiElement element) { diff --git a/python/testData/refactoring/introduceParameter/localVariable.py b/python/testData/refactoring/introduceParameter/localVariable.py new file mode 100644 index 000000000000..a1f9d46d8a0b --- /dev/null +++ b/python/testData/refactoring/introduceParameter/localVariable.py @@ -0,0 +1,3 @@ +def f(): + a = 1 + print a + 3 \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceParameterTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceParameterTest.java index 972b414ce359..19047fc12fea 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceParameterTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceParameterTest.java @@ -31,6 +31,10 @@ public class PyIntroduceParameterTest extends PyIntroduceTestCase { doTest(); } + public void testLocalVariable() { + doTestCannotPerform(PyBundle.message("refactoring.introduce.selection.error")); + } + @Override protected String getTestDataPath() { return super.getTestDataPath() + "/refactoring/introduceParameter";