From e53e8d8b0d5a67b923d79d94864d018131ccd78a Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Wed, 30 Nov 2011 14:45:22 +0400 Subject: [PATCH 1/4] Cleanup --- .../extractmethod/PyExtractMethodHandler.java | 10 +++--- .../extractmethod/PyExtractMethodUtil.java | 34 ++++++++++++------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodHandler.java b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodHandler.java index 0d39ea8356fe..d1d758503719 100644 --- a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodHandler.java +++ b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodHandler.java @@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable; * @author oleg */ public class PyExtractMethodHandler implements RefactoringActionHandler { - + @Override public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file, final DataContext dataContext) { editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); // select editor text fragment @@ -35,12 +35,11 @@ public class PyExtractMethodHandler implements RefactoringActionHandler { invokeOnEditor(project, editor, file); } - + @Override public void invoke(@NotNull final Project project, @NotNull final PsiElement[] elements, final DataContext dataContext) { - // ignore this } - private void invokeOnEditor(final Project project, final Editor editor, final PsiFile file) { + private static void invokeOnEditor(final Project project, final Editor editor, final PsiFile file) { CommonRefactoringUtil.checkReadOnlyStatus(project, file); PsiElement element1 = null; PsiElement element2 = null; @@ -112,7 +111,7 @@ public class PyExtractMethodHandler implements RefactoringActionHandler { } @Nullable - private PsiElement[] getStatementsRange(final PsiElement element1, final PsiElement element2) { + private static PsiElement[] getStatementsRange(final PsiElement element1, final PsiElement element2) { final PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2); if (parent == null) { return null; @@ -136,5 +135,4 @@ public class PyExtractMethodHandler implements RefactoringActionHandler { } return null; } - } diff --git a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java index bf8c95f91033..69b6d60d18cb 100644 --- a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java +++ b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java @@ -2,6 +2,7 @@ package com.jetbrains.python.refactoring.extractmethod; import com.intellij.codeInsight.codeFragment.CodeFragment; import com.intellij.lang.LanguageNamesValidation; +import com.intellij.lang.refactoring.NamesValidator; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; @@ -45,7 +46,6 @@ import java.util.Map; * @author oleg */ public class PyExtractMethodUtil { - public static final String NAME = "extract.method.name"; private PyExtractMethodUtil() { @@ -108,16 +108,17 @@ public class PyExtractMethodUtil { builder.append("(").append(createCallArgsString(variableData)).append(")"); PsiElement callElement = PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyCallExpression.class, builder.toString()); - //# replace statements with call + // Replace statements with call callElement = replaceElements(elementsRange, callElement); - // # Set editor + // Set editor setSelectionAndCaret(editor, callElement); } }); } }, "Extract method", null); - } else { + } + else { CommandProcessor.getInstance().executeCommand(project, new Runnable() { public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -210,8 +211,10 @@ public class PyExtractMethodUtil { if (fragment.getOutputVariables().isEmpty()) { CommandProcessor.getInstance().executeCommand(project, new Runnable() { + @Override public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override public void run() { // Generate method PyFunction generatedMethod = generateMethodFromExpression(project, methodName, variableData, expression, flags); @@ -234,7 +237,9 @@ public class PyExtractMethodUtil { PsiElement callElement = fragment.isReturnInstructionInside() ? returnStatement : returnStatement.getExpression(); // replace statements with call - callElement = PyPsiUtils.replaceExpression(expression, callElement); + if (callElement != null) { + callElement = PyPsiUtils.replaceExpression(expression, callElement); + } // Set editor setSelectionAndCaret(editor, callElement); @@ -372,15 +377,18 @@ public class PyExtractMethodUtil { addFakeParameters(builder, variableData); final PyFunction method = builder.buildFunction(project, LanguageLevel.getDefault()); final PyStatementList statementList = method.getStatementList(); - + assert statementList != null; for (PsiElement element : elementsRange) { - if (element instanceof PsiWhiteSpace){ + if (element instanceof PsiWhiteSpace) { continue; } statementList.add(element); } // remove last instruction - statementList.getFirstChild().delete(); + final PsiElement child = statementList.getFirstChild(); + if (child != null) { + child.delete(); + } return method; } @@ -406,15 +414,15 @@ public class PyExtractMethodUtil { final PsiElement element, final boolean isClassMethod, final boolean isStaticMethod) { - final ExtractMethodValidator validator = new PyExtractMethodValidator(element, project); - if (ApplicationManager.getApplication().isUnitTestMode()){ + final ExtractMethodValidator validator = new PyExtractMethodValidator(element, project); + if (ApplicationManager.getApplication().isUnitTestMode()) { String name = System.getProperty(NAME); if (name == null){ name = "foo"; } final String error = validator.check(name); if (error != null){ - if (ApplicationManager.getApplication().isUnitTestMode()){ + if (ApplicationManager.getApplication().isUnitTestMode()) { throw new CommonRefactoringUtil.RefactoringErrorHintException(error); } final StringBuilder builder = new StringBuilder(); @@ -517,7 +525,9 @@ public class PyExtractMethodUtil { } public boolean isValidName(final String name) { - return LanguageNamesValidation.INSTANCE.forLanguage(PythonLanguage.getInstance()).isIdentifier(name, myProject); + final NamesValidator validator = LanguageNamesValidation.INSTANCE.forLanguage(PythonLanguage.getInstance()); + assert validator != null; + return validator.isIdentifier(name, myProject); } } } From 904a1be8ba3d9eb96952fc76ced3ee7b5534b3a7 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Wed, 30 Nov 2011 15:07:24 +0400 Subject: [PATCH 2/4] Fixed extract method for assert type instructions in CFG (PY-5123) --- .../codeInsight/codeFragment/PyCodeFragmentUtil.java | 4 ++++ .../refactoring/extractmethod/methodInIf.after.py | 10 ++++++++++ .../refactoring/extractmethod/methodInIf.before.py | 7 +++++++ .../python/refactoring/PyExtractMethodTest.java | 5 +++++ 4 files changed, 26 insertions(+) create mode 100644 python/testData/refactoring/extractmethod/methodInIf.after.py create mode 100644 python/testData/refactoring/extractmethod/methodInIf.before.py diff --git a/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java b/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java index c58cade63a2b..0d3be71ba1dc 100644 --- a/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java @@ -11,6 +11,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.HashSet; import com.jetbrains.python.PyBundle; import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; +import com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyBinaryExpressionNavigator; @@ -76,6 +77,9 @@ public class PyCodeFragmentUtil { if (next instanceof ConditionalInstruction){ continue; } + if (next instanceof ReadWriteInstruction && ((ReadWriteInstruction)next).getAccess().isAssertTypeAccess()) { + continue; + } final PsiElement nextElement = next.getElement(); // Ignore binary operations control flow if (nextElement != null && PyBinaryExpressionNavigator.getBinaryExpressionByOperand(nextElement) != null){ diff --git a/python/testData/refactoring/extractmethod/methodInIf.after.py b/python/testData/refactoring/extractmethod/methodInIf.after.py new file mode 100644 index 000000000000..56a5e579abfa --- /dev/null +++ b/python/testData/refactoring/extractmethod/methodInIf.after.py @@ -0,0 +1,10 @@ +class C: + def baz(self, arg_new): + self.bar(arg_new) + + def foo(self, option, arg): + if option: + self.baz(arg) + + def bar(self, arg): + pass \ No newline at end of file diff --git a/python/testData/refactoring/extractmethod/methodInIf.before.py b/python/testData/refactoring/extractmethod/methodInIf.before.py new file mode 100644 index 000000000000..c4011231c895 --- /dev/null +++ b/python/testData/refactoring/extractmethod/methodInIf.before.py @@ -0,0 +1,7 @@ +class C: + def foo(self, option, arg): + if option: + self.bar(arg) + + def bar(self, arg): + pass \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java index dabbf42061bf..2827d4b074de 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java @@ -147,4 +147,9 @@ public class PyExtractMethodTest extends LightMarkedTestCase { public void testStaticMethod() { doTest("staticmethod.before.py", "baz", "staticmethod.after.py"); } + + // PY-5123 + public void testMethodInIf() { + doTest("methodInIf.before.py", "baz", "methodInIf.after.py"); + } } From 8cc8253c40dfad85e0bcdd172cae1c0288be5eff Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Wed, 30 Nov 2011 16:17:12 +0400 Subject: [PATCH 3/4] Fixed bug in generating builtin skeletons in case of errors --- python/helpers/generator3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py index b737a3def8ff..296fc406fa8a 100644 --- a/python/helpers/generator3.py +++ b/python/helpers/generator3.py @@ -2434,7 +2434,7 @@ if __name__ == "__main__": names.remove('__main__') # we don't want ourselves processed ok = True for name in names: - ok = ok and processOne(name, None, True) + ok = processOne(name, None, True) and ok if not ok: sys.exit(1) From c6bf564628484c31278441a38a5855dd93cdd974 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Wed, 30 Nov 2011 16:20:02 +0400 Subject: [PATCH 4/4] Fixed determining PyPy interpreter name (PY-5097) --- .../com/jetbrains/python/sdk/IronPythonSdkFlavor.java | 2 +- .../src/com/jetbrains/python/sdk/JythonSdkFlavor.java | 2 +- .../src/com/jetbrains/python/sdk/PyPySdkFlavor.java | 2 +- .../src/com/jetbrains/python/sdk/PythonSdkFlavor.java | 11 +++++++---- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/python/src/com/jetbrains/python/sdk/IronPythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/IronPythonSdkFlavor.java index 6598c72b4907..bbb08aae87e9 100644 --- a/python/src/com/jetbrains/python/sdk/IronPythonSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/IronPythonSdkFlavor.java @@ -49,7 +49,7 @@ public class IronPythonSdkFlavor extends PythonSdkFlavor { @Override public String getVersionString(String sdkHome) { - return "IronPython " + getVersionFromOutput(sdkHome, "-V", "\\w+ ([0-9\\.]+).*", true); + return "IronPython " + getVersionFromOutput(sdkHome, "-V", "\\w+ ([0-9\\.]+).*"); } @Override diff --git a/python/src/com/jetbrains/python/sdk/JythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/JythonSdkFlavor.java index a3a7da4e822b..70e5b9624bac 100644 --- a/python/src/com/jetbrains/python/sdk/JythonSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/JythonSdkFlavor.java @@ -36,7 +36,7 @@ public class JythonSdkFlavor extends PythonSdkFlavor { @Override public String getVersionString(String sdkHome) { - return getVersionFromOutput(sdkHome, "--version", "(Jython \\S+)( on .*)?", false); + return getVersionFromOutput(sdkHome, "--version", "(Jython \\S+)( on .*)?"); } @Override diff --git a/python/src/com/jetbrains/python/sdk/PyPySdkFlavor.java b/python/src/com/jetbrains/python/sdk/PyPySdkFlavor.java index cf5ea8c54919..5f69d18c5ad2 100644 --- a/python/src/com/jetbrains/python/sdk/PyPySdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/PyPySdkFlavor.java @@ -21,6 +21,6 @@ public class PyPySdkFlavor extends PythonSdkFlavor { @Override public String getVersionString(String sdkHome) { - return getVersionFromOutput(sdkHome, "--version", "\\[(PyPy .+)\\]", true); + return getVersionFromOutput(sdkHome, "--version", "\\[(PyPy [^ ]+).*\\]"); } } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java index 7a1be292bb38..5a394f3f3e9d 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java @@ -80,11 +80,11 @@ public abstract class PythonSdkFlavor { @Nullable public String getVersionString(String sdkHome) { - return getVersionFromOutput(sdkHome, "-V", "(Python \\S+).*", false); + return getVersionFromOutput(sdkHome, "-V", "(Python \\S+).*"); } @Nullable - protected static String getVersionFromOutput(String sdkHome, String version_opt, String version_regexp, boolean stdout) { + protected static String getVersionFromOutput(String sdkHome, String version_opt, String version_regexp) { Pattern pattern = Pattern.compile(version_regexp); String run_dir = new File(sdkHome).getParent(); final ProcessOutput process_output = SdkUtil.getProcessOutput(run_dir, new String[]{sdkHome, version_opt}); @@ -97,8 +97,11 @@ public abstract class PythonSdkFlavor { ); return null; } - final List lines = stdout ? process_output.getStdoutLines() : process_output.getStderrLines(); - return SdkUtil.getFirstMatch(lines, pattern); + final String result = SdkUtil.getFirstMatch(process_output.getStderrLines(), pattern); + if (result != null) { + return result; + } + return SdkUtil.getFirstMatch(process_output.getStdoutLines(), pattern); } public Collection getExtraDebugOptions() {