Commits

Anonymous committed 8e8abac

Adding LogicalLinesFinder.generate_starts()

Comments (0)

Files changed (2)

rope/base/codeanalyze.py

                 lineno = e.lineno + block_start - 1
                 indents = count_line_indents(self.lines.get_line(lineno))
 
+    def generate_starts(self, start_line=1, end_line=None):
+        block_start = get_block_start(self.lines, start_line)
+        readline = LinesToReadline(self.lines, block_start)
+        shifted = start_line - block_start + 1
+        for start, end in self._logical_lines(readline):
+            real_start = start + block_start - 1
+            real_start = self._first_non_blank(real_start)
+            if end_line is not None and real_start >= end_line:
+                break
+            if real_start >= start_line:
+                yield real_start
+
     def _block_logical_line(self, block_start, line_number):
         readline = LinesToReadline(self.lines, block_start)
         shifted = line_number - block_start + 1
         region = self._calculate_logical(readline, shifted)
-        start = self._get_first_non_blank(region[0] + block_start - 1)
+        start = self._first_non_blank(region[0] + block_start - 1)
         if region[1] is None:
             end = self.lines.length()
         else:
         return start, end
 
     def _calculate_logical(self, readline, line_number):
-        last_line_start = 1
+        last_end = 1
         try:
-            for current in tokenize.generate_tokens(readline):
-                current_lineno = current[2][0]
-                if current[0] == token.NEWLINE:
-                    if current_lineno >= line_number:
-                        return (last_line_start, current_lineno)
-                    last_line_start = current_lineno + 1
+            for start, end in self._logical_lines(readline):
+                if line_number <= end:
+                    return (start, end)
+                last_end = end
         except tokenize.TokenError:
-            return (last_line_start, None)
-        return (last_line_start, None)
+            return (last_end, None)
+        return (last_end, None)
 
-    def _get_first_non_blank(self, line_number):
+    def _logical_lines(self, readline):
+        last_end = 1
+        for current in self._logical_ends(readline):
+            yield (last_end, current)
+            last_end = current + 1
+
+    def _logical_ends(self, readline):
+        for current in tokenize.generate_tokens(readline):
+            current_lineno = current[2][0]
+            if current[0] == token.NEWLINE:
+                yield current_lineno
+
+    def _first_non_blank(self, line_number):
         current = line_number
         while current < self.lines.length():
             line = self.lines.get_line(current).strip()

ropetest/codeanalyzetest.py

         line_finder = LogicalLineFinder(SourceLinesAdapter(code))
         self.assertEquals((4, 4), line_finder.get_logical_line_in(4))
 
+    def test_generating_line_starts(self):
+        code = 'a = 1\na = 2\n\na = 3\n'
+        line_finder = LogicalLineFinder(SourceLinesAdapter(code))
+        self.assertEquals([1, 2, 4], list(line_finder.generate_starts()))
+
+    def test_generating_line_starts2(self):
+        code = 'a = 1\na = 2\n\na = \\ 3\n'
+        line_finder = LogicalLineFinder(SourceLinesAdapter(code))
+        self.assertEquals([2, 4], list(line_finder.generate_starts(2)))
+
+    def test_generating_line_starts3(self):
+        code = 'a = 1\na = 2\n\na = \\ 3\n'
+        line_finder = LogicalLineFinder(SourceLinesAdapter(code))
+        self.assertEquals([2], list(line_finder.generate_starts(2, 3)))
+
+    def test_generating_line_starts_for_multi_line_statements(self):
+        code = '\na = \\\n 1 + \\\n 1\n'
+        line_finder = LogicalLineFinder(SourceLinesAdapter(code))
+        self.assertEquals([2], list(line_finder.generate_starts()))
+
 
 def suite():
     result = unittest.TestSuite()
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.