de39bc37b6b90155a3d3d8f05de240997967d3c8
[sbcl.git] / src / pcl / defclass.lisp
1 ;;;; This software is part of the SBCL system. See the README file for
2 ;;;; more information.
3
4 ;;;; This software is derived from software originally released by Xerox
5 ;;;; Corporation. Copyright and release statements follow. Later modifications
6 ;;;; to the software are in the public domain and are provided with
7 ;;;; absolutely no warranty. See the COPYING and CREDITS files for more
8 ;;;; information.
9
10 ;;;; copyright information from original PCL sources:
11 ;;;;
12 ;;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
13 ;;;; All rights reserved.
14 ;;;;
15 ;;;; Use and copying of this software and preparation of derivative works based
16 ;;;; upon this software are permitted. Any distribution of this software or
17 ;;;; derivative works must comply with all applicable United States export
18 ;;;; control laws.
19 ;;;;
20 ;;;; This software is made available AS IS, and Xerox Corporation makes no
21 ;;;; warranty about the software, its performance or its conformity to any
22 ;;;; specification.
23
24 (in-package "SB-PCL")
25 \f
26 ;;;; DEFCLASS macro and close personal friends
27
28 ;;; state for the current DEFCLASS expansion
29 (defvar *initfunctions-for-this-defclass*)
30 (defvar *readers-for-this-defclass*)
31 (defvar *writers-for-this-defclass*)
32 (defvar *slot-names-for-this-defclass*)
33
34 ;;; Like the DEFMETHOD macro, the expansion of the DEFCLASS macro is
35 ;;; fixed. DEFCLASS always expands into a call to LOAD-DEFCLASS. Until
36 ;;; the meta-braid is set up, LOAD-DEFCLASS has a special definition
37 ;;; which simply collects all class definitions up, when the metabraid
38 ;;; is initialized it is done from those class definitions.
39 ;;;
40 ;;; After the metabraid has been setup, and the protocol for defining
41 ;;; classes has been defined, the real definition of LOAD-DEFCLASS is
42 ;;; installed by the file std-class.lisp
43 (defmacro defclass (&environment env name direct-superclasses direct-slots &rest options)
44   (let (*initfunctions-for-this-defclass*
45         *readers-for-this-defclass* ;Truly a crock, but we got
46         *writers-for-this-defclass* ;to have it to live nicely.
47         *slot-names-for-this-defclass*)
48     ;; FIXME: It would be nice to collect all errors from the
49     ;; expansion of a defclass and signal them in a single go.
50     (multiple-value-bind (metaclass canonical-options)
51         (canonize-defclass-options name options)
52     (let ((canonical-slots (canonize-defclass-slots name direct-slots env))
53           ;; DEFSTRUCT-P should be true if the class is defined
54           ;; with a metaclass STRUCTURE-CLASS, so that a DEFSTRUCT
55           ;; is compiled for the class.
56           (defstruct-p (and (eq **boot-state** 'complete)
57                             (let ((mclass (find-class metaclass nil)))
58                               (and mclass
59                                    (*subtypep
60                                     mclass
61                                     *the-class-structure-class*))))))
62       (let* ((defclass-form
63               `(let ,(mapcar #'cdr *initfunctions-for-this-defclass*)
64                  (load-defclass ',name
65                                 ',metaclass
66                                 ',direct-superclasses
67                                 (list ,@canonical-slots)
68                                 (list ,@(apply #'append
69                                                (when defstruct-p
70                                                  '(:from-defclass-p t))
71                                                 canonical-options))
72                                 ',*readers-for-this-defclass*
73                                 ',*writers-for-this-defclass*
74                                 ',*slot-names-for-this-defclass*
75                                 (sb-c:source-location)
76                                 ',(safe-code-p env)))))
77         (if defstruct-p
78             (progn
79               ;; FIXME: (YUK!) Why do we do this? Because in order
80               ;; to make the defstruct form, we need to know what
81               ;; the accessors for the slots are, so we need already
82               ;; to have hooked into the CLOS machinery.
83               ;;
84               ;; There may be a better way to do this: it would
85               ;; involve knowing enough about PCL to ask "what will
86               ;; my slot names and accessors be"; failing this, we
87               ;; currently just evaluate the whole kaboodle, and
88               ;; then use CLASS-DIRECT-SLOTS. -- CSR, 2002-06-07
89               (eval defclass-form)
90               (let* ((include (or (and direct-superclasses
91                                        (find-class (car direct-superclasses) nil))
92                                   (and (not (eq name 'structure-object))
93                                        *the-class-structure-object*)))
94                      (defstruct-form (make-structure-class-defstruct-form
95                                       name (class-direct-slots (find-class name))
96                                       include)))
97                 `(progn
98                    (eval-when (:compile-toplevel :load-toplevel :execute)
99                      ,defstruct-form) ; really compile the defstruct-form
100                    (eval-when (:compile-toplevel :load-toplevel :execute)
101                      ,defclass-form))))
102             `(progn
103                ;; By telling the type system at compile time about
104                ;; the existence of a class named NAME, we can avoid
105                ;; various bogus warnings about "type isn't defined yet"
106                ;; for code elsewhere in the same file which uses
107                ;; the name of the type.
108                ;;
109                ;; We only need to do this at compile time, because
110                ;; at load and execute time we write the actual
111                ;; full-blown class, so the "a class of this name is
112                ;; coming" note we write here would be irrelevant.
113                (eval-when (:compile-toplevel)
114                  (%compiler-defclass ',name
115                                      ',*readers-for-this-defclass*
116                                      ',*writers-for-this-defclass*
117                                      ',*slot-names-for-this-defclass*))
118                (eval-when (:load-toplevel :execute)
119                  ,defclass-form))))))))
120
121 (defun canonize-defclass-options (class-name options)
122   (maplist (lambda (sublist)
123              (let ((option-name (first (pop sublist))))
124                (when (member option-name sublist :key #'first :test #'eq)
125                  (error 'simple-program-error
126                         :format-control "Multiple ~S options in DEFCLASS ~S."
127                         :format-arguments (list option-name class-name)))))
128            options)
129   (let (metaclass
130         default-initargs
131         documentation
132         canonized-options)
133       (dolist (option options)
134         (unless (listp option)
135           (error "~S is not a legal defclass option." option))
136         (case (first option)
137           (:metaclass
138            (let ((maybe-metaclass (second option)))
139              (unless (and maybe-metaclass (legal-class-name-p maybe-metaclass))
140                (error 'simple-program-error
141                       :format-control "~@<The value of the :metaclass option (~S) ~
142                          is not a legal class name.~:@>"
143                       :format-arguments (list maybe-metaclass)))
144              (setf metaclass maybe-metaclass)))
145           (:default-initargs
146            (let (initargs arg-names)
147              (doplist (key val) (cdr option)
148                (when (member key arg-names :test #'eq)
149                  (error 'simple-program-error
150                         :format-control "~@<Duplicate initialization argument ~
151                                            name ~S in :DEFAULT-INITARGS of ~
152                                            DEFCLASS ~S.~:>"
153                         :format-arguments (list key class-name)))
154                (push key arg-names)
155                (push ``(,',key ,',val ,,(make-initfunction val)) initargs))
156              (setf default-initargs t)
157              (push `(:direct-default-initargs (list ,@(nreverse initargs)))
158                    canonized-options)))
159           (:documentation
160            (unless (stringp (second option))
161              (error "~S is not a legal :documentation value" (second option)))
162            (setf documentation t)
163            (push `(:documentation ,(second option)) canonized-options))
164           (otherwise
165            (push `(',(car option) ',(cdr option)) canonized-options))))
166       (unless default-initargs
167         (push '(:direct-default-initargs nil) canonized-options))
168       (values (or metaclass 'standard-class) (nreverse canonized-options))))
169
170 (defun canonize-defclass-slots (class-name slots env)
171   (let (canonized-specs)
172     (dolist (spec slots)
173       (when (atom spec)
174         (setf spec (list spec)))
175       (when (and (cdr spec) (null (cddr spec)))
176         (error 'simple-program-error
177                :format-control "~@<in DEFCLASS ~S, the slot specification ~S ~
178                                 is invalid; the probable intended meaning may ~
179                                 be achieved by specifiying ~S instead.~:>"
180                :format-arguments (list class-name spec
181                                        `(,(car spec) :initform ,(cadr spec)))))
182       (let* ((name (car spec))
183              (plist (cdr spec))
184              (readers ())
185              (writers ())
186              (initargs ())
187              (others ())
188              (unsupplied (list nil))
189              (type t)
190              (initform unsupplied))
191         (check-slot-name-for-defclass name class-name env)
192         (push name *slot-names-for-this-defclass*)
193         (flet ((note-reader (x)
194                  (unless (symbolp x)
195                    (error 'simple-program-error
196                           :format-control "Slot reader name ~S for slot ~S in ~
197                                            DEFCLASS ~S is not a symbol."
198                           :format-arguments (list x name class-name)))
199                  (push x readers)
200                  (push x *readers-for-this-defclass*))
201                (note-writer (x)
202                  (push x writers)
203                  (push x *writers-for-this-defclass*)))
204           (doplist (key val) plist
205             (case key
206               (:accessor (note-reader val) (note-writer `(setf ,val)))
207               (:reader   (note-reader val))
208               (:writer   (note-writer val))
209               (:initarg
210                (unless (symbolp val)
211                  (error 'simple-program-error
212                         :format-control "Slot initarg name ~S for slot ~S in ~
213                                          DEFCLASS ~S is not a symbol."
214                         :format-arguments (list val name class-name)))
215                (push val initargs))
216               (otherwise
217                (when (member key '(:initform :allocation :type :documentation))
218                  (when (eq key :initform)
219                    (setf initform val))
220                  (when (eq key :type)
221                    (setf type val))
222                  (when (get-properties others (list key))
223                    (error 'simple-program-error
224                           :format-control "Duplicate slot option ~S for slot ~
225                                            ~S in DEFCLASS ~S."
226                           :format-arguments (list key name class-name))))
227                ;; For non-standard options multiple entries go in a list
228                (push val (getf others key))))))
229         ;; Unwrap singleton lists (AMOP 5.4.2)
230         (do ((head others (cddr head)))
231             ((null head))
232           (unless (cdr (second head))
233             (setf (second head) (car (second head)))))
234         (let* ((type-check-function
235                 (if (eq type t)
236                     nil
237                     `('type-check-function
238                       (named-lambda (slot-typecheck ,class-name ,name) (value)
239                         (declare (type ,type value)
240                                  (optimize (sb-c:store-coverage-data 0)))
241                         value))))
242                (canon `(:name ',name :readers ',readers :writers ',writers
243                               :initargs ',initargs
244                               ,@type-check-function
245                               ',others)))
246           (push (if (eq initform unsupplied)
247                     `(list* ,@canon)
248                     `(list* :initfunction ,(make-initfunction initform)
249                             ,@canon))
250                 canonized-specs))))
251     (nreverse canonized-specs)))
252
253
254 (defun check-slot-name-for-defclass (name class-name env)
255   (flet ((slot-name-illegal (reason)
256            (error 'simple-program-error
257                   :format-control
258                   (format nil "~~@<In DEFCLASS ~~S, the slot name ~~S ~
259                                is ~A.~~@:>" reason)
260                   :format-arguments (list class-name name))))
261     (cond ((not (symbolp name))
262            (slot-name-illegal "not a symbol"))
263           ((keywordp name)
264            (slot-name-illegal "a keyword"))
265           ((constantp name env)
266            (slot-name-illegal "a constant"))
267           ((member name *slot-names-for-this-defclass* :test #'eq)
268            (error 'simple-program-error
269                   :format-control "Multiple slots named ~S in DEFCLASS ~S."
270                   :format-arguments (list name class-name))))))
271
272 (defun make-initfunction (initform)
273   (cond ((or (eq initform t)
274              (equal initform ''t))
275          '(function constantly-t))
276         ((or (eq initform nil)
277              (equal initform ''nil))
278          '(function constantly-nil))
279         ((or (eql initform 0)
280              (equal initform ''0))
281          '(function constantly-0))
282         (t
283          (let ((entry (assoc initform *initfunctions-for-this-defclass*
284                              :test #'equal)))
285            (unless entry
286              (setq entry (list initform
287                                (gensym)
288                                `(function (lambda ()
289                                   (declare (optimize
290                                             (sb-c:store-coverage-data 0)))
291                                   ,initform))))
292              (push entry *initfunctions-for-this-defclass*))
293            (cadr entry)))))
294
295 (defun %compiler-defclass (name readers writers slots)
296   ;; ANSI says (Macro DEFCLASS, section 7.7) that DEFCLASS, if it
297   ;; "appears as a top level form, the compiler must make the class
298   ;; name be recognized as a valid type name in subsequent
299   ;; declarations (as for deftype) and be recognized as a valid class
300   ;; name for defmethod parameter specializers and for use as the
301   ;; :metaclass option of a subsequent defclass."
302   (preinform-compiler-about-class-type name)
303   (preinform-compiler-about-accessors readers writers slots))
304
305 (defun preinform-compiler-about-class-type (name)
306   ;; Unless the type system already has an actual type attached to
307   ;; NAME (in which case (1) writing a placeholder value over that
308   ;; actual type as a compile-time side-effect would probably be a bad
309   ;; idea and (2) anyway we don't need to modify it in order to make
310   ;; NAME be recognized as a valid type name)
311   (unless (info :type :kind name)
312     ;; Tell the compiler to expect a class with the given NAME, by
313     ;; writing a kind of minimal placeholder type information. This
314     ;; placeholder will be overwritten later when the class is defined.
315     (setf (info :type :kind name) :forthcoming-defclass-type))
316   (values))
317
318 (defun preinform-compiler-about-accessors (readers writers slots)
319   (flet ((inform (name type)
320            ;; FIXME: This matches what PROCLAIM FTYPE does, except
321            ;; that :WHERE-FROM is :DEFINED, not :DECLARED, and should
322            ;; probably be factored into a common function -- eg.
323            ;; (%proclaim-ftype name declared-or-defined).
324            (when (eq (info :function :where-from name) :assumed)
325              (proclaim-as-fun-name name)
326              (note-name-defined name :function)
327              (setf (info :function :where-from name) :defined
328                    (info :function :type name) type))))
329     (let ((rtype (specifier-type '(function (t) t)))
330           (wtype (specifier-type '(function (t t) t))))
331       (dolist (reader readers)
332         (inform reader rtype))
333       (dolist (writer writers)
334         (inform writer wtype))
335       (dolist (slot slots)
336         (inform (slot-reader-name slot) rtype)
337         (inform (slot-boundp-name slot) rtype)
338         (inform (slot-writer-name slot) wtype)))))
339 \f
340 ;;; This is the early definition of LOAD-DEFCLASS. It just collects up
341 ;;; all the class definitions in a list. Later, in braid1.lisp, these
342 ;;; are actually defined.
343
344 ;;; Each entry in *EARLY-CLASS-DEFINITIONS* is an EARLY-CLASS-DEFINITION.
345 (defparameter *early-class-definitions* ())
346
347 (defun early-class-definition (class-name)
348   (or (find class-name *early-class-definitions* :key #'ecd-class-name)
349       (error "~S is not a class in *early-class-definitions*." class-name)))
350
351 (defun make-early-class-definition
352        (name source-location metaclass
353         superclass-names canonical-slots other-initargs)
354   (list 'early-class-definition
355         name source-location metaclass
356         superclass-names canonical-slots other-initargs))
357
358 (defun ecd-class-name        (ecd) (nth 1 ecd))
359 (defun ecd-source-location   (ecd) (nth 2 ecd))
360 (defun ecd-metaclass         (ecd) (nth 3 ecd))
361 (defun ecd-superclass-names  (ecd) (nth 4 ecd))
362 (defun ecd-canonical-slots   (ecd) (nth 5 ecd))
363 (defun ecd-other-initargs    (ecd) (nth 6 ecd))
364
365 (defvar *early-class-slots* nil)
366
367 (defun canonical-slot-name (canonical-slot)
368   (getf canonical-slot :name))
369
370 (defun early-class-slots (class-name)
371   (cdr (or (assoc class-name *early-class-slots*)
372            (let ((a (cons class-name
373                           (mapcar #'canonical-slot-name
374                                   (early-collect-inheritance class-name)))))
375              (push a *early-class-slots*)
376              a))))
377
378 (defun early-class-size (class-name)
379   (length (early-class-slots class-name)))
380
381 (defun early-collect-inheritance (class-name)
382   ;;(declare (values slots cpl default-initargs direct-subclasses))
383   (let ((cpl (early-collect-cpl class-name)))
384     (values (early-collect-slots cpl)
385             cpl
386             (early-collect-default-initargs cpl)
387             (let (collect)
388               (dolist (definition *early-class-definitions*)
389                 (when (memq class-name (ecd-superclass-names definition))
390                   (push (ecd-class-name definition) collect)))
391               (nreverse collect)))))
392
393 (defun early-collect-slots (cpl)
394   (let* ((definitions (mapcar #'early-class-definition cpl))
395          (super-slots (mapcar #'ecd-canonical-slots definitions))
396          (slots (apply #'append (reverse super-slots))))
397     (dolist (s1 slots)
398       (let ((name1 (canonical-slot-name s1)))
399         (dolist (s2 (cdr (memq s1 slots)))
400           (when (eq name1 (canonical-slot-name s2))
401             (error "More than one early class defines a slot with the~%~
402                     name ~S. This can't work because the bootstrap~%~
403                     object system doesn't know how to compute effective~%~
404                     slots."
405                    name1)))))
406     slots))
407
408 (defun early-collect-cpl (class-name)
409   (labels ((walk (c)
410              (let* ((definition (early-class-definition c))
411                     (supers (ecd-superclass-names definition)))
412                (cons c
413                      (apply #'append (mapcar #'early-collect-cpl supers))))))
414     (remove-duplicates (walk class-name) :from-end nil :test #'eq)))
415
416 (defun early-collect-default-initargs (cpl)
417   (let ((default-initargs ()))
418     (dolist (class-name cpl)
419       (let* ((definition (early-class-definition class-name))
420              (others (ecd-other-initargs definition)))
421         (loop (when (null others) (return nil))
422               (let ((initarg (pop others)))
423                 (unless (eq initarg :direct-default-initargs)
424                  (error "~@<The defclass option ~S is not supported by ~
425                         the bootstrap object system.~:@>"
426                         initarg)))
427               (setq default-initargs
428                     (nconc default-initargs (reverse (pop others)))))))
429     (reverse default-initargs)))
430
431 (defun !bootstrap-slot-index (class-name slot-name)
432   (or (position slot-name (early-class-slots class-name))
433       (error "~S not found" slot-name)))
434
435 ;;; !BOOTSTRAP-GET-SLOT and !BOOTSTRAP-SET-SLOT are used to access and
436 ;;; change the values of slots during bootstrapping. During
437 ;;; bootstrapping, there are only two kinds of objects whose slots we
438 ;;; need to access, CLASSes and SLOT-DEFINITIONs. The first argument
439 ;;; to these functions tells whether the object is a CLASS or a
440 ;;; SLOT-DEFINITION.
441 ;;;
442 ;;; Note that the way this works it stores the slot in the same place
443 ;;; in memory that the full object system will expect to find it
444 ;;; later. This is critical to the bootstrapping process, the whole
445 ;;; changeover to the full object system is predicated on this.
446 ;;;
447 ;;; One important point is that the layout of standard classes and
448 ;;; standard slots must be computed the same way in this file as it is
449 ;;; by the full object system later.
450 (defmacro !bootstrap-get-slot (type object slot-name)
451   `(clos-slots-ref (get-slots ,object)
452                    (!bootstrap-slot-index ,type ,slot-name)))
453 (defun !bootstrap-set-slot (type object slot-name new-value)
454   (setf (!bootstrap-get-slot type object slot-name) new-value))
455
456 (defun early-class-name (class)
457   (!bootstrap-get-slot 'class class 'name))
458
459 (defun early-class-precedence-list (class)
460   (!bootstrap-get-slot 'pcl-class class '%class-precedence-list))
461
462 (defun early-class-name-of (instance)
463   (early-class-name (class-of instance)))
464
465 (defun early-class-slotds (class)
466   (!bootstrap-get-slot 'slot-class class 'slots))
467
468 (defun early-slot-definition-name (slotd)
469   (!bootstrap-get-slot 'standard-effective-slot-definition slotd 'name))
470
471 (defun early-slot-definition-location (slotd)
472   (!bootstrap-get-slot 'standard-effective-slot-definition slotd 'location))
473
474 (defun early-accessor-method-slot-name (method)
475   (!bootstrap-get-slot 'standard-accessor-method method 'slot-name))
476
477 (unless (fboundp 'class-name-of)
478   (setf (symbol-function 'class-name-of)
479         (symbol-function 'early-class-name-of)))
480 (unintern 'early-class-name-of)
481
482 (defun early-class-direct-subclasses (class)
483   (!bootstrap-get-slot 'class class 'direct-subclasses))
484
485 (declaim (notinline load-defclass))
486 (defun load-defclass (name metaclass supers canonical-slots canonical-options
487                       readers writers slot-names source-location safe-p)
488   ;; SAFE-P is used by REAL-LOAD-DEFCLASS, but can be ignored here, since
489   ;; during the bootstrap we won't have (SAFETY 3).
490   (declare (ignore safe-p))
491   (%compiler-defclass name readers writers slot-names)
492   (setq supers  (copy-tree supers)
493         canonical-slots   (copy-tree canonical-slots)
494         canonical-options (copy-tree canonical-options))
495   (let ((ecd
496          (make-early-class-definition name
497                                       source-location
498                                       metaclass
499                                       supers
500                                       canonical-slots
501                                       canonical-options))
502         (existing
503          (find name *early-class-definitions* :key #'ecd-class-name)))
504     (setq *early-class-definitions*
505           (cons ecd (remove existing *early-class-definitions*)))
506     ecd))