X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fdescribe.lisp;h=828227a2b42d9eed47f4fc7af9dbdd666bc3f328;hb=f7faed97898dd0e94a18b0d1fca03aaa0fe24ab0;hp=1f13b6fb4b07a4755a584b681f31aabff12c9744;hpb=b2a467878ff55db8f1c1f21b7b41031211ec5e9e;p=sbcl.git diff --git a/src/code/describe.lisp b/src/code/describe.lisp index 1f13b6f..828227a 100644 --- a/src/code/describe.lisp +++ b/src/code/describe.lisp @@ -49,7 +49,12 @@ #+sb-doc "Print a description of OBJECT to STREAM-DESIGNATOR." (let ((stream (out-synonym-of stream-designator)) - (*print-right-margin* (or *print-right-margin* 72))) + (*print-right-margin* (or *print-right-margin* 72)) + (*print-circle* t) + (*suppress-print-errors* + (if (subtypep 'serious-condition *suppress-print-errors*) + *suppress-print-errors* + 'serious-condition))) ;; Until sbcl-0.8.0.x, we did ;; (FRESH-LINE STREAM) ;; (PPRINT-LOGICAL-BLOCK (STREAM NIL) @@ -65,7 +70,8 @@ ;; here. (The example method for DESCRIBE-OBJECT does its own ;; FRESH-LINEing, which is a physical directive which works poorly ;; inside a pretty-printer logical block.) - (describe-object object stream) + (handler-bind ((print-not-readable #'print-unreadably)) + (describe-object object stream)) ;; We don't TERPRI here either (any more since sbcl-0.8.0.x), because ;; again ANSI's specification of DESCRIBE doesn't mention it and ;; ANSI's example of DESCRIBE-OBJECT does its own final TERPRI. @@ -167,39 +173,42 @@ (base-char "base-char") (t "character"))) +(defun print-standard-describe-header (x stream) + (format stream "~&~A~% [~A]~%" + (object-self-string x) + (object-type-string x))) + (defgeneric describe-object (x stream)) ;;; Catch-all. + (defmethod describe-object ((x t) s) - (format s "~&~A~% [~A]~%" - (object-self-string x) - (object-type-string x)) - (values)) + (print-standard-describe-header x s)) (defmethod describe-object ((x cons) s) - (call-next-method) + (print-standard-describe-header x s) (describe-function x nil s)) (defmethod describe-object ((x function) s) - (call-next-method) + (print-standard-describe-header x s) (describe-function nil x s)) (defmethod describe-object ((x class) s) - (call-next-method) + (print-standard-describe-header x s) (describe-class nil x s) (describe-instance x s)) (defmethod describe-object ((x sb-pcl::slot-object) s) - (call-next-method) + (print-standard-describe-header x s) (describe-instance x s)) (defmethod describe-object ((x character) s) - (call-next-method) + (print-standard-describe-header x s) (format s "~%:_Char-code: ~S" (char-code x)) (format s "~%:_Char-name: ~A~%_" (char-name x))) (defmethod describe-object ((x array) s) - (call-next-method) + (print-standard-describe-header x s) (format s "~%Element-type: ~S" (array-element-type x)) (if (vectorp x) (if (array-has-fill-pointer-p x) @@ -222,7 +231,7 @@ (terpri s))) (defmethod describe-object ((x hash-table) s) - (call-next-method) + (print-standard-describe-header x s) ;; Don't print things which are already apparent from the printed ;; representation -- COUNT, TEST, and WEAKNESS (format s "~%Occupancy: ~,1F" (float (/ (hash-table-count x) @@ -234,7 +243,7 @@ (terpri s)) (defmethod describe-object ((symbol symbol) stream) - (call-next-method) + (print-standard-describe-header symbol stream) ;; Describe the value cell. (let* ((kind (info :variable :kind symbol)) (wot (ecase kind @@ -246,11 +255,13 @@ (:alien "an alien variable")))) (when (or (not (eq :unknown kind)) (boundp symbol)) (pprint-logical-block (stream nil) - (format stream "~%~A names ~A:" symbol wot) + (format stream "~@:_~A names ~A:" symbol wot) (pprint-indent :block 2 stream) (when (eq (info :variable :where-from symbol) :declared) (format stream "~@:_Declared type: ~S" (type-specifier (info :variable :type symbol)))) + (when (info :variable :always-bound symbol) + (format stream "~@:_Declared always-bound.")) (cond ((eq kind :alien) (let ((info (info :variable :alien-info symbol))) @@ -291,10 +302,10 @@ (when fun (pprint-newline :mandatory stream) (pprint-logical-block (stream nil) - (pprint-indent :block 2 stream) - (format stream "~A names a ~@[primitive~* ~]type-specifier:" + (format stream "~@:_~A names a ~@[primitive~* ~]type-specifier:" symbol (eq kind :primitive)) + (pprint-indent :block 2 stream) (describe-documentation symbol 'type stream (eq t fun)) (unless (eq t fun) (describe-lambda-list (if (eq :primitive kind) @@ -305,6 +316,17 @@ (format stream "~@:_Expansion: ~S" (funcall fun (list symbol)))))) (terpri stream))) + (when (or (member symbol sb-c::*policy-qualities*) + (assoc symbol sb-c::*policy-dependent-qualities*)) + (pprint-logical-block (stream nil) + (pprint-newline :mandatory stream) + (pprint-indent :block 2 stream) + (format stream "~A names a~:[ dependent~;n~] optimization policy quality:" + symbol + (member symbol sb-c::*policy-qualities*)) + (describe-documentation symbol 'optimize stream t)) + (terpri stream)) + ;; Print out properties. (let ((plist (symbol-plist symbol))) (when plist @@ -318,42 +340,43 @@ (terpri stream)))) (defmethod describe-object ((package package) stream) - (call-next-method) - (describe-documentation package t stream) - (flet ((humanize (list) - (sort (mapcar (lambda (x) - (if (packagep x) - (package-name x) - x)) - list) - #'string<)) - (out (label list) - (describe-stuff label list stream :escape nil))) - (let ((implemented (humanize (package-implemented-by-list package))) - (implements (humanize (package-implements-list package))) - (nicks (humanize (package-nicknames package))) - (uses (humanize (package-use-list package))) - (used (humanize (package-used-by-list package))) - (shadows (humanize (package-shadowing-symbols package))) - (this (list (package-name package))) - (exports nil)) - (do-external-symbols (ext package) - (push ext exports)) - (setf exports (humanize exports)) - (when (package-locked-p package) - (format stream "~@:_Locked.")) - (when (set-difference implemented this :test #'string=) - (out "Implemented-by-list" implemented)) - (when (set-difference implements this :test #'string=) - (out "Implements-list" implements)) - (out "Nicknames" nicks) - (out "Use-list" uses) - (out "Used-by-list" used) - (out "Shadows" shadows) - (out "Exports" exports) - (format stream "~@:_~S internal symbols." - (package-internal-symbol-count package)))) - (terpri stream)) + (print-standard-describe-header package stream) + (pprint-logical-block (stream nil) + (describe-documentation package t stream) + (flet ((humanize (list) + (sort (mapcar (lambda (x) + (if (packagep x) + (package-name x) + x)) + list) + #'string<)) + (out (label list) + (describe-stuff label list stream :escape nil))) + (let ((implemented (humanize (package-implemented-by-list package))) + (implements (humanize (package-implements-list package))) + (nicks (humanize (package-nicknames package))) + (uses (humanize (package-use-list package))) + (used (humanize (package-used-by-list package))) + (shadows (humanize (package-shadowing-symbols package))) + (this (list (package-name package))) + (exports nil)) + (do-external-symbols (ext package) + (push ext exports)) + (setf exports (humanize exports)) + (when (package-locked-p package) + (format stream "~@:_Locked.")) + (when (set-difference implemented this :test #'string=) + (out "Implemented-by-list" implemented)) + (when (set-difference implements this :test #'string=) + (out "Implements-list" implements)) + (out "Nicknames" nicks) + (out "Use-list" uses) + (out "Used-by-list" used) + (out "Shadows" shadows) + (out "Exports" exports) + (format stream "~@:_~S internal symbols." + (package-internal-symbol-count package)))) + (terpri stream))) ;;;; Helpers to deal with shared functionality @@ -365,7 +388,7 @@ (let ((metaclass-name (class-name (class-of class)))) (pprint-logical-block (stream nil) (when by-name - (format stream "~%~A names the ~(~A~) ~S:" + (format stream "~@:_~A names the ~(~A~) ~S:" name metaclass-name class) @@ -424,6 +447,7 @@ (quiet-doc slotd t))) slots)) (format stream "~@:_No direct slots.")))) + (pprint-indent :block 0 stream) (pprint-newline :mandatory stream)))))) (defun describe-instance (object stream) @@ -495,9 +519,7 @@ (format stream "~@:_Source file: ~A" namestring)) ((sb-di:debug-source-form source) (format stream "~@:_Source form:~@:_ ~S" - (sb-di:debug-source-form source))) - (t (bug "Don't know how to use a DEBUG-SOURCE without ~ - a namestring or a form.")))))))) + (sb-di:debug-source-form source))))))))) #+sb-eval (let ((source (sb-eval:interpreted-function-source-location function))) (when source @@ -619,7 +641,9 @@ (format stream "~&~A has a complex setf-expansion:" name) (pprint-indent :block 2 stream) - (describe-documentation name2 'setf stream t)) + (describe-lambda-list (%fun-lambda-list expander) stream) + (describe-documentation name2 'setf stream t) + (describe-function-source expander stream)) (terpri stream))))) (when (symbolp name) (describe-function `(setf ,name) nil stream))))