From 24c1a13db00b73885b70bc5e705e143b7e45ee30 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Mon, 16 May 2011 15:05:41 +0400 Subject: [PATCH 1/6] Fixed bug in control flow ordering for named function arguments --- .../controlflow/PyControlFlowBuilder.java | 4 +- .../codeInsight/controlflow/function.py | 2 +- .../codeInsight/controlflow/function.txt | 85 ++++++++++--------- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java index 28a3a7bf1eb0..cdda3784820f 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java @@ -159,12 +159,12 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { @Override public void visitPyNamedParameter(final PyNamedParameter node) { - final ReadWriteInstruction instruction = ReadWriteInstruction.write(myBuilder, node, node.getName()); - myBuilder.addNode(instruction); final PyExpression defaultValue = node.getDefaultValue(); if (defaultValue != null) { defaultValue.accept(this); } + final ReadWriteInstruction instruction = ReadWriteInstruction.write(myBuilder, node, node.getName()); + myBuilder.addNode(instruction); myBuilder.checkPending(instruction); } diff --git a/python/testData/codeInsight/controlflow/function.py b/python/testData/codeInsight/controlflow/function.py index e23c5cffc3eb..94a025bd8b14 100644 --- a/python/testData/codeInsight/controlflow/function.py +++ b/python/testData/codeInsight/controlflow/function.py @@ -1,4 +1,4 @@ -def help(object, spacing=10, collapse=1): +def help(object, spacing=foo, collapse=1): """Выводит методы и строки документации. В качестве аргумента может использоваться модуль, класс, список, словарь diff --git a/python/testData/codeInsight/controlflow/function.txt b/python/testData/codeInsight/controlflow/function.txt index 3cc397d79d4b..1d86cdc55796 100644 --- a/python/testData/codeInsight/controlflow/function.txt +++ b/python/testData/codeInsight/controlflow/function.txt @@ -1,44 +1,45 @@ 0(1) element: null 1(2) WRITE ACCESS: object -2(3) WRITE ACCESS: spacing -3(4) WRITE ACCESS: collapse -4(5) element: PyExpressionStatement -5(6) element: PyAssignmentStatement -6(7) element: PyListCompExpression -7(8) element: PyCallExpression: dir -8(9) READ ACCESS: dir -9(10,19) READ ACCESS: object -10(11) element: PyTargetExpression: method -11(12) WRITE ACCESS: method -12(13) element: PyCallExpression: callable -13(14) READ ACCESS: callable -14(15) READ ACCESS: getattr -15(16) READ ACCESS: object -16(10,17,19) READ ACCESS: method -17(18) element: PyReferenceExpression: method. Condition: callable(getattr(object, method)):true -18(10,19) READ ACCESS: method -19(20) WRITE ACCESS: methodList -20(21) element: PyAssignmentStatement -21(22) READ ACCESS: collapse -22(23) element: PyLambdaExpression -23(24) WRITE ACCESS: s -24(25) READ ACCESS: s -25(26) element: PyLambdaExpression -26(27) WRITE ACCESS: s -27(28) READ ACCESS: s -28(29) WRITE ACCESS: processFunc -29(30) element: PyPrintStatement -30(31) element: PyListCompExpression -31(32) element: PyReferenceExpression: methodList -32(33,43) READ ACCESS: methodList -33(34) element: PyTargetExpression: method -34(35) WRITE ACCESS: method -35(36) element: PyBinaryExpression -36(37) READ ACCESS: method -37(38) READ ACCESS: spacing -38(39) READ ACCESS: processFunc -39(40) READ ACCESS: str -40(41) READ ACCESS: getattr -41(42) READ ACCESS: object -42(33,43) READ ACCESS: method -43() element: null \ No newline at end of file +2(3) READ ACCESS: foo +3(4) WRITE ACCESS: spacing +4(5) WRITE ACCESS: collapse +5(6) element: PyExpressionStatement +6(7) element: PyAssignmentStatement +7(8) element: PyListCompExpression +8(9) element: PyCallExpression: dir +9(10) READ ACCESS: dir +10(11,20) READ ACCESS: object +11(12) element: PyTargetExpression: method +12(13) WRITE ACCESS: method +13(14) element: PyCallExpression: callable +14(15) READ ACCESS: callable +15(16) READ ACCESS: getattr +16(17) READ ACCESS: object +17(11,18,20) READ ACCESS: method +18(19) element: PyReferenceExpression: method. Condition: callable(getattr(object, method)):true +19(11,20) READ ACCESS: method +20(21) WRITE ACCESS: methodList +21(22) element: PyAssignmentStatement +22(23) READ ACCESS: collapse +23(24) element: PyLambdaExpression +24(25) WRITE ACCESS: s +25(26) READ ACCESS: s +26(27) element: PyLambdaExpression +27(28) WRITE ACCESS: s +28(29) READ ACCESS: s +29(30) WRITE ACCESS: processFunc +30(31) element: PyPrintStatement +31(32) element: PyListCompExpression +32(33) element: PyReferenceExpression: methodList +33(34,44) READ ACCESS: methodList +34(35) element: PyTargetExpression: method +35(36) WRITE ACCESS: method +36(37) element: PyBinaryExpression +37(38) READ ACCESS: method +38(39) READ ACCESS: spacing +39(40) READ ACCESS: processFunc +40(41) READ ACCESS: str +41(42) READ ACCESS: getattr +42(43) READ ACCESS: object +43(34,44) READ ACCESS: method +44() element: null \ No newline at end of file From 776455661ce1e75d308bc9afe21dc399c602fc08 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Mon, 16 May 2011 15:13:28 +0400 Subject: [PATCH 2/6] Fixed bug in scoping rules for references in default function argument values (PY-3550) --- .../python/codeInsight/dataflow/scope/ScopeUtil.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/codeInsight/dataflow/scope/ScopeUtil.java b/python/src/com/jetbrains/python/codeInsight/dataflow/scope/ScopeUtil.java index db362f5e6e2d..5c769e20a430 100644 --- a/python/src/com/jetbrains/python/codeInsight/dataflow/scope/ScopeUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/dataflow/scope/ScopeUtil.java @@ -46,8 +46,14 @@ public class ScopeUtil { @Nullable public static ScopeOwner getDeclarationScopeOwner(PyReferenceExpression node) { final String name = node.getName(); + PsiElement element = node; if (name != null) { - ScopeOwner owner = PsiTreeUtil.getParentOfType(node, ScopeOwner.class); + // References in default values of parameters are defined somewhere in outer scopes + if (PsiTreeUtil.getParentOfType(node, PyParameter.class) != null) { + element = PsiTreeUtil.getParentOfType(node, ScopeOwner.class); + } + + ScopeOwner owner = PsiTreeUtil.getParentOfType(element, ScopeOwner.class); while (owner != null) { Scope scope = ControlFlowCache.getScope(owner); if (scope.containsDeclaration(name)) { From f0b36684cd7f929b12d00481aa9e58022770a471 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Mon, 16 May 2011 15:38:56 +0400 Subject: [PATCH 3/6] Fixed default arguments scoping in unbound locals inspection (PY-3550) --- .../inspections/PyUnboundLocalVariableInspection.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java b/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java index 4133b84e6baa..66e02a4104bc 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java @@ -17,6 +17,7 @@ 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.codeInsight.dataflow.scope.Scope; +import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeVariable; import com.jetbrains.python.console.PydevConsoleRunner; import com.jetbrains.python.psi.*; @@ -56,8 +57,12 @@ public class PyUnboundLocalVariableInspection extends PyInspection { if (PyImportStatementNavigator.getImportStatementByElement(node) != null){ return; } - final ScopeOwner owner = PsiTreeUtil.getParentOfType(node, ScopeOwner.class); - if (owner == null){ + final ScopeOwner owner = ScopeUtil.getDeclarationScopeOwner(node); + if (owner == null) { + return; + } + // Ignore references declared in outer scopes + if (owner != PsiTreeUtil.getParentOfType(node, ScopeOwner.class)) { return; } final String name = node.getReferencedName(); From d6ab1ad0b504a259429a0f37789c2b5e8d57bc39 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Mon, 16 May 2011 18:14:30 +0400 Subject: [PATCH 4/6] Lambda expressions became ScopeOwners and got their own CFG (PY-3532) --- .../controlflow/PyControlFlowBuilder.java | 19 ---------- .../PyUnusedLocalInspectionVisitor.java | 2 +- .../python/psi/PyLambdaExpression.java | 3 +- .../psi/impl/PyLambdaExpressionImpl.java | 7 ++++ .../codeInsight/controlflow/function.txt | 38 +++++++++---------- .../codeInsight/controlflow/lambda.txt | 9 ++--- 6 files changed, 30 insertions(+), 48 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java index cdda3784820f..700d30719949 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java @@ -610,25 +610,6 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { @Override public void visitPyLambdaExpression(final PyLambdaExpression node) { myBuilder.startNode(node); - for (PyParameter parameter : node.getParameterList().getParameters()){ - final PyExpression value = parameter.getDefaultValue(); - if (value != null){ - value.accept(this); - } - final PyNamedParameter namedParameter = parameter.getAsNamed(); - if (namedParameter != null){ - final PsiElement paramName = namedParameter.getFirstChild(); - final ReadWriteInstruction instruction = ReadWriteInstruction.newInstruction(myBuilder, paramName, - parameter.getName(), - ReadWriteInstruction.ACCESS.WRITE); - myBuilder.addNode(instruction); - myBuilder.checkPending(instruction); - } - } - final PyExpression body = node.getBody(); - if (body != null){ - body.accept(this); - } } @Override diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java index b1d30a0ecec5..7918113161f2 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java +++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java @@ -69,7 +69,7 @@ class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { @Override public void visitPyLambdaExpression(final PyLambdaExpression node) { - processScope(PsiTreeUtil.getParentOfType(node, ScopeOwner.class), node); + processScope(node, node); } static class DontPerformException extends RuntimeException {} diff --git a/python/src/com/jetbrains/python/psi/PyLambdaExpression.java b/python/src/com/jetbrains/python/psi/PyLambdaExpression.java index 813a6f593068..ffb542639e41 100644 --- a/python/src/com/jetbrains/python/psi/PyLambdaExpression.java +++ b/python/src/com/jetbrains/python/psi/PyLambdaExpression.java @@ -1,11 +1,12 @@ package com.jetbrains.python.psi; +import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import org.jetbrains.annotations.Nullable; /** * @author yole */ -public interface PyLambdaExpression extends PyExpression, Callable { +public interface PyLambdaExpression extends PyExpression, Callable, ScopeOwner { @Nullable PyExpression getBody(); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java index 58c190a44534..c2fd8e0a7ca7 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java @@ -6,6 +6,7 @@ import com.intellij.psi.ResolveState; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.PyElementTypes; +import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; @@ -57,6 +58,12 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp return processParamLayer(parameters, processor, state, lastParent); } + @Override + public void subtreeChanged() { + super.subtreeChanged(); + ControlFlowCache.clear(this); + } + private boolean processParamLayer(@NotNull final PyParameter[] parameters, @NotNull final PsiScopeProcessor processor, @NotNull final ResolveState state, diff --git a/python/testData/codeInsight/controlflow/function.txt b/python/testData/codeInsight/controlflow/function.txt index 1d86cdc55796..6b674b44d6de 100644 --- a/python/testData/codeInsight/controlflow/function.txt +++ b/python/testData/codeInsight/controlflow/function.txt @@ -22,24 +22,20 @@ 21(22) element: PyAssignmentStatement 22(23) READ ACCESS: collapse 23(24) element: PyLambdaExpression -24(25) WRITE ACCESS: s -25(26) READ ACCESS: s -26(27) element: PyLambdaExpression -27(28) WRITE ACCESS: s -28(29) READ ACCESS: s -29(30) WRITE ACCESS: processFunc -30(31) element: PyPrintStatement -31(32) element: PyListCompExpression -32(33) element: PyReferenceExpression: methodList -33(34,44) READ ACCESS: methodList -34(35) element: PyTargetExpression: method -35(36) WRITE ACCESS: method -36(37) element: PyBinaryExpression -37(38) READ ACCESS: method -38(39) READ ACCESS: spacing -39(40) READ ACCESS: processFunc -40(41) READ ACCESS: str -41(42) READ ACCESS: getattr -42(43) READ ACCESS: object -43(34,44) READ ACCESS: method -44() element: null \ No newline at end of file +24(25) element: PyLambdaExpression +25(26) WRITE ACCESS: processFunc +26(27) element: PyPrintStatement +27(28) element: PyListCompExpression +28(29) element: PyReferenceExpression: methodList +29(30,40) READ ACCESS: methodList +30(31) element: PyTargetExpression: method +31(32) WRITE ACCESS: method +32(33) element: PyBinaryExpression +33(34) READ ACCESS: method +34(35) READ ACCESS: spacing +35(36) READ ACCESS: processFunc +36(37) READ ACCESS: str +37(38) READ ACCESS: getattr +38(39) READ ACCESS: object +39(30,40) READ ACCESS: method +40() element: null \ No newline at end of file diff --git a/python/testData/codeInsight/controlflow/lambda.txt b/python/testData/codeInsight/controlflow/lambda.txt index 1a740c2d5ed7..0a48427a36b7 100644 --- a/python/testData/codeInsight/controlflow/lambda.txt +++ b/python/testData/codeInsight/controlflow/lambda.txt @@ -2,12 +2,9 @@ 1(2) element: PyExpressionStatement 2(3) element: PySetCompExpression 3(4) element: PyCallExpression: range -4(5,12) READ ACCESS: range +4(5,9) READ ACCESS: range 5(6) element: PyTargetExpression: i 6(7) WRITE ACCESS: i 7(8) element: PyParenthesizedExpression -8(9) element: PyLambdaExpression -9(10) READ ACCESS: i -10(11) WRITE ACCESS: i -11(5,12) READ ACCESS: i -12() element: null \ No newline at end of file +8(5,9) element: PyLambdaExpression +9() element: null \ No newline at end of file From 33e061f81acfbc41412389e0f7b3b3c380841e12 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Mon, 16 May 2011 19:18:56 +0400 Subject: [PATCH 5/6] Improved GUI captions and added help ID for move class refactoring (PY-3561) --- .../src/com/jetbrains/python/PyBundle.properties | 6 +++--- .../move/PyMoveClassOrFunctionDialog.java | 5 +++++ .../move/PyMoveClassOrFunctionPanel.form | 16 ++++------------ 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index 3b4ad8e3c0e7..b1e8613ed4cb 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -444,9 +444,9 @@ refactoring.extract.super.name.0.must.be.ident=Name ''{0}'' is invalid.
Must # move refactoring.move.class.or.function=Move class or function refactoring.move.class.or.function.dialog.title=Move Class or Function -refactoring.move.class.$0=Move class {0} -refactoring.move.function.$0=Move function {0}() -refactoring.move.selected.elements=Move selected elements +refactoring.move.class.$0=Move class {0} to file: +refactoring.move.function.$0=Move function {0}() to file: +refactoring.move.selected.elements=Move selected elements to file: refactoring.move.class.or.function.choose.destination.file.title=Choose Destination File refactoring.move.class.or.function.to.file=To file: refactoring.move.class.or.function.error.cannot.place.elements.into.nonpython.file=Cannot place elements into a non-Python file diff --git a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDialog.java b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDialog.java index 90d7ad196b9a..cb3d90dcb185 100644 --- a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDialog.java +++ b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDialog.java @@ -80,6 +80,11 @@ public class PyMoveClassOrFunctionDialog extends RefactoringDialog { close(OK_EXIT_CODE); } + @Override + protected String getHelpId() { + return "refactoring.moveClass"; + } + private static String getContainingFileName(PsiElement element) { VirtualFile file = element.getContainingFile().getVirtualFile(); if (file != null) { diff --git a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionPanel.form b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionPanel.form index 888dd271ad46..2129e087538b 100644 --- a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionPanel.form +++ b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionPanel.form @@ -6,11 +6,11 @@ - + - + @@ -20,7 +20,7 @@ - + @@ -33,18 +33,10 @@ - + - - - - - - - - From 9c1926858ddf4da12a5a6780661d41d1867a97df Mon Sep 17 00:00:00 2001 From: Dmitry Cheryasov Date: Mon, 16 May 2011 18:36:47 +0300 Subject: [PATCH 6/6] PY-1894: frozenset signature fixed --- python/helpers/generator3.py | 4 ++-- python/helpers/required_gen_version | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py index 29230c2aa25e..651eb999151e 100644 --- a/python/helpers/generator3.py +++ b/python/helpers/generator3.py @@ -24,7 +24,7 @@ but seemingly no one uses them in C extensions yet anyway. # * re.search-bound, ~30% time, in likes of builtins and _gtk with complex docstrings. # None of this can seemingly be easily helped. Maybe there's a simpler and faster parser library? -VERSION = "1.87" # Must be a number-dot-number string, updated with each change that affects generated skeletons +VERSION = "1.88" # Must be a number-dot-number string, updated with each change that affects generated skeletons # Note: DON'T FORGET TO UPDATE! import sys @@ -790,7 +790,7 @@ class ModuleRedeclarator(object): (None, "range"): "(start=None, stop=None, step=None)", # suboptimal: allows empty arglist (None, "filter"): "(function_or_none, sequence)", (None, "iter"): "(source, sentinel=None)", - ('frozenset', "__init__"): "(seq=())", + ('frozenset', "__init__"): "(self, seq=())", } if version[0] < 3: diff --git a/python/helpers/required_gen_version b/python/helpers/required_gen_version index 9d85d35fe181..a02f2f59c9d7 100644 --- a/python/helpers/required_gen_version +++ b/python/helpers/required_gen_version @@ -6,7 +6,7 @@ (default) 1.85 # anything not explicitly marked -(built-in) 1.87 # skeletons of all built-in modules are built together +(built-in) 1.88 # skeletons of all built-in modules are built together # Note: modules like itertools, etc are "(built-in)" and are ignored if given separately # pygame._numericsndarray 1.81