compute-chains generic
compute-cpl generic
finalize-sod-class generic
+ guess-metaclass generic
class-layout-impl.lisp
sod-class-effective-slot class
check-message-type generic
check-method-type generic
define-sod-class macro
- guess-metaclass generic
make-sod-class function
make-sod-class-initializer generic
make-sod-initializer-using-slot generic
\dhead{gf}{sod-class-vtables @<class> @> @<list>}}
\end{describe*}
-\begin{describe}{gf}{guess-metaclass @<class> @> @<metaclass>}
-\end{describe}
-
\begin{describe}{fun}
{make-sod-class @<name> @<superclasses> @<pset> \&optional @<floc>
@> @<class>}
\begin{describe}{gf}{compute-chains @<class> @> @<list>}
\end{describe}
+\begin{describe}{gf}{guess-metaclass @<class> @> @<metaclass>}
+\end{describe}
+
\begin{describe}{gf}{check-sod-class @<class>}
\end{describe}
(gethash super table))
(cdr class-precedence-list)))))))))
+;;;--------------------------------------------------------------------------
+;;; Metaclasses.
+
+(defun maximum (items order what)
+ "Return a maximum item according to the non-strict partial ORDER."
+ (reduce (lambda (best this)
+ (cond ((funcall order best this) best)
+ ((funcall order this best) this)
+ (t (error "Unable to choose best ~A." what))))
+ items))
+
+(defmethod guess-metaclass ((class sod-class))
+ "Default metaclass-guessing function for classes.
+
+ Return the most specific metaclass of any of the CLASS's direct
+ superclasses."
+
+ ;; During bootstrapping, our superclasses might not have their own
+ ;; metaclasses resolved yet. If we find this, then throw `bootstrapping'
+ ;; so that `shared-initialize' on `sod-class' can catch it (or as a shot
+ ;; across the bows of anyone else who calls us).
+ (maximum (mapcar (lambda (super)
+ (if (slot-boundp super 'metaclass)
+ (slot-value super 'metaclass)
+ (throw 'bootstrapping nil)))
+ (sod-class-direct-superclasses class))
+ #'sod-subclass-p
+ (format nil "metaclass for `~A'" class)))
+
;;;--------------------------------------------------------------------------
;;; Sanity checking.
;; If this fails, mark the class as a loss.
(setf (slot-value class 'state) :broken)
+ ;; Set up the metaclass if it's not been set already. This is delayed
+ ;; to give bootstrapping a chance to set up metaclass and superclass
+ ;; circularities.
+ (default-slot (class 'metaclass) (guess-metaclass class))
+
;; Finalize all of the superclasses. There's some special pleading
;; here to make bootstrapping work: we don't try to finalize the
;; metaclass if we're a root class (no direct superclasses -- because
If the chains are ill-formed (i.e., not distinct) then an error is
signalled."))
+(export 'guess-metaclass)
+(defgeneric guess-metaclass (class)
+ (:documentation
+ "Determine a suitable metaclass for the CLASS.
+
+ The default behaviour is to choose the most specific metaclass of any of
+ the direct superclasses of CLASS, or to signal an error if that failed."))
+
(export 'check-sod-class)
(defgeneric check-sod-class (class)
(:documentation
;;;--------------------------------------------------------------------------
;;; Classes.
-(defun maximum (items order what)
- "Return a maximum item according to the non-strict partial ORDER."
- (reduce (lambda (best this)
- (cond ((funcall order best this) best)
- ((funcall order this best) this)
- (t (error "Unable to choose best ~A." what))))
- items))
-
-(defmethod guess-metaclass ((class sod-class))
- "Default metaclass-guessing function for classes.
-
- Return the most specific metaclass of any of the CLASS's direct
- superclasses."
- (maximum (mapcar #'sod-class-metaclass
- (sod-class-direct-superclasses class))
- #'sod-subclass-p
- (format nil "metaclass for `~A'" class)))
-
(defmethod shared-initialize :after ((class sod-class) slot-names &key pset)
"Specific behaviour for SOD class initialization.
(pset :nick :id)
(string-downcase (slot-value class 'name)))
- ;; If no metaclass, guess one in a (Lisp) class-specific way.
+ ;; Set the metaclass if the appropriate property has been provided;
+ ;; otherwise leave it unbound for now, and we'll sort out the mess during
+ ;; finalization.
(default-slot-from-property (class 'metaclass slot-names)
- (pset :metaclass :id meta (find-sod-class meta))
- (and (sod-class-direct-superclasses class)
- (guess-metaclass class)))
+ (pset :metaclass :id meta (find-sod-class meta)))
;; If no chain-link, then start a new chain here.
(default-slot-from-property (class 'chain-link slot-names)
:pset pset)))
class)))
-(export 'guess-metaclass)
-(defgeneric guess-metaclass (class)
- (:documentation
- "Determine a suitable metaclass for the CLASS.
-
- The default behaviour is to choose the most specific metaclass of any of
- the direct superclasses of CLASS, or to signal an error if that failed."))
-
;;;--------------------------------------------------------------------------
;;; Slots and slot initializers.