/[slime]/slime/swank-backend.lisp
ViewVC logotype

Contents of /slime/swank-backend.lisp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.44 - (hide annotations)
Sun Apr 25 06:35:29 2004 UTC (9 years, 11 months ago) by heller
Branch: MAIN
CVS Tags: SLIME-0-13, SLIME-0-12
Changes since 1.43: +2 -5 lines
(arglist): Return a list or :not-available.  Don't return strings or
raise exceptions.
1 lgorrie 1.1 ;;;; -*- Mode: lisp; indent-tabs-mode: nil; outline-regexp: ";;;;;*" -*-
2     ;;;
3 lgorrie 1.13 ;;; slime-backend.lisp --- SLIME backend interface.
4 lgorrie 1.1 ;;;
5 lgorrie 1.13 ;;; Created by James Bielman in 2003. Released into the public domain.
6 lgorrie 1.1 ;;;
7 lgorrie 1.13 ;;; This file defines the functions that must be implemented
8     ;;; separately for each Lisp. Each is declared as a generic function
9     ;;; for which swank-<implementation>.lisp provides methods.
10 lgorrie 1.1
11 heller 1.36 (defpackage :swank-backend
12 lgorrie 1.1 (:use :common-lisp)
13 heller 1.36 (:export #:sldb-condition
14     #:original-condition
15     #:compiler-condition
16     #:message
17     #:short-message
18     #:condition
19     #:severity
20     #:location
21     #:location-p
22     #:location-buffer
23     #:location-position
24     #:position-p
25     #:position-pos
26     #:print-output-to-string
27 mbaringer 1.42 #:quit-lisp
28 heller 1.5 ))
29 lgorrie 1.1
30 heller 1.36 (in-package :swank-backend)
31 lgorrie 1.1
32    
33 lgorrie 1.21 ;;;; Metacode
34    
35     (defparameter *interface-functions* '()
36     "The names of all interface functions.")
37    
38     (defparameter *unimplemented-interfaces* '()
39     "List of interface functions that are not implemented.
40     DEFINTERFACE adds to this list and DEFIMPLEMENTATION removes.")
41    
42     (defmacro definterface (name args documentation &body default-body)
43     "Define an interface function for the backend to implement.
44     A generic function is defined with NAME, ARGS, and DOCUMENTATION.
45    
46     If a DEFAULT-BODY is supplied then NO-APPLICABLE-METHOD is specialized
47     to execute the body if the backend doesn't provide a specific
48     implementation.
49    
50     Backends implement these functions using DEFIMPLEMENTATION."
51 lgorrie 1.43 (check-type documentation string "a documentation string")
52 lgorrie 1.21 (flet ((gen-default-impl ()
53     (let ((received-args (gensym "ARGS-")))
54     `(defmethod no-applicable-method ((#:method
55     (eql (function ,name)))
56     &rest ,received-args)
57     (destructuring-bind ,args ,received-args
58     ,@default-body)))))
59 heller 1.36 ` (progn (defgeneric ,name ,args (:documentation ,documentation))
60     (pushnew ',name *interface-functions*)
61     ,(if (null default-body)
62     `(pushnew ',name *unimplemented-interfaces*)
63     (gen-default-impl))
64     (export ',name :swank-backend)
65     ',name)))
66 lgorrie 1.21
67     (defmacro defimplementation (name args &body body)
68 heller 1.25 `(progn (defmethod ,name ,args ,@body)
69     (if (member ',name *interface-functions*)
70     (setq *unimplemented-interfaces*
71     (remove ',name *unimplemented-interfaces*))
72     (warn "DEFIMPLEMENTATION of undefined interface (~S)" ',name))
73     ',name))
74 lgorrie 1.21
75     (defun warn-unimplemented-interfaces ()
76     "Warn the user about unimplemented backend features.
77     The portable code calls this function at startup."
78     (warn "These Swank interfaces are unimplemented:~% ~A"
79     (sort (copy-list *unimplemented-interfaces*) #'string<)))
80    
81    
82 lgorrie 1.13 ;;;; TCP server
83    
84 heller 1.29 (definterface create-socket (host port)
85     "Create a listening TCP socket on interface HOST and port PORT .")
86 lgorrie 1.13
87 lgorrie 1.21 (definterface local-port (socket)
88     "Return the local port number of SOCKET.")
89 lgorrie 1.1
90 lgorrie 1.21 (definterface close-socket (socket)
91     "Close the socket SOCKET.")
92 lgorrie 1.1
93 lgorrie 1.21 (definterface accept-connection (socket)
94 heller 1.16 "Accept a client connection on the listening socket SOCKET. Return
95 lgorrie 1.21 a stream for the new connection.")
96 heller 1.16
97 heller 1.31 (definterface add-sigio-handler (socket fn)
98 lgorrie 1.21 "Call FN whenever SOCKET is readable.")
99 heller 1.16
100 heller 1.31 (definterface remove-sigio-handlers (socket)
101     "Remove all sigio handlers for SOCKET.")
102    
103     (definterface add-fd-handler (socket fn)
104     "Call FN when Lisp is waiting for input and SOCKET is readable.")
105    
106     (definterface remove-fd-handlers (socket)
107     "Remove all fd-handlers for SOCKET.")
108 heller 1.18
109 heller 1.36 (definterface preferred-communication-style ()
110     "Return one of the symbols :spawn, :sigio, :fd-handler, or NIL."
111     nil)
112    
113 lgorrie 1.13 ;;; Base condition for networking errors.
114     (define-condition network-error (error) ())
115    
116 lgorrie 1.21 (definterface emacs-connected ()
117 lgorrie 1.13 "Hook called when the first connection from Emacs is established.
118     Called from the INIT-FN of the socket server that accepts the
119     connection.
120 lgorrie 1.1
121 lgorrie 1.13 This is intended for setting up extra context, e.g. to discover
122 lgorrie 1.21 that the calling thread is the one that interacts with Emacs."
123     nil)
124 lgorrie 1.1
125    
126 heller 1.20 ;;;; Unix signals
127    
128     (defconstant +sigint+ 2)
129    
130 heller 1.36 (definterface call-without-interrupts (fn)
131     "Call FN in a context where interrupts are disabled."
132     (funcall fn))
133 heller 1.20
134 heller 1.32 (definterface getpid ()
135     "Return the (Unix) process ID of this superior Lisp.")
136    
137     (definterface lisp-implementation-type-name ()
138     "Return a short name for the Lisp implementation."
139     (lisp-implementation-type))
140 heller 1.20
141 heller 1.39 (definterface set-default-directory (directory)
142     "Set the default directory.
143     This is used to resolve filenames without directory component."
144     (setf *default-pathname-defaults* (truename (merge-pathnames directory)))
145     (namestring *default-pathname-defaults*))
146    
147 heller 1.20
148 lgorrie 1.1 ;;;; Compilation
149 dbarlow 1.8
150 lgorrie 1.21 (definterface call-with-compilation-hooks (func)
151     "Call FUNC with hooks to trigger SLDB on compiler errors.")
152 lgorrie 1.13
153 vsedach 1.14 (defmacro with-compilation-hooks ((&rest ignore) &body body)
154     (declare (ignore ignore))
155 dbarlow 1.8 `(call-with-compilation-hooks (lambda () (progn ,@body))))
156 lgorrie 1.1
157 heller 1.36 (definterface swank-compile-string (string &key buffer position)
158 lgorrie 1.1 "Compile source from STRING. During compilation, compiler
159     conditions must be trapped and resignalled as COMPILER-CONDITIONs.
160    
161     If supplied, BUFFER and POSITION specify the source location in Emacs.
162    
163     Additionally, if POSITION is supplied, it must be added to source
164 lgorrie 1.21 positions reported in compiler conditions.")
165 lgorrie 1.1
166 lgorrie 1.43 (definterface operate-on-system (system-name operation-name &rest keyword-args)
167     "Perform OPERATION-NAME on SYSTEM-NAME using ASDF.
168     The KEYWORD-ARGS are passed on to the operation.
169     Example:
170     \(operate-on-system \"SWANK\" \"COMPILE-OP\" :force t)"
171     (unless (member :asdf *features*)
172     (error "ASDF is not loaded."))
173 heller 1.30 (with-compilation-hooks ()
174 lgorrie 1.43 (let ((operate (find-symbol "OPERATE" :asdf))
175     (operation (find-symbol operation-name :asdf)))
176     (when (null operation)
177     (error "Couldn't find ASDF operation ~S" operation-name))
178     (apply operate operation system-name keyword-args))))
179 mbaringer 1.26
180 heller 1.36 (definterface swank-compile-file (filename load-p)
181 lgorrie 1.1 "Compile FILENAME signalling COMPILE-CONDITIONs.
182 lgorrie 1.21 If LOAD-P is true, load the file after compilation.")
183 lgorrie 1.1
184 lgorrie 1.13 (deftype severity () '(member :error :warning :style-warning :note))
185    
186     ;; Base condition type for compiler errors, warnings and notes.
187     (define-condition compiler-condition (condition)
188     ((original-condition
189     ;; The original condition thrown by the compiler if appropriate.
190     ;; May be NIL if a compiler does not report using conditions.
191     :type (or null condition)
192     :initarg :original-condition
193     :accessor original-condition)
194    
195     (severity :type severity
196     :initarg :severity
197     :accessor severity)
198    
199     (message :initarg :message
200     :accessor message)
201    
202 heller 1.30 (short-message :initarg :short-message
203     :initform nil
204     :accessor short-message)
205    
206 lgorrie 1.13 (location :initarg :location
207     :accessor location)))
208 heller 1.30
209 lgorrie 1.17
210 lgorrie 1.13 ;;;; Streams
211    
212 lgorrie 1.21 (definterface make-fn-streams (input-fn output-fn)
213 lgorrie 1.13 "Return character input and output streams backended by functions.
214     When input is needed, INPUT-FN is called with no arguments to
215     return a string.
216     When output is ready, OUTPUT-FN is called with the output as its
217     argument.
218    
219     Output should be forced to OUTPUT-FN before calling INPUT-FN.
220    
221 lgorrie 1.21 The streams are returned as two values.")
222 lgorrie 1.13
223 lgorrie 1.1
224     ;;;; Documentation
225    
226 heller 1.36 (definterface arglist (name)
227     "Return the lambda list for the symbol NAME.
228    
229 heller 1.44 The result can be a list or the :not-available if the arglist cannot
230     be determined.")
231 lgorrie 1.1
232 lgorrie 1.21 (definterface macroexpand-all (form)
233 lgorrie 1.1 "Recursively expand all macros in FORM.
234 lgorrie 1.21 Return the resulting form.")
235 lgorrie 1.1
236 lgorrie 1.21 (definterface describe-symbol-for-emacs (symbol)
237 lgorrie 1.1 "Return a property list describing SYMBOL.
238    
239     The property list has an entry for each interesting aspect of the
240     symbol. The recognised keys are:
241    
242     :VARIABLE :FUNCTION :SETF :TYPE :CLASS :MACRO :COMPILER-MACRO
243     :ALIEN-TYPE :ALIEN-STRUCT :ALIEN-UNION :ALIEN-ENUM
244    
245     The value of each property is the corresponding documentation string,
246     or :NOT-DOCUMENTED. It is legal to include keys not listed here.
247    
248     Properties should be included if and only if they are applicable to
249     the symbol. For example, only (and all) fbound symbols should include
250     the :FUNCTION property.
251    
252     Example:
253     \(describe-symbol-for-emacs 'vector)
254     => (:CLASS :NOT-DOCUMENTED
255     :TYPE :NOT-DOCUMENTED
256 lgorrie 1.21 :FUNCTION \"Constructs a simple-vector from the given objects.\")")
257    
258     (definterface describe-definition (name type)
259     "Describe the definition NAME of TYPE.
260     TYPE can be any value returned by DESCRIBE-SYMBOL-FOR-EMACS.
261    
262     Return a documentation string, or NIL if none is available.")
263 lgorrie 1.2
264    
265     ;;;; Debugging
266    
267 lgorrie 1.21 (definterface call-with-debugging-environment (debugger-loop-fn)
268 lgorrie 1.2 "Call DEBUGGER-LOOP-FN in a suitable debugging environment.
269    
270     This function is called recursively at each debug level to invoke the
271     debugger loop. The purpose is to setup any necessary environment for
272     other debugger callbacks that will be called within the debugger loop.
273    
274     For example, this is a reasonable place to compute a backtrace, switch
275 lgorrie 1.21 to safe reader/printer settings, and so on.")
276 lgorrie 1.2
277     (define-condition sldb-condition (condition)
278     ((original-condition
279     :initarg :original-condition
280 heller 1.5 :accessor original-condition))
281 lgorrie 1.2 (:documentation
282     "Wrapper for conditions that should not be debugged.
283    
284     When a condition arises from the internals of the debugger, it is not
285     desirable to debug it -- we'd risk entering an endless loop trying to
286     debug the debugger! Instead, such conditions can be reported to the
287     user without (re)entering the debugger by wrapping them as
288     `sldb-condition's."))
289    
290 heller 1.36 (definterface compute-backtrace (start end)
291 lgorrie 1.3 "Return a list containing a backtrace of the condition current
292     being debugged. The results are unspecified if this function is
293 heller 1.36 called outside the dynamic contour CALL-WITH-DEBUGGING-ENVIRONMENT.
294    
295     START and END are zero-based indices constraining the number of frames
296     returned. Frame zero is defined as the frame which invoked the
297     debugger. If END is nil, return the frames from START to the end of
298     the stack.")
299 lgorrie 1.3
300 heller 1.36 (definterface print-frame (frame stream)
301     "Print frame to stream.")
302 lgorrie 1.3
303 lgorrie 1.21 (definterface frame-source-location-for-emacs (frame-number)
304     "Return the source location for FRAME-NUMBER.")
305 lgorrie 1.3
306 lgorrie 1.21 (definterface frame-catch-tags (frame-number)
307 lgorrie 1.3 "Return a list of XXX list of what? catch tags for a debugger
308     stack frame. The results are undefined unless this is called
309     within the dynamic contour of a function defined by
310 lgorrie 1.21 DEFINE-DEBUGGER-HOOK.")
311 lgorrie 1.3
312 lgorrie 1.21 (definterface frame-locals (frame-number)
313 lgorrie 1.3 "Return a list of XXX local variable designators define me
314     for a debugger stack frame. The results are undefined unless
315     this is called within the dynamic contour of a function defined
316 lgorrie 1.21 by DEFINE-DEBUGGER-HOOK.")
317 heller 1.37
318     (definterface disassemble-frame (frame-number)
319     "Disassemble the code for the FRAME-NUMBER.
320     The output should be written to standard output.
321     FRAME-NUMBER is a non-negative interger.")
322    
323 lgorrie 1.21 (definterface eval-in-frame (form frame-number)
324 lgorrie 1.3 "Evaluate a Lisp form in the lexical context of a stack frame
325     in the debugger. The results are undefined unless called in the
326     dynamic contour of a function defined by DEFINE-DEBUGGER-HOOK.
327    
328     FRAME-NUMBER must be a positive integer with 0 indicating the
329     frame which invoked the debugger.
330    
331     The return value is the result of evaulating FORM in the
332 lgorrie 1.21 appropriate context.")
333 heller 1.22
334     (definterface return-from-frame (frame-number form)
335     "Unwind the stack to the frame FRAME-NUMBER and return the value(s)
336     produced by evaluating FORM in the frame context to its caller.
337    
338     Execute any clean-up code from unwind-protect forms above the frame
339     during unwinding.
340    
341     Return a string describing the error if it's not possible to return
342     from the frame.")
343    
344     (definterface restart-frame (frame-number)
345     "Restart execution of the frame FRAME-NUMBER with the same arguments
346     as it was called originally.")
347 lgorrie 1.3
348    
349 heller 1.36 ;;;; Definition finding
350    
351     (defstruct (:location (:type list) :named
352     (:constructor make-location (buffer position)))
353     buffer position)
354    
355     (defstruct (:error (:type list) :named (:constructor)) message)
356     (defstruct (:file (:type list) :named (:constructor)) name)
357     (defstruct (:buffer (:type list) :named (:constructor)) name)
358     (defstruct (:position (:type list) :named (:constructor)) pos)
359    
360     (definterface find-definitions (name)
361     "Return a list ((DSPEC LOCATION) ...) for NAME's definitions.
362    
363 heller 1.38 NAME is a \"definition specifier\".
364 heller 1.36
365 heller 1.38 DSPEC is a \"definition specifier\" describing the
366 heller 1.36 definition, e.g., FOO or (METHOD FOO (STRING NUMBER)) or
367 heller 1.38 \(DEFVAR FOO).
368    
369     LOCATION is the source location for the definition.")
370 heller 1.36
371    
372     ;;;; XREF
373    
374     (definterface who-calls (function-name)
375     "Return the call sites of FUNCTION-NAME (a symbol).
376     The results is a list ((DSPEC LOCATION) ...).")
377    
378     (definterface who-references (variable-name)
379     "Return the locations where VARIABLE-NAME (a symbol) is referenced.
380     See WHO-CALLS for a description of the return value.")
381    
382     (definterface who-binds (variable-name)
383     "Return the locations where VARIABLE-NAME (a symbol) is bound.
384     See WHO-CALLS for a description of the return value.")
385    
386     (definterface who-sets (variable-name)
387     "Return the locations where VARIABLE-NAME (a symbol) is set.
388     See WHO-CALLS for a description of the return value.")
389    
390     (definterface who-macroexpands (macro-name)
391     "Return the locations where MACRO-NAME (a symbol) is expanded.
392     See WHO-CALLS for a description of the return value.")
393    
394     (definterface who-specializes (class-name)
395     "Return the locations where CLASS-NAME (a symbol) is specialized.
396     See WHO-CALLS for a description of the return value.")
397    
398     ;;; Simpler variants.
399    
400     (definterface list-callers (function-name)
401     "List the callers of FUNCTION-NAME.
402     This function is like WHO-CALLS except that it is expected to use
403     lower-level means. Whereas WHO-CALLS is usually implemented with
404     special compiler support, LIST-CALLERS is usually implemented by
405     groveling for constants in function objects throughout the heap.
406    
407     The return value is as for WHO-CALLS.")
408    
409     (definterface list-callees (function-name)
410     "List the functions called by FUNCTION-NAME.
411     See LIST-CALLERS for a description of the return value.")
412    
413    
414 heller 1.23 ;;;; Profiling
415    
416     ;;; The following functions define a minimal profiling interface.
417    
418     (definterface profile (fname)
419     "Marks symbol FNAME for profiling.")
420    
421     (definterface profiled-functions ()
422     "Returns a list of profiled functions.")
423    
424     (definterface unprofile (fname)
425     "Marks symbol FNAME as not profiled.")
426    
427     (definterface unprofile-all ()
428     "Marks all currently profiled functions as not profiled."
429     (dolist (f (profiled-functions))
430     (unprofile f)))
431    
432     (definterface profile-report ()
433     "Prints profile report.")
434    
435     (definterface profile-reset ()
436     "Resets profile counters.")
437    
438     (definterface profile-package (package callers-p methods)
439     "Wrap profiling code around all functions in PACKAGE. If a function
440     is already profiled, then unprofile and reprofile (useful to notice
441     function redefinition.)
442    
443     If CALLERS-P is T names have counts of the most common calling
444     functions recorded.
445    
446     When called with arguments :METHODS T, profile all methods of all
447     generic functions having names in the given package. Generic functions
448     themselves, that is, their dispatch functions, are left alone.")
449    
450    
451 heller 1.19 ;;;; Inspector
452    
453 heller 1.35 (definterface inspected-parts (object)
454     "Return a short description and a list of (LABEL . VALUE) pairs."
455     (values (format nil "~S is an atom." object) '()))
456 heller 1.19
457 heller 1.29 (definterface describe-primitive-type (object)
458 heller 1.35 "Return a string describing the primitive type of object."
459 heller 1.36 (declare (ignore object))
460 heller 1.35 "N/A")
461 heller 1.19
462    
463 heller 1.36 ;;;; Multithreading
464 lgorrie 1.21 ;;;
465     ;;; The default implementations are sufficient for non-multiprocessing
466     ;;; implementations.
467 lgorrie 1.9
468 lgorrie 1.21 (definterface startup-multiprocessing ()
469 lgorrie 1.9 "Initialize multiprocessing, if necessary.
470    
471     This function is called directly through the listener, not in an RPC
472     from Emacs. This is to support interfaces such as CMUCL's
473     MP::STARTUP-IDLE-AND-TOP-LEVEL-LOOPS which does not return like a
474 lgorrie 1.21 normal function."
475     nil)
476 lgorrie 1.9
477 lgorrie 1.21 (definterface spawn (fn &key name)
478     "Create a new thread to call FN.")
479 lgorrie 1.17
480 heller 1.28 (definterface thread-name (thread)
481     "Return the name of THREAD.
482 lgorrie 1.9
483     Thread names are be single-line strings and are meaningful to the
484 lgorrie 1.21 user. They do not have to be unique."
485 heller 1.28 (declare (ignore thread))
486 lgorrie 1.21 "The One True Thread")
487 lgorrie 1.9
488 heller 1.28 (definterface thread-status (thread)
489     "Return a string describing THREAD's state."
490     (declare (ignore thread))
491     "")
492    
493 lgorrie 1.21 (definterface make-lock (&key name)
494 lgorrie 1.17 "Make a lock for thread synchronization.
495 lgorrie 1.21 Only one thread may hold the lock (via CALL-WITH-LOCK-HELD) at a time."
496 heller 1.23 (declare (ignore name))
497 lgorrie 1.21 :null-lock)
498 lgorrie 1.9
499 lgorrie 1.21 (definterface call-with-lock-held (lock function)
500     "Call FUNCTION with LOCK held, queueing if necessary."
501 heller 1.24 (declare (ignore lock)
502     (type function function))
503 lgorrie 1.21 (funcall function))
504 heller 1.25
505     (definterface current-thread ()
506     "Return the currently executing thread."
507     0)
508 heller 1.28
509     (definterface all-threads ()
510     "Return a list of all threads.")
511    
512     (definterface thread-alive-p (thread)
513 heller 1.35 "Test if THREAD is termintated."
514     (member thread (all-threads)))
515 heller 1.25
516     (definterface interrupt-thread (thread fn)
517     "Cause THREAD to execute FN.")
518    
519 mbaringer 1.34 (definterface kill-thread (thread)
520     "Kill THREAD."
521     (declare (ignore thread))
522     nil)
523    
524 heller 1.25 (definterface send (thread object)
525     "Send OBJECT to thread THREAD.")
526    
527     (definterface receive ()
528     "Return the next message from current thread's mailbox.")
529 mbaringer 1.42
530     (definterface quit-lisp ()
531     "Exit the current lisp image.")

  ViewVC Help
Powered by ViewVC 1.1.5