- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
(closer-mop:defclass virtual-metaclass (closer-mop:standard-class) ())
(closer-mop:defclass virtual-slot-definition
(closer-mop:standard-slot-definition)
((function :initarg :function
:accessor virtual-slot-definition-function)))
(defmethod slot-definition-allocation ((slotd virtual-slot-definition))
:virtual)
(defmethod (setf slot-definition-allocation)
(allocation (slotd virtual-slot-definition))
(unless (eq allocation :virtual)
(error "Cannot change the allocation of a ~S"
'virtual-direct-slot-definition)) allocation)
(closer-mop:defclass virtual-direct-slot-definition
(closer-mop:standard-direct-slot-definition
virtual-slot-definition) ())
(defmethod closer-mop:direct-slot-definition-class
((class virtual-metaclass) &rest initargs)
;; Use virtual-direct-slot-definition if appropriate.
(if (eq (getf initargs :allocation) :virtual)
(find-class 'virtual-direct-slot-definition)
(call-next-method)))
(closer-mop:defclass virtual-effective-slot-definition
(closer-mop:standard-effective-slot-definition
virtual-slot-definition) ())
(defmethod closer-mop:effective-slot-definition-class
((class virtual-metaclass) &rest initargs)
;; Use virtual-effective-slot-definition if appropriate.
(let ((slot-initargs (getf initargs :initargs)))
(if (member :virtual-slot slot-initargs)
(find-class 'virtual-effective-slot-definition)
(call-next-method))))
(defmethod closer-mop:compute-effective-slot-definition
((class virtual-metaclass) name direct-slot-definitions)
;; Copy the function into the effective slot definition
;; if appropriate.
(let ((effective-slotd (call-next-method)))
(dolist (slotd direct-slot-definitions)
(when (typep slotd 'virtual-slot-definition)
(setf (virtual-slot-definition-function effective-slotd)
(virtual-slot-definition-function slotd))
(return)))
effective-slotd))
(defmethod closer-mop:slot-value-using-class
((class virtual-metaclass) object slot-name)
(let ((slotd (find slot-name (closer-mop:class-slots class)
:key 'closer-mop:slot-definition-name)))
(if (typep slotd 'virtual-slot-definition)
(funcall (cadr (virtual-slot-definition-function slotd)) :get object)
(call-next-method))))
(defmethod (setf closer-mop:slot-value-using-class)
(value (class virtual-metaclass) object slotd)
(if (typep slotd 'virtual-slot-definition)
;; This is ugly and probably not portable, but what if?
(funcall (cadr (virtual-slot-definition-function slotd))
:set object value)
(call-next-method)))
(defmethod closer-mop:slot-boundp-using-class
((class virtual-metaclass) object slot-name)
(let ((slotd (find slot-name (closer-mop:class-slots class)
:key 'closer-mop:slot-definition-name)))
(if (typep slotd 'virtual-slot-definition)
(funcall (cadr (virtual-slot-definition-function slotd)) :is-set object)
(call-next-method))))
(defmethod closer-mop:slot-makunbound-using-class
((class virtual-metaclass) object slot-name)
(let ((slotd (find slot-name (closer-mop:class-slots class)
:key 'closer-mop:slot-definition-name)))
(if (typep slotd 'virtual-slot-definition)
(funcall (virtual-slot-definition-function slotd) :unset object)
(call-next-method))))