From 49da8bb4ea5899e3d23cef4c80c246b2101cfaac Mon Sep 17 00:00:00 2001 From: Juho Snellman Date: Tue, 5 Jun 2007 09:56:50 +0000 Subject: [PATCH] 1.0.6.23: fix a source location tracking problem in sb-cover * The logic for selecting the innermost form that contains a given character in the source file did not work correctly in cases where an exact location could not be found for some source path. This should mainly happen when reader macros are involved. * Instead of sorting the source paths by the length of the path, sort them by the length of the character range of the source location. --- contrib/sb-cover/cover.lisp | 27 ++++++++++++++++++--------- version.lisp-expr | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/contrib/sb-cover/cover.lisp b/contrib/sb-cover/cover.lisp index a4eb33b..e749e6d 100644 --- a/contrib/sb-cover/cover.lisp +++ b/contrib/sb-cover/cover.lisp @@ -138,16 +138,17 @@ files can be specified with the EXTERNAL-FORMAT parameter." maps) ;; Go through all records, find the matching source in the file, ;; and update STATES to contain the state of the record in the - ;; indexes matching the source location. Process the longest paths - ;; first, so that the state of each index will reflect the state - ;; of the innermost containing form. Processes branch-records - ;; before expr-records of the same length, for the same reason. + ;; indexes matching the source location. We do this in two stages: + ;; the first stage records the character ranges, and the second stage + ;; does the update, in order from shortest to longest ranges. This + ;; ensures that for each index in STATES will reflect the state of + ;; the innermost containing form. (let ((counts (list :branch (make-instance 'sample-count :mode :branch) :expression (make-instance 'sample-count :mode :expression)))) - (let ((records (append branch-records expr-records))) - (dolist (record (stable-sort records #'> - :key (lambda (e) (length (second e))))) + (let ((records (append branch-records expr-records)) + (locations nil)) + (dolist (record records) (destructuring-bind (mode path state) record (let* ((path (reverse path)) (tlf (car path)) @@ -174,10 +175,18 @@ files can be specified with the EXTERNAL-FORMAT parameter." (source-path-source-position (cons 0 source-path) source-form source-map) - (fill-with-state source states state start end)) + (push (list start end source state) locations)) (error () (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)))))) + (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))))) + (destructuring-bind (start end source state) location + (fill-with-state source states state start end)))) (print-report html-stream file counts states source) (format html-stream "") (list (getf counts :expression) diff --git a/version.lisp-expr b/version.lisp-expr index 1f59118..c7c8eb8 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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.6.22" +"1.0.6.23" -- 1.7.10.4