1 ;;; eieio-comp.el -- eieio routines to help with byte compilation
4 ;; Copyright (C) 1995,1996, 1998, 1999, 2000, 2001, 2002, 2005 Eric M. Ludlam
6 ;; Author: <zappo@gnu.org>
7 ;; RCS: $Id: eieio-comp.el,v 1.6 2010-03-28 12:44:26 sperber-guest Exp $
8 ;; Keywords: oop, lisp, tools
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;; Please send bug reports, etc. to zappo@gnu.org
29 ;; Byte compiler functions for defmethod. This will affect the new GNU
30 ;; byte compiler for Emacs 19 and better. This function will be called by
31 ;; the byte compiler whenever a `defmethod' is encountered in a file.
32 ;; It will output a function call to `eieio-defmethod' with the byte
33 ;; compiled function as a parameter.
37 ;; Some compatibility stuff
39 (if (not (fboundp 'byte-compile-compiled-obj-to-list))
40 ;; XEmacs change; b-c-c-o-t-l has been removed in 21.5
41 (defun byte-compile-compiled-obj-to-list (compiled-function)
43 (compiled-function-arglist compiled-function)
44 (compiled-function-instructions compiled-function)
45 (compiled-function-constants compiled-function)
46 (compiled-function-stack-depth compiled-function)
47 (compiled-function-doc-string compiled-function))
48 (if (commandp compiled-function)
49 (list (nth 1 (compiled-function-interactive
50 compiled-function)))))))
51 (if (not (boundp 'byte-compile-outbuffer))
52 (defvar byte-compile-outbuffer nil))
55 ;; This teaches the byte compiler how to do this sort of thing.
56 (put 'defmethod 'byte-hunk-handler 'byte-compile-file-form-defmethod)
58 (defun byte-compile-file-form-defmethod (form)
59 "Mumble about the method we are compiling.
60 This function is mostly ripped from `byte-compile-file-form-defun', but
61 it's been modified to handle the special syntax of the defmethod
62 command. There should probably be one for defgeneric as well, but
63 that is called but rarely. Argument FORM is the body of the method."
64 (setq form (cdr form))
65 (let* ((meth (car form))
66 (key (progn (setq form (cdr form))
67 (cond ((eq ':BEFORE (car form))
68 (setq form (cdr form))
70 ((eq ':AFTER (car form))
71 (setq form (cdr form))
73 ((eq ':PRIMARY (car form))
74 (setq form (cdr form))
76 ((eq ':STATIC (car form))
77 (setq form (cdr form))
81 (lamparams (byte-compile-defmethod-param-convert params))
83 (class (if (listp arg1) (nth 1 arg1) nil))
84 (my-outbuffer (if (eval-when-compile
85 (string-match "XEmacs" emacs-version))
86 byte-compile-outbuffer outbuffer))
88 (let ((name (format "%s::%s" (or class "#<generic>") meth)))
89 (if byte-compile-verbose
90 ;; #### filename used free
91 (message "Compiling %s... (%s)" (or filename "") name))
92 (setq byte-compile-current-form name) ; for warnings
94 ;; Flush any pending output
95 (byte-compile-flush-pending)
96 ;; Byte compile the body. For the byte compiled forms, add the
97 ;; rest arguments, which will get ignored by the engine which will
98 ;; add them later (I hope)
99 (let* ((new-one (byte-compile-lambda
100 (append (list 'lambda lamparams)
102 (code (byte-compile-byte-code-maker new-one)))
103 (princ "\n(eieio-defmethod '" my-outbuffer)
104 (princ meth my-outbuffer)
105 (princ " '(" my-outbuffer)
106 (princ key my-outbuffer)
107 (prin1 params my-outbuffer)
108 (princ " " my-outbuffer)
109 (eieio-byte-compile-princ-code code my-outbuffer)
110 (princ "))" my-outbuffer)
112 ;; Now add this function to the list of known functions.
113 ;; Don't bother with a doc string. Not relevant here.
114 (add-to-list 'byte-compile-function-environment
116 (eieio-defgeneric-form meth "")))
118 ;; Remove it from the undefined list if it is there.
119 (let ((elt (assq meth byte-compile-unresolved-functions)))
120 (if elt (setq byte-compile-unresolved-functions
121 (delq elt byte-compile-unresolved-functions))))
123 ;; nil prevents cruft from appearing in the output buffer.
127 (defun eieio-byte-compile-princ-code (code outbuffer)
128 "Xemacs and GNU Emacs do their things differently.
129 Lets do it right on both platforms
130 Argument CODE is the code to output.
131 Argument OUTBUFFER is the buffer to dump the created code to."
132 (if (eval-when-compile (not (featurep 'xemacs)))
134 (prin1 code outbuffer)
137 (princ "#[" outbuffer)
138 (princ "'(" outbuffer))
139 (let ((codelist (if (byte-code-function-p code)
140 (byte-compile-compiled-obj-to-list code)
143 (eieio-prin1 (car codelist) outbuffer)
144 (princ " " outbuffer)
145 (setq codelist (cdr codelist))
148 (princ "]" outbuffer)
149 (princ ")" outbuffer))))
151 (defun eieio-prin1 (code outbuffer)
152 "For XEmacs only, princ one item.
153 Recurse into lists in search of `byte-code' which needs expanding...
154 Argument CODE is the code to output.
155 Argument OUTBUFFER is the buffer to dump the created code to."
156 (cond ((byte-code-function-p code)
157 (let ((codelist (byte-compile-compiled-obj-to-list code)))
158 (princ "#[" outbuffer)
160 (eieio-prin1 (car codelist) outbuffer)
161 (princ " " outbuffer)
162 (setq codelist (cdr codelist))
164 (princ "]" outbuffer)))
166 (let ((i 0) (ln (length code)))
167 (princ "[" outbuffer)
169 (eieio-prin1 (aref code i) outbuffer)
170 (princ " " outbuffer)
172 (princ "]" outbuffer)))
173 (t (prin1 code outbuffer))))
176 (defun byte-compile-defmethod-param-convert (paramlist)
177 "Convert method params into the params used by the defmethod thingy.
178 Argument PARAMLIST is the paramter list to convert."
181 (setq argfix (cons (if (listp (car paramlist))
182 (car (car paramlist))
185 (setq paramlist (cdr paramlist)))
188 (provide 'eieio-comp)
190 ;;; eieio-comp.el ends here