Anonymous avatar Anonymous committed 965c57d

Looking inside for loops

Comments (0)

Files changed (11)

 * Having a persistant format for PyNames and PyObjects for saving
   hard to compute information like class hierarchies
 * Using a modification of `compiler` AST for simplifying refactorings
-* `What rope assumes...`_
+* Indexing source files
 
 
 Undo Unification
   * Reorder
 
 
-* Single line extract method and variable @ 10h
-
-
 * Inline method @ 20h
 
 
 * Removing imports from the same module @8h
 
 
+* Single line extract method and variable @ 10h
+
+
 > Public Release 0.3m5 : October 15, 2006
 
 

docs/workingon.txt

-Release Planning And Estimation
-===============================
-
+Move a module or package to another package
+===========================================
 
 * Problems when organizing imports in `ropetests.codeanalyzetest` module
 
+
 Remaining Stories
 =================
 
 * Test `difflib` for `Editor.set_text`
 * Caching `PyCore.classes`
 * Handling `Scope.lookup` for ::
-  
+
     class A(object):
         a_var = 10
         another_var = a_var

rope/importutils.py

         self.pycore = pycore
     
     def get_import_for_module(self, module):
-        module_name = ImportTools._get_module_name(self.pycore, module.get_resource())
+        module_name = ImportTools.get_module_name(self.pycore, module.get_resource())
         return NormalImport(((module_name, None), ))
     
     def get_from_import_for_module(self, module, name):
-        module_name = ImportTools._get_module_name(self.pycore, module.get_resource())
+        module_name = ImportTools.get_module_name(self.pycore, module.get_resource())
         return FromImport(module_name, 0, ((name, None),),
                           module.get_resource().get_parent(), self.pycore)
 
-    @staticmethod
-    def _get_module_name(pycore, resource):
-        if resource.is_folder():
-            module_name = resource.get_name()
-            source_folder = resource.get_parent()
-        elif resource.get_name() == '__init__.py':
-            module_name = resource.get_parent().get_name()
-            source_folder = resource.get_parent().get_parent()
-        else:
-            module_name = resource.get_name()[:-3]
-            source_folder = resource.get_parent()
-
-        source_folders = pycore.get_source_folders()
-        source_folders.extend(pycore.get_python_path_folders())
-        while source_folder != source_folder.get_parent() and \
-              source_folder not in source_folders:
-            module_name = source_folder.get_name() + '.' + module_name
-            source_folder = source_folder.get_parent()
-        return module_name
-    
     def get_module_with_imports(self, module):
         return ModuleWithImports(self.pycore, module)
     
             return False
         return True
 
+    @staticmethod
+    def get_module_name(pycore, resource):
+        if resource.is_folder():
+            module_name = resource.get_name()
+            source_folder = resource.get_parent()
+        elif resource.get_name() == '__init__.py':
+            module_name = resource.get_parent().get_name()
+            source_folder = resource.get_parent().get_parent()
+        else:
+            module_name = resource.get_name()[:-3]
+            source_folder = resource.get_parent()
+
+        source_folders = pycore.get_source_folders()
+        source_folders.extend(pycore.get_python_path_folders())
+        while source_folder != source_folder.get_parent() and \
+              source_folder not in source_folders:
+            module_name = source_folder.get_name() + '.' + module_name
+            source_folder = source_folder.get_parent()
+        return module_name
+    
 
 class ModuleWithImports(object):
     
             if resource is None:
                 new_pairs.append((name, alias))
                 continue
-            absolute_name = ImportTools._get_module_name(pycore, resource)
+            absolute_name = ImportTools.get_module_name(pycore, resource)
             new_pairs.append((absolute_name, alias))
         if not self._are_name_and_alias_lists_equal(new_pairs, self.names_and_aliases):
             return NormalImport(new_pairs)
             resource = pycore.find_module(name, current_folder=current_folder)
             if resource is None:
                 continue
-            absolute_name = ImportTools._get_module_name(pycore, resource)
+            absolute_name = ImportTools.get_module_name(pycore, resource)
             if absolute_name != name:
                 result.append((name, absolute_name))
         return result
                 self.module_name, current_folder, self.level)
         if resource is None:
             return None
-        absolute_name = ImportTools._get_module_name(pycore, resource)
+        absolute_name = ImportTools.get_module_name(pycore, resource)
         if self.module_name != absolute_name:
             return FromImport(absolute_name, 0, self.names_and_aliases,
                               current_folder, pycore)

rope/pyobjects.py

     
     def visitFor(self, node):
         self.visitAssign(node.assign)
+        compiler.walk(node.body, self)
     
     def visitImport(self, node):
         for import_pair in node.names:

rope/refactor/introduce_factory.py

                 continue
             rename_in_module = rope.refactor.rename.RenameInModule(
                 self.pycore, [self.old_pyname], self.old_name, changed_name,
-                only_function_calls=True,
-                replace_primary=self.global_factory)
+                only_calls=True, replace_primary=self.global_factory)
             changed_code = rename_in_module.get_changed_module(resource=file_)
             if changed_code is not None:
                 if self.global_factory:

rope/refactor/move.py

     def __init__(self, pycore, resource, offset, dest_resource):
         self.pycore = pycore
         self.dest_resource = dest_resource
-        if dest_resource.is_folder():
-            self.dest_resource = dest_resource.get_child('__init__.py')
-        self.old_pyname = rope.codeanalyze.get_pyname_at(self.pycore, resource, offset)
+        pyname = rope.codeanalyze.get_pyname_at(self.pycore, resource, offset)
+        if pyname is None:
+            raise rope.exceptions.RefactoringException(
+                'Move works on classes,functions or modules.')
+        moving_object = pyname.get_object()
+        if moving_object.get_type() == rope.pyobjects.PyObject.get_base_type('Module'):
+            self.mover = _ModuleMover(pycore, pyname, dest_resource)
+        else:
+            self.mover = _GlobalMover(pycore, pyname, dest_resource)
+    
+    def move(self):
+        return self.mover.move()
+
+
+class _Mover(object):
+    
+    def __init__(self, pycore, pyname, destination):
+        self.pycore = pycore
+        self.dest_resource = destination
+        self.old_pyname = pyname
+        self.import_tools = rope.importutils.ImportTools(self.pycore)
         
         self._check_exceptional_conditions()
+    
+    def _check_exceptional_conditions(self):
+        pass
+
+
+class _GlobalMover(_Mover):
+    
+    def __init__(self, pycore, pyname, destination):
+        super(_GlobalMover, self).__init__(pycore, pyname, destination)
         
         self.old_name = self.old_pyname.get_object()._get_ast().name
-        self.pymodule = self.old_pyname.get_object().get_module()
-        self.resource = self.pymodule.get_resource()
-        self.import_tools = rope.importutils.ImportTools(self.pycore)
+        pymodule = self.old_pyname.get_object().get_module()
+        self.resource = pymodule.get_resource()
         self.new_import = self.import_tools.get_import_for_module(
             self.pycore.resource_to_pyobject(self.dest_resource))
         self.new_imported_name = self.new_import.names_and_aliases[0][0] + '.' + self.old_name
         if self.old_pyname is None or \
            not isinstance(self.old_pyname.get_object(), rope.pyobjects.PyDefinedObject):
             raise rope.exceptions.RefactoringException(
-                'Move refactoring should be performed on a class/function')
-        if not self._is_global(self.old_pyname.get_object()):
+                'Move refactoring should be performed on a class/function.')
+        moving_pyobject = self.old_pyname.get_object()
+        if not self._is_global(moving_pyobject):
             raise rope.exceptions.RefactoringException(
-                'Move refactoring should be performed on a global class/function')
+                'Move refactoring should be performed on a global class/function.')
+        if self.dest_resource.is_folder():
+            raise rope.exceptions.RefactoringException(
+                'Move destination for non-modules should not be folders.')
+    
+    def _is_module(self, pyobject):
+        return pyobject.get_type() == rope.pyobjects.PyObject.get_base_type('Module')
     
     def _is_global(self, pyobject):
         return pyobject.get_scope().parent == pyobject.get_module().get_scope()
         module_with_imports.filter_names(can_select)
         return module_with_imports.get_changed_source()
 
+
+class _ModuleMover(_Mover):
+    
+    def __init__(self, pycore, pyname, destination):
+        super(_ModuleMover, self).__init__(pycore, pyname, destination)
+        self.source = pyname.get_object().get_resource()
+        self.destination = destination
+        self.old_name = self.source.get_name()[:-3]
+        self.new_name = rope.importutils.ImportTools.get_module_name(
+            self.pycore, self.dest_resource) + '.' + self.old_name
+    
+    def _check_exceptional_conditions(self):
+        moving_pyobject = self.old_pyname.get_object()
+        if not self.dest_resource.is_folder():
+            raise rope.exceptions.RefactoringException(
+                'Move destination for modules should be packages.')
+    
+    def move(self):
+        changes = ChangeSet()
+        self._change_other_modules()
+        return changes
+
+    def _change_other_modules(self):
+        for module in self.pycore.get_python_files():
+            pymodule = self.pycore.resource_to_pyobject(module)
+            rename_in_module = rope.refactor.rename.RenameInModule(
+                self.pycore, [self.old_pyname], self.old_name,
+                self.new_name, replace_primary=True, imports=False)
+            self._remove_old_pyname_imports()
+    
+    def _remove_old_pyname_imports(self, pymodule):
+        module_with_imports = self.import_tools.get_module_with_imports(pymodule)
+        def can_select(name):
+            try:
+                if name == self.old_name and \
+                   pymodule.get_attribute(name).get_object() == self.old_pyname.get_object():
+                    return False
+            except rope.exceptions.AttributeNotFoundException:
+                pass
+            return True
+        module_with_imports.filter_names(can_select)
+        pymodule = self.pycore.get_string_module(module_with_imports.get_changed_source(),
+                                                 resource)
+        return pymodule
+

rope/refactor/occurances.py

 
 class OccurrenceFinder(object):
     
-    def __init__(self, pycore, pynames, name,
-                 function_calls=False, whole_primary=False,
-                 imports=True):
+    def __init__(self, pycore, pynames, name, only_calls=False,
+                 whole_primary=False, imports=True):
         self.pycore = pycore
         self.pynames = pynames
         self.name = name
-        self.function_calls = function_calls
+        self.only_calls = only_calls
         self.whole_primary = whole_primary
         self.imports = imports
         self.comment_pattern = OccurrenceFinder.any("comment", [r"#[^\n]*"])
     
     def find_occurances(self, resource=None, pymodule=None):
         source_code = self._get_source(resource, pymodule)
-        name_finder_creator = rope.refactor.occurances._LazyNameFinderCreator(self.pycore, resource, pymodule)
+        name_finder_creator = rope.refactor.occurances.\
+                              _LazyNameFinderCreator(self.pycore,
+                                                     resource, pymodule)
         word_finder = rope.codeanalyze.WordRangeFinder(source_code)
         for match in self.pattern.finditer(source_code):
             for key, value in match.groupdict().items():
             return pymodule.source_code
 
     def _is_a_match(self, name_finder_creator, word_finder, match_start):
-        if self.function_calls and \
+        if self.only_calls and \
            not word_finder.is_a_function_being_called(match_start + 1):
             return False
         if self.whole_primary and \

rope/refactor/rename.py

 class RenameInModule(object):
     
     def __init__(self, pycore, old_pynames, old_name, new_name,
-                 only_function_calls=False, replace_primary=False, imports=True):
-        self.occurances_finder = rope.refactor.occurances.OccurrenceFinder(pycore, old_pynames, old_name,
-                                                  only_function_calls, replace_primary,
-                                                  imports)
+                 only_calls=False, replace_primary=False, imports=True):
+        self.occurances_finder = rope.refactor.occurances.OccurrenceFinder(
+            pycore, old_pynames, old_name, only_calls,
+            replace_primary, imports)
         self.new_name = new_name
     
     def get_changed_module(self, resource=None, pymodule=None):

ropetest/pyscopestest.py

         scope = self.pycore.get_string_scope('for a_var in range(10):\n    pass\n')
         self.assertTrue('a_var' in scope.get_names())
 
+    def test_assists_inside_fors(self):
+        scope = self.pycore.get_string_scope('for i in range(10):\n    a_var = i\n')
+        self.assertTrue('a_var' in scope.get_names())
+
 
 def suite():
     result = unittest.TestSuite()

ropetest/refactortest.py

         self.assertEquals('class AClass(object):\n    pass\na_var = AClass()\n',
                           self.mod2.read())
 
+    @testutils.assert_raises(RefactoringException)
     def test_folder_destination(self):
         pkg = self.pycore.create_package(self.project.get_root_folder(), 'pkg')
         self.mod1.write('class AClass(object):\n    pass\n')
         self.refactoring.move(self.mod1, self.mod1.read().index('AClass') + 1, pkg)
-        self.assertEquals('class AClass(object):\n    pass\n',
-                          pkg.get_child('__init__.py').read())
-        self.assertEquals('', self.mod1.read())
     
     @testutils.assert_raises(RefactoringException)
     def test_raising_exception_for_moving_non_global_elements(self):
                               self.mod1)
         self.assertEquals('import pkg.mod5\n\n\ndef a_func():\n    print pkg.mod5\n',
                           self.mod1.read())
+    
+    # TODO: Moving modules
+    def xxx_test_moving_modules(self):
+        pkg = self.pycore.create_package(self.project.get_root_folder(), 'pkg')
+        self.mod2.write('import mod1\nprint mod1')
+        self.refactoring.move(self.mod2, self.mod2.read().index('mod1') + 1, pkg)
+        self.assertEquals('import pkg.mod1\nprint pkg.mod1', self.mod1.read())
+        self.assertEquals('pkg/mod1.py', self.mod1.get_path())
+        
 
 
 class RefactoringUndoTest(unittest.TestCase):
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.