Anonymous avatar Anonymous committed aa18c3c

finding primary start on a dict should not include the atom before

some other methods of WordRangeFinder was refactored, too.

Comments (0)

Files changed (2)

rope/base/codeanalyze.py

 
 
 class WordRangeFinder(object):
+    # XXX: many of these methods fail on comments
 
     def __init__(self, source_code):
         self.source = source_code
             return 0
         current_offset = offset
         while current_offset >= 0 and self.source[current_offset] in ' \t\n':
-            while current_offset >= 0 and self.source[current_offset] in ' \t':
+            if self.source[current_offset - 1:current_offset + 1] == '\\\n':
                 current_offset -= 1
-            if current_offset >= 0 and self.source[current_offset] == '\n':
-                current_offset -= 1
-                if current_offset >= 0 and self.source[current_offset] == '\\':
-                    current_offset -= 1
+            current_offset -= 1
         return current_offset
 
-    def get_word_before(self, offset):
-        return self.source[self._find_word_start(offset - 1):offset]
-
-
     def get_word_at(self, offset):
         offset = self._get_fixed_offset(offset)
         return self.source[self._find_word_start(offset):
         return self.source[offset].isalnum() or self.source[offset] == '_'
 
     def _find_string_start(self, offset):
+        # XXX: should it handle triple quotes?
         kind = self.source[offset]
         current_offset = offset - 1
         while self.source[current_offset] != kind:
         return old_offset
 
     def _find_primary_without_dot_start(self, offset):
-        last_parens = offset
-        current_offset = self._find_last_non_space_char(offset)
-        while current_offset > 0 and self.source[current_offset] in ')]}':
-            last_parens = self._find_parens_start(current_offset)
-            current_offset = self._find_last_non_space_char(last_parens - 1)
-        if self.source[last_parens] == '(' and self._is_id_char(current_offset):
-            return self._find_primary_without_dot_start(current_offset)
+        """It tries to find the undotted primary start
 
+        It is different from `self._get_atom_start()` in that it
+        follows function calls, too; such as in ``f(x)``.
 
-        if current_offset > 0 and self.source[current_offset] in '\'"':
-            return self._find_string_start(current_offset)
-        elif current_offset > 0 and self._is_id_char(current_offset):
-            return self._find_word_start(current_offset)
-        return last_parens
+        """
+        last_atom = offset
+        current_offset = self._find_last_non_space_char(last_atom)
+        while current_offset > 0 and self.source[current_offset] in ')]':
+            last_atom = self._find_parens_start(current_offset)
+            current_offset = self._find_last_non_space_char(last_atom - 1)
+        if current_offset >= 0 and (self.source[current_offset] in '"\'})]' or
+                                   self._is_id_char(current_offset)):
+            return self._find_atom_start(current_offset)
+        return last_atom
 
     def _find_primary_start(self, offset):
         if offset >= len(self.source):

ropetest/codeanalyzetest.py

 
     def test_dictionaries(self):
         word_finder = WordRangeFinder('print {1: "one", 2: "two"}.keys()')
-        self.assertEquals('print {1: "one", 2: "two"}.keys',
+        self.assertEquals('{1: "one", 2: "two"}.keys',
                           word_finder.get_primary_at(29))
 
     def test_following_parens(self):
         self.assertEquals('a_func()()',
                           word_finder.get_primary_at(code.index(')(') + 3))
 
-    # TODO: eliminating comments
+    # XXX: eliminating comments
     def xxx_test_comments_for_finding_statements(self):
         word_finder = WordRangeFinder('# var2 . \n  var3')
         self.assertEquals('var3',
         result = word_finder.get_word_parens_range(code.rindex('()') - 1)
         self.assertEquals((len(code) - 3, len(code) - 1), result)
 
+    def test_getting_primary_before_get_index(self):
+        code = '\na = (b + c).d[0]()\n'
+        word_finder = WordRangeFinder(code)
+        result = word_finder.get_primary_at(len(code) - 2)
+        self.assertEquals('(b + c).d[0]()', result)
+
+    # XXX: not crossing new lines
+    def xxx_test_getting_primary_and_not_crossing_newlines(self):
+        code = '\na = (b + c)\n(4 + 1).x\n'
+        word_finder = WordRangeFinder(code)
+        result = word_finder.get_primary_at(len(code) - 1)
+        self.assertEquals('(4 + 1).x', result)
+
+    # XXX: cancatenated string literals
+    def xxx_test_getting_primary_cancatenating_strs(self):
+        code = 's = "a"\n"b" "c"\n'
+        word_finder = WordRangeFinder(code)
+        result = word_finder.get_primary_at(len(code) - 1)
+        self.assertEquals('"b" "c"', result)
+
+    # XXX: not crossing new lines
+    def xxx_test_is_a_function_being_called_with_parens_on_next_line(self):
+        code = 'func\n(1, 2)\n'
+        word_finder = WordRangeFinder(code)
+        self.assertFalse(word_finder.is_a_function_being_called(1))
+
 
 class ScopeNameFinderTest(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.