-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathentity-impl-accessor-description.lisp
109 lines (89 loc) · 4.11 KB
/
entity-impl-accessor-description.lisp
1
2
3
4
5
6
7
8
9
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
;;;; entity-impl-accessor-description.lisp
;;
;;;; Copyright (c) 2019 Ivan Podmazov
(in-package #:cl-multiagent-system)
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun accessor-full-name (accessor)
(caar accessor))
(defun accessor-type (accessor)
(let ((name (accessor-full-name accessor)))
(cond
((symbolp name)
:getter)
((and (listp name) (eq (car name) 'setf) (symbolp (cadr name))
(null (cddr name)))
:setter)
(t (error "Invalid name (~A) in accessor description." name)))))
(defun accessor-name (accessor)
(let ((full-name (accessor-full-name accessor)))
(case (accessor-type accessor)
(:getter full-name)
(:setter (cadr full-name)))))
(defun accessor-full-lambda-list (accessor)
(cadar accessor))
(defun accessor-lambda-list (accessor)
(let ((full-lambda-list (accessor-full-lambda-list accessor)))
(case (accessor-type accessor)
(:getter full-lambda-list)
(:setter (cdr full-lambda-list)))))
(defun accessor-store-variable (accessor)
(case (accessor-type accessor)
(:getter (error "Getters don't use store variable."))
(:setter (alexandria:if-let ((store-var (caadar accessor)))
store-var
(error "No store variable provided for accessor ~A."
accessor)))))
(defmacro accessor-descriptor-plist (accessor)
`(cddar ,accessor))
(defun accessor-written-resources (accessor)
(getf (accessor-descriptor-plist accessor) :writes))
(defun (setf accessor-written-resources) (value accessor)
(setf (getf (accessor-descriptor-plist accessor) :writes) value))
(defun accessor-read-resources (accessor)
(getf (accessor-descriptor-plist accessor) :reads))
(defun (setf accessor-read-resources) (value accessor)
(setf (getf (accessor-descriptor-plist accessor) :reads) value))
(defun accessor-write-locks (accessor)
(getf (accessor-descriptor-plist accessor) :writes))
(defun (setf accessor-write-locks) (value accessor)
(setf (getf (accessor-descriptor-plist accessor) :writes) value))
(defun accessor-read-locks (accessor)
(getf (accessor-descriptor-plist accessor) :reads))
(defun (setf accessor-read-locks) (value accessor)
(setf (getf (accessor-descriptor-plist accessor) :reads) value))
(defun accessor-called-accessors (accessor)
(getf (accessor-descriptor-plist accessor) :calls))
(defun (setf accessor-called-accessors) (value accessor)
(setf (getf (accessor-descriptor-plist accessor) :calls) value))
(defun accessor-visibility (accessor)
(ecase (getf (accessor-descriptor-plist accessor) :visibility :public)
(:public :public)
(:private :private)))
(defun accessor-declarations (accessor)
(getf (accessor-descriptor-plist accessor) :declarations))
(defun check-accessor-descriptor-plist (accessor)
(loop :for key :in (accessor-descriptor-plist accessor) :by #'cddr :do
(unless (member key '(:reads :writes :calls
:visibility :declarations))
(error "Unknown key ~A in accessor declarations." key))))
(defun accessor-body (accessor)
(cdr accessor))
(defun normalize-accessor (accessor)
(let ((accessor (cond
((symbolp accessor)
`((,accessor () :reads (,accessor))
,accessor))
((and (listp accessor) (eq (car accessor) 'setf)
(symbolp (cadr accessor)) (null (cddr accessor)))
`((,accessor (value) :writes (,(cadr accessor)))
(setf ,(cadr accessor) value)))
(t accessor))))
(check-accessor-descriptor-plist accessor)
accessor))
(defun prepare-accessors (entity-type accessors)
(setf accessors (mapcar #'normalize-accessor accessors))
(if (= (length accessors)
(length (remove-duplicates accessors :test #'equal
:key #'accessor-full-name)))
accessors
(error "Accessor name collision detected in entity ~A." entity-type))))