Anonymous avatar Anonymous committed 61fd6dc

Adding rope.ide.sort module

Comments (0)

Files changed (9)

docs/dev/issues.txt

 * Each scopes should own the blanks after it except the last one
 
 
+Specifying The Scope To Sort
+----------------------------
+
+* The scope current offset is in
+* The scope of the PyName in current offset
+
+
 Specifying The New Order
 ------------------------
 
-How to specify the new order?
+It is only the manual ordering that requires specifying the new order.
+We can specify the new order the same way we do that for change method
+signature.  The IDE can do better by using scope name and kind.
 
 
 Sort Kinds
 * Alphabetically
 * Classes first
 * Functions first
-* Not-underlined first
-* With-pydocs first
-* Longest first
+* Not-underlined first/last
+* With-pydocs first/last
+* Longest first/last
 * Manual
+* Specials first/last
+
+
+Insert Before In Restructurings
+===============================
+
+Consider a restructuring like this::
+
+  pattern: ${?a} if ${?b} else ${?c}
+  goal: replacement
+  before: if ${?b}:\n    replacement = ${?a}\nelse:\n    replacement = ${?c}
 
 
 Enhancing Refactorings

docs/dev/stories.txt

 * Split tuple assignment refactoring
 
 
+> Public Release 0.7m1 : August 19, 2007
+
+
 * Sorting methods
-
-
-> Public Release 0.7m1 : August 19, 2007

docs/dev/workingon.txt

-Small Stories
-=============
+Sorting Scopes
+==============
 
-* Renaming `rope.py` to `ropeide.py`?
+* Handling blanks after scopes
+* Handling blanks for the final scope
+* Moving statements
+* Sorting 
+
+  * Alphabetically
+  * Classes first
+  * Functions first
+  * Not-underlined first/last
+  * With-pydocs first/last
+  * Longest first/last
+  * Manual
+  * Specials first/last
+
+* Adding sorttest to testsuit
+* Adding a dialog
+
+* Adding an option to inline not to remove the definition
+* Renaming ``rope.py`` to ``ropeide.py`` and ``~/.rope`` to
+  ``~/.ropeide.py``?
 * Changing the default font on linux to courier?
-
 * Lots of exceptions for `PyFunction`
 * Commenting based on the line of syntax error in codeassist?
 * Adding restructuring scope; local scope, module, all files?
+from rope.base import change
+
+
+class SortScopes(object):
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        self.resource = resource
+        self.pymodule = self.pycore.resource_to_pyobject(resource)
+        self.scope = self.pymodule.get_scope().\
+                     get_inner_scope_for_offset(offset)
+
+    def get_changes(self):
+        changes = change.ChangeSet('Sorting scopes')
+        scopes = self._get_scopes()
+        if not scopes:
+            return changes
+        start = scopes[0].start
+        end = scopes[-1].end
+        blanks = scopes[0].blanks
+        scopes[-1].blanks = blanks
+        self._sort_scopes(scopes)
+        scopes[-1].blanks = 0
+        result = []
+        result.append(self._get_text(1, start - 1))
+        for scope in scopes:
+            extracted = self._get_text(scope.start, scope.end)
+            result.append(extracted + '\n' * scope.blanks)
+        result.append(self._get_text(end + 1))
+        changes.add_change(change.ChangeContents(self.resource,
+                                                 ''.join(result)))
+        return changes
+
+    def _sort_scopes(self, scopes):
+        def compare_scopes(scope1, scope2):
+            return cmp(scope1.name, scope2.name)
+        scopes.sort(cmp=compare_scopes)
+
+    def _get_scopes(self):
+        subs = self.scope.get_scopes()
+        if not subs:
+            return []
+        result = []
+        for scope in subs:
+            start = scope.get_start()
+            end = scope.get_end()
+            blanks = self._count_blanks(end + 1)
+            result.append(_Scope(scope, start, end, blanks))
+        result[-1].blanks = 0
+        return result
+
+    def _count_blanks(self, start):
+        lines = self.pymodule.lines
+        blanks = 0
+        for lineno in range(start, lines.length() + 1):
+            line = lines.get_line(lineno)
+            if not line.strip():
+                blanks += 1
+            else:
+                break
+        return blanks
+
+    def _get_text(self, start_line, end_line=None):
+        lines = self.pymodule.lines
+        source = self.pymodule.source_code
+        if end_line is None:
+            end_line = lines.length()
+        if start_line > end_line:
+            return ''
+        start = lines.get_line_start(start_line)
+        end = min(lines.get_line_end(end_line) + 1, len(source))
+        return source[start:end]
+
+
+class _Scope(object):
+
+    def __init__(self, scope, start, end, blanks):
+        self.start = start
+        self.end = end
+        self.blanks = blanks
+        self.name = scope.pyobject.get_name()
+
+
+class _Statements(object):
+
+    def __init__(self, start, end, blanks):
+        self.start = start
+        self.end = end
+        self.blanks = blanks

rope/refactor/extract.py

     def _Yield(self, node):
         self.returns = True
 
-    def _Function(self, node):
+    def _FunctionDef(self, node):
         pass
 
-    def _Class(self, node):
+    def _ClassDef(self, node):
         pass
 
     @staticmethod

ropetest/ide/sorttest.py

+import unittest
+from rope.ide import sort
+from ropetest import testutils
+
+
+class SortScopesTest(unittest.TestCase):
+
+    def setUp(self):
+        super(SortScopesTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.get_pycore()
+        self.mod = self.pycore.create_module(self.project.root, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(SortScopesTest, self).tearDown()
+
+    def _do_sort(self, offset):
+        sorter = sort.SortScopes(self.project, self.mod, offset)
+        self.project.do(sorter.get_changes())
+
+    def test_trivial_case(self):
+        self.mod.write('\ndef a():\n    pass\n')
+        self._do_sort(0)
+        self.assertEquals('\ndef a():\n    pass\n', self.mod.read())
+
+    def test_alphabetical_sorting_in_module_scope(self):
+        self.mod.write('\ndef b():\n    pass\ndef a():\n    pass\n')
+        self._do_sort(0)
+        self.assertEquals('\ndef a():\n    pass\ndef b():\n    pass\n',
+                          self.mod.read())
+
+    def test_handling_blanks(self):
+        self.mod.write('\ndef b():\n    pass\n\n\ndef a():\n    pass\n')
+        self._do_sort(0)
+        self.assertEquals('\ndef a():\n    pass\n\n\ndef b():\n    pass\n',
+                          self.mod.read())
+
+    def xxx_test_handling_statements(self):
+        self.mod.write('\ndef a():\n    pass\nprint(b())\n'
+                       'def b():\n    pass\n')
+        self._do_sort(0)
+        self.assertEquals(
+            '\ndef a():\n    pass\nprint(b())\ndef b():\n    pass\n',
+            self.mod.read())
+
+
+if __name__ == '__main__':
+    unittest.main()

ropetest/refactor/extracttest.py

         expected = 'new_var = 10\na_var = new_var'
         self.assertEquals(expected, refactored)
 
+    def test_extract_method_containing_return_in_functions(self):
+        code = 'def f(arg):\n    return arg\nprint(f(1))\n'
+        start, end = self._convert_line_range_to_offset(code, 1, 3)
+        refactored = self.do_extract_method(code, start, end, 'a_func')
+        expected = '\ndef a_func():\n    def f(arg):\n        return arg\n' \
+                   '    print(f(1))\n\na_func()\n'
+        self.assertEquals(expected, refactored)
+
 
 if __name__ == '__main__':
     unittest.main()

ropetest/refactor/importutilstest.py

         self.assertEquals(0, len(imports))
 
     def test_simple_getting_used_imports(self):
-        self.mod.write('import pkg\nprint pkg\n')
+        self.mod.write('import pkg\nprint(pkg)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         imports = module_with_imports.get_used_imports(pymod)
         self.assertEquals('import pkg', imports[0].get_import_statement())
 
     def test_simple_getting_used_imports2(self):
-        self.mod.write('import pkg\ndef a_func():\n    print pkg\n')
+        self.mod.write('import pkg\ndef a_func():\n    print(pkg)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         imports = module_with_imports.get_used_imports(pymod)
         self.assertEquals('import pkg', imports[0].get_import_statement())
 
     def test_getting_used_imports_for_nested_scopes(self):
-        self.mod.write('import pkg1\nprint pkg1\ndef a_func():\n    pass\nprint pkg1\n')
+        self.mod.write('import pkg1\nprint(pkg1)\ndef a_func():\n    pass\nprint(pkg1)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         imports = module_with_imports.get_used_imports(
         self.assertEquals(0, len(imports))
 
     def test_getting_used_imports_for_nested_scopes2(self):
-        self.mod.write('from pkg1 import mod1\ndef a_func():\n    print mod1\n')
+        self.mod.write('from pkg1 import mod1\ndef a_func():\n    print(mod1)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         imports = module_with_imports.get_used_imports(
         self.assertEquals('from pkg1 import mod1', imports[0].get_import_statement())
 
     def test_empty_removing_unused_imports(self):
-        self.mod.write('import pkg1\nprint pkg1\n')
+        self.mod.write('import pkg1\nprint(pkg1)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         module_with_imports.remove_unused_imports()
-        self.assertEquals('import pkg1\nprint pkg1\n',
+        self.assertEquals('import pkg1\nprint(pkg1)\n',
                           module_with_imports.get_changed_source())
 
     def test_simple_removing_unused_imports(self):
 
     def test_removing_unused_imports_and_reoccuring_names2(self):
         self.mod.write('import pkg2.mod2\nimport pkg2.mod3\n'
-                       'print pkg2.mod2, pkg2.mod3')
+                       'print(pkg2.mod2, pkg2.mod3)')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         module_with_imports.remove_unused_imports()
         self.assertEquals(
-            'import pkg2.mod2\nimport pkg2.mod3\nprint pkg2.mod2, pkg2.mod3',
+            'import pkg2.mod2\nimport pkg2.mod3\nprint(pkg2.mod2, pkg2.mod3)',
             module_with_imports.get_changed_source())
 
     def test_removing_unused_imports_and_common_packages(self):
-        self.mod.write('import pkg1.mod1\nimport pkg1\nprint pkg1, pkg1.mod1\n')
+        self.mod.write('import pkg1.mod1\nimport pkg1\nprint(pkg1, pkg1.mod1)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         module_with_imports.remove_unused_imports()
-        self.assertEquals('import pkg1.mod1\nprint pkg1, pkg1.mod1\n',
+        self.assertEquals('import pkg1.mod1\nprint(pkg1, pkg1.mod1)\n',
                           module_with_imports.get_changed_source())
 
     def test_removing_unused_imports_and_common_packages_reversed(self):
-        self.mod.write('import pkg1\nimport pkg1.mod1\nprint pkg1, pkg1.mod1\n')
+        self.mod.write('import pkg1\nimport pkg1.mod1\nprint(pkg1, pkg1.mod1)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         module_with_imports.remove_duplicates()
-        self.assertEquals('import pkg1.mod1\nprint pkg1, pkg1.mod1\n',
+        self.assertEquals('import pkg1.mod1\nprint(pkg1, pkg1.mod1)\n',
                           module_with_imports.get_changed_source())
 
     def test_removing_unused_imports_and_common_packages2(self):
-        self.mod.write('import pkg1.mod1\nimport pkg1.mod2\nprint pkg1\n')
+        self.mod.write('import pkg1.mod1\nimport pkg1.mod2\nprint(pkg1)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         module_with_imports.remove_unused_imports()
-        self.assertEquals('import pkg1.mod1\nprint pkg1\n',
+        self.assertEquals('import pkg1.mod1\nprint(pkg1)\n',
                           module_with_imports.get_changed_source())
 
     def test_removing_unused_imports_and_froms(self):
 
     def test_transforming_froms_to_normal_changing_imports(self):
         self.mod1.write('def a_func():\n    pass\n')
-        self.mod.write('from pkg1.mod1 import a_func\nprint a_func\n')
+        self.mod.write('from pkg1.mod1 import a_func\nprint(a_func)\n')
         pymod = self.pycore.get_module('mod')
         changed_module = self.import_tools.froms_to_imports(pymod)
-        self.assertEquals('import pkg1.mod1\nprint pkg1.mod1.a_func\n',
+        self.assertEquals('import pkg1.mod1\nprint(pkg1.mod1.a_func)\n',
                           changed_module)
 
     def test_transforming_froms_to_normal_changing_occurances(self):
     def test_transforming_froms_to_normal_from_stars2(self):
         self.mod1.write('a_var = 10')
         self.mod.write('import pkg1.mod1\nfrom pkg1.mod1 import a_var\n' \
-                       'def a_func():\n    print pkg1.mod1, a_var\n')
+                       'def a_func():\n    print(pkg1.mod1, a_var)\n')
         pymod = self.pycore.get_module('mod')
         changed_module = self.import_tools.froms_to_imports(pymod)
         self.assertEquals('import pkg1.mod1\n' \
-                          'def a_func():\n    print pkg1.mod1, pkg1.mod1.a_var\n',
+                          'def a_func():\n    print(pkg1.mod1, pkg1.mod1.a_var)\n',
                           changed_module)
 
     def test_transforming_froms_to_normal_from_with_alias(self):
                           self.import_tools.relatives_to_absolutes(pymod))
 
     def test_transform_relatives_to_absolute_imports_for_normal_imports2(self):
-        self.mod2.write('import mod3\nprint mod3')
+        self.mod2.write('import mod3\nprint(mod3)')
         pymod = self.pycore.resource_to_pyobject(self.mod2)
-        self.assertEquals('import pkg2.mod3\nprint pkg2.mod3',
+        self.assertEquals('import pkg2.mod3\nprint(pkg2.mod3)',
                           self.import_tools.relatives_to_absolutes(pymod))
 
     def test_transform_relatives_to_absolute_imports_for_aliases(self):
-        self.mod2.write('import mod3 as mod3\nprint mod3')
+        self.mod2.write('import mod3 as mod3\nprint(mod3)')
         pymod = self.pycore.resource_to_pyobject(self.mod2)
-        self.assertEquals('import pkg2.mod3 as mod3\nprint mod3',
+        self.assertEquals('import pkg2.mod3 as mod3\nprint(mod3)',
                           self.import_tools.relatives_to_absolutes(pymod))
 
     def test_organizing_imports(self):
         self.assertEquals('', self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports(self):
-        self.mod.write('import mod\nmod.a_var = 1\nprint mod.a_var\n')
+        self.mod.write('import mod\nmod.a_var = 1\nprint(mod.a_var)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports2(self):
         self.mod1.write('import pkg1.mod1\npkg1.mod1.a_var = 1\n'
-                        'print pkg1.mod1.a_var\n')
+                        'print(pkg1.mod1.a_var)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod1)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports_with_as(self):
         self.mod.write('import mod as mymod\n'
-                       'mymod.a_var = 1\nprint mymod.a_var\n')
+                       'mymod.a_var = 1\nprint(mymod.a_var)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports_for_froms(self):
         self.mod1.write('from pkg1 import mod1\n'
-                        'mod1.a_var = 1\nprint mod1.a_var\n')
+                        'mod1.a_var = 1\nprint(mod1.a_var)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod1)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports_for_froms_with_as(self):
         self.mod1.write('from pkg1 import mod1 as mymod\n'
-                        'mymod.a_var = 1\nprint mymod.a_var\n')
+                        'mymod.a_var = 1\nprint(mymod.a_var)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod1)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports_for_froms2(self):
-        self.mod.write('from mod import a_var\na_var = 1\nprint a_var\n')
+        self.mod.write('from mod import a_var\na_var = 1\nprint(a_var)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports_for_froms3(self):
-        self.mod.write('from mod import a_var\na_var = 1\nprint a_var\n')
+        self.mod.write('from mod import a_var\na_var = 1\nprint(a_var)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports_for_froms4(self):
         self.mod.write('from mod import a_var as myvar\n'
-                       'a_var = 1\nprint myvar\n')
+                       'a_var = 1\nprint(myvar)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports_with_no_dot_after_mod(self):
-        self.mod.write('import mod\nprint mod\n')
+        self.mod.write('import mod\nprint(mod)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
-        self.assertEquals('import mod\n\n\nprint mod\n',
+        self.assertEquals('import mod\n\n\nprint(mod)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_removing_self_imports_with_no_dot_after_mod2(self):
         self.mod.write('import mod\na_var = 1\n'
-                       'print mod\\\n     \\\n     .var\n\n')
+                       'print(mod\\\n     \\\n     .var)\n\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
-        self.assertEquals('a_var = 1\nprint var\n\n',
+        self.assertEquals('a_var = 1\nprint(var)\n\n',
                           self.import_tools.organize_imports(pymod))
 
     # XXX: causes stack overflow
     def xxx_test_removing_self_imports_for_from_import_star(self):
-        self.mod.write('from mod import *\na_var = 1\nprint myvar\n')
+        self.mod.write('from mod import *\na_var = 1\nprint(myvar)\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
-        self.assertEquals('a_var = 1\nprint a_var\n',
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
                           self.import_tools.organize_imports(pymod))
 
     def test_sorting_empty_imports(self):
             self.import_tools.handle_long_imports(pymod, maxdots=2))
 
     def test_empty_removing_unused_imports_and_eating_blank_lines(self):
-        self.mod.write('import pkg1\nimport pkg2\n\n\nprint pkg1\n')
+        self.mod.write('import pkg1\nimport pkg2\n\n\nprint(pkg1)\n')
         pymod = self.pycore.get_module('mod')
         module_with_imports = self.import_tools.get_module_imports(pymod)
         module_with_imports.remove_unused_imports()
-        self.assertEquals('import pkg1\n\n\nprint pkg1\n',
+        self.assertEquals('import pkg1\n\n\nprint(pkg1)\n',
                           module_with_imports.get_changed_source())
 
     def test_sorting_imports_moving_to_top(self):

ropetest/refactor/inlinetest.py

                   '    var = 10\n' \
                   '    @staticmethod\n' \
                   '    def a_func(param):\n' \
-                  '        print param\n' \
+                  '        print(param)\n' \
                   'an_a = A()\n' \
                   'an_a.a_func(1)\n' \
                   'A.a_func(2)\n'
         expected = 'class A(object):\n' \
                   '    var = 10\n' \
                   'an_a = A()\n' \
-                  'print 1\n' \
-                  'print 2\n'
+                  'print(1)\n' \
+                  'print(2)\n'
         self.assertEquals(expected, self.mod.read())
 
     def test_inlining_classmethods(self):
 
     @testutils.assert_raises(rope.base.exceptions.RefactoringError)
     def test_raising_exception_for_list_arguments(self):
-        self.mod.write('def a_func(*args):\n    print args\na_func(1)\n')
+        self.mod.write('def a_func(*args):\n    print(args)\na_func(1)\n')
         self._inline2(self.mod, self.mod.read().index('a_func') + 1)
 
     @testutils.assert_raises(rope.base.exceptions.RefactoringError)
     def test_raising_exception_for_list_keywods(self):
-        self.mod.write('def a_func(**kwds):\n    print kwds\na_func(n=1)\n')
+        self.mod.write('def a_func(**kwds):\n    print(kwds)\na_func(n=1)\n')
         self._inline2(self.mod, self.mod.read().index('a_func') + 1)
 
     def test_function_parameters_and_returns_in_other_functions(self):
 
     @testutils.assert_raises(rope.base.exceptions.RefactoringError)
     def test_function_references_other_than_call(self):
-        self.mod.write('def a_func(param):\n    print param\nf = a_func\n')
+        self.mod.write('def a_func(param):\n    print(param)\nf = a_func\n')
         self._inline2(self.mod, self.mod.read().index('a_func') + 1)
 
     @testutils.assert_raises(rope.base.exceptions.RefactoringError)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.