Commits

Antonio Cuni committed 6ab7104

show source lines that are *not* executed by the loop in gray

Comments (0)

Files changed (4)

     """ A representation of a single code object suitable for display
     """
     def __init__(self, source, code, loop):
-        startline, endline = loop.linerange
+        #startline, endline = loop.linerange
+        lineset = loop.lineset
         self.lines = []
         self.firstlineno = code.co_firstlineno
         for i, line in enumerate(source.split("\n")):
             no = i + code.co_firstlineno
-            if no < startline or no > endline:
-                self.lines.append(LineRepr(line, False))
-            else:
-                self.lines.append(LineRepr(line, True))
+            in_loop = no in lineset
+            self.lines.append(LineRepr(line, in_loop))
 
         last_lineno = -1
         for chunk in loop.chunks:
     name = None
     startlineno = 0
     _linerange = None
+    _lineset = None
     is_bytecode = False
     
     def __init__(self, chunks, path, storage):
 
     def getlinerange(self):
         if self._linerange is None:
-            minline = sys.maxint
-            maxline = -1
-            for chunk in self.chunks:
-                if chunk.is_bytecode and chunk.filename is not None:
-                    lineno = chunk.lineno
-                    minline = min(minline, lineno)
-                    maxline = max(maxline, lineno)
-            if minline == sys.maxint:
-                minline = 0
-                maxline = 0
-            self._linerange = minline, maxline
+            self._compute_linerange()
         return self._linerange
     linerange = property(getlinerange)
 
+    def getlineset(self):
+        if self._lineset is None:
+            self._compute_linerange()
+        return self._lineset
+    lineset = property(getlineset)
+
+    def _compute_linerange(self):
+        self._lineset = set()
+        minline = sys.maxint
+        maxline = -1
+        for chunk in self.chunks:
+            if chunk.is_bytecode and chunk.filename is not None:
+                lineno = chunk.lineno
+                minline = min(minline, lineno)
+                maxline = max(maxline, lineno)
+                self._lineset.add(lineno)
+        if minline == sys.maxint:
+            minline = 0
+            maxline = 0
+        self._linerange = minline, maxline
+
     def html_repr(self):
         return "inlined call to %s in %s" % (self.name, self.filename)
 

test/test_loops.py

     debug_merge_point("<code object f, file '%(fname)s', line 5> #9 LOAD_FAST")
     debug_merge_point("<code object f, file '%(fname)s', line 5> #12 LOAD_CONST")
     debug_merge_point("<code object f, file '%(fname)s', line 5> #22 LOAD_CONST")
+    debug_merge_point("<code object f, file '%(fname)s', line 5> #28 LOAD_CONST")
     debug_merge_point("<code object f, file '%(fname)s', line 5> #6 SETUP_LOOP")
     ''' % locals())
     res = slice_debug_merge_points(ops.operations, LoopStorage())
-    assert res.linerange == (7, 8)
+    assert res.linerange == (7, 9)
+    assert res.lineset == set([7, 8, 9])
 
 def test_reassign_loops():
     main = parse('''
 def g():
     i = 0
     while i < 10:
+        a = 'foo'
         i += 1