chiark / gitweb /
src/class-finalize-*.lisp: Improve finalization error reporting.
[sod] / src / class-finalize-proto.lisp
CommitLineData
dea4d055
MW
1;;; -*-lisp-*-
2;;;
3;;; Class finalization protocol
4;;;
5;;; (c) 2009 Straylight/Edgeware
6;;;
7
8;;;----- Licensing notice ---------------------------------------------------
9;;;
e0808c47 10;;; This file is part of the Sensible Object Design, an object system for C.
dea4d055
MW
11;;;
12;;; SOD is free software; you can redistribute it and/or modify
13;;; it under the terms of the GNU General Public License as published by
14;;; the Free Software Foundation; either version 2 of the License, or
15;;; (at your option) any later version.
16;;;
17;;; SOD is distributed in the hope that it will be useful,
18;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;;; GNU General Public License for more details.
21;;;
22;;; You should have received a copy of the GNU General Public License
23;;; along with SOD; if not, write to the Free Software Foundation,
24;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26(cl:in-package #:sod)
27
e45a106d
MW
28;;;--------------------------------------------------------------------------
29;;; Finalization error handling.
30
31;; These variables are internal to the implementation.
32(defvar-unbound *finalization-errors*
33 "A list of tokens for errors reported about the class being finalized.
34
35 During finalization, this is bound to a list of tokens corresponding to
36 the problems which have been reported so far via `finalization-error'.")
37(defvar-unbound *finalization-error-token*
38 "The token to store in `*finalization-errors*' in the event of an error.")
39
40(export 'finalization-error)
41(defmacro finalization-error ((token &rest args) &body body)
42 "Check for a kind of finalization error denoted by TOKEN and the ARGS.
43
44 The TOKEN and ARGS are convered into an error token as follows. If no
45 ARGS are given, then the TOKEN itself is evaluated and used directly;
46 otherwise, the token is a list whose first element is the result of
47 evaluating TOKEN, and the remaining elements are the results of evaluating
48 the ARGS. Error tokens are compared with `equal'.
49
50 If a finalization error denoted by this token has already been reported,
51 then do nothing: the BODY is not evaluated, and the result is nil.
52 Special exception: a nil token denotes a `generic' error which can be
53 repeated indefintely.
54
55 If the BODY signals an error (and doesn't handle it), then the error token
56 is added to a list of reported errors. That way, future calls to
57 `finalization-error' with an equal error token won't cause the user to be
58 inundated with duplicate reports."
59 `(let ((*finalization-error-token* ,(if (null args) token
60 `(list ,token ,@args))))
61 ,@body))
62
63(export 'finalization-failed)
64(defun finalization-failed ()
65 "Give up on finalizing the current class."
66 (throw '%finalization-failed nil))
67
dea4d055
MW
68;;;--------------------------------------------------------------------------
69;;; Protocol definition.
70
11e41ddf 71(export 'compute-cpl)
dea4d055
MW
72(defgeneric compute-cpl (class)
73 (:documentation
74 "Returns the class precedence list for CLASS."))
75
11e41ddf 76(export 'compute-chains)
dea4d055
MW
77(defgeneric compute-chains (class)
78 (:documentation
79 "Compute the layout chains for CLASS.
80
81 Returns the following three values.
82
83 * the head of the class's primary chain;
84
85 * the class's primary chain as a list, most- to least-specific; and
86
87 * the complete collection of chains, as a list of lists, each most- to
88 least-specific, with the primary chain first.
89
90 These values will be stored in the CHAIN-HEAD, CHAIN and CHAINS slots.
91
92 If the chains are ill-formed (i.e., not distinct) then an error is
93 signalled."))
94
981b6fb6
MW
95(export 'guess-metaclass)
96(defgeneric guess-metaclass (class)
97 (:documentation
98 "Determine a suitable metaclass for the CLASS.
99
100 The default behaviour is to choose the most specific metaclass of any of
101 the direct superclasses of CLASS, or to signal an error if that failed."))
102
11e41ddf 103(export 'check-sod-class)
dea4d055
MW
104(defgeneric check-sod-class (class)
105 (:documentation
106 "Check the CLASS for validity.
107
108 This is done as part of class finalization. The checks performed are as
109 follows.
110
111 * The class name and nickname, and the names of messages, obey the
112 rules (see VALID-NAME-P).
113
114 * The messages and slots have distinct names.
115
116 * The classes in the class-precedence-list have distinct nicknames.
117
118 * The chain-link is actually a proper (though not necessarily direct)
119 superclass.
120
121 * The chosen metaclass is actually a subclass of all of the
122 superclasses' metaclasses.
123
8b06ce6e
MW
124 If no attempt has previously been made to finalize the class, then errors
125 are signalled for the problems found. If finalizing it has been tried
126 before and failed (or this is a recursive attempt to finalize the class)
127 then nil is returned immediately. Otherwise a non-nil value is
128 returned."))
dea4d055 129
11e41ddf 130(export 'finalize-sod-class)
dea4d055
MW
131(defgeneric finalize-sod-class (class)
132 (:documentation
133 "Computes all of the gory details about a class.
134
135 Once one has stopped inserting methods and slots and so on into a class,
136 one needs to finalize it to determine the layout structure and the class
137 precedence list and so on. More precisely that gets done is this:
138
139 * Related classes (i.e., direct superclasses and the metaclass) are
140 finalized if they haven't been already.
141
142 * If you've been naughty and failed to store a list of slots or
143 whatever, then an empty list is inserted.
144
145 * The class precedence list is computed and stored.
146
147 * The class is checked for compiance with the well-formedness rules.
148
32bb097f
MW
149 * The layout chains are computed.
150
e45a106d
MW
151 Returns a generalized boolean: non-nil if the class has been successfully
152 finalized -- either just now, or if it was finalized already and nothing
153 needed to be done -- or nil if finalization failed -- either just now, or
154 because the class had previously been marked as broken following a failed
155 finalization attempt.
156
32bb097f 157 User methods can assume that the class in question has not yet been
e45a106d
MW
158 finalized. Errors during finalization can be reported in the usual way.
159 See also `finalization-error' and `finalization-failed' above."))
dea4d055
MW
160
161;;;----- That's all, folks --------------------------------------------------