[slime-cvs] CVS update: slime/swank-lispworks.lisp
Martin Simmons
msimmons at common-lisp.net
Wed Jun 9 12:40:53 UTC 2004
Update of /project/slime/cvsroot/slime
In directory common-lisp.net:/tmp/cvs-serv28507
Modified Files:
swank-lispworks.lisp
Log Message:
(dspec-stream-position): New function to make source location work for anything
complicated e.g. methods.
(with-swank-compilation-unit): Refactoring.
(who-macroexpands): Implemented.
(list-callers): Implemented.
Date: Wed Jun 9 05:40:52 2004
Author: msimmons
Index: slime/swank-lispworks.lisp
diff -u slime/swank-lispworks.lisp:1.41 slime/swank-lispworks.lisp:1.42
--- slime/swank-lispworks.lisp:1.41 Sat May 1 09:37:43 2004
+++ slime/swank-lispworks.lisp Wed Jun 9 05:40:52 2004
@@ -291,12 +291,17 @@
;;; Compilation
+(defmacro with-swank-compilation-unit ((location &rest options) &body body)
+ (lw:rebinding (location)
+ `(let ((compiler::*error-database* '()))
+ (with-compilation-unit ,options
+ , at body
+ (signal-error-data-base compiler::*error-database* ,location)
+ (signal-undefined-functions compiler::*unknown-functions* ,location)))))
+
(defimplementation swank-compile-file (filename load-p)
- (let ((compiler::*error-database* '()))
- (with-compilation-unit ()
- (compile-file filename :load load-p)
- (signal-error-data-base compiler::*error-database* filename)
- (signal-undefined-functions compiler::*unknown-functions* filename))))
+ (with-swank-compilation-unit (filename)
+ (compile-file filename :load load-p)))
(defun map-error-database (database fn)
(loop for (filename . defs) in database do
@@ -340,6 +345,34 @@
(null (list :position offset))
(symbol (list :function-name (string dspec)))))
+#-(or lispworks-4.1 lispworks-4.2) ; no dspec:parse-form-dspec prior to 4.3
+(defun dspec-stream-position (stream dspec)
+ (with-standard-io-syntax
+ (let ((*read-eval* nil))
+ (loop (let* ((pos (file-position stream))
+ (form (read stream nil '#1=#:eof)))
+ (when (eq form '#1#)
+ (return nil))
+ (labels ((check-dspec (form)
+ (when (consp form)
+ (let ((operator (car form)))
+ (case operator
+ ((progn)
+ (mapcar #'check-dspec
+ (cdr form)))
+ ((eval-when locally macrolet symbol-macrolet)
+ (mapcar #'check-dspec
+ (cddr form)))
+ ((in-package)
+ (let ((package (find-package (second form))))
+ (when package
+ (setq *package* package))))
+ (otherwise
+ (let ((form-dspec (dspec:parse-form-dspec form)))
+ (when (dspec:dspec-equal dspec form-dspec)
+ (return pos)))))))))
+ (check-dspec form)))))))
+
(defun emacs-buffer-location-p (location)
(and (consp location)
(eq (car location) :emacs-buffer)))
@@ -357,9 +390,17 @@
(symbol (symbol-name dspec))
(cons (string (dspec:dspec-primary-name dspec))))))
(etypecase location
- ((or pathname string)
- (make-location `(:file ,(filename location))
- (dspec-buffer-position dspec 1)))
+ ((or pathname string)
+ (let ((checked-filename (filename location)))
+ (make-location `(:file ,checked-filename)
+ #+(or lispworks-4.1 lispworks-4.2)
+ (dspec-buffer-position dspec 1)
+ #-(or lispworks-4.1 lispworks-4.2)
+ (with-open-file (stream checked-filename)
+ (let ((position (dspec-stream-position stream dspec)))
+ (if position
+ (list :position (1+ position) t)
+ (dspec-buffer-position dspec 1)))))))
(symbol `(:error ,(format nil "Cannot resolve location: ~S" location)))
((satisfies emacs-buffer-location-p)
(destructuring-bind (_ buffer offset string) location
@@ -367,6 +408,16 @@
(make-location `(:buffer ,buffer)
(dspec-buffer-position dspec offset)))))))
+(defun make-dspec-progenitor-location (dspec location)
+ (let ((canon-dspec (dspec:canonicalize-dspec dspec)))
+ (make-dspec-location
+ (if canon-dspec
+ (if (dspec:local-dspec-p canon-dspec)
+ (dspec:dspec-progenitor canon-dspec)
+ canon-dspec)
+ nil)
+ location)))
+
(defun signal-error-data-base (database location)
(map-error-database
database
@@ -374,7 +425,7 @@
(declare (ignore filename))
(signal-compiler-condition
(format nil "~A" condition)
- (make-dspec-location dspec location)
+ (make-dspec-progenitor-location dspec location)
condition))))
(defun signal-undefined-functions (htab filename)
@@ -382,7 +433,7 @@
(dolist (dspec dspecs)
(signal-compiler-condition
(format nil "Undefined function ~A" unfun)
- (make-dspec-location dspec filename)
+ (make-dspec-progenitor-location dspec filename)
nil)))
htab))
@@ -390,16 +441,13 @@
(assert buffer)
(assert position)
(let* ((location (list :emacs-buffer buffer position string))
- (compiler::*error-database* '())
(tmpname (hcl:make-temp-file nil "lisp")))
- (with-compilation-unit ()
+ (with-swank-compilation-unit (location)
(compile-from-temp-file
(format nil "~S~%~A" `(eval-when (:compile-toplevel)
(setq dspec::*location* (list , at location)))
string)
- tmpname)
- (signal-error-data-base compiler::*error-database* location)
- (signal-undefined-functions compiler::*unknown-functions* location))))
+ tmpname))))
;;; xref
@@ -408,7 +456,26 @@
(xref-results (,function name))))
(defxref who-calls hcl:who-calls)
+(defxref who-macroexpands hcl:who-calls) ; macros are in the calls table too
(defxref list-callees hcl:calls-who)
+(defxref list-callers list-callers-internal)
+
+(defun list-callers-internal (name)
+ (let ((callers (make-array 100
+ :fill-pointer 0
+ :adjustable t)))
+ (hcl:sweep-all-objects
+ #'(lambda (object)
+ (when (and #+Harlequin-PC-Lisp (low:compiled-code-p object)
+ #-Harlequin-PC-Lisp (sys::callablep object)
+ (system::find-constant$funcallable name object))
+ (vector-push-extend object callers))))
+ ;; Delay dspec:object-dspec until after sweep-all-objects
+ ;; to reduce allocation problems.
+ (loop for object across callers
+ collect (if (symbolp object)
+ (list 'function object)
+ (dspec:object-dspec object)))))
;; only for lispworks 4.2 and above
#-lispworks4.1
More information about the slime-cvs
mailing list