(constantly (make-member-type :members (list (specializer-object specl))))))
(defun real-load-defclass (name metaclass-name supers slots other
- readers writers slot-names source-location)
+ readers writers slot-names source-location safe-p)
(with-single-package-locked-error (:symbol name "defining ~S as a class")
(%compiler-defclass name readers writers slot-names)
(let ((res (apply #'ensure-class name :metaclass metaclass-name
:direct-superclasses supers
:direct-slots slots
:definition-source source-location
+ 'safe-p safe-p
other)))
res)))
(defmethod ensure-class-using-class ((class null) name &rest args &key)
(multiple-value-bind (meta initargs)
- (ensure-class-values class args)
+ (frob-ensure-class-args args)
(setf class (apply #'make-instance meta :name name initargs))
(without-package-locks
(setf (find-class name) class))
(defmethod ensure-class-using-class ((class pcl-class) name &rest args &key)
(multiple-value-bind (meta initargs)
- (ensure-class-values class args)
+ (frob-ensure-class-args args)
(unless (eq (class-of class) meta)
(apply #'change-class class meta initargs))
(apply #'reinitialize-instance class initargs)
(set-class-type-translation class name)
class))
-(defun fix-super (s)
- (cond ((classp s) s)
- ((not (legal-class-name-p s))
- (error "~S is not a class or a legal class name." s))
- (t
- (or (find-class s nil)
- (ensure-class s :metaclass 'forward-referenced-class)))))
-
-(defun ensure-class-values (class initargs)
+(defun frob-ensure-class-args (args)
(let (metaclass metaclassp reversed-plist)
- (doplist (key val) initargs
- (cond ((eq key :metaclass)
- (setf metaclass val
- metaclassp key))
- (t
- (when (eq key :direct-superclasses)
- (setf val (mapcar #'fix-super val)))
- (setf reversed-plist (list* val key reversed-plist)))))
- (values (cond (metaclassp
- (if (classp metaclass)
- metaclass
- (find-class metaclass)))
- ((or (null class) (forward-referenced-class-p class))
- *the-class-standard-class*)
- (t
- (class-of class)))
- (nreverse reversed-plist))))
-
+ (flet ((frob-superclass (s)
+ (cond
+ ((classp s) s)
+ ((legal-class-name-p s)
+ (or (find-class s nil)
+ (ensure-class s :metaclass 'forward-referenced-class)))
+ (t (error "Not a class or a legal class name: ~S." s)))))
+ (doplist (key val) args
+ (cond ((eq key :metaclass)
+ (unless metaclassp
+ (setf metaclass val metaclassp key)))
+ (t
+ (when (eq key :direct-superclasses)
+ (setf val (mapcar #'frob-superclass val)))
+ (setf reversed-plist (list* val key reversed-plist)))))
+ (values (cond (metaclassp
+ (if (classp metaclass)
+ metaclass
+ (find-class metaclass)))
+ (t *the-class-standard-class*))
+ (nreverse reversed-plist)))))
\f
(defmethod shared-initialize :after
((class std-class) slot-names &key
(fix-slot-accessors class dslotds 'remove))
(defun fix-slot-accessors (class dslotds add/remove)
- (flet ((fix (gfspec name r/w)
+ (flet ((fix (gfspec name r/w doc)
(let ((gf (cond ((eq add/remove 'add)
- (if (fboundp gfspec)
- (without-package-locks
- (ensure-generic-function gfspec))
+ (or (find-generic-function gfspec nil)
(ensure-generic-function
gfspec :lambda-list (case r/w
(r '(object))
(w '(new-value object))))))
- ((generic-function-p (and (fboundp gfspec)
- (fdefinition gfspec)))
- (without-package-locks
- (ensure-generic-function gfspec))))))
+ (t
+ (find-generic-function gfspec nil)))))
(when gf
(case r/w
(r (if (eq add/remove 'add)
- (add-reader-method class gf name)
+ (add-reader-method class gf name doc)
(remove-reader-method class gf)))
(w (if (eq add/remove 'add)
- (add-writer-method class gf name)
+ (add-writer-method class gf name doc)
(remove-writer-method class gf))))))))
(dolist (dslotd dslotds)
- (let ((slot-name (slot-definition-name dslotd)))
+ (let ((slot-name (slot-definition-name dslotd))
+ (slot-doc (%slot-definition-documentation dslotd)))
(dolist (r (slot-definition-readers dslotd))
- (fix r slot-name 'r))
+ (fix r slot-name 'r slot-doc))
(dolist (w (slot-definition-writers dslotd))
- (fix w slot-name 'w))))))
+ (fix w slot-name 'w slot-doc))))))
\f
(defun add-direct-subclasses (class supers)
(dolist (super supers)
;;; or reinitialized. The class may or may not be finalized.
(defun update-class (class finalizep)
(without-package-locks
- (when (or finalizep (class-finalized-p class))
- (update-cpl class (compute-class-precedence-list class))
- ;; This invocation of UPDATE-SLOTS, in practice, finalizes the
- ;; class.
- (update-slots class (compute-slots class))
- (update-gfs-of-class class)
- (update-initargs class (compute-default-initargs class))
- (update-ctors 'finalize-inheritance :class class))
- (dolist (sub (class-direct-subclasses class))
- (update-class sub nil))))
+ (when (or finalizep (class-finalized-p class))
+ (update-cpl class (compute-class-precedence-list class))
+ ;; This invocation of UPDATE-SLOTS, in practice, finalizes the
+ ;; class.
+ (update-slots class (compute-slots class))
+ (update-gfs-of-class class)
+ (update-initargs class (compute-default-initargs class))
+ (update-ctors 'finalize-inheritance :class class))
+ (dolist (sub (class-direct-subclasses class))
+ (update-class sub nil))))
(define-condition cpl-protocol-violation (reference-condition error)
((class :initarg :class :reader cpl-protocol-violation-class)
wrapper nwrapper)
(do* ((slots (slot-value class 'slots) (cdr slots))
(dupes nil))
- ((null slots)
+ ((null slots)
(when dupes
(style-warn
"~@<slot names with the same SYMBOL-NAME but ~
class dupes)))
(let* ((slot (car slots))
(oslots (remove (slot-definition-name slot) (cdr slots)
- :test #'string/=
+ :test #'string/=
:key #'slot-definition-name)))
(when oslots
(pushnew (cons (slot-definition-name slot)
(allocation nil)
(allocation-class nil)
(type t)
+ (type-check-function nil)
(documentation nil)
(documentationp nil)
(namep nil)
allocation-class (slot-definition-class slotd)
allocp t))
(setq initargs (append (slot-definition-initargs slotd) initargs))
+ (let ((fun (slot-definition-type-check-function slotd)))
+ (when fun
+ (setf type-check-function
+ (if type-check-function
+ (let ((old-function type-check-function))
+ (lambda (value)
+ (funcall old-function value)
+ (funcall fun value)))
+ fun))))
(let ((slotd-type (slot-definition-type slotd)))
(setq type (cond
((eq type t) slotd-type)
:allocation allocation
:allocation-class allocation-class
:type type
+ 'type-check-function type-check-function
:class class
:documentation documentation)))
(declare (ignore direct-slot initargs))
(find-class 'standard-reader-method))
-(defmethod add-reader-method ((class slot-class) generic-function slot-name)
+(defmethod add-reader-method ((class slot-class) generic-function slot-name slot-documentation)
(add-method generic-function
(make-a-method 'standard-reader-method
()
(list (or (class-name class) 'object))
(list class)
(make-reader-method-function class slot-name)
- "automatically generated reader method"
- slot-name)))
+ (or slot-documentation "automatically generated reader method")
+ :slot-name slot-name
+ :object-class class
+ :method-class-function #'reader-method-class)))
(defmethod writer-method-class ((class slot-class) direct-slot &rest initargs)
(declare (ignore direct-slot initargs))
(find-class 'standard-writer-method))
-(defmethod add-writer-method ((class slot-class) generic-function slot-name)
+(defmethod add-writer-method ((class slot-class) generic-function slot-name slot-documentation)
(add-method generic-function
(make-a-method 'standard-writer-method
()
(list 'new-value (or (class-name class) 'object))
(list *the-class-t* class)
(make-writer-method-function class slot-name)
- "automatically generated writer method"
- slot-name)))
+ (or slot-documentation "automatically generated writer method")
+ :slot-name slot-name
+ :object-class class
+ :method-class-function #'writer-method-class)))
-(defmethod add-boundp-method ((class slot-class) generic-function slot-name)
+(defmethod add-boundp-method ((class slot-class) generic-function slot-name slot-documentation)
(add-method generic-function
- (make-a-method 'standard-boundp-method
+ (make-a-method (constantly (find-class 'standard-boundp-method))
+ class
()
(list (or (class-name class) 'object))
(list class)
(make-boundp-method-function class slot-name)
- "automatically generated boundp method"
+ (or slot-documentation "automatically generated boundp method")
slot-name)))
(defmethod remove-reader-method ((class slot-class) generic-function)
(let ((method (get-method generic-function () (list class) nil)))
(when method (remove-method generic-function method))))
\f
-;;; MAKE-READER-METHOD-FUNCTION and MAKE-WRITE-METHOD function are NOT
-;;; part of the standard protocol. They are however useful, PCL makes
-;;; use of them internally and documents them for PCL users.
+;;; MAKE-READER-METHOD-FUNCTION and MAKE-WRITER-METHOD-FUNCTION
+;;; function are NOT part of the standard protocol. They are however
+;;; useful; PCL makes use of them internally and documents them for
+;;; PCL users. (FIXME: but SBCL certainly doesn't)
;;;
;;; *** This needs work to make type testing by the writer functions which
;;; *** do type testing faster. The idea would be to have one constructor
;;; *** defined for this metaclass a chance to run.
(defmethod make-reader-method-function ((class slot-class) slot-name)
- (make-std-reader-method-function (class-name class) slot-name))
+ (make-std-reader-method-function class slot-name))
(defmethod make-writer-method-function ((class slot-class) slot-name)
- (make-std-writer-method-function (class-name class) slot-name))
+ (make-std-writer-method-function class slot-name))
(defmethod make-boundp-method-function ((class slot-class) slot-name)
- (make-std-boundp-method-function (class-name class) slot-name))
+ (make-std-boundp-method-function class slot-name))
\f
(defmethod compatible-meta-class-change-p (class proto-new-class)
(eq (class-of class) (class-of proto-new-class)))
;; FILE-STREAM and STRING-STREAM (as they have the same
;; layout-depthoid). Is there any way we can provide a useful
;; error message? -- CSR, 2005-05-03
- (eq s *the-class-file-stream*) (eq s *the-class-string-stream*)))
+ (eq s *the-class-file-stream*) (eq s *the-class-string-stream*)
+ ;; TODO
+ (eq s *the-class-sequence*)))
\f
;;; Some necessary methods for FORWARD-REFERENCED-CLASS
(defmethod class-direct-slots ((class forward-referenced-class)) ())