1 ;;;; implementation of CL:DOCUMENTATION
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is in the public domain and is provided with absolutely no
7 ;;;; warranty. See the COPYING and CREDITS files for more information.
9 (in-package "SB-C") ; FIXME: not the best package for FDOCUMENTATION
11 ;;; FDOCUMENTATION refers to STRUCTURE-CLASS which has only a skeletal
12 ;;; representation during cross-compilation. Better to define this late.
13 (defun fdocumentation (x doc-type
)
17 (symbol (values (info :variable
:documentation x
)))))
18 ;; FUNCTION is not used at the momemnt, just here for symmetry.
22 ((and (legal-fun-name-p x
) (fboundp x
))
23 (%fun-doc
(or (and (symbolp x
) (macro-function x
))
28 ((eq (info :type
:kind x
) :instance
)
29 (values (info :type
:documentation x
)))
30 ((info :typed-structure
:info x
)
31 (values (info :typed-structure
:documentation x
)))))))
34 (structure-class (values (info :type
:documentation
(class-name x
))))
35 (t (and (typep x
'symbol
) (values (info :type
:documentation x
))))))
36 (setf (values (info :setf
:documentation x
)))
39 (function (%fun-doc x
))
40 (package (package-doc-string x
))
41 (structure-class (values (info :type
:documentation
(class-name x
))))
43 (random-documentation x doc-type
))))
45 (when (typep x
'(or symbol cons
))
46 (random-documentation x doc-type
)))))
51 (if (typep x
'generic-function
)
52 (slot-value x
'%documentation
)
55 (defun (setf fun-doc
) (new-value x
)
56 (if (typep x
'generic-function
)
57 (setf (slot-value x
'%documentation
) new-value
)
58 (setf (%fun-doc x
) new-value
)))
60 ;;; FIXME: There's already fun-name in code/describe.lisp, but it's
61 ;;; loaded after PCL, so it cannot be used, because we set
62 ;;; some documentation at the end of this file.
64 (if (typep x
'generic-function
)
65 (sb-pcl:generic-function-name x
)
68 (defun real-function-name (name)
69 ;; Resolve the actual name of the function named by NAME
70 ;; e.g. (setf (name-function 'x) #'car)
71 ;; (real-function-name 'x) => CAR
72 (cond ((not (fboundp name
))
75 (special-operator-p name
))
76 (%fun-name
(fdefinition name
)))
78 (macro-function name
))
79 (let ((name (%fun-name
(macro-function name
))))
81 (eq (car name
) 'macro-function
)
84 (fun-name (fdefinition name
)))))
86 (defun ignore-nil-doc (type)
87 (style-warn "Ignoring doc-type ~a for ~a."
90 (defun set-function-name-documentation (name documentation
)
92 (ignore-nil-doc 'function
))
93 ((not (legal-fun-name-p name
))
95 ((not (equal (real-function-name name
) name
))
96 (setf (random-documentation name
'function
) documentation
))
98 (setf (fun-doc (or (and (symbolp name
)
99 (macro-function name
))
106 ;;; default if DOC-TYPE doesn't match one of the specified types
107 (defmethod documentation (object doc-type
)
108 (warn "unsupported DOCUMENTATION: doc-type ~S for object of type ~S"
109 doc-type
(type-of object
))
112 ;;; default if DOC-TYPE doesn't match one of the specified types
113 (defmethod (setf documentation
) (new-value object doc-type
)
114 ;; CMU CL made this an error, but since ANSI says that even for supported
115 ;; doc types an implementation is permitted to discard docs at any time
116 ;; for any reason, this feels to me more like a warning. -- WHN 19991214
117 (warn "discarding unsupported DOCUMENTATION: doc-type ~S for object of type ~S"
118 doc-type
(type-of object
))
123 (defun maybe-add-deprecation-note (namespace name documentation
)
124 (unless (member namespace
'(function variable type
))
125 (return-from maybe-add-deprecation-note documentation
))
126 (binding* (((state since replacements
)
127 (deprecated-thing-p namespace name
))
129 (with-output-to-string (stream)
130 (sb-impl::print-deprecation-message
131 namespace name
(first since
) (second since
)
132 replacements stream
)))))
134 ((and documentation note
)
136 'string note
#.
(format nil
"~2%") documentation
))
140 (defmethod documentation :around
((x t
) (doc-type t
))
141 (let ((namespace (cond
144 ((eq doc-type
'compiler-macro
)
148 ((eq doc-type
'structure
)
159 (documentation (call-next-method)))
160 (maybe-add-deprecation-note namespace name documentation
)))
162 ;;; functions, macros, and special forms
164 (flet ((maybe-function-documentation (name)
166 ((not (legal-fun-name-p name
)))
167 ((random-documentation name
'function
))
168 ;; Nothing under the name, check the function object.
171 ((and (symbolp name
) (special-operator-p name
))
173 ((and (symbolp name
) (macro-function name
)))
174 ((fdefinition name
))))))))
176 (defmethod documentation ((x function
) (doc-type (eql 't
)))
179 (defmethod documentation ((x function
) (doc-type (eql 'function
)))
182 (defmethod documentation ((x list
) (doc-type (eql 'compiler-macro
)))
183 (awhen (compiler-macro-function x
)
184 (documentation it t
)))
186 (defmethod documentation ((x list
) (doc-type (eql 'function
)))
187 (maybe-function-documentation x
))
189 (defmethod documentation ((x symbol
) (doc-type (eql 'function
)))
190 (maybe-function-documentation x
))
192 (defmethod documentation ((x symbol
) (doc-type (eql 'compiler-macro
)))
193 (awhen (compiler-macro-function x
)
194 (documentation it t
)))
196 (defmethod documentation ((x symbol
) (doc-type (eql 'setf
)))
197 (fdocumentation x
'setf
)))
199 (defmethod documentation ((x symbol
) (doc-type (eql 'optimize
)))
200 (random-documentation x
'optimize
))
202 (defmethod (setf documentation
) (new-value (x function
) (doc-type (eql 't
)))
203 (setf (fun-doc x
) new-value
))
205 (defmethod (setf documentation
) (new-value (x function
) (doc-type (eql 'function
)))
206 (setf (fun-doc x
) new-value
))
208 (defmethod (setf documentation
) (new-value (x list
) (doc-type (eql 'function
)))
209 (set-function-name-documentation x new-value
))
211 (defmethod (setf documentation
) (new-value (x list
) (doc-type (eql 'compiler-macro
)))
212 (awhen (compiler-macro-function x
)
213 (setf (documentation it t
) new-value
)))
215 (defmethod (setf documentation
) (new-value (x symbol
) (doc-type (eql 'function
)))
216 (set-function-name-documentation x new-value
))
218 (defmethod (setf documentation
) (new-value (x symbol
) (doc-type (eql 'compiler-macro
)))
220 (awhen (compiler-macro-function x
)
221 (setf (documentation it t
) new-value
)))
223 (ignore-nil-doc 'compiler-macro
)
226 (defmethod (setf documentation
) (new-value (x symbol
) (doc-type (eql 'setf
)))
228 (setf (fdocumentation x
'setf
) new-value
))
230 (ignore-nil-doc 'setf
)
233 ;;; method combinations
234 (defmethod documentation ((x method-combination
) (doc-type (eql 't
)))
235 (slot-value x
'%documentation
))
237 (defmethod documentation
238 ((x method-combination
) (doc-type (eql 'method-combination
)))
239 (slot-value x
'%documentation
))
241 (defmethod documentation ((x symbol
) (doc-type (eql 'method-combination
)))
242 (random-documentation x
'method-combination
))
244 (defmethod (setf documentation
)
245 (new-value (x method-combination
) (doc-type (eql 't
)))
246 (setf (slot-value x
'%documentation
) new-value
))
248 (defmethod (setf documentation
)
249 (new-value (x method-combination
) (doc-type (eql 'method-combination
)))
250 (setf (slot-value x
'%documentation
) new-value
))
252 (defmethod (setf documentation
)
253 (new-value (x symbol
) (doc-type (eql 'method-combination
)))
255 (setf (random-documentation x
'method-combination
) new-value
))
257 (ignore-nil-doc 'method-combination
)
261 (defmethod documentation ((x standard-method
) (doc-type (eql 't
)))
262 (slot-value x
'%documentation
))
264 (defmethod (setf documentation
)
265 (new-value (x standard-method
) (doc-type (eql 't
)))
266 (setf (slot-value x
'%documentation
) new-value
))
270 ;;; KLUDGE: It's nasty having things like this accessor
271 ;;; (PACKAGE-DOC-STRING) floating around out in this mostly-unrelated
272 ;;; source file. Perhaps it would be better to support WARM-INIT-FORMS
273 ;;; by analogy with the existing !COLD-INIT-FORMS and have them be
274 ;;; EVAL'ed after basic warm load is done? That way things like this
275 ;;; could be defined alongside the other code which does low-level
276 ;;; hacking of packages.. -- WHN 19991203
278 (defmethod documentation ((x package
) (doc-type (eql 't
)))
279 (package-doc-string x
))
281 (defmethod (setf documentation
) (new-value (x package
) (doc-type (eql 't
)))
282 (setf (package-doc-string x
) new-value
))
284 ;;; types, classes, and structure names
286 (defmethod documentation ((x structure-class
) (doc-type (eql 't
)))
287 (fdocumentation (class-name x
) 'type
))
289 (defmethod documentation ((x structure-class
) (doc-type (eql 'type
)))
290 (fdocumentation (class-name x
) 'type
))
292 (defmethod (setf documentation
) (new-value
295 (setf (fdocumentation (class-name x
) 'type
) new-value
))
297 (defmethod (setf documentation
) (new-value
299 (doc-type (eql 'type
)))
300 (setf (fdocumentation (class-name x
) 'type
) new-value
))
302 (defmethod documentation ((x class
) (doc-type (eql 't
)))
303 (slot-value x
'%documentation
))
305 (defmethod documentation ((x class
) (doc-type (eql 'type
)))
306 (slot-value x
'%documentation
))
308 (defmethod (setf documentation
) (new-value
311 (setf (slot-value x
'%documentation
) new-value
))
313 (defmethod (setf documentation
) (new-value
315 (doc-type (eql 'type
)))
316 (setf (slot-value x
'%documentation
) new-value
))
318 ;;; although the CLHS doesn't mention this, it is reasonable to assume
319 ;;; that parallel treatment of condition-class was intended (if
320 ;;; condition-class is in fact not implemented as a standard-class or
321 ;;; structure-class).
322 (defmethod documentation ((x condition-class
) (doc-type (eql 't
)))
323 (fdocumentation (class-name x
) 'type
))
325 (defmethod documentation ((x condition-class
) (doc-type (eql 'type
)))
326 (fdocumentation (class-name x
) 'type
))
328 (defmethod (setf documentation
) (new-value
331 (setf (fdocumentation (class-name x
) 'type
) new-value
))
333 (defmethod (setf documentation
) (new-value
335 (doc-type (eql 'type
)))
336 (setf (fdocumentation (class-name x
) 'type
) new-value
))
338 (defmethod documentation ((x symbol
) (doc-type (eql 'type
)))
339 (or (fdocumentation x
'type
)
340 (awhen (find-class x nil
)
341 (slot-value it
'%documentation
))))
343 (defmethod documentation ((x symbol
) (doc-type (eql 'structure
)))
344 (fdocumentation x
'structure
))
346 (defmethod (setf documentation
) (new-value (x symbol
) (doc-type (eql 'type
)))
347 (if (or (structure-type-p x
) (condition-type-p x
))
348 (setf (fdocumentation x
'type
) new-value
)
349 (let ((class (find-class x nil
)))
351 (setf (slot-value class
'%documentation
) new-value
)
352 (setf (fdocumentation x
'type
) new-value
)))))
354 (defmethod (setf documentation
) (new-value
356 (doc-type (eql 'structure
)))
358 (setf (fdocumentation x
'structure
) new-value
))
360 (ignore-nil-doc 'structure
)
364 (defmethod documentation ((x symbol
) (doc-type (eql 'variable
)))
365 (fdocumentation x
'variable
))
367 (defmethod (setf documentation
) (new-value
369 (doc-type (eql 'variable
)))
371 (setf (fdocumentation x
'variable
) new-value
))
373 (ignore-nil-doc 'variable
)
376 ;;; extra-standard methods, for getting at slot documentation
377 (defmethod documentation ((slotd standard-slot-definition
) (doc-type (eql 't
)))
378 (declare (ignore doc-type
))
379 (slot-value slotd
'%documentation
))
381 (defmethod (setf documentation
)
382 (new-value (slotd standard-slot-definition
) (doc-type (eql 't
)))
383 (declare (ignore doc-type
))
384 (setf (slot-value slotd
'%documentation
) new-value
))
386 ;;; Now that we have created the machinery for setting documentation, we can
387 ;;; set the documentation for the machinery for setting documentation.
389 (setf (documentation 'documentation
'function
)
390 "Return the documentation string of Doc-Type for X, or NIL if none
391 exists. System doc-types are VARIABLE, FUNCTION, STRUCTURE, TYPE, SETF, and T.
393 Function documentation is stored separately for function names and objects:
394 DEFUN, LAMBDA, &co create function objects with the specified documentation
397 \(SETF (DOCUMENTATION NAME 'FUNCTION) STRING)
399 sets the documentation string stored under the specified name, and
401 \(SETF (DOCUMENTATION FUNC T) STRING)
403 sets the documentation string stored in the function object.
405 \(DOCUMENTATION NAME 'FUNCTION)
407 returns the documentation stored under the function name if any, and
408 falls back on the documentation in the function object if necessary.")