1.0.8.42: Fix some source-location bugs, alternate sb-cover annotation mode
authorJuho Snellman <jsnell@iki.fi>
Mon, 20 Aug 2007 17:12:49 +0000 (17:12 +0000)
committerJuho Snellman <jsnell@iki.fi>
Mon, 20 Aug 2007 17:12:49 +0000 (17:12 +0000)
         * Bug introduced in the code coverage commit caused sldb-show-source
           to highlight the wrong forms in many cases.
         * Changes in 1.0.6.23 caused branch forms to be not annotated as
           such in sb-cover.
         * Add a new annotation mode to sb-cover, which basically uses
           the source location information of the car of the form instead
           of using the information for the form itself. This mode shows
           explicitly which forms have been instrumented. According to
           a #lisp poll, the old version looks nicer, so it's been retained
           as the default.

NEWS
contrib/sb-cover/cover.lisp
src/compiler/ir1tran.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index ee5c4db..90a6eb7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ changes in sbcl-1.0.9 relative to sbcl-1.0.8:
   * enhancement: as an extension to MOP, SBCL now supports SETF of
     STANDARD-INSTANCE-ACCESS and FUNCALLABLE-STANDARD-INSTANCE-ACCESS.
     (thanks to Attila Lendvai)
+  * enhancement: sb-cover has an alternate annotation mode which puts
+    the form annotations at the car of the form, instead of annotating
+    it completely. The benefit of this mode is that it shows better
+    which forms were instrumented by the compiler.
   * bug fix: new compiler transforms for MEMBER and ASSOC were affected
     by printer control variables. (reported by Dan Corkill)
   * bug fix: system leaked memory when delayed output was performed by
@@ -21,6 +25,12 @@ changes in sbcl-1.0.9 relative to sbcl-1.0.8:
     the underlying file descriptor.
   * bug fix: multiple threads operating in parallel on the same stream
     could cause buffer-overflows.
+  * bug fix: source location information is stored correctly 
+    (broken since 1.0.6). This bug would generally show up as the
+    Slime debugger higlighting the wrong form when the sldb-show-source
+    command was used.
+  * bug fix: Branch forms are again annotated as branches in the sb-cover
+    annotations.
 
 changes in sbcl-1.0.8 relative to sbcl-1.0.7:
   * enhancement: experimental macro SB-EXT:COMPARE-AND-SWAP provides
index c507289..03ac9da 100644 (file)
@@ -15,6 +15,9 @@
 
 (in-package #:sb-cover)
 
+(declaim (type (member :whole :car) *source-path-mode*))
+(defvar *source-path-mode* :whole)
+
 (defclass sample-count ()
   ((mode :accessor mode-of :initarg :mode)
    (all :accessor all-of :initform 0)
@@ -76,11 +79,18 @@ result to RESTORE-COVERAGE."
         (restore-coverage (read stream))))
     (values)))
 
-(defun report (directory &key (external-format :default))
+(defun report (directory &key ((:form-mode *source-path-mode*) :whole)
+               (external-format :default))
   "Print a code coverage report of all instrumented files into DIRECTORY.
 If DIRECTORY does not exist, it will be created. The main report will be
 printed to the file cover-index.html. The external format of the source
-files can be specified with the EXTERNAL-FORMAT parameter."
+files can be specified with the EXTERNAL-FORMAT parameter.
+
+If the keyword argument FORM-MODE has the value :CAR, the annotations in
+the coverage report will be placed on the CARs of any cons-forms, while if
+it has the value :WHOLE the whole form will be annotated (the default).
+The former mode shows explicitly which forms were instrumented, while the
+latter mode is generally easier to read."
   (let ((paths)
         (*default-pathname-defaults* (merge-pathnames (pathname directory))))
     (ensure-directories-exist *default-pathname-defaults*)
@@ -227,11 +237,15 @@ files can be specified with the EXTERNAL-FORMAT parameter."
                       (warn "Error finding source location for source path ~A in file ~A~%" source-path file)))
                   (warn "Unable to find a source map for toplevel form ~A in file ~A~%" tlf file)))))
         ;; Now process the locations, from the shortest range to the longest
-        ;; one.
-        (dolist (location (sort locations #'<
-                                :key (lambda (location)
-                                       (- (second location)
-                                          (first location)))))
+        ;; one. If two locations have the same range, the one with the higher
+        ;; state takes precedence. The latter condition ensures that if
+        ;; there are both normal- and a branch-states for the same form,
+        ;; the branch-state will be used.
+        (setf locations (sort locations #'> :key #'fourth))
+        (dolist (location (stable-sort locations #'<
+                                       :key (lambda (location)
+                                              (- (second location)
+                                                 (first location)))))
           (destructuring-bind (start end source state) location
             (fill-with-state source states state start end))))
       (print-report html-stream file counts states source)
@@ -477,7 +491,7 @@ The source locations are stored in SOURCE-MAP."
             ;; allows the possibility that a comment was read
             (when listobj
              (unless (consp (car listobj))
-                (setf (car listobj) (gensym))
+               (setf (car listobj) (gensym))
                 (push (list start end *read-suppress*)
                       (gethash (car listobj) source-map)))
               (rplacd listtail listobj)
@@ -543,15 +557,15 @@ subforms along the path are considered and the start and end position
 of the deepest (i.e. smallest) possible form is returned."
   ;; compute all subforms along path
   (let ((forms (loop for n in path
-                     for m on path
-                     for dummy = (when (eql n :progn)
-                                   (return forms))
                      for f = form then (nth n f)
-                     unless (null (cdr m))
                      collect f into forms
                      finally (return forms))))
     ;; select the first subform present in source-map
-    (loop for form in (reverse forms)
+    (loop for real-form in (reverse forms)
+          for form = (if (or (eql *source-path-mode* :whole)
+                             (not (consp real-form)))
+                         real-form
+                         (car real-form))
           for positions = (gethash form source-map)
           until (and positions (null (cdr positions)))
           finally (destructuring-bind ((start end suppress)) positions
index 8f80aef..15ac812 100644 (file)
                             (sub-find-source-paths fm (cons pos path))
                             ;; Otherwise store the containing form. It's
                             ;; not perfect, but better than nothing.
-                            (setf (gethash subform *source-paths*)
-                                  (list* 'original-source-start
-                                         *current-form-number*
-                                         pos
-                                         path)))
+                            (unless (zerop pos)
+                              (setf (gethash subform *source-paths*)
+                                    (list* 'original-source-start
+                                           *current-form-number*
+                                           pos
+                                           path))))
                         (incf pos))
                       (setq subform (cdr subform))
                       (when (eq subform trail) (return)))))
                  (not (gethash form *source-paths*)))
         (let ((*current-path* (gethash forms *source-paths*)))
           (when *current-path*
-            (instrument-coverage start :progn form))))
+            (instrument-coverage start nil form))))
       start))
 
 (defun record-code-coverage (info cc)
index 0c8ea42..8c6c05d 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.8.41"
+"1.0.8.42"