report-class-list-merge-error function
class-finalize-proto.lisp
+ check-class-initializer generic
check-sod-class generic
compute-chains generic
compute-cpl generic
check-aggregating-message-type
t t t
aggregating-message (eql :progn) c-function-type
+check-class-initializer
+ effective-slot sod-class
+ sod-class-effective-slot sod-class
check-message-type
aggregating-message t
sod-message c-function-type
;;;--------------------------------------------------------------------------
;;; Sanity checking.
+(defmethod check-class-initializer ((slot effective-slot) (class sod-class))
+ (finalization-error (:missing-class-initializer)
+ (unless (find-class-initializer slot class)
+ (let ((dslot (effective-slot-direct-slot slot)))
+ (cerror* "Missing initializer for class slot `~A', ~
+ defined by meta-superclass `~A' of `~A'"
+ dslot (sod-slot-class dslot) class)))))
+
+(defmethod check-class-initializer
+ ((slot sod-class-effective-slot) (class sod-class))
+ ;; The programmer shouldn't set an explicit initializer here.
+ (finalization-error (:invalid-class-initializer)
+ (let ((init (find-class-initializer slot class))
+ (dslot (effective-slot-direct-slot slot)))
+ (when init
+ (cerror* "Initializers not permitted for class slot `~A', ~
+ defined by meta-superclass `~A' of `~A'"
+ dslot (sod-slot-class dslot) class)
+ (info-with-location init "Offending initializer defined here")))))
+
(defmethod check-sod-class ((class sod-class))
;; Check the names of things are valid.
(info-with-location super
"Direct superclass `~A' defined here ~
has metaclass `~A'"
- super supermeta)))))))
+ super supermeta))))))
+
+ ;; Check that an initializer is available for every slot in the class's
+ ;; metaclass. Skip this and trust the caller if the metaclass isn't
+ ;; finalized yet: in that case, we must be bootstrapping, and we must hope
+ ;; that the caller knows what they're doing.
+ (let* ((meta (sod-class-metaclass class))
+ (ilayout (and (eq (sod-class-state meta) :finalized)
+ (sod-class-ilayout meta))))
+ (dolist (ichain (and ilayout (ilayout-ichains ilayout)))
+ (dolist (item (cdr (ichain-body ichain)))
+ (when (typep item 'islots)
+ (dolist (slot (islots-slots item))
+ (check-class-initializer slot class)))))))
;;;--------------------------------------------------------------------------
;;; Finalization.
If the chains are ill-formed (i.e., not distinct) then an error is
signalled."))
+(export 'check-class-initializer)
+(defgeneric check-class-initializer (slot class)
+ (:documentation
+ "Check that SLOT has an appropriate initializer.
+
+ Signal an appropriate continuable error, possibly protected by
+ `finalization-error'.
+
+ The initializer might come either from the SLOT's defining class (which it
+ already knows), or from the prospective instance CLASS, of which the
+ defining class will be (a superclass of) the metaclass. Or, if the slot
+ is magical, then the initial value might come from somewhere else and it
+ might be forbidden for a programmer to set it explicitly."))
+
(export 'check-sod-class)
(defgeneric check-sod-class (class)
(:documentation