1 (in-package :lisp-on-lines
)
3 ;;;; A simpler implementation of descriptions based on plists
5 (setf (find-class 'simple-attribute nil
) nil
)
7 (define-layered-class simple-attribute
()
8 ((%property-access-function
9 :initarg property-access-function
)
10 (%initial-slot-values-plist
)))
12 (defun ensure-property-access-function (attribute)
13 (if (slot-boundp attribute
'%property-access-function
)
14 (slot-value attribute
'%property-access-function
)
15 (let ((fn-name (gensym)))
16 (ensure-layered-function fn-name
:lambda-list
'() :method-combination
'(append))
17 (setf (slot-value attribute
'%property-access-function
) fn-name
))))
19 (defconstant +property-not-found
+ '=lisp-on-lines-property-not-found-indicator
=)
21 (define-layered-method
22 contextl
:slot-value-using-layer
(class (attribute simple-attribute
) slotd reader
)
23 (if (or contextl
:*symbol-access
*
24 (not (slot-definition-layeredp slotd
)))
26 (let ((value (getf (funcall (ensure-property-access-function attribute
))
27 (slot-definition-name slotd
)
28 +property-not-found
+)))
29 (if (eq value
+property-not-found
+)
33 (define-layered-method
34 contextl
:slot-value-using-layer
(class (attribute simple-attribute
) slotd reader
)
35 (if (or contextl
:*symbol-access
*
36 (not (slot-definition-layeredp slotd
))
37 (dynamic-symbol-boundp (with-symbol-access (call-next-method))))
39 (let ((value (getf (ignore-errors (funcall (ensure-property-access-function attribute
)))
40 (slot-definition-name slotd
)
41 +property-not-found
+)))
42 (if (eq value
+property-not-found
+)
43 (let ((value (get (ensure-property-access-function attribute
)
44 (slot-definition-name slotd
)
45 +property-not-found
+)))
46 (if (eq value
+property-not-found
+)
51 (define-layered-method
52 (setf contextl
:slot-value-using-layer
) (value class
(attribute simple-attribute
) slotd reader
)
53 (if (and (not contextl
:*symbol-access
*)
54 (slot-definition-layeredp slotd
))
55 (setf (get (ensure-property-access-function attribute
) (slot-definition-name slotd
))
59 (defmethod initialize-attribute-for-layer (attribute layer-name
&rest args
)
60 (let* ((class (class-of attribute
))
61 (slotds (class-slots class
)))
62 (ensure-layered-method
63 (ensure-property-access-function attribute
)
66 :for
(key val
) :on args
:by
#'cddr
70 :do
(when (find key
(slot-definition-initargs slotd
))
71 (return (slot-definition-name slotd
))))
74 :in-layer layer-name
)))
77 (define-layered-class direct-attribute-slot-definition-class
78 (special-layered-direct-slot-definition
79 contextl
::singleton-direct-slot-definition
)
80 ((attribuite-properties
81 :accessor slot-definition-attribute-properties
82 :documentation
"Holds the initargs passed to the slotd")))
84 (defmethod initialize-instance
85 :after
((slotd direct-attribute-slot-definition-class
)
87 (setf (slot-definition-attribute-properties slotd
) initargs
))
89 (defmethod reinitialize-instance
90 :after
((slotd direct-attribute-slot-definition-class
)
92 (setf (slot-definition-attribute-properties slotd
) initargs
))
94 (define-layered-class effective-attribute-slot-definition-class
95 (special-layered-effective-slot-definition)
97 :accessor slot-definition-attribute-object
)))
99 (define-layered-class description-access-class
(standard-layer-class contextl
::special-layered-access-class
)
100 ((defined-in-descriptions :initarg
:in-description
)
101 (class-active-attributes-definition :initarg
:attributes
)
102 (mixin-class-p :initarg
:mixinp
)))
104 (defmethod direct-slot-definition-class
105 ((class description-access-class
) &key
&allow-other-keys
)
106 (find-class 'direct-attribute-slot-definition-class
))
108 (defmethod effective-slot-definition-class
109 ((class description-access-class
) &key
&allow-other-keys
)
110 (find-class 'effective-attribute-slot-definition-class
))
111 (fmakunbound 'initialize-slot-definition-attribute
)
113 (defmethod initialize-slot-definition-attribute ((slotd effective-attribute-slot-definition-class
) name direct-slot-definitions
)
114 (let ((tbl (make-hash-table))
115 (attribute (make-instance 'simple-standard-attribute
:name name
)))
116 (loop for ds in direct-slot-definitions
117 :when
(typep ds
'direct-attribute-slot-definition-class
)
118 :do
(setf (gethash (slot-definition-layer ds
) tbl
)
119 (append (gethash (slot-definition-layer ds
) tbl
'())
120 (slot-definition-attribute-properties ds
))))
121 (maphash (lambda (layer properties
)
122 (apply #'initialize-attribute-for-layer attribute layer properties
))
124 (setf (slot-definition-attribute-object slotd
) attribute
)))
126 (defmethod compute-effective-slot-definition
127 ((class description-access-class
) name direct-slot-definitions
)
128 (declare (ignore name
))
129 (let ((slotd (call-next-method)))
130 (initialize-slot-definition-attribute slotd name direct-slot-definitions
)
133 (defclass standard-description-class
(description-access-class layered-class
)
134 ((attributes :accessor description-class-attributes
:initform
(list)))
135 (:default-initargs
:defining-metaclass
'description-access-class
))
137 (defmethod validate-superclass
138 ((class standard-description-class
)
139 (superclass standard-class
))
142 (define-layered-class standard-description-object
(standard-layer-object)
143 ((described-object :accessor described-object
146 (defmethod initialize-instance :around
((class standard-description-class
) &rest initargs
&key
(direct-superclasses '()))
147 (declare (dynamic-extent initargs
))
149 (if (loop for direct-superclass in direct-superclasses
150 thereis
(ignore-errors (subtypep direct-superclass
'standard-description-object
)))
152 (apply #'call-next-method
155 (append direct-superclasses
156 (list (find-class 'standard-description-object
)))
160 (defmethod reinitialize-instance :around
((class standard-description-class
) &rest initargs
&key
(direct-superclasses '() direct-superclasses-p
))
161 (declare (dynamic-extent initargs
))
162 ; (warn "CLASS ~A ARGS ~A:" class initargs)
164 (if (or (not direct-superclasses-p
)
165 (loop for direct-superclass in direct-superclasses
166 thereis
(ignore-errors (subtypep direct-superclass
'standard-description-object
))))
168 (apply #'call-next-method
171 (append direct-superclasses
172 (list (find-class 'standard-description-object
)))