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

Contents of /slime/swank-backend.lisp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (hide annotations)
Thu Jan 15 11:42:12 2004 UTC (10 years, 3 months ago) by lgorrie
Branch: MAIN
Changes since 1.16: +13 -50 lines
Changed multiprocessing interface.
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     (defpackage :swank
12     (:use :common-lisp)
13 lgorrie 1.3 (:nicknames #:swank-backend)
14 lgorrie 1.9 (:export #:*sldb-pprint-frames*
15     #:apropos-list-for-emacs
16     #:arglist-string
17     #:backtrace
18     #:call-with-I/O-lock
19     #:call-with-conversation-lock
20 heller 1.5 #:compiler-notes-for-emacs
21 lgorrie 1.9 #:completions
22 lgorrie 1.13 #:create-server
23 lgorrie 1.9 #:create-swank-server
24     #:describe-alien-enum
25     #:describe-alien-struct
26 heller 1.5 #:describe-alien-type
27 lgorrie 1.9 #:describe-alien-union
28     #:describe-class
29 heller 1.5 #:describe-function
30     #:describe-inspectee
31     #:describe-setf-function
32 lgorrie 1.9 #:describe-symbol
33     #:describe-type
34     #:disassemble-symbol
35 heller 1.5 #:documentation-symbol
36 lgorrie 1.9 #:eval-in-frame
37     #:eval-string
38     #:eval-string-in-frame
39 heller 1.7 #:find-function-locations
40 heller 1.5 #:frame-catch-tags
41 lgorrie 1.9 #:frame-locals
42     #:frame-source-location-for-emacs
43 heller 1.5 #:frame-source-position
44 lgorrie 1.9 #:getpid
45     #:give-goahead
46     #:give-gohead
47     #:init-inspector
48     #:inspect-in-frame
49     #:inspect-nth-part
50     #:inspector-next
51 heller 1.5 #:inspector-pop
52 lgorrie 1.9 #:interactive-eval
53     #:interactive-eval-region
54 heller 1.5 #:invoke-nth-restart
55 lgorrie 1.10 #:invoke-nth-restart-for-emacs
56 lgorrie 1.9 #:list-all-package-names
57     #:list-callees
58     #:list-callers
59     #:listener-eval
60     #:load-file
61     #:pprint-eval
62 heller 1.5 #:pprint-eval-string-in-frame
63 lgorrie 1.9 #:quit-inspector
64     #:re-evaluate-defvar
65     #:set-default-directory
66     #:set-package
67 heller 1.5 #:sldb-abort
68 lgorrie 1.10 #:sldb-break-with-default-debugger
69 heller 1.5 #:sldb-continue
70 lgorrie 1.9 #:slime-debugger-function
71     #:start-server
72     #:startup-multiprocessing
73     #:startup-multiprocessing-for-emacs
74     #:swank-compile-file
75     #:swank-compile-string
76     #:swank-macroexpand
77     #:swank-macroexpand-1
78     #:swank-macroexpand-all
79 heller 1.5 #:take-input
80 lgorrie 1.9 #:thread-id
81     #:thread-name
82     #:throw-to-toplevel
83     #:toggle-trace-fdefinition
84     #:untrace-all
85     #:wait-goahead
86     #:who-binds
87     #:who-calls
88     #:who-macroexpands
89     #:who-references
90     #:who-sets
91 heller 1.5 ))
92 lgorrie 1.1
93     (in-package :swank)
94    
95    
96 lgorrie 1.13 ;;;; TCP server
97    
98 heller 1.16 (defgeneric create-socket (port)
99     (:documentation "Create a listening TCP socket on port PORT."))
100 lgorrie 1.13
101 heller 1.16 (defgeneric local-port (socket)
102     (:documentation "Return the local port number of SOCKET."))
103 lgorrie 1.1
104 heller 1.16 (defgeneric close-socket (socket)
105     (:documentation "Close the socket SOCKET."))
106 lgorrie 1.1
107 heller 1.16 (defgeneric accept-connection (socket)
108     (:documentation
109     "Accept a client connection on the listening socket SOCKET. Return
110     a stream for the new connection."))
111    
112     (defgeneric add-input-handler (socket fn)
113     (:documentation "Call FN whenever SOCKET is readable."))
114    
115 lgorrie 1.13 ;;; Base condition for networking errors.
116     (define-condition network-error (error) ())
117    
118     (defgeneric emacs-connected ()
119     (:documentation
120     "Hook called when the first connection from Emacs is established.
121     Called from the INIT-FN of the socket server that accepts the
122     connection.
123 lgorrie 1.1
124 lgorrie 1.13 This is intended for setting up extra context, e.g. to discover
125     that the calling thread is the one that interacts with Emacs."))
126 lgorrie 1.1
127 lgorrie 1.13 (defmethod no-applicable-method ((m (eql #'emacs-connected)) &rest _)
128     (declare (ignore _))
129     nil)
130 lgorrie 1.1
131    
132     ;;;; Compilation
133 dbarlow 1.8
134     (defgeneric call-with-compilation-hooks (func)
135     (:documentation
136     "Call FUNC with hooks to trigger SLDB on compiler errors."))
137 lgorrie 1.13
138 vsedach 1.14 (defmacro with-compilation-hooks ((&rest ignore) &body body)
139     (declare (ignore ignore))
140 dbarlow 1.8 `(call-with-compilation-hooks (lambda () (progn ,@body))))
141 lgorrie 1.1
142     (defgeneric compile-string-for-emacs (string &key buffer position)
143     (:documentation
144     "Compile source from STRING. During compilation, compiler
145     conditions must be trapped and resignalled as COMPILER-CONDITIONs.
146    
147     If supplied, BUFFER and POSITION specify the source location in Emacs.
148    
149     Additionally, if POSITION is supplied, it must be added to source
150     positions reported in compiler conditions."))
151    
152     (defgeneric compile-file-for-emacs (filename load-p)
153     (:documentation
154     "Compile FILENAME signalling COMPILE-CONDITIONs.
155     If LOAD-P is true, load the file after compilation."))
156    
157 lgorrie 1.13 (deftype severity () '(member :error :warning :style-warning :note))
158    
159     ;; Base condition type for compiler errors, warnings and notes.
160     (define-condition compiler-condition (condition)
161     ((original-condition
162     ;; The original condition thrown by the compiler if appropriate.
163     ;; May be NIL if a compiler does not report using conditions.
164     :type (or null condition)
165     :initarg :original-condition
166     :accessor original-condition)
167    
168     (severity :type severity
169     :initarg :severity
170     :accessor severity)
171    
172     (message :initarg :message
173     :accessor message)
174    
175     (location :initarg :location
176     :accessor location)))
177    
178 lgorrie 1.17
179 lgorrie 1.13 ;;;; Streams
180    
181     (defgeneric make-fn-streams (input-fn output-fn)
182     (:documentation
183     "Return character input and output streams backended by functions.
184     When input is needed, INPUT-FN is called with no arguments to
185     return a string.
186     When output is ready, OUTPUT-FN is called with the output as its
187     argument.
188    
189     Output should be forced to OUTPUT-FN before calling INPUT-FN.
190    
191     The streams are returned as two values."))
192    
193 lgorrie 1.1
194     ;;;; Documentation
195    
196     (defgeneric arglist-string (function-name)
197     (:documentation
198     "Return the argument for FUNCTION-NAME as a string.
199     The result should begin and end with parenthesis."))
200    
201     (defgeneric macroexpand-all (form)
202     (:documentation
203     "Recursively expand all macros in FORM.
204     Return the resulting form."))
205    
206     (defgeneric describe-symbol-for-emacs (symbol)
207     (:documentation
208     "Return a property list describing SYMBOL.
209    
210     The property list has an entry for each interesting aspect of the
211     symbol. The recognised keys are:
212    
213     :VARIABLE :FUNCTION :SETF :TYPE :CLASS :MACRO :COMPILER-MACRO
214     :ALIEN-TYPE :ALIEN-STRUCT :ALIEN-UNION :ALIEN-ENUM
215    
216     The value of each property is the corresponding documentation string,
217     or :NOT-DOCUMENTED. It is legal to include keys not listed here.
218    
219     Properties should be included if and only if they are applicable to
220     the symbol. For example, only (and all) fbound symbols should include
221     the :FUNCTION property.
222    
223     Example:
224     \(describe-symbol-for-emacs 'vector)
225     => (:CLASS :NOT-DOCUMENTED
226     :TYPE :NOT-DOCUMENTED
227     :FUNCTION \"Constructs a simple-vector from the given objects.\")"))
228 lgorrie 1.2
229    
230     ;;;; Debugging
231    
232     (defgeneric call-with-debugging-environment (debugger-loop-fn)
233     (:documentation
234     "Call DEBUGGER-LOOP-FN in a suitable debugging environment.
235    
236     This function is called recursively at each debug level to invoke the
237     debugger loop. The purpose is to setup any necessary environment for
238     other debugger callbacks that will be called within the debugger loop.
239    
240     For example, this is a reasonable place to compute a backtrace, switch
241     to safe reader/printer settings, and so on."))
242    
243     (define-condition sldb-condition (condition)
244     ((original-condition
245     :initarg :original-condition
246 heller 1.5 :accessor original-condition))
247 lgorrie 1.2 (:documentation
248     "Wrapper for conditions that should not be debugged.
249    
250     When a condition arises from the internals of the debugger, it is not
251     desirable to debug it -- we'd risk entering an endless loop trying to
252     debug the debugger! Instead, such conditions can be reported to the
253     user without (re)entering the debugger by wrapping them as
254     `sldb-condition's."))
255    
256     (defgeneric debugger-info-for-emacs (start end)
257     (:documentation
258     "Return debugger state, with stack frames from START to END.
259     The result is a list:
260 heller 1.12 (condition ({restart}*) ({stack-frame}*)
261 lgorrie 1.2 where
262 heller 1.12 condition ::= (description type)
263 lgorrie 1.2 restart ::= (name description)
264     stack-frame ::= (number description)
265    
266 heller 1.12 condition---a pair of strings: message, and type.
267 lgorrie 1.2
268     restart---a pair of strings: restart name, and description.
269    
270     stack-frame---a number from zero (the top), and a printed
271     representation of the frame's call.
272    
273     Below is an example return value. In this case the condition was a
274     division by zero (multi-line description), and only one frame is being
275     fetched (start=0, end=1).
276    
277 heller 1.12 ((\"Arithmetic error DIVISION-BY-ZERO signalled.
278     Operation was KERNEL::DIVISION, operands (1 0).\"
279     \"[Condition of type DIVISION-BY-ZERO]\")
280 lgorrie 1.2 ((\"ABORT\" \"Return to Slime toplevel.\")
281     (\"ABORT\" \"Return to Top-Level.\"))
282 heller 1.12 ((0 \"(KERNEL::INTEGER-/-INTEGER 1 0)\")))"))
283 lgorrie 1.1
284 lgorrie 1.3 (defgeneric backtrace (start end)
285     (:documentation
286     "Return a list containing a backtrace of the condition current
287     being debugged. The results are unspecified if this function is
288     called outside the dynamic contour of a debugger hook defined by
289     DEFINE-DEBUGGER-HOOK.
290    
291     START and END are zero-based indices constraining the number of
292     frames returned. Frame zero is defined as the frame which invoked
293     the debugger.
294    
295     The backtrace is returned as a list of tuples of the form
296     \(FRAME-NUMBER FRAME-DESCRIPTION), where FRAME-NUMBER is the
297     index of the frame, defined like START/END, and FRAME-DESCRIPTION
298     is a string containing text to display in the debugger for this
299     frame.
300    
301     An example return value:
302    
303     ((0 \"(HELLO \"world\")\")
304     (1 \"(RUN-EXCITING-LISP-DEMO)\")
305     (2 \"(SYS::%TOPLEVEL #<SYS::ENVIRONMENT #x394834>)\"))"))
306    
307     (defgeneric frame-source-location-for-emacs (frame-number)
308     (:documentation
309     "Return the source location for FRAME-NUMBER."))
310    
311     (defgeneric frame-catch-tags (frame-number)
312     (:documentation
313     "Return a list of XXX list of what? catch tags for a debugger
314     stack frame. The results are undefined unless this is called
315     within the dynamic contour of a function defined by
316     DEFINE-DEBUGGER-HOOK."))
317    
318     (defgeneric frame-locals (frame-number)
319     (:documentation
320     "Return a list of XXX local variable designators define me
321     for a debugger stack frame. The results are undefined unless
322     this is called within the dynamic contour of a function defined
323     by DEFINE-DEBUGGER-HOOK."))
324    
325     (defgeneric eval-in-frame (form frame-number)
326     (:documentation
327     "Evaluate a Lisp form in the lexical context of a stack frame
328     in the debugger. The results are undefined unless called in the
329     dynamic contour of a function defined by DEFINE-DEBUGGER-HOOK.
330    
331     FRAME-NUMBER must be a positive integer with 0 indicating the
332     frame which invoked the debugger.
333    
334     The return value is the result of evaulating FORM in the
335     appropriate context."))
336    
337    
338     ;;;; Queries
339    
340 heller 1.7 #+(or)
341     ;;; This is probably a better interface than find-function-locations.
342     (defgeneric find-definitions (name)
343 lgorrie 1.3 (:documentation
344 heller 1.7 "Return a list of (LABEL . LOCATION) pairs for NAME's definitions.
345 lgorrie 1.3
346 heller 1.7 NAME is string denoting a symbol or \"definition specifier\".
347    
348     LABEL is a string describing the definition, e.g., \"foo\" or
349     \"(method foo (string number))\" or \"(variable bar)\".
350    
351     LOCATION is a source location of the form:
352    
353     <location> ::= (:location <buffer> <position>)
354     | (:error <message>)
355    
356     <buffer> ::= (:file <filename>)
357     | (:buffer <buffername>)
358     | (:source-form <string>)
359    
360     <position> ::= (:position <fixnum> [<align>]) ; 1 based
361     | (:function-name <string>)
362     "))
363    
364     (defgeneric find-function-locations (name)
365     (:documentation
366     "Return a list (LOCATION LOCATION ...) for NAME's definitions.
367    
368     LOCATION is a source location of the form:
369    
370     <location> ::= (:location <buffer> <position>)
371     | (:error <message>)
372    
373     <buffer> ::= (:file <filename>)
374     | (:buffer <buffername>)
375     | (:source-form <string>)
376    
377     <position> ::= (:position <fixnum> [<align>]) ; 1 based
378 heller 1.12 | (:line <fixnum> [<fixnum>])
379     | (:function-name <string>)
380     | (:source-path <list> <start-position>)
381     "))
382 lgorrie 1.9
383    
384     ;;;; Multiprocessing
385    
386     (defgeneric startup-multiprocessing ()
387     (:documentation
388     "Initialize multiprocessing, if necessary.
389    
390     This function is called directly through the listener, not in an RPC
391     from Emacs. This is to support interfaces such as CMUCL's
392     MP::STARTUP-IDLE-AND-TOP-LEVEL-LOOPS which does not return like a
393     normal function."))
394    
395 lgorrie 1.17 (defgeneric spawn (fn &key name)
396     (:documentation "Create a new thread to call FN."))
397    
398 lgorrie 1.9 (defgeneric thread-id ()
399     (:documentation
400     "Return a value that uniquely identifies the current thread.
401     Thread-IDs allow Emacs to refer to individual threads.
402    
403     When called several times by the same thread, all return values are
404     EQUAL. The value has a READable printed representation that preserves
405     equality. The printed representation must be identical in Emacs Lisp
406     and Common Lisp, and short enough to include in the REPL prompt.
407    
408     For example, a THREAD-ID could be an integer or a short ASCII string.
409    
410     Systems that do not support multiprocessing return NIL."))
411    
412     (defgeneric thread-name (thread-id)
413     (:documentation
414     "Return the name of the thread identified by THREAD-ID.
415    
416     Thread names are be single-line strings and are meaningful to the
417     user. They do not have to be unique."))
418    
419 lgorrie 1.17 (defgeneric make-lock (&key name)
420 lgorrie 1.9 (:documentation
421 lgorrie 1.17 "Make a lock for thread synchronization.
422     Only one thread may hold the lock (via CALL-WITH-LOCK-HELD) at a time."))
423 lgorrie 1.9
424 lgorrie 1.17 (defgeneric call-with-lock-held (lock function)
425 lgorrie 1.9 (:documentation
426 lgorrie 1.17 "Call FUNCTION with LOCK held, queueing if necessary."))
427 lgorrie 1.9
428 lgorrie 1.13
429 lgorrie 1.9 ;;;;; Default implementation for non-MP systems
430    
431     ;;; Using NO-APPLICABLE-METHOD to supply a default implementation that
432     ;;; works in systems that don't have multiprocessing.
433     ;;; (Good or bad idea? -luke)
434    
435     (defmethod no-applicable-method ((m (eql #'startup-multiprocessing)) &rest _)
436 lgorrie 1.13 (declare (ignore _))
437 lgorrie 1.9 nil)
438     (defmethod no-applicable-method ((m (eql #'thread-id)) &rest _)
439 lgorrie 1.13 (declare (ignore _))
440 lgorrie 1.9 nil)
441     (defmethod no-applicable-method ((m (eql #'thread-name)) &rest _)
442 lgorrie 1.13 (declare (ignore _))
443 lgorrie 1.9 "The One True Thread")
444 lgorrie 1.17 (defmethod no-applicable-method ((m (eql #'make-lock)) &rest _)
445 lgorrie 1.13 (declare (ignore _))
446 lgorrie 1.17 :null-lock)
447     (defmethod no-applicable-method ((m (eql #'call-with-lock-held)) &rest args)
448     (funcall (second args)))
449 lgorrie 1.1

  ViewVC Help
Powered by ViewVC 1.1.5