[slime-cvs] CVS update: slime/swank-allegro.lisp
Helmut Eller
heller at common-lisp.net
Sun Aug 1 06:44:47 UTC 2004
Update of /project/slime/cvsroot/slime
In directory common-lisp.net:/tmp/cvs-serv18752
Modified Files:
swank-allegro.lisp
Log Message:
(swank-compile-string): Use a temporary file and set
excl::*source-pathname* manually. This way we can find the source
buffer of functions compiled with C-c C-c.
(call-with-temp-file, compile-from-temp-file): New functions.
(list-callers, function-callers, in-constants-p)
(map-function-constants): Implements list callers by groveling through
all fbound symbols.
Date: Sat Jul 31 23:44:47 2004
Author: heller
Index: slime/swank-allegro.lisp
diff -u slime/swank-allegro.lisp:1.45 slime/swank-allegro.lisp:1.46
--- slime/swank-allegro.lisp:1.45 Sat Jul 3 17:36:14 2004
+++ slime/swank-allegro.lisp Sat Jul 31 23:44:46 2004
@@ -230,13 +230,37 @@
(let ((*buffer-name* nil))
(compile-file *compile-filename* :load-after-compile load-p))))
+(defun call-with-temp-file (fn)
+ (let ((tmpname (system:make-temp-file-name)))
+ (unwind-protect
+ (with-open-file (file tmpname :direction :output :if-exists :error)
+ (funcall fn file tmpname))
+ (delete-file tmpname))))
+
+(defun compile-from-temp-file (string)
+ (call-with-temp-file
+ (lambda (stream filename)
+ (write-string string stream)
+ (finish-output stream)
+ (let ((binary-filename (compile-file filename :load-after-compile t)))
+ (when binary-filename
+ (delete-file binary-filename))))))
+
(defimplementation swank-compile-string (string &key buffer position)
+ ;; We store the source buffer in excl::*source-pathname* as a string
+ ;; of the form <buffername>:<start-offset>. Quite ugly encoding, but
+ ;; the fasl file is corrupted if we use some other datatype.
(with-compilation-hooks ()
(let ((*buffer-name* buffer)
(*buffer-start-position* position)
(*buffer-string* string))
- (funcall (compile nil (read-from-string
- (format nil "(~S () ~A)" 'lambda string)))))))
+ (compile-from-temp-file
+ (format nil "~S ~S~%~A"
+ `(in-package ,(package-name *package*))
+ `(eval-when (:compile-toplevel :load-toplevel)
+ (setq excl::*source-pathname*
+ (format nil "~A:~D" ',buffer ',position)))
+ string)))))
;;;; Definition Finding
@@ -257,6 +281,11 @@
pos)))
((member :top-level)
(list :error (format nil "Defined at toplevel: ~A" fspec)))
+ (string
+ (let ((pos (position #\: file)))
+ (make-location
+ (list :buffer (subseq file 0 pos))
+ (list :position (parse-integer (subseq file (1+ pos)))))))
(null
(list :error (format nil "Unknown source location for ~A" fspec))))))
@@ -284,6 +313,42 @@
(defun xref-result (fspecs)
(loop for fspec in fspecs
append (fspec-definition-locations fspec)))
+
+;; list-callers implemented by groveling through all fbound symbols.
+;; Only symbols are considered. Functions in the constant pool are
+;; searched recursevly. Closure environments are ignored at the
+;; moment (constants in methods are therefore not found).
+
+(defun map-function-constants (function fn depth)
+ "Call FN with the elements of FUNCTION's constant pool."
+ (do ((i 0 (1+ i))
+ (max (excl::function-constant-count function)))
+ ((= i max))
+ (let ((c (excl::function-constant function i)))
+ (cond ((and (functionp c)
+ (not (eq c function))
+ (plusp depth))
+ (map-function-constants c fn (1- depth)))
+ (t
+ (funcall fn c))))))
+
+(defun in-constants-p (fn symbol)
+ (map-function-constants
+ fn
+ (lambda (c) (if (eq c symbol) (return-from in-constants-p t)))
+ 3))
+
+(defun function-callers (name)
+ (let ((callers '()))
+ (do-all-symbols (sym)
+ (when (fboundp sym)
+ (let ((fn (fdefinition sym)))
+ (when (in-constants-p fn name)
+ (push sym callers)))))
+ callers))
+
+(defimplementation list-callers (name)
+ (xref-result (function-callers name)))
;;;; Inspecting
More information about the slime-cvs
mailing list