Commits

Anonymous committed d2da3ff

Only looking in the holding scope range for renaming

Comments (0)

Files changed (6)

docs/workingon.txt

 Pre-Release Refactorings
 ========================
 
-- Putting a plus for nodes with children in outline view;
+- Only looking in the holding scope range for renaming
 
 * Go to definition for packages should go to __init__.py; for FilteredPackages also
 * Eliminate FilteredPackage
   * The list of available children; derived from `__init__.py` or imports/froms
   * An import_name function that throws exception if the name cannot be found
 
-* Only looking in the holding scope range for renaming
 * Testing all in windows
+* Not viewing inherited names in outlines
 
 
 Before 0.2 Release

rope/codeanalyze.py

     def get_line_number(self, offset):
         return len(self.source_code[:offset].split('\n'))
 
+    def get_line_start(self, line_number):
+        if line_number == 1:
+            return 0
+        current_line = 1
+        current_pos = 0
+        for c in self.source_code:
+            current_pos += 1
+            if c == '\n':
+                current_line += 1
+                if current_line == line_number:
+                    return current_pos
+        return current_pos
+    
+    def get_line_end(self, line_number):
+        current_line = 0
+        current_pos = 0
+        for c in self.source_code:
+            current_pos += 1
+            if c == '\n':
+                current_line += 1
+                if current_line == line_number:
+                    return current_pos - 1
+        return current_pos
     
 class ArrayLinesAdapter(Lines):
 
     def goto_definition(self):
         result = self.code_assist.get_definition_location(self.get_text(),
                                                           self.get_current_offset())
+        self._goto_editor_location(result[0], result[1])
+            
+    def _goto_editor_location(self, resource, lineno):
         editor = self
-        if result[0] is not None:
+        if resource is not None:
             import rope.core
             editor = rope.core.Core.get_core().get_editor_manager().\
-                     get_resource_editor(result[0]).get_editor()
-        if result[1] is not None:
-            editor.goto_line(result[1])
+                     get_resource_editor(resource).get_editor()
+        if lineno is not None:
+            editor.goto_line(lineno)
             
     def _rename_refactoring_dialog(self, event):
         toplevel = Toplevel()

rope/refactoring.py

 import re
 
-from rope.codeanalyze import (WordRangeFinder, ScopeNameFinder)
+from rope.codeanalyze import (WordRangeFinder, ScopeNameFinder,
+                              StatementRangeFinder, SourceLinesAdapter,
+                              HoldingScopeFinder)
 
 class Refactoring(object):
 
     def __init__(self, pycore):
         self.pycore = pycore
     
-    def _get_previous_char(self, source_code, offset):
-        offset -= 1
-        while offset >= 0 and source_code[offset].isspace():
-            if source_code[offset] == '\n':
-                offset -= 1
-                if offset >= 0 and source_code[offset] == '\\':
-                    offset -= 1
-            offset -= 1
-        if offset > 0:
-            return source_code[offset]
-        else:
-            return ''
-        
     def rename(self, source_code, offset, new_name):
         result = []
         module_scope = self.pycore.get_string_scope(source_code)
             return source_code
         pattern = re.compile('\\b' + old_name + '\\b')
         last_modified_char = 0
-        for match in pattern.finditer(source_code):
-            if self._get_previous_char(source_code, match.start()) == '.':
-                continue
+        scope_start, scope_end = self._get_scope_range(source_code, offset, module_scope,
+                                                       old_pyname.get_definition_location()[1])
+        for match in pattern.finditer(source_code[scope_start:scope_end]):
+            match_start = scope_start + match.start()
+            match_end = scope_start + match.end()
             new_pyname = None
             try:
-                new_pyname = pyname_finder.get_pyname_at(match.start() + 1)
+                new_pyname = pyname_finder.get_pyname_at(match_start + 1)
             except SyntaxError:
                 pass
             if new_pyname == old_pyname:
-                result.append(source_code[last_modified_char:match.start()] + new_name)
-                last_modified_char = match.end()
+                result.append(source_code[last_modified_char:match_start] + new_name)
+                last_modified_char = match_end
         result.append(source_code[last_modified_char:])
         return ''.join(result)
 
+    def _get_scope_range(self, source_code, offset, module_scope, lineno):
+        lines = SourceLinesAdapter(source_code)
+        scope_finder = HoldingScopeFinder(source_code)
+        holding_scope = scope_finder.get_holding_scope(module_scope, lineno)
+        range_finder = StatementRangeFinder(lines, lineno)
+        range_finder.analyze()
+        start = lines.get_line_start(holding_scope.get_lineno())
+        end = lines.get_line_end(range_finder.get_scope_end()) + 1
+        return (start, end)
 
 class NoRefactoring(Refactoring):
 

rope/uihelpers.py

                    ' ' + self.handle.entry_to_string(entry)
         old_text = self.list.get(index)
         if old_text != new_text:
-            old_selection = 1
+            old_selection = 0
             selection = self.list.curselection()
             if selection:
                 old_selection = int(selection[0])

ropetest/codeanalyzetest.py

         self.assertEquals(1, to_lines.get_line_number(0))
         self.assertEquals(2, to_lines.get_line_number(7))
 
+    def test_source_lines_get_line_start(self):
+        to_lines = SourceLinesAdapter('line1\nline2\n')
+        self.assertEquals(0, to_lines.get_line_start(1))
+        self.assertEquals(6, to_lines.get_line_start(2))
+        self.assertEquals(12, to_lines.get_line_start(3))
+
+    def test_source_lines_get_line_end(self):
+        to_lines = SourceLinesAdapter('line1\nline2\n')
+        self.assertEquals(5, to_lines.get_line_end(1))
+        self.assertEquals(11, to_lines.get_line_end(2))
+        self.assertEquals(12, to_lines.get_line_end(3))
+
         
 class WordRangeFinderTest(unittest.TestCase):