aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Verona2015-01-22 00:05:27 +0100
committerJoakim Verona2015-01-22 00:05:27 +0100
commitd6ada5ae0fad7a5c85eb28b102bc460e9fe0aceb (patch)
treeaa8b504032eb09caa6f5eae6038a38b87ada198b
parent487d6cdc4dfc6500885dfa57a7c2fac8a1760fec (diff)
parent20f66485526b69eb26f2e70bd835a5e1333559d5 (diff)
downloademacs-d6ada5ae0fad7a5c85eb28b102bc460e9fe0aceb.tar.gz
emacs-d6ada5ae0fad7a5c85eb28b102bc460e9fe0aceb.zip
Merge branch 'master' into xwidget
-rw-r--r--ChangeLog7
-rw-r--r--configure.ac24
-rw-r--r--etc/NEWS7
-rw-r--r--lib-src/ChangeLog12
-rw-r--r--lib-src/Makefile.in16
-rw-r--r--lib-src/update-game-score.c33
-rw-r--r--lisp/ChangeLog70
-rw-r--r--lisp/emacs-lisp/cl-generic.el122
-rw-r--r--lisp/emacs-lisp/eieio-base.el36
-rw-r--r--lisp/emacs-lisp/eieio-compat.el33
-rw-r--r--lisp/emacs-lisp/eieio-core.el23
-rw-r--r--lisp/emacs-lisp/eieio-custom.el12
-rw-r--r--lisp/emacs-lisp/eieio-datadebug.el4
-rw-r--r--lisp/emacs-lisp/eieio-opt.el113
-rw-r--r--lisp/emacs-lisp/eieio-speedbar.el20
-rw-r--r--lisp/emacs-lisp/eieio.el89
-rw-r--r--lisp/emacs-lisp/package.el11
-rw-r--r--lisp/play/gamegrid.el6
-rw-r--r--lisp/progmodes/xref.el130
-rw-r--r--test/ChangeLog11
-rw-r--r--test/automated/cl-generic-tests.el5
-rw-r--r--test/automated/eieio-test-methodinvoke.el2
22 files changed, 508 insertions, 278 deletions
diff --git a/ChangeLog b/ChangeLog
index 309b04f26ab..b02203dbe75 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
12015-01-21 Ulrich Müller <ulm@gentoo.org>
2
3 * configure.ac (gamegroup): New AC_SUBST.
4 (--with-gameuser): Allow to specify a group instead of a user.
5 In the default case, check at configure time if a 'games' user
6 exists.
7
12015-01-16 Paul Eggert <eggert@cs.ucla.edu> 82015-01-16 Paul Eggert <eggert@cs.ucla.edu>
2 9
3 Give up on -Wsuggest-attribute=const 10 Give up on -Wsuggest-attribute=const
diff --git a/configure.ac b/configure.ac
index 1d206dbc5a0..0c2555792c9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -394,10 +394,25 @@ OPTION_DEFAULT_ON([compress-install],
394make GZIP_PROG= install]) 394make GZIP_PROG= install])
395 395
396AC_ARG_WITH(gameuser,dnl 396AC_ARG_WITH(gameuser,dnl
397[AS_HELP_STRING([--with-gameuser=USER],[user for shared game score files])]) 397[AS_HELP_STRING([--with-gameuser=USER_OR_GROUP],
398test "X${with_gameuser}" != X && test "${with_gameuser}" != yes \ 398 [user for shared game score files.
399 && gameuser="${with_gameuser}" 399 An argument prefixed by ':' specifies a group instead.])])
400test "X$gameuser" = X && gameuser=games 400gameuser=
401gamegroup=
402case ${with_gameuser} in
403 no) ;;
404 "" | yes)
405 AC_MSG_CHECKING([whether a 'games' user exists])
406 if id -u games >/dev/null 2>&1; then
407 AC_MSG_RESULT([yes])
408 gameuser=games
409 else
410 AC_MSG_RESULT([no])
411 fi
412 ;;
413 :*) gamegroup=`echo "${with_gameuser}" | sed -e "s/://"` ;;
414 *) gameuser=${with_gameuser} ;;
415esac
401 416
402AC_ARG_WITH([gnustep-conf],dnl 417AC_ARG_WITH([gnustep-conf],dnl
403[AS_HELP_STRING([--with-gnustep-conf=FILENAME], 418[AS_HELP_STRING([--with-gnustep-conf=FILENAME],
@@ -4721,6 +4736,7 @@ AC_SUBST(etcdocdir)
4721AC_SUBST(bitmapdir) 4736AC_SUBST(bitmapdir)
4722AC_SUBST(gamedir) 4737AC_SUBST(gamedir)
4723AC_SUBST(gameuser) 4738AC_SUBST(gameuser)
4739AC_SUBST(gamegroup)
4724## FIXME? Nothing uses @LD_SWITCH_X_SITE@. 4740## FIXME? Nothing uses @LD_SWITCH_X_SITE@.
4725## src/Makefile.in did add LD_SWITCH_X_SITE (as a cpp define) to the 4741## src/Makefile.in did add LD_SWITCH_X_SITE (as a cpp define) to the
4726## end of LIBX_BASE, but nothing ever set it. 4742## end of LIBX_BASE, but nothing ever set it.
diff --git a/etc/NEWS b/etc/NEWS
index 548b54df0da..120d8b920c6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -46,6 +46,13 @@ and silent rules are now quieter. To get the old behavior where
46build with 'make V=1'. 46build with 'make V=1'.
47 47
48--- 48---
49** The configure option '--with-gameuser' now allows to specify a
50group instead of a user if its argument is prefixed by ':' (a colon).
51This will cause the game score files in ${localstatedir}/games/emacs
52to be owned by that group, and the helper program for updating them to
53be installed setgid.
54
55---
49** The `grep-changelog' script (and its manual page) are no longer included. 56** The `grep-changelog' script (and its manual page) are no longer included.
50It has no particular connection to Emacs and has not changed in years, 57It has no particular connection to Emacs and has not changed in years,
51so if you want to use it, you can always take a copy from an older Emacs. 58so if you want to use it, you can always take a copy from an older Emacs.
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 37f037ef324..b67038ff81a 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,15 @@
12015-01-21 Ulrich Müller <ulm@gentoo.org>
2
3 * update-game-score.c: Allow the program to run sgid instead
4 of suid, in order to match common practice for most games.
5 (main): Check if we are running sgid. Pass appropriate file
6 permission bits to 'write_scores'.
7 (write_scores): New 'mode' argument, instead of hardcoding 0644.
8 (get_prefix): Update error message.
9 * Makefile.in (gamegroup): New variable, set by configure.
10 ($(DESTDIR)${archlibdir}): Handle both suid or sgid when
11 installing the 'update-game-score' program.
12
12015-01-16 Eli Zaretskii <eliz@gnu.org> 132015-01-16 Eli Zaretskii <eliz@gnu.org>
2 14
3 * Makefile.in (AM_V_RC, am__v_RC_, am__v_RC_0, am__v_RC_1): New 15 * Makefile.in (AM_V_RC, am__v_RC_, am__v_RC_0, am__v_RC_1): New
diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in
index 01592bd21a5..2997f1b35a8 100644
--- a/lib-src/Makefile.in
+++ b/lib-src/Makefile.in
@@ -122,6 +122,7 @@ archlibdir=@archlibdir@
122 122
123gamedir=@gamedir@ 123gamedir=@gamedir@
124gameuser=@gameuser@ 124gameuser=@gameuser@
125gamegroup=@gamegroup@
125 126
126# ==================== Utility Programs for the Build ================= 127# ==================== Utility Programs for the Build =================
127 128
@@ -263,10 +264,17 @@ $(DESTDIR)${archlibdir}: all
263 umask 022; ${MKDIR_P} "$(DESTDIR)${gamedir}"; \ 264 umask 022; ${MKDIR_P} "$(DESTDIR)${gamedir}"; \
264 touch "$(DESTDIR)${gamedir}/snake-scores"; \ 265 touch "$(DESTDIR)${gamedir}/snake-scores"; \
265 touch "$(DESTDIR)${gamedir}/tetris-scores" 266 touch "$(DESTDIR)${gamedir}/tetris-scores"
266 -if chown ${gameuser} "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}" && chmod u+s "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}"; then \ 267ifneq ($(gameuser),)
267 chown ${gameuser} "$(DESTDIR)${gamedir}"; \ 268 chown ${gameuser} "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}"
268 chmod u=rwx,g=rwx,o=rx "$(DESTDIR)${gamedir}"; \ 269 chmod u+s,go-r "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}"
269 fi 270 chown ${gameuser} "$(DESTDIR)${gamedir}"
271 chmod u=rwx,g=rx,o=rx "$(DESTDIR)${gamedir}"
272else ifneq ($(gamegroup),)
273 chgrp ${gamegroup} "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}"
274 chmod g+s,o-r "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}"
275 chgrp ${gamegroup} "$(DESTDIR)${gamedir}"
276 chmod u=rwx,g=rwx,o=rx "$(DESTDIR)${gamedir}"
277endif
270 exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd`; \ 278 exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd`; \
271 if [ "$$exp_archlibdir" != "`cd ${srcdir} && /bin/pwd`" ]; then \ 279 if [ "$$exp_archlibdir" != "`cd ${srcdir} && /bin/pwd`" ]; then \
272 for file in ${SCRIPTS}; do \ 280 for file in ${SCRIPTS}; do \
diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c
index d3354af2783..4f154832c81 100644
--- a/lib-src/update-game-score.c
+++ b/lib-src/update-game-score.c
@@ -21,8 +21,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22 22
23/* This program allows a game to securely and atomically update a 23/* This program allows a game to securely and atomically update a
24 score file. It should be installed setuid, owned by an appropriate 24 score file. It should be installed either setuid or setgid, owned
25 user like `games'. 25 by an appropriate user or group like `games'.
26 26
27 Alternatively, it can be compiled without HAVE_SHARED_GAME_DIR 27 Alternatively, it can be compiled without HAVE_SHARED_GAME_DIR
28 defined, and in that case it will store scores in the user's home 28 defined, and in that case it will store scores in the user's home
@@ -88,7 +88,7 @@ static int push_score (struct score_entry **scores, ptrdiff_t *count,
88 ptrdiff_t *size, struct score_entry const *newscore); 88 ptrdiff_t *size, struct score_entry const *newscore);
89static void sort_scores (struct score_entry *scores, ptrdiff_t count, 89static void sort_scores (struct score_entry *scores, ptrdiff_t count,
90 bool reverse); 90 bool reverse);
91static int write_scores (const char *filename, 91static int write_scores (const char *filename, mode_t mode,
92 const struct score_entry *scores, ptrdiff_t count); 92 const struct score_entry *scores, ptrdiff_t count);
93 93
94static _Noreturn void 94static _Noreturn void
@@ -122,18 +122,19 @@ get_user_id (void)
122} 122}
123 123
124static const char * 124static const char *
125get_prefix (bool running_suid, const char *user_prefix) 125get_prefix (bool privileged, const char *user_prefix)
126{ 126{
127 if (!running_suid && user_prefix == NULL) 127 if (privileged)
128 lose ("Not using a shared game directory, and no prefix given.");
129 if (running_suid)
130 { 128 {
131#ifdef HAVE_SHARED_GAME_DIR 129#ifdef HAVE_SHARED_GAME_DIR
132 return HAVE_SHARED_GAME_DIR; 130 return HAVE_SHARED_GAME_DIR;
133#else 131#else
134 lose ("This program was compiled without HAVE_SHARED_GAME_DIR,\n and should not be suid."); 132 lose ("This program was compiled without HAVE_SHARED_GAME_DIR,\n"
133 "and should not run with elevated privileges.");
135#endif 134#endif
136 } 135 }
136 if (user_prefix == NULL)
137 lose ("Not using a shared game directory, and no prefix given.");
137 return user_prefix; 138 return user_prefix;
138} 139}
139 140
@@ -173,7 +174,7 @@ int
173main (int argc, char **argv) 174main (int argc, char **argv)
174{ 175{
175 int c; 176 int c;
176 bool running_suid; 177 bool running_suid, running_sgid;
177 void *lockstate; 178 void *lockstate;
178 char *scorefile; 179 char *scorefile;
179 char *end, *nl, *user, *data; 180 char *end, *nl, *user, *data;
@@ -214,8 +215,11 @@ main (int argc, char **argv)
214 usage (EXIT_FAILURE); 215 usage (EXIT_FAILURE);
215 216
216 running_suid = (getuid () != geteuid ()); 217 running_suid = (getuid () != geteuid ());
218 running_sgid = (getgid () != getegid ());
219 if (running_suid && running_sgid)
220 lose ("This program can run either suid or sgid, but not both.");
217 221
218 prefix = get_prefix (running_suid, user_prefix); 222 prefix = get_prefix (running_suid || running_sgid, user_prefix);
219 223
220 scorefile = malloc (strlen (prefix) + strlen (argv[optind]) + 2); 224 scorefile = malloc (strlen (prefix) + strlen (argv[optind]) + 2);
221 if (!scorefile) 225 if (!scorefile)
@@ -270,7 +274,8 @@ main (int argc, char **argv)
270 scores += scorecount - max_scores; 274 scores += scorecount - max_scores;
271 scorecount = max_scores; 275 scorecount = max_scores;
272 } 276 }
273 if (write_scores (scorefile, scores, scorecount) < 0) 277 if (write_scores (scorefile, running_sgid ? 0664 : 0644,
278 scores, scorecount) < 0)
274 { 279 {
275 unlock_file (scorefile, lockstate); 280 unlock_file (scorefile, lockstate);
276 lose_syserr ("Failed to write scores file"); 281 lose_syserr ("Failed to write scores file");
@@ -421,8 +426,8 @@ sort_scores (struct score_entry *scores, ptrdiff_t count, bool reverse)
421} 426}
422 427
423static int 428static int
424write_scores (const char *filename, const struct score_entry *scores, 429write_scores (const char *filename, mode_t mode,
425 ptrdiff_t count) 430 const struct score_entry *scores, ptrdiff_t count)
426{ 431{
427 int fd; 432 int fd;
428 FILE *f; 433 FILE *f;
@@ -435,7 +440,7 @@ write_scores (const char *filename, const struct score_entry *scores,
435 if (fd < 0) 440 if (fd < 0)
436 return -1; 441 return -1;
437#ifndef DOS_NT 442#ifndef DOS_NT
438 if (fchmod (fd, 0644) != 0) 443 if (fchmod (fd, mode) != 0)
439 return -1; 444 return -1;
440#endif 445#endif
441 f = fdopen (fd, "w"); 446 f = fdopen (fd, "w");
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b5824abd01f..7aa66bf9ad5 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,73 @@
12015-01-21 Ulrich Müller <ulm@gentoo.org>
2
3 * play/gamegrid.el (gamegrid-add-score-with-update-game-score):
4 Allow the 'update-game-score' helper program to run suid or sgid.
5
62015-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
7
8 * emacs-lisp/eieio.el: Use cl-defmethod.
9 (defclass): Generate cl-defmethod calls; use setf methods for :accessor.
10 (eieio-object-name-string): Declare as obsolete.
11
12 * emacs-lisp/eieio-opt.el: Adapt to cl-generic.
13 (eieio--specializers-apply-to-class-p): New function.
14 (eieio-all-generic-functions): Use it.
15 (eieio-method-documentation): Use it as well as cl--generic-method-info.
16 Change format of return value.
17 (eieio-help-class): Adapt accordingly.
18
19 * emacs-lisp/eieio-compat.el (eieio--defmethod): Avoid no-next-method
20 errors when there's a `before' but no `primary' (bug#19645).
21 (next-method-p): Return nil rather than signal an error.
22 (eieio-defgeneric): Remove bogus (fboundp 'method).
23
24 * emacs-lisp/eieio-speedbar.el:
25 * emacs-lisp/eieio-datadebug.el:
26 * emacs-lisp/eieio-custom.el:
27 * emacs-lisp/eieio-base.el: Use cl-defmethod.
28
29 * emacs-lisp/cl-generic.el (cl-defgeneric): Add support for `declare'.
30 (cl--generic-setf-rewrite): Setup the setf expander right away.
31 (cl-defmethod): Make sure the setf expander is setup before we expand
32 the body.
33 (cl-defmethod): Silence byte-compiler warnings.
34 (cl-generic-define-method): Shuffle code to change return value.
35 (cl--generic-method-info): New function, extracted from
36 cl--generic-describe.
37 (cl--generic-describe): Use it.
38
392015-01-21 Dmitry Gutov <dgutov@yandex.ru>
40
41 * progmodes/xref.el (xref--xref-buffer-mode-map): Define before
42 the major mode. Remap `quit-window' to `xref-quit'.
43 (xref--xref-buffer-mode): Inherit from special-mode.
44
45 xref: Keep track of temporary buffers (bug#19466).
46 * progmodes/xref.el (xref--temporary-buffers, xref--selected)
47 (xref--inhibit-mark-selected): New variables.
48 (xref--mark-selected): New function.
49 (xref--show-location): Maybe add the buffer to
50 `xref--temporary-buffers', add `xref--mark-selected' to
51 `buffer-list-update-hook' there.
52 (xref--window): Add docstring.
53 (xref-quit): Rename from `xref--quit'. Update both references.
54 Add KILL argument. When it's non-nil, kill the temporary buffers
55 that haven't been selected by the user.
56 (xref--show-xref-buffer): Change the second argument to alist,
57 extract the values for `xref--window' and
58 `xref--temporary-buffers' from it. Add `xref--mark-selected' to
59 `buffer-list-update-hook' to each buffer in the list.
60 (xref--show-xrefs): Move the logic of calling `xref-find-function'
61 here. Save the difference between buffer lists before and after
62 it's called as "temporary buffers", and `pass it to
63 `xref-show-xrefs-function'.
64 (xref--find-definitions, xref-find-references)
65 (xref-find-apropos): Update accordingly.
66
672015-01-20 Artur Malabarba <bruce.connor.am@gmail.com>
68
69 * emacs-lisp/package.el (package-dir-info): Fix `while' logic.
70
12015-01-20 Stefan Monnier <monnier@iro.umontreal.ca> 712015-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
2 72
3 * emacs-lisp/eieio-generic.el: Remove. 73 * emacs-lisp/eieio-generic.el: Remove.
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 3bbddfc45a1..8dee9a38ab0 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -98,19 +98,20 @@ They should be sorted from most specific to least specific.")
98 (:constructor cl--generic-make 98 (:constructor cl--generic-make
99 (name &optional dispatches method-table)) 99 (name &optional dispatches method-table))
100 (:predicate nil)) 100 (:predicate nil))
101 (name nil :read-only t) ;Pointer back to the symbol. 101 (name nil :type symbol :read-only t) ;Pointer back to the symbol.
102 ;; `dispatches' holds a list of (ARGNUM . TAGCODES) where ARGNUM is the index 102 ;; `dispatches' holds a list of (ARGNUM . TAGCODES) where ARGNUM is the index
103 ;; of the corresponding argument and TAGCODES is a list of (PRIORITY . EXP) 103 ;; of the corresponding argument and TAGCODES is a list of (PRIORITY . EXP)
104 ;; where the EXPs are expressions (to be `or'd together) to compute the tag 104 ;; where the EXPs are expressions (to be `or'd together) to compute the tag
105 ;; on which to dispatch and PRIORITY is the priority of each expression to 105 ;; on which to dispatch and PRIORITY is the priority of each expression to
106 ;; decide in which order to sort them. 106 ;; decide in which order to sort them.
107 ;; The most important dispatch is last in the list (and the least is first). 107 ;; The most important dispatch is last in the list (and the least is first).
108 dispatches 108 (dispatches nil :type (list-of (cons natnum (list-of tagcode))))
109 ;; `method-table' is a list of 109 ;; `method-table' is a list of
110 ;; ((SPECIALIZERS . QUALIFIER) USES-CNM . FUNCTION), where 110 ;; ((SPECIALIZERS . QUALIFIER) USES-CNM . FUNCTION), where
111 ;; USES-CNM is a boolean indicating if FUNCTION calls `cl-call-next-method' 111 ;; USES-CNM is a boolean indicating if FUNCTION calls `cl-call-next-method'
112 ;; (and hence expects an extra argument holding the next-method). 112 ;; (and hence expects an extra argument holding the next-method).
113 method-table) 113 (method-table nil :type (list-of (cons (cons (list-of type) keyword)
114 (cons boolean function)))))
114 115
115(defmacro cl--generic (name) 116(defmacro cl--generic (name)
116 `(get ,name 'cl--generic)) 117 `(get ,name 'cl--generic))
@@ -134,15 +135,16 @@ They should be sorted from most specific to least specific.")
134 generic)) 135 generic))
135 136
136(defun cl--generic-setf-rewrite (name) 137(defun cl--generic-setf-rewrite (name)
137 (let ((setter (intern (format "cl-generic-setter--%s" name)))) 138 (let* ((setter (intern (format "cl-generic-setter--%s" name)))
138 (cons setter 139 (exp `(unless (eq ',setter (get ',name 'cl-generic-setter))
139 `(eval-and-compile 140 ;; (when (get ',name 'gv-expander)
140 (unless (eq ',setter (get ',name 'cl-generic-setter)) 141 ;; (error "gv-expander conflicts with (setf %S)" ',name))
141 ;; (when (get ',name 'gv-expander) 142 (setf (get ',name 'cl-generic-setter) ',setter)
142 ;; (error "gv-expander conflicts with (setf %S)" ',name)) 143 (gv-define-setter ,name (val &rest args)
143 (setf (get ',name 'cl-generic-setter) ',setter) 144 (cons ',setter (cons val args))))))
144 (gv-define-setter ,name (val &rest args) 145 ;; Make sure `setf' can be used right away, e.g. in the body of the method.
145 (cons ',setter (cons val args)))))))) 146 (eval exp t)
147 (cons setter exp)))
146 148
147;;;###autoload 149;;;###autoload
148(defmacro cl-defgeneric (name args &rest options-and-methods) 150(defmacro cl-defgeneric (name args &rest options-and-methods)
@@ -151,8 +153,9 @@ DOC-STRING is the base documentation for this class. A generic
151function has no body, as its purpose is to decide which method body 153function has no body, as its purpose is to decide which method body
152is appropriate to use. Specific methods are defined with `cl-defmethod'. 154is appropriate to use. Specific methods are defined with `cl-defmethod'.
153With this implementation the ARGS are currently ignored. 155With this implementation the ARGS are currently ignored.
154OPTIONS-AND-METHODS is currently only used to specify the docstring, 156OPTIONS-AND-METHODS currently understands:
155via (:documentation DOCSTRING)." 157- (:documentation DOCSTRING)
158- (declare DECLARATIONS)"
156 (declare (indent 2) (doc-string 3)) 159 (declare (indent 2) (doc-string 3))
157 (let* ((docprop (assq :documentation options-and-methods)) 160 (let* ((docprop (assq :documentation options-and-methods))
158 (doc (cond ((stringp (car-safe options-and-methods)) 161 (doc (cond ((stringp (car-safe options-and-methods))
@@ -161,13 +164,26 @@ via (:documentation DOCSTRING)."
161 (prog1 164 (prog1
162 (cadr docprop) 165 (cadr docprop)
163 (setq options-and-methods 166 (setq options-and-methods
164 (delq docprop options-and-methods))))))) 167 (delq docprop options-and-methods))))))
168 (declarations (assq 'declare options-and-methods)))
169 (when declarations
170 (setq options-and-methods
171 (delq declarations options-and-methods)))
165 `(progn 172 `(progn
166 ,(when (eq 'setf (car-safe name)) 173 ,(when (eq 'setf (car-safe name))
167 (pcase-let ((`(,setter . ,code) (cl--generic-setf-rewrite 174 (pcase-let ((`(,setter . ,code) (cl--generic-setf-rewrite
168 (cadr name)))) 175 (cadr name))))
169 (setq name setter) 176 (setq name setter)
170 code)) 177 code))
178 ,@(mapcar (lambda (declaration)
179 (let ((f (cdr (assq (car declaration)
180 defun-declarations-alist))))
181 (cond
182 (f (apply (car f) name args (cdr declaration)))
183 (t (message "Warning: Unknown defun property `%S' in %S"
184 (car declaration) name)
185 nil))))
186 (cdr declarations))
171 (defalias ',name 187 (defalias ',name
172 (cl-generic-define ',name ',args ',options-and-methods) 188 (cl-generic-define ',name ',args ',options-and-methods)
173 ,(help-add-fundoc-usage doc args))))) 189 ,(help-add-fundoc-usage doc args)))))
@@ -292,18 +308,19 @@ which case this method will be invoked when the argument is `eql' to VAL.
292 list ; arguments 308 list ; arguments
293 [ &optional stringp ] ; documentation string 309 [ &optional stringp ] ; documentation string
294 def-body))) ; part to be debugged 310 def-body))) ; part to be debugged
295 (let ((qualifiers nil)) 311 (let ((qualifiers nil)
312 (setfizer (if (eq 'setf (car-safe name))
313 ;; Call it before we call cl--generic-lambda.
314 (cl--generic-setf-rewrite (cadr name)))))
296 (while (keywordp args) 315 (while (keywordp args)
297 (push args qualifiers) 316 (push args qualifiers)
298 (setq args (pop body))) 317 (setq args (pop body)))
299 (pcase-let* ((with-cnm (not (memq (car qualifiers) '(:before :after)))) 318 (pcase-let* ((with-cnm (not (memq (car qualifiers) '(:before :after))))
300 (`(,uses-cnm . ,fun) (cl--generic-lambda args body with-cnm))) 319 (`(,uses-cnm . ,fun) (cl--generic-lambda args body with-cnm)))
301 `(progn 320 `(progn
302 ,(when (eq 'setf (car-safe name)) 321 ,(when setfizer
303 (pcase-let ((`(,setter . ,code) (cl--generic-setf-rewrite 322 (setq name (car setfizer))
304 (cadr name)))) 323 (cdr setfizer))
305 (setq name setter)
306 code))
307 ,(and (get name 'byte-obsolete-info) 324 ,(and (get name 'byte-obsolete-info)
308 (or (not (fboundp 'byte-compile-warning-enabled-p)) 325 (or (not (fboundp 'byte-compile-warning-enabled-p))
309 (byte-compile-warning-enabled-p 'obsolete)) 326 (byte-compile-warning-enabled-p 'obsolete))
@@ -311,6 +328,11 @@ which case this method will be invoked when the argument is `eql' to VAL.
311 (macroexp--warn-and-return 328 (macroexp--warn-and-return
312 (macroexp--obsolete-warning name obsolete "generic function") 329 (macroexp--obsolete-warning name obsolete "generic function")
313 nil))) 330 nil)))
331 ;; You could argue that `defmethod' modifies rather than defines the
332 ;; function, so warnings like "not known to be defined" are fair game.
333 ;; But in practice, it's common to use `cl-defmethod'
334 ;; without a previous `cl-defgeneric'.
335 (declare-function ,name "")
314 (cl-generic-define-method ',name ',qualifiers ',args 336 (cl-generic-define-method ',name ',qualifiers ',args
315 ,uses-cnm ,fun))))) 337 ,uses-cnm ,fun)))))
316 338
@@ -344,14 +366,14 @@ which case this method will be invoked when the argument is `eql' to VAL.
344 (if me (setcdr me (cons uses-cnm function)) 366 (if me (setcdr me (cons uses-cnm function))
345 (setf (cl--generic-method-table generic) 367 (setf (cl--generic-method-table generic)
346 (cons `(,key ,uses-cnm . ,function) mt))) 368 (cons `(,key ,uses-cnm . ,function) mt)))
347 ;; For aliases, cl--generic-name gives us the actual name. 369 (cl-pushnew `(cl-defmethod . (,(cl--generic-name generic) . ,specializers))
370 current-load-list :test #'equal)
348 (let ((gfun (cl--generic-make-function generic)) 371 (let ((gfun (cl--generic-make-function generic))
349 ;; Prevent `defalias' from recording this as the definition site of 372 ;; Prevent `defalias' from recording this as the definition site of
350 ;; the generic function. 373 ;; the generic function.
351 current-load-list) 374 current-load-list)
352 (defalias (cl--generic-name generic) gfun)) 375 ;; For aliases, cl--generic-name gives us the actual name.
353 (cl-pushnew `(cl-defmethod . (,(cl--generic-name generic) . ,specializers)) 376 (defalias (cl--generic-name generic) gfun))))
354 current-load-list :test #'equal)))
355 377
356(defmacro cl--generic-with-memoization (place &rest code) 378(defmacro cl--generic-with-memoization (place &rest code)
357 (declare (indent 1) (debug t)) 379 (declare (indent 1) (debug t))
@@ -448,8 +470,12 @@ for all those different tags in the method-cache.")
448 ;; We don't currently have "method objects" like CLOS 470 ;; We don't currently have "method objects" like CLOS
449 ;; does so we can't really do it the CLOS way. 471 ;; does so we can't really do it the CLOS way.
450 ;; The closest would be to pass the lambda corresponding 472 ;; The closest would be to pass the lambda corresponding
451 ;; to the method, but the caller wouldn't be able to do 473 ;; to the method, or maybe the ((SPECIALIZERS
452 ;; much with it anyway. So we pass nil for now. 474 ;; . QUALIFIER) USE-CNM . FUNCTION) entry from the method
475 ;; table, but the caller wouldn't be able to do much with
476 ;; it anyway. So we pass nil for now.
477 ;; FIXME: signal `no-primary-method' if there's
478 ;; no primary.
453 (apply #'cl-no-next-method generic-name nil args))) 479 (apply #'cl-no-next-method generic-name nil args)))
454 ;; We use `cdr' to drop the `uses-cnm' annotations. 480 ;; We use `cdr' to drop the `uses-cnm' annotations.
455 (before 481 (before
@@ -566,6 +592,24 @@ Can only be used from within the lexical body of a primary or around method."
566 (add-to-list 'find-function-regexp-alist 592 (add-to-list 'find-function-regexp-alist
567 `(cl-defmethod . ,#'cl--generic-search-method))) 593 `(cl-defmethod . ,#'cl--generic-search-method)))
568 594
595(defun cl--generic-method-info (method)
596 (pcase-let ((`((,specializers . ,qualifier) ,uses-cnm . ,function) method))
597 (let* ((args (help-function-arglist function 'names))
598 (docstring (documentation function))
599 (doconly (if docstring
600 (let ((split (help-split-fundoc docstring nil)))
601 (if split (cdr split) docstring))))
602 (combined-args ()))
603 (if uses-cnm (setq args (cdr args)))
604 (dolist (specializer specializers)
605 (let ((arg (if (eq '&rest (car args))
606 (intern (format "arg%d" (length combined-args)))
607 (pop args))))
608 (push (if (eq specializer t) arg (list arg specializer))
609 combined-args)))
610 (setq combined-args (append (nreverse combined-args) args))
611 (list qualifier combined-args doconly))))
612
569(add-hook 'help-fns-describe-function-functions #'cl--generic-describe) 613(add-hook 'help-fns-describe-function-functions #'cl--generic-describe)
570(defun cl--generic-describe (function) 614(defun cl--generic-describe (function)
571 (let ((generic (if (symbolp function) (cl--generic function)))) 615 (let ((generic (if (symbolp function) (cl--generic function))))
@@ -575,25 +619,11 @@ Can only be used from within the lexical body of a primary or around method."
575 (insert "\n\nThis is a generic function.\n\n") 619 (insert "\n\nThis is a generic function.\n\n")
576 (insert (propertize "Implementations:\n\n" 'face 'bold)) 620 (insert (propertize "Implementations:\n\n" 'face 'bold))
577 ;; Loop over fanciful generics 621 ;; Loop over fanciful generics
578 (pcase-dolist (`((,specializers . ,qualifier) ,uses-cnm . ,method) 622 (dolist (method (cl--generic-method-table generic))
579 (cl--generic-method-table generic)) 623 (let* ((info (cl--generic-method-info method)))
580 (let* ((args (help-function-arglist method 'names))
581 (docstring (documentation method))
582 (doconly (if docstring
583 (let ((split (help-split-fundoc docstring nil)))
584 (if split (cdr split) docstring))))
585 (combined-args ()))
586 (if uses-cnm (setq args (cdr args)))
587 (dolist (specializer specializers)
588 (let ((arg (if (eq '&rest (car args))
589 (intern (format "arg%d" (length combined-args)))
590 (pop args))))
591 (push (if (eq specializer t) arg (list arg specializer))
592 combined-args)))
593 (setq combined-args (append (nreverse combined-args) args))
594 ;; FIXME: Add hyperlinks for the types as well. 624 ;; FIXME: Add hyperlinks for the types as well.
595 (insert (format "%S %S" qualifier combined-args)) 625 (insert (format "%S %S" (nth 0 info) (nth 1 info)))
596 (let* ((met-name (cons function specializers)) 626 (let* ((met-name (cons function (caar method)))
597 (file (find-lisp-object-file-name met-name 'cl-defmethod))) 627 (file (find-lisp-object-file-name met-name 'cl-defmethod)))
598 (when file 628 (when file
599 (insert " in `") 629 (insert " in `")
@@ -601,7 +631,7 @@ Can only be used from within the lexical body of a primary or around method."
601 'help-function-def met-name file 631 'help-function-def met-name file
602 'cl-defmethod) 632 'cl-defmethod)
603 (insert "'.\n"))) 633 (insert "'.\n")))
604 (insert "\n" (or doconly "Undocumented") "\n\n"))))))) 634 (insert "\n" (or (nth 2 info) "Undocumented") "\n\n")))))))
605 635
606;;; Support for (eql <val>) specializers. 636;;; Support for (eql <val>) specializers.
607 637
diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el
index 9931fbd114e..feb06711cb3 100644
--- a/lisp/emacs-lisp/eieio-base.el
+++ b/lisp/emacs-lisp/eieio-base.el
@@ -52,7 +52,7 @@ a parent instance. When a slot in the child is referenced, and has
52not been set, use values from the parent." 52not been set, use values from the parent."
53 :abstract t) 53 :abstract t)
54 54
55(defmethod slot-unbound ((object eieio-instance-inheritor) 55(cl-defmethod slot-unbound ((object eieio-instance-inheritor)
56 _class slot-name _fn) 56 _class slot-name _fn)
57 "If a slot OBJECT in this CLASS is unbound, try to inherit, or throw a signal. 57 "If a slot OBJECT in this CLASS is unbound, try to inherit, or throw a signal.
58SLOT-NAME is the offending slot. FN is the function signaling the error." 58SLOT-NAME is the offending slot. FN is the function signaling the error."
@@ -61,16 +61,16 @@ SLOT-NAME is the offending slot. FN is the function signaling the error."
61 ;; method if the parent instance's slot is unbound. 61 ;; method if the parent instance's slot is unbound.
62 (eieio-oref (oref object parent-instance) slot-name) 62 (eieio-oref (oref object parent-instance) slot-name)
63 ;; Throw the regular signal. 63 ;; Throw the regular signal.
64 (call-next-method))) 64 (cl-call-next-method)))
65 65
66(defmethod clone ((obj eieio-instance-inheritor) &rest _params) 66(cl-defmethod clone ((obj eieio-instance-inheritor) &rest _params)
67 "Clone OBJ, initializing `:parent' to OBJ. 67 "Clone OBJ, initializing `:parent' to OBJ.
68All slots are unbound, except those initialized with PARAMS." 68All slots are unbound, except those initialized with PARAMS."
69 (let ((nobj (call-next-method))) 69 (let ((nobj (cl-call-next-method)))
70 (oset nobj parent-instance obj) 70 (oset nobj parent-instance obj)
71 nobj)) 71 nobj))
72 72
73(defmethod eieio-instance-inheritor-slot-boundp ((object eieio-instance-inheritor) 73(cl-defmethod eieio-instance-inheritor-slot-boundp ((object eieio-instance-inheritor)
74 slot) 74 slot)
75 "Return non-nil if the instance inheritor OBJECT's SLOT is bound. 75 "Return non-nil if the instance inheritor OBJECT's SLOT is bound.
76See `slot-boundp' for details on binding slots. 76See `slot-boundp' for details on binding slots.
@@ -103,7 +103,7 @@ Inheritors from this class must overload `tracking-symbol' which is
103a variable symbol used to store a list of all instances." 103a variable symbol used to store a list of all instances."
104 :abstract t) 104 :abstract t)
105 105
106(defmethod initialize-instance :AFTER ((this eieio-instance-tracker) 106(cl-defmethod initialize-instance :after ((this eieio-instance-tracker)
107 &rest _slots) 107 &rest _slots)
108 "Make sure THIS is in our master list of this class. 108 "Make sure THIS is in our master list of this class.
109Optional argument SLOTS are the initialization arguments." 109Optional argument SLOTS are the initialization arguments."
@@ -112,7 +112,7 @@ Optional argument SLOTS are the initialization arguments."
112 (if (not (memq this (symbol-value sym))) 112 (if (not (memq this (symbol-value sym)))
113 (set sym (append (symbol-value sym) (list this)))))) 113 (set sym (append (symbol-value sym) (list this))))))
114 114
115(defmethod delete-instance ((this eieio-instance-tracker)) 115(cl-defmethod delete-instance ((this eieio-instance-tracker))
116 "Remove THIS from the master list of this class." 116 "Remove THIS from the master list of this class."
117 (set (oref this tracking-symbol) 117 (set (oref this tracking-symbol)
118 (delq this (symbol-value (oref this tracking-symbol))))) 118 (delq this (symbol-value (oref this tracking-symbol)))))
@@ -140,7 +140,7 @@ Multiple calls to `make-instance' will return this object."))
140A singleton is a class which will only ever have one instance." 140A singleton is a class which will only ever have one instance."
141 :abstract t) 141 :abstract t)
142 142
143(defmethod eieio-constructor :STATIC ((class eieio-singleton) &rest _slots) 143(cl-defmethod eieio-constructor ((class (subclass eieio-singleton)) &rest _slots)
144 "Constructor for singleton CLASS. 144 "Constructor for singleton CLASS.
145NAME and SLOTS initialize the new object. 145NAME and SLOTS initialize the new object.
146This constructor guarantees that no matter how many you request, 146This constructor guarantees that no matter how many you request,
@@ -149,7 +149,7 @@ only one object ever exists."
149 ;; with class allocated slots or default values. 149 ;; with class allocated slots or default values.
150 (let ((old (oref-default class singleton))) 150 (let ((old (oref-default class singleton)))
151 (if (eq old eieio-unbound) 151 (if (eq old eieio-unbound)
152 (oset-default class singleton (call-next-method)) 152 (oset-default class singleton (cl-call-next-method))
153 old))) 153 old)))
154 154
155 155
@@ -198,7 +198,7 @@ object. For this reason, only slots which do not have an `:initarg'
198specified will not be saved." 198specified will not be saved."
199 :abstract t) 199 :abstract t)
200 200
201(defmethod eieio-persistent-save-interactive ((this eieio-persistent) prompt 201(cl-defmethod eieio-persistent-save-interactive ((this eieio-persistent) prompt
202 &optional name) 202 &optional name)
203 "Prepare to save THIS. Use in an `interactive' statement. 203 "Prepare to save THIS. Use in an `interactive' statement.
204Query user for file name with PROMPT if THIS does not yet specify 204Query user for file name with PROMPT if THIS does not yet specify
@@ -417,17 +417,17 @@ If no class is referenced there, then return nil."
417 ;; No match, not a class. 417 ;; No match, not a class.
418 nil))) 418 nil)))
419 419
420(defmethod object-write ((this eieio-persistent) &optional comment) 420(cl-defmethod object-write ((this eieio-persistent) &optional comment)
421 "Write persistent object THIS out to the current stream. 421 "Write persistent object THIS out to the current stream.
422Optional argument COMMENT is a header line comment." 422Optional argument COMMENT is a header line comment."
423 (call-next-method this (or comment (oref this file-header-line)))) 423 (cl-call-next-method this (or comment (oref this file-header-line))))
424 424
425(defmethod eieio-persistent-path-relative ((this eieio-persistent) file) 425(cl-defmethod eieio-persistent-path-relative ((this eieio-persistent) file)
426 "For object THIS, make absolute file name FILE relative." 426 "For object THIS, make absolute file name FILE relative."
427 (file-relative-name (expand-file-name file) 427 (file-relative-name (expand-file-name file)
428 (file-name-directory (oref this file)))) 428 (file-name-directory (oref this file))))
429 429
430(defmethod eieio-persistent-save ((this eieio-persistent) &optional file) 430(cl-defmethod eieio-persistent-save ((this eieio-persistent) &optional file)
431 "Save persistent object THIS to disk. 431 "Save persistent object THIS to disk.
432Optional argument FILE overrides the file name specified in the object 432Optional argument FILE overrides the file name specified in the object
433instance." 433instance."
@@ -474,21 +474,21 @@ instance."
474 "Object with a name." 474 "Object with a name."
475 :abstract t) 475 :abstract t)
476 476
477(defmethod eieio-object-name-string ((obj eieio-named)) 477(cl-defmethod eieio-object-name-string ((obj eieio-named))
478 "Return a string which is OBJ's name." 478 "Return a string which is OBJ's name."
479 (or (slot-value obj 'object-name) 479 (or (slot-value obj 'object-name)
480 (symbol-name (eieio-object-class obj)))) 480 (symbol-name (eieio-object-class obj))))
481 481
482(defmethod eieio-object-set-name-string ((obj eieio-named) name) 482(cl-defmethod eieio-object-set-name-string ((obj eieio-named) name)
483 "Set the string which is OBJ's NAME." 483 "Set the string which is OBJ's NAME."
484 (eieio--check-type stringp name) 484 (eieio--check-type stringp name)
485 (eieio-oset obj 'object-name name)) 485 (eieio-oset obj 'object-name name))
486 486
487(defmethod clone ((obj eieio-named) &rest params) 487(cl-defmethod clone ((obj eieio-named) &rest params)
488 "Clone OBJ, initializing `:parent' to OBJ. 488 "Clone OBJ, initializing `:parent' to OBJ.
489All slots are unbound, except those initialized with PARAMS." 489All slots are unbound, except those initialized with PARAMS."
490 (let* ((newname (and (stringp (car params)) (pop params))) 490 (let* ((newname (and (stringp (car params)) (pop params)))
491 (nobj (apply #'call-next-method obj params)) 491 (nobj (apply #'cl-call-next-method obj params))
492 (nm (slot-value obj 'object-name))) 492 (nm (slot-value obj 'object-name)))
493 (eieio-oset obj 'object-name 493 (eieio-oset obj 'object-name
494 (or newname 494 (or newname
diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el
index 34c06c01763..c2dabf7f446 100644
--- a/lisp/emacs-lisp/eieio-compat.el
+++ b/lisp/emacs-lisp/eieio-compat.el
@@ -190,13 +190,27 @@ Summary:
190 (if split (cdr split) docstring)))) 190 (if split (cdr split) docstring))))
191 (new-docstring (help-add-fundoc-usage doc-only 191 (new-docstring (help-add-fundoc-usage doc-only
192 (cons 'cl-cnm args)))) 192 (cons 'cl-cnm args))))
193 ;; FIXME: ¡Add the new-docstring to those closures! 193 ;; FIXME: ¡Add new-docstring to those closures!
194 (lambda (cnm &rest args) 194 (lambda (cnm &rest args)
195 (cl-letf (((symbol-function 'call-next-method) cnm) 195 (cl-letf (((symbol-function 'call-next-method) cnm)
196 ((symbol-function 'next-method-p) 196 ((symbol-function 'next-method-p)
197 (lambda () (cl--generic-isnot-nnm-p cnm)))) 197 (lambda () (cl--generic-isnot-nnm-p cnm))))
198 (apply code args)))) 198 (apply code args))))
199 code)))) 199 code))
200 ;; The old EIEIO code did not signal an error when there are methods
201 ;; applicable but only of the before/after kind. So if we add a :before
202 ;; or :after, make sure there's a matching dummy primary.
203 (when (and (memq kind '(:before :after))
204 (not (assoc (cons (mapcar (lambda (arg)
205 (if (consp arg) (nth 1 arg) t))
206 specializers)
207 :primary)
208 (cl--generic-method-table (cl--generic method)))))
209 (cl-generic-define-method method () specializers t
210 (lambda (cnm &rest args)
211 (if (cl--generic-isnot-nnm-p cnm)
212 (apply cnm args)))))
213 method))
200 214
201;; Compatibility with code which tries to catch `no-method-definition' errors. 215;; Compatibility with code which tries to catch `no-method-definition' errors.
202(push 'no-method-definition (get 'cl-no-applicable-method 'error-conditions)) 216(push 'no-method-definition (get 'cl-no-applicable-method 'error-conditions))
@@ -212,7 +226,12 @@ Summary:
212 (apply #'cl-no-applicable-method method object args)) 226 (apply #'cl-no-applicable-method method object args))
213 227
214(define-obsolete-function-alias 'call-next-method 'cl-call-next-method "25.1") 228(define-obsolete-function-alias 'call-next-method 'cl-call-next-method "25.1")
215(define-obsolete-function-alias 'next-method-p 'cl-next-method-p "25.1") 229(defun next-method-p ()
230 (declare (obsolete cl-next-method-p "25.1"))
231 ;; EIEIO's `next-method-p' just returned nil when called in an
232 ;; invalid context.
233 (message "next-method-p called outside of a primary or around method")
234 nil)
216 235
217;;;###autoload 236;;;###autoload
218(defun eieio-defmethod (method args) 237(defun eieio-defmethod (method args)
@@ -225,11 +244,9 @@ Summary:
225(defun eieio-defgeneric (method doc-string) 244(defun eieio-defgeneric (method doc-string)
226 "Obsolete work part of an old version of the `defgeneric' macro." 245 "Obsolete work part of an old version of the `defgeneric' macro."
227 (declare (obsolete cl-defgeneric "24.1")) 246 (declare (obsolete cl-defgeneric "24.1"))
228 ;; Don't do this over and over. 247 (eval `(defgeneric ,method (x) ,@(if doc-string `(,doc-string))))
229 (unless (fboundp 'method) 248 ;; Return the method
230 (eval `(defgeneric ,method (x) ,@(if doc-string `(,doc-string)))) 249 'method)
231 ;; Return the method
232 'method))
233 250
234;;;###autoload 251;;;###autoload
235(defun eieio-defclass (cname superclasses slots options) 252(defun eieio-defclass (cname superclasses slots options)
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index b89ccfdfb2b..0297accaa05 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -1258,7 +1258,7 @@ method invocation orders of the involved classes."
1258 (eieio--class-precedence-list tag)))) 1258 (eieio--class-precedence-list tag))))
1259 1259
1260 1260
1261;;;### (autoloads nil "eieio-compat" "eieio-compat.el" "b177169dfbad7fb2e9d500b9c40002fa") 1261;;;### (autoloads nil "eieio-compat" "eieio-compat.el" "51667b1cd372f45acdae14f838cedcc6")
1262;;; Generated autoloads from eieio-compat.el 1262;;; Generated autoloads from eieio-compat.el
1263 1263
1264(autoload 'eieio--defalias "eieio-compat" "\ 1264(autoload 'eieio--defalias "eieio-compat" "\
@@ -1325,6 +1325,27 @@ Summary:
1325 1325
1326\(fn METHOD KIND ARGCLASS CODE)" nil nil) 1326\(fn METHOD KIND ARGCLASS CODE)" nil nil)
1327 1327
1328(autoload 'eieio-defmethod "eieio-compat" "\
1329Obsolete work part of an old version of the `defmethod' macro.
1330
1331\(fn METHOD ARGS)" nil nil)
1332
1333(make-obsolete 'eieio-defmethod 'cl-defmethod '"24.1")
1334
1335(autoload 'eieio-defgeneric "eieio-compat" "\
1336Obsolete work part of an old version of the `defgeneric' macro.
1337
1338\(fn METHOD DOC-STRING)" nil nil)
1339
1340(make-obsolete 'eieio-defgeneric 'cl-defgeneric '"24.1")
1341
1342(autoload 'eieio-defclass "eieio-compat" "\
1343
1344
1345\(fn CNAME SUPERCLASSES SLOTS OPTIONS)" nil nil)
1346
1347(make-obsolete 'eieio-defclass 'eieio-defclass-internal '"25.1")
1348
1328;;;*** 1349;;;***
1329 1350
1330 1351
diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el
index 8ab74ae3352..0e0b31e4e7e 100644
--- a/lisp/emacs-lisp/eieio-custom.el
+++ b/lisp/emacs-lisp/eieio-custom.el
@@ -322,7 +322,7 @@ Optional argument IGNORE is an extraneous parameter."
322 ;; This is the same object we had before. 322 ;; This is the same object we had before.
323 obj)) 323 obj))
324 324
325(defmethod eieio-done-customizing ((_obj eieio-default-superclass)) 325(cl-defmethod eieio-done-customizing ((_obj eieio-default-superclass))
326 "When applying change to a widget, call this method. 326 "When applying change to a widget, call this method.
327This method is called by the default widget-edit commands. 327This method is called by the default widget-edit commands.
328User made commands should also call this method when applying changes. 328User made commands should also call this method when applying changes.
@@ -345,7 +345,7 @@ Optional argument GROUP is the sub-group of slots to display."
345 "Major mode for customizing EIEIO objects. 345 "Major mode for customizing EIEIO objects.
346\\{eieio-custom-mode-map}") 346\\{eieio-custom-mode-map}")
347 347
348(defmethod eieio-customize-object ((obj eieio-default-superclass) 348(cl-defmethod eieio-customize-object ((obj eieio-default-superclass)
349 &optional group) 349 &optional group)
350 "Customize OBJ in a specialized custom buffer. 350 "Customize OBJ in a specialized custom buffer.
351To override call the `eieio-custom-widget-insert' to just insert the 351To override call the `eieio-custom-widget-insert' to just insert the
@@ -386,7 +386,7 @@ These groups are specified with the `:group' slot flag."
386 (make-local-variable 'eieio-cog) 386 (make-local-variable 'eieio-cog)
387 (setq eieio-cog g))) 387 (setq eieio-cog g)))
388 388
389(defmethod eieio-custom-object-apply-reset ((_obj eieio-default-superclass)) 389(cl-defmethod eieio-custom-object-apply-reset ((_obj eieio-default-superclass))
390 "Insert an Apply and Reset button into the object editor. 390 "Insert an Apply and Reset button into the object editor.
391Argument OBJ is the object being customized." 391Argument OBJ is the object being customized."
392 (widget-create 'push-button 392 (widget-create 'push-button
@@ -417,7 +417,7 @@ Argument OBJ is the object being customized."
417 (bury-buffer)) 417 (bury-buffer))
418 "Cancel")) 418 "Cancel"))
419 419
420(defmethod eieio-custom-widget-insert ((obj eieio-default-superclass) 420(cl-defmethod eieio-custom-widget-insert ((obj eieio-default-superclass)
421 &rest flags) 421 &rest flags)
422 "Insert the widget used for editing object OBJ in the current buffer. 422 "Insert the widget used for editing object OBJ in the current buffer.
423Arguments FLAGS are widget compatible flags. 423Arguments FLAGS are widget compatible flags.
@@ -446,7 +446,7 @@ Must return the created widget."
446;; These functions provide the ability to create dynamic menus to 446;; These functions provide the ability to create dynamic menus to
447;; customize specific sections of an object. They do not hook directly 447;; customize specific sections of an object. They do not hook directly
448;; into a filter, but can be used to create easymenu vectors. 448;; into a filter, but can be used to create easymenu vectors.
449(defmethod eieio-customize-object-group ((obj eieio-default-superclass)) 449(cl-defmethod eieio-customize-object-group ((obj eieio-default-superclass))
450 "Create a list of vectors for customizing sections of OBJ." 450 "Create a list of vectors for customizing sections of OBJ."
451 (mapcar (lambda (group) 451 (mapcar (lambda (group)
452 (vector (concat "Group " (symbol-name group)) 452 (vector (concat "Group " (symbol-name group))
@@ -457,7 +457,7 @@ Must return the created widget."
457(defvar eieio-read-custom-group-history nil 457(defvar eieio-read-custom-group-history nil
458 "History for the custom group reader.") 458 "History for the custom group reader.")
459 459
460(defmethod eieio-read-customization-group ((obj eieio-default-superclass)) 460(cl-defmethod eieio-read-customization-group ((obj eieio-default-superclass))
461 "Do a completing read on the name of a customization group in OBJ. 461 "Do a completing read on the name of a customization group in OBJ.
462Return the symbol for the group, or nil" 462Return the symbol for the group, or nil"
463 (let ((g (eieio--class-option (eieio--object-class-object obj) 463 (let ((g (eieio--class-option (eieio--object-class-object obj)
diff --git a/lisp/emacs-lisp/eieio-datadebug.el b/lisp/emacs-lisp/eieio-datadebug.el
index ab8d41e4ac4..6534bd0fecf 100644
--- a/lisp/emacs-lisp/eieio-datadebug.el
+++ b/lisp/emacs-lisp/eieio-datadebug.el
@@ -79,7 +79,7 @@ PREBUTTONTEXT is some text between PREFIX and the object button."
79;; 79;;
80;; Each object should have an opportunity to show stuff about itself. 80;; Each object should have an opportunity to show stuff about itself.
81 81
82(defmethod data-debug/eieio-insert-slots ((obj eieio-default-superclass) 82(cl-defmethod data-debug/eieio-insert-slots ((obj eieio-default-superclass)
83 prefix) 83 prefix)
84 "Insert the slots of OBJ into the current DDEBUG buffer." 84 "Insert the slots of OBJ into the current DDEBUG buffer."
85 (let ((inhibit-read-only t)) 85 (let ((inhibit-read-only t))
@@ -124,7 +124,7 @@ PREBUTTONTEXT is some text between PREFIX and the object button."
124;; 124;;
125;; A generic function to run DDEBUG on an object and popup a new buffer. 125;; A generic function to run DDEBUG on an object and popup a new buffer.
126;; 126;;
127(defmethod data-debug-show ((obj eieio-default-superclass)) 127(cl-defmethod data-debug-show ((obj eieio-default-superclass))
128 "Run ddebug against any EIEIO object OBJ." 128 "Run ddebug against any EIEIO object OBJ."
129 (data-debug-new-buffer (format "*%s DDEBUG*" (eieio-object-name obj))) 129 (data-debug-new-buffer (format "*%s DDEBUG*" (eieio-object-name obj)))
130 (data-debug-insert-object-slots obj "]")) 130 (data-debug-insert-object-slots obj "]"))
diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el
index 13ad120a9b5..a131b02ee16 100644
--- a/lisp/emacs-lisp/eieio-opt.el
+++ b/lisp/emacs-lisp/eieio-opt.el
@@ -122,29 +122,18 @@ If CLASS is actually an object, then also display current values of that object.
122 ;; Describe all the slots in this class. 122 ;; Describe all the slots in this class.
123 (eieio-help-class-slots class) 123 (eieio-help-class-slots class)
124 ;; Describe all the methods specific to this class. 124 ;; Describe all the methods specific to this class.
125 (let ((methods (eieio-all-generic-functions class)) 125 (let ((generics (eieio-all-generic-functions class)))
126 (type [":STATIC" ":BEFORE" ":PRIMARY" ":AFTER"]) 126 (when generics
127 counter doc)
128 (when methods
129 (insert (propertize "Specialized Methods:\n\n" 'face 'bold)) 127 (insert (propertize "Specialized Methods:\n\n" 'face 'bold))
130 (while methods 128 (dolist (generic generics)
131 (setq doc (eieio-method-documentation (car methods) class)) 129 (insert "`")
132 (insert "`") 130 (help-insert-xref-button (symbol-name generic) 'help-function generic)
133 (help-insert-xref-button (symbol-name (car methods)) 131 (insert "'")
134 'help-function (car methods)) 132 (pcase-dolist (`(,qualifier ,args ,doc)
135 (insert "'") 133 (eieio-method-documentation generic class))
136 (if (not doc) 134 (insert (format " %S %S\n" qualifier args)
137 (insert " Undocumented") 135 (or doc "")))
138 (setq counter 0) 136 (insert "\n\n")))))
139 (dolist (cur doc)
140 (when cur
141 (insert " " (aref type counter) " "
142 (prin1-to-string (car cur) (current-buffer))
143 "\n"
144 (or (cdr cur) "")))
145 (setq counter (1+ counter))))
146 (insert "\n\n")
147 (setq methods (cdr methods))))))
148 137
149(defun eieio-help-class-slots (class) 138(defun eieio-help-class-slots (class)
150 "Print help description for the slots in CLASS. 139 "Print help description for the slots in CLASS.
@@ -311,6 +300,20 @@ are not abstract."
311 (eieio-help-class ctr)) 300 (eieio-help-class ctr))
312 )))) 301 ))))
313 302
303(defun eieio--specializers-apply-to-class-p (specializers class)
304 "Return non-nil if a method with SPECIALIZERS applies to CLASS."
305 (let ((applies nil))
306 (dolist (specializer specializers)
307 (if (eq 'subclass (car-safe specializer))
308 (setq specializer (nth 1 specializer)))
309 ;; Don't include the methods that are "too generic", such as those
310 ;; applying to `eieio-default-superclass'.
311 (and (not (memq specializer '(t eieio-default-superclass)))
312 (class-p specializer)
313 (child-of-class-p class specializer)
314 (setq applies t)))
315 applies))
316
314(defun eieio-all-generic-functions (&optional class) 317(defun eieio-all-generic-functions (&optional class)
315 "Return a list of all generic functions. 318 "Return a list of all generic functions.
316Optional CLASS argument returns only those functions that contain 319Optional CLASS argument returns only those functions that contain
@@ -318,53 +321,31 @@ methods for CLASS."
318 (let ((l nil)) 321 (let ((l nil))
319 (mapatoms 322 (mapatoms
320 (lambda (symbol) 323 (lambda (symbol)
321 (let ((tree (get symbol 'eieio-method-hashtable))) 324 (let ((generic (and (fboundp symbol) (cl--generic symbol))))
322 (when tree 325 (and generic
323 ;; A symbol might be interned for that class in one of 326 (catch 'found
324 ;; these three slots in the method-obarray. 327 (if (null class) (throw 'found t))
325 (if (or (not class) 328 (pcase-dolist (`((,specializers . ,_qualifier) . ,_)
326 (car (gethash class (aref tree 0))) 329 (cl--generic-method-table generic))
327 (car (gethash class (aref tree 1))) 330 (if (eieio--specializers-apply-to-class-p
328 (car (gethash class (aref tree 2)))) 331 specializers class)
329 (setq l (cons symbol l))))))) 332 (throw 'found t))))
333 (push symbol l)))))
330 l)) 334 l))
331 335
332(defun eieio-method-documentation (generic class) 336(defun eieio-method-documentation (generic class)
333 "Return a list of the specific documentation of GENERIC for CLASS. 337 "Return info for all methods of GENERIC applicable to CLASS.
334If there is not an explicit method for CLASS in GENERIC, or if that 338The value returned is a list of elements of the form
335function has no documentation, then return nil." 339\(QUALIFIER ARGS DOC)."
336 (let ((tree (get generic 'eieio-method-hashtable))) 340 (let ((generic (cl--generic generic))
337 (when tree 341 (docs ()))
338 ;; A symbol might be interned for that class in one of 342 (when generic
339 ;; these three slots in the method-hashtable. 343 (dolist (method (cl--generic-method-table generic))
340 ;; FIXME: Where do these 0/1/2 come from? Isn't 0 for :static, 344 (pcase-let ((`((,specializers . ,_qualifier) . ,_) method))
341 ;; 1 for before, and 2 for primary (and 3 for after)? 345 (when (eieio--specializers-apply-to-class-p
342 (let ((before (car (gethash class (aref tree 0)))) 346 specializers class)
343 (primary (car (gethash class (aref tree 1)))) 347 (push (cl--generic-method-info method) docs)))))
344 (after (car (gethash class (aref tree 2))))) 348 docs))
345 (if (not (or before primary after))
346 nil
347 (list (if before
348 (cons (help-function-arglist before)
349 (documentation before))
350 nil)
351 (if primary
352 (cons (help-function-arglist primary)
353 (documentation primary))
354 nil)
355 (if after
356 (cons (help-function-arglist after)
357 (documentation after))
358 nil)))))))
359
360(defvar eieio-read-generic nil
361 "History of the `eieio-read-generic' prompt.")
362
363(defun eieio-read-generic (prompt &optional historyvar)
364 "Read a generic function from the minibuffer with PROMPT.
365Optional argument HISTORYVAR is the variable to use as history."
366 (intern (completing-read prompt obarray #'generic-p
367 t nil (or historyvar 'eieio-read-generic))))
368 349
369;;; METHOD STATS 350;;; METHOD STATS
370;; 351;;
diff --git a/lisp/emacs-lisp/eieio-speedbar.el b/lisp/emacs-lisp/eieio-speedbar.el
index b236f0f03e1..a1eabcf9700 100644
--- a/lisp/emacs-lisp/eieio-speedbar.el
+++ b/lisp/emacs-lisp/eieio-speedbar.el
@@ -196,19 +196,19 @@ that path."
196;; when no other methods are found, allowing multiple inheritance to work 196;; when no other methods are found, allowing multiple inheritance to work
197;; reliably with eieio-speedbar. 197;; reliably with eieio-speedbar.
198 198
199(defmethod eieio-speedbar-description (object) 199(cl-defmethod eieio-speedbar-description (object)
200 "Return a string describing OBJECT." 200 "Return a string describing OBJECT."
201 (eieio-object-name-string object)) 201 (eieio-object-name-string object))
202 202
203(defmethod eieio-speedbar-derive-line-path (_object) 203(cl-defmethod eieio-speedbar-derive-line-path (_object)
204 "Return the path which OBJECT has something to do with." 204 "Return the path which OBJECT has something to do with."
205 nil) 205 nil)
206 206
207(defmethod eieio-speedbar-object-buttonname (object) 207(cl-defmethod eieio-speedbar-object-buttonname (object)
208 "Return a string to use as a speedbar button for OBJECT." 208 "Return a string to use as a speedbar button for OBJECT."
209 (eieio-object-name-string object)) 209 (eieio-object-name-string object))
210 210
211(defmethod eieio-speedbar-make-tag-line (object depth) 211(cl-defmethod eieio-speedbar-make-tag-line (object depth)
212 "Insert a tag line into speedbar at point for OBJECT. 212 "Insert a tag line into speedbar at point for OBJECT.
213By default, all objects appear as simple TAGS with no need to inherit from 213By default, all objects appear as simple TAGS with no need to inherit from
214the special `eieio-speedbar' classes. Child classes should redefine this 214the special `eieio-speedbar' classes. Child classes should redefine this
@@ -221,7 +221,7 @@ Argument DEPTH is the depth at which the tag line is inserted."
221 'speedbar-tag-face 221 'speedbar-tag-face
222 depth)) 222 depth))
223 223
224(defmethod eieio-speedbar-handle-click (object) 224(cl-defmethod eieio-speedbar-handle-click (object)
225 "Handle a click action on OBJECT in speedbar. 225 "Handle a click action on OBJECT in speedbar.
226Any object can be represented as a tag in SPEEDBAR without special 226Any object can be represented as a tag in SPEEDBAR without special
227attributes. These default objects will be pulled up in a custom 227attributes. These default objects will be pulled up in a custom
@@ -285,7 +285,7 @@ Add one of the child classes to this class to the parent list of a class."
285 285
286;;; Methods to eieio-speedbar-* which do not need to be overridden 286;;; Methods to eieio-speedbar-* which do not need to be overridden
287;; 287;;
288(defmethod eieio-speedbar-make-tag-line ((object eieio-speedbar) 288(cl-defmethod eieio-speedbar-make-tag-line ((object eieio-speedbar)
289 depth) 289 depth)
290 "Insert a tag line into speedbar at point for OBJECT. 290 "Insert a tag line into speedbar at point for OBJECT.
291All objects a child of symbol `eieio-speedbar' can be created from 291All objects a child of symbol `eieio-speedbar' can be created from
@@ -321,12 +321,12 @@ Argument DEPTH is the depth at which the tag line is inserted."
321 (if exp 321 (if exp
322 (eieio-speedbar-expand object (1+ depth)))))) 322 (eieio-speedbar-expand object (1+ depth))))))
323 323
324(defmethod eieio-speedbar-child-make-tag-lines ((object eieio-speedbar) _depth) 324(cl-defmethod eieio-speedbar-child-make-tag-lines ((object eieio-speedbar) _depth)
325 "Base method for creating tag lines for non-object children." 325 "Base method for creating tag lines for non-object children."
326 (error "You must implement `eieio-speedbar-child-make-tag-lines' for %s" 326 (error "You must implement `eieio-speedbar-child-make-tag-lines' for %s"
327 (eieio-object-name object))) 327 (eieio-object-name object)))
328 328
329(defmethod eieio-speedbar-expand ((object eieio-speedbar) depth) 329(cl-defmethod eieio-speedbar-expand ((object eieio-speedbar) depth)
330 "Expand OBJECT at indentation DEPTH. 330 "Expand OBJECT at indentation DEPTH.
331Inserts a list of new tag lines representing expanded elements within 331Inserts a list of new tag lines representing expanded elements within
332OBJECT." 332OBJECT."
@@ -362,7 +362,7 @@ TOKEN is the object. INDENT is the current indentation level."
362 (t (error "Ooops... not sure what to do"))) 362 (t (error "Ooops... not sure what to do")))
363 (speedbar-center-buffer-smartly)) 363 (speedbar-center-buffer-smartly))
364 364
365(defmethod eieio-speedbar-child-description ((obj eieio-speedbar)) 365(cl-defmethod eieio-speedbar-child-description ((obj eieio-speedbar))
366 "Return a description for a child of OBJ which is not an object." 366 "Return a description for a child of OBJ which is not an object."
367 (error "You must implement `eieio-speedbar-child-description' for %s" 367 (error "You must implement `eieio-speedbar-child-description' for %s"
368 (eieio-object-name obj))) 368 (eieio-object-name obj)))
@@ -412,7 +412,7 @@ Optional DEPTH is the depth we start at."
412 412
413;;; Methods to the eieio-speedbar-* classes which need to be overridden. 413;;; Methods to the eieio-speedbar-* classes which need to be overridden.
414;; 414;;
415(defmethod eieio-speedbar-object-children ((_object eieio-speedbar)) 415(cl-defmethod eieio-speedbar-object-children ((_object eieio-speedbar))
416 "Return a list of children to be displayed in speedbar. 416 "Return a list of children to be displayed in speedbar.
417If the return value is a list of OBJECTs, then those objects are 417If the return value is a list of OBJECTs, then those objects are
418queried for details. If the return list is made of strings, 418queried for details. If the return list is made of strings,
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index b64eba1de1f..7672d7f0b6e 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -179,36 +179,31 @@ and reference them using the function `class-option'."
179 ;; of the specified name, and also performs a `defsetf' if applicable 179 ;; of the specified name, and also performs a `defsetf' if applicable
180 ;; so that users can `setf' the space returned by this function. 180 ;; so that users can `setf' the space returned by this function.
181 (when acces 181 (when acces
182 ;; FIXME: The defmethod below only defines a part of the generic 182 (push `(cl-defmethod (setf ,acces) (value (this ,name))
183 ;; function (good), but the define-setter below affects the whole 183 (eieio-oset this ',sname value))
184 ;; generic function (bad)!
185 (push `(gv-define-setter ,acces (store object)
186 ;; Apparently, eieio-oset-default doesn't work like
187 ;; oref-default and only accept class arguments!
188 (list ',(if nil ;; (eq alloc :class)
189 'eieio-oset-default
190 'eieio-oset)
191 object '',sname store))
192 accessors) 184 accessors)
193 (push `(defmethod ,acces ,(if (eq alloc :class) :static :primary) 185 (push `(cl-defmethod ,acces ((this ,name))
194 ((this ,name))
195 ,(format 186 ,(format
196 "Retrieve the slot `%S' from an object of class `%S'." 187 "Retrieve the slot `%S' from an object of class `%S'."
197 sname name) 188 sname name)
198 (if (slot-boundp this ',sname) 189 ;; FIXME: Why is this different from the :reader case?
199 ;; Use oref-default for :class allocated slots, since 190 (if (slot-boundp this ',sname) (eieio-oref this ',sname)))
200 ;; these also accept the use of a class argument instead 191 accessors)
201 ;; of an object argument. 192 (when (and eieio-backward-compatibility (eq alloc :class))
202 (,(if (eq alloc :class) 'eieio-oref-default 'eieio-oref) 193 ;; FIXME: How could I declare this *method* as obsolete.
203 this ',sname) 194 (push `(cl-defmethod ,acces ((this (subclass ,name)))
204 ;; Else - Some error? nil? 195 ,(format
205 nil)) 196 "Retrieve the class slot `%S' from a class `%S'.
206 accessors)) 197This method is obsolete."
198 sname name)
199 (if (slot-boundp this ',sname)
200 (eieio-oref-default this ',sname)))
201 accessors)))
207 202
208 ;; If a writer is defined, then create a generic method of that 203 ;; If a writer is defined, then create a generic method of that
209 ;; name whose purpose is to set the value of the slot. 204 ;; name whose purpose is to set the value of the slot.
210 (if writer 205 (if writer
211 (push `(defmethod ,writer ((this ,name) value) 206 (push `(cl-defmethod ,writer ((this ,name) value)
212 ,(format "Set the slot `%S' of an object of class `%S'." 207 ,(format "Set the slot `%S' of an object of class `%S'."
213 sname name) 208 sname name)
214 (setf (slot-value this ',sname) value)) 209 (setf (slot-value this ',sname) value))
@@ -216,7 +211,7 @@ and reference them using the function `class-option'."
216 ;; If a reader is defined, then create a generic method 211 ;; If a reader is defined, then create a generic method
217 ;; of that name whose purpose is to access this slot value. 212 ;; of that name whose purpose is to access this slot value.
218 (if reader 213 (if reader
219 (push `(defmethod ,reader ((this ,name)) 214 (push `(cl-defmethod ,reader ((this ,name))
220 ,(format "Access the slot `%S' from object of class `%S'." 215 ,(format "Access the slot `%S' from object of class `%S'."
221 sname name) 216 sname name)
222 (slot-value this ',sname)) 217 (slot-value this ',sname))
@@ -372,6 +367,10 @@ variable name of the same name as the slot."
372(define-obsolete-function-alias 367(define-obsolete-function-alias
373 'object-class-fast #'eieio--object-class-name "24.4") 368 'object-class-fast #'eieio--object-class-name "24.4")
374 369
370(cl-defgeneric eieio-object-name-string (obj)
371 "Return a string which is OBJ's name."
372 (declare (obsolete eieio-named "25.1")))
373
375(defun eieio-object-name (obj &optional extra) 374(defun eieio-object-name (obj &optional extra)
376 "Return a Lisp like symbol string for object OBJ. 375 "Return a Lisp like symbol string for object OBJ.
377If EXTRA, include that in the string returned to represent the symbol." 376If EXTRA, include that in the string returned to represent the symbol."
@@ -386,15 +385,13 @@ If EXTRA, include that in the string returned to represent the symbol."
386;; below "for free". Since this field is very rarely used, we got rid of it 385;; below "for free". Since this field is very rarely used, we got rid of it
387;; and instead we keep it in a weak hash-tables, for those very rare objects 386;; and instead we keep it in a weak hash-tables, for those very rare objects
388;; that use it. 387;; that use it.
389(defmethod eieio-object-name-string (obj) 388(cl-defmethod eieio-object-name-string (obj)
390 "Return a string which is OBJ's name."
391 (declare (obsolete eieio-named "25.1"))
392 (or (gethash obj eieio--object-names) 389 (or (gethash obj eieio--object-names)
393 (symbol-name (eieio-object-class obj)))) 390 (symbol-name (eieio-object-class obj))))
394(define-obsolete-function-alias 391(define-obsolete-function-alias
395 'object-name-string #'eieio-object-name-string "24.4") 392 'object-name-string #'eieio-object-name-string "24.4")
396 393
397(defmethod eieio-object-set-name-string (obj name) 394(cl-defmethod eieio-object-set-name-string (obj name)
398 "Set the string which is OBJ's NAME." 395 "Set the string which is OBJ's NAME."
399 (declare (obsolete eieio-named "25.1")) 396 (declare (obsolete eieio-named "25.1"))
400 (eieio--check-type stringp name) 397 (eieio--check-type stringp name)
@@ -648,13 +645,13 @@ This class is not stored in the `parent' slot of a class vector."
648 645
649(defalias 'standard-class 'eieio-default-superclass) 646(defalias 'standard-class 'eieio-default-superclass)
650 647
651(defgeneric eieio-constructor (class &rest slots) 648(cl-defgeneric eieio-constructor (class &rest slots)
652 "Default constructor for CLASS `eieio-default-superclass'.") 649 "Default constructor for CLASS `eieio-default-superclass'.")
653 650
654(define-obsolete-function-alias 'constructor #'eieio-constructor "25.1") 651(define-obsolete-function-alias 'constructor #'eieio-constructor "25.1")
655 652
656(defmethod eieio-constructor :static 653(cl-defmethod eieio-constructor
657 ((class eieio-default-superclass) &rest slots) 654 ((class (subclass eieio-default-superclass)) &rest slots)
658 "Default constructor for CLASS `eieio-default-superclass'. 655 "Default constructor for CLASS `eieio-default-superclass'.
659SLOTS are the initialization slots used by `shared-initialize'. 656SLOTS are the initialization slots used by `shared-initialize'.
660This static method is called when an object is constructed. 657This static method is called when an object is constructed.
@@ -674,11 +671,11 @@ calls `shared-initialize' on that object."
674 ;; Return the created object. 671 ;; Return the created object.
675 new-object)) 672 new-object))
676 673
677(defgeneric shared-initialize (obj slots) 674(cl-defgeneric shared-initialize (obj slots)
678 "Set slots of OBJ with SLOTS which is a list of name/value pairs. 675 "Set slots of OBJ with SLOTS which is a list of name/value pairs.
679Called from the constructor routine.") 676Called from the constructor routine.")
680 677
681(defmethod shared-initialize ((obj eieio-default-superclass) slots) 678(cl-defmethod shared-initialize ((obj eieio-default-superclass) slots)
682 "Set slots of OBJ with SLOTS which is a list of name/value pairs. 679 "Set slots of OBJ with SLOTS which is a list of name/value pairs.
683Called from the constructor routine." 680Called from the constructor routine."
684 (while slots 681 (while slots
@@ -689,10 +686,10 @@ Called from the constructor routine."
689 (eieio-oset obj rn (car (cdr slots))))) 686 (eieio-oset obj rn (car (cdr slots)))))
690 (setq slots (cdr (cdr slots))))) 687 (setq slots (cdr (cdr slots)))))
691 688
692(defgeneric initialize-instance (this &optional slots) 689(cl-defgeneric initialize-instance (this &optional slots)
693 "Construct the new object THIS based on SLOTS.") 690 "Construct the new object THIS based on SLOTS.")
694 691
695(defmethod initialize-instance ((this eieio-default-superclass) 692(cl-defmethod initialize-instance ((this eieio-default-superclass)
696 &optional slots) 693 &optional slots)
697 "Construct the new object THIS based on SLOTS. 694 "Construct the new object THIS based on SLOTS.
698SLOTS is a tagged list where odd numbered elements are tags, and 695SLOTS is a tagged list where odd numbered elements are tags, and
@@ -724,10 +721,10 @@ dynamically set from SLOTS."
724 ;; Shared initialize will parse our slots for us. 721 ;; Shared initialize will parse our slots for us.
725 (shared-initialize this slots)) 722 (shared-initialize this slots))
726 723
727(defgeneric slot-missing (object slot-name operation &optional new-value) 724(cl-defgeneric slot-missing (object slot-name operation &optional new-value)
728 "Method invoked when an attempt to access a slot in OBJECT fails.") 725 "Method invoked when an attempt to access a slot in OBJECT fails.")
729 726
730(defmethod slot-missing ((object eieio-default-superclass) slot-name 727(cl-defmethod slot-missing ((object eieio-default-superclass) slot-name
731 _operation &optional _new-value) 728 _operation &optional _new-value)
732 "Method invoked when an attempt to access a slot in OBJECT fails. 729 "Method invoked when an attempt to access a slot in OBJECT fails.
733SLOT-NAME is the name of the failed slot, OPERATION is the type of access 730SLOT-NAME is the name of the failed slot, OPERATION is the type of access
@@ -739,10 +736,10 @@ directly reference slots in EIEIO objects."
739 (signal 'invalid-slot-name (list (eieio-object-name object) 736 (signal 'invalid-slot-name (list (eieio-object-name object)
740 slot-name))) 737 slot-name)))
741 738
742(defgeneric slot-unbound (object class slot-name fn) 739(cl-defgeneric slot-unbound (object class slot-name fn)
743 "Slot unbound is invoked during an attempt to reference an unbound slot.") 740 "Slot unbound is invoked during an attempt to reference an unbound slot.")
744 741
745(defmethod slot-unbound ((object eieio-default-superclass) 742(cl-defmethod slot-unbound ((object eieio-default-superclass)
746 class slot-name fn) 743 class slot-name fn)
747 "Slot unbound is invoked during an attempt to reference an unbound slot. 744 "Slot unbound is invoked during an attempt to reference an unbound slot.
748OBJECT is the instance of the object being reference. CLASS is the 745OBJECT is the instance of the object being reference. CLASS is the
@@ -757,14 +754,14 @@ EIEIO can only dispatch on the first argument, so the first two are swapped."
757 (signal 'unbound-slot (list (eieio-class-name class) (eieio-object-name object) 754 (signal 'unbound-slot (list (eieio-class-name class) (eieio-object-name object)
758 slot-name fn))) 755 slot-name fn)))
759 756
760(defgeneric clone (obj &rest params) 757(cl-defgeneric clone (obj &rest params)
761 "Make a copy of OBJ, and then supply PARAMS. 758 "Make a copy of OBJ, and then supply PARAMS.
762PARAMS is a parameter list of the same form used by `initialize-instance'. 759PARAMS is a parameter list of the same form used by `initialize-instance'.
763 760
764When overloading `clone', be sure to call `call-next-method' 761When overloading `clone', be sure to call `call-next-method'
765first and modify the returned object.") 762first and modify the returned object.")
766 763
767(defmethod clone ((obj eieio-default-superclass) &rest params) 764(cl-defmethod clone ((obj eieio-default-superclass) &rest params)
768 "Make a copy of OBJ, and then apply PARAMS." 765 "Make a copy of OBJ, and then apply PARAMS."
769 (let ((nobj (copy-sequence obj))) 766 (let ((nobj (copy-sequence obj)))
770 (if (stringp (car params)) 767 (if (stringp (car params))
@@ -773,24 +770,24 @@ first and modify the returned object.")
773 (if params (shared-initialize nobj params)) 770 (if params (shared-initialize nobj params))
774 nobj)) 771 nobj))
775 772
776(defgeneric destructor (this &rest params) 773(cl-defgeneric destructor (this &rest params)
777 "Destructor for cleaning up any dynamic links to our object.") 774 "Destructor for cleaning up any dynamic links to our object.")
778 775
779(defmethod destructor ((_this eieio-default-superclass) &rest _params) 776(cl-defmethod destructor ((_this eieio-default-superclass) &rest _params)
780 "Destructor for cleaning up any dynamic links to our object. 777 "Destructor for cleaning up any dynamic links to our object.
781Argument THIS is the object being destroyed. PARAMS are additional 778Argument THIS is the object being destroyed. PARAMS are additional
782ignored parameters." 779ignored parameters."
783 ;; No cleanup... yet. 780 ;; No cleanup... yet.
784 ) 781 )
785 782
786(defgeneric object-print (this &rest strings) 783(cl-defgeneric object-print (this &rest strings)
787 "Pretty printer for object THIS. Call function `object-name' with STRINGS. 784 "Pretty printer for object THIS. Call function `object-name' with STRINGS.
788 785
789It is sometimes useful to put a summary of the object into the 786It is sometimes useful to put a summary of the object into the
790default #<notation> string when using EIEIO browsing tools. 787default #<notation> string when using EIEIO browsing tools.
791Implement this method to customize the summary.") 788Implement this method to customize the summary.")
792 789
793(defmethod object-print ((this eieio-default-superclass) &rest strings) 790(cl-defmethod object-print ((this eieio-default-superclass) &rest strings)
794 "Pretty printer for object THIS. Call function `object-name' with STRINGS. 791 "Pretty printer for object THIS. Call function `object-name' with STRINGS.
795The default method for printing object THIS is to use the 792The default method for printing object THIS is to use the
796function `object-name'. 793function `object-name'.
@@ -807,11 +804,11 @@ to prepend a space."
807(defvar eieio-print-depth 0 804(defvar eieio-print-depth 0
808 "When printing, keep track of the current indentation depth.") 805 "When printing, keep track of the current indentation depth.")
809 806
810(defgeneric object-write (this &optional comment) 807(cl-defgeneric object-write (this &optional comment)
811 "Write out object THIS to the current stream. 808 "Write out object THIS to the current stream.
812Optional COMMENT will add comments to the beginning of the output.") 809Optional COMMENT will add comments to the beginning of the output.")
813 810
814(defmethod object-write ((this eieio-default-superclass) &optional comment) 811(cl-defmethod object-write ((this eieio-default-superclass) &optional comment)
815 "Write object THIS out to the current stream. 812 "Write object THIS out to the current stream.
816This writes out the vector version of this object. Complex and recursive 813This writes out the vector version of this object. Complex and recursive
817object are discouraged from being written. 814object are discouraged from being written.
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 0f094b556ba..88fc950ee21 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -1316,9 +1316,14 @@ The return result is a `package-desc'."
1316 (while files 1316 (while files
1317 (with-temp-buffer 1317 (with-temp-buffer
1318 (insert-file-contents (pop files)) 1318 (insert-file-contents (pop files))
1319 (if (setq info (ignore-errors (package-buffer-info))) 1319 ;; When we find the file with the data,
1320 (setq files nil) 1320 (when (setq info (ignore-errors (package-buffer-info)))
1321 (setf (package-desc-kind info) 'dir)))))))) 1321 ;; stop looping,
1322 (setq files nil)
1323 ;; set the 'dir kind,
1324 (setf (package-desc-kind info) 'dir))))
1325 ;; and return the info.
1326 info))))
1322 1327
1323(defun package--read-pkg-desc (kind) 1328(defun package--read-pkg-desc (kind)
1324 "Read a `define-package' form in current buffer. 1329 "Read a `define-package' form in current buffer.
diff --git a/lisp/play/gamegrid.el b/lisp/play/gamegrid.el
index 1e265a635a0..b4c3c594731 100644
--- a/lisp/play/gamegrid.el
+++ b/lisp/play/gamegrid.el
@@ -486,13 +486,13 @@ FILE is created there."
486 (not (zerop (logand (file-modes 486 (not (zerop (logand (file-modes
487 (expand-file-name "update-game-score" 487 (expand-file-name "update-game-score"
488 exec-directory)) 488 exec-directory))
489 #o4000))))) 489 #o6000)))))
490 (cond ((file-name-absolute-p file) 490 (cond ((file-name-absolute-p file)
491 (gamegrid-add-score-insecure file score)) 491 (gamegrid-add-score-insecure file score))
492 ((and gamegrid-shared-game-dir 492 ((and gamegrid-shared-game-dir
493 (file-exists-p (expand-file-name file shared-game-score-directory))) 493 (file-exists-p (expand-file-name file shared-game-score-directory)))
494 ;; Use the setuid "update-game-score" program to update a 494 ;; Use the setuid (or setgid) "update-game-score" program
495 ;; system-wide score file. 495 ;; to update a system-wide score file.
496 (gamegrid-add-score-with-update-game-score-1 file 496 (gamegrid-add-score-with-update-game-score-1 file
497 (expand-file-name file shared-game-score-directory) score)) 497 (expand-file-name file shared-game-score-directory) score))
498 ;; Else: Add the score to a score file in the user's home 498 ;; Else: Add the score to a score file in the user's home
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 92144cf8049..ee8125073aa 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -339,6 +339,20 @@ WINDOW controls how the buffer is displayed:
339(defvar-local xref--display-history nil 339(defvar-local xref--display-history nil
340 "List of pairs (BUFFER . WINDOW), for temporarily displayed buffers.") 340 "List of pairs (BUFFER . WINDOW), for temporarily displayed buffers.")
341 341
342(defvar-local xref--temporary-buffers nil
343 "List of buffers created by xref code.")
344
345(defvar-local xref--selected nil
346 "t if the current buffer has ever been selected.
347Used for temporary buffers.")
348
349(defvar xref--inhibit-mark-selected nil)
350
351(defun xref--mark-selected ()
352 (unless xref--inhibit-mark-selected
353 (setq xref--selected t))
354 (remove-hook 'buffer-list-update-hook #'xref--mark-selected t))
355
342(defun xref--save-to-history (buf win) 356(defun xref--save-to-history (buf win)
343 (let ((restore (window-parameter win 'quit-restore))) 357 (let ((restore (window-parameter win 'quit-restore)))
344 ;; Save the new entry if the window displayed another buffer 358 ;; Save the new entry if the window displayed another buffer
@@ -359,8 +373,16 @@ WINDOW controls how the buffer is displayed:
359 373
360(defun xref--show-location (location) 374(defun xref--show-location (location)
361 (condition-case err 375 (condition-case err
362 (let ((xref-buf (current-buffer))) 376 (let ((xref-buf (current-buffer))
377 (bl (buffer-list))
378 (xref--inhibit-mark-selected t))
363 (xref--goto-location location) 379 (xref--goto-location location)
380 (let ((buf (current-buffer)))
381 (unless (memq buf bl)
382 ;; Newly created.
383 (add-hook 'buffer-list-update-hook #'xref--mark-selected nil t)
384 (with-current-buffer xref-buf
385 (push buf xref--temporary-buffers))))
364 (xref--display-position (point) t 1 xref-buf)) 386 (xref--display-position (point) t 1 xref-buf))
365 (user-error (message (error-message-string err))))) 387 (user-error (message (error-message-string err)))))
366 388
@@ -386,7 +408,8 @@ WINDOW controls how the buffer is displayed:
386(defun xref--location-at-point () 408(defun xref--location-at-point ()
387 (get-text-property (point) 'xref-location)) 409 (get-text-property (point) 'xref-location))
388 410
389(defvar-local xref--window nil) 411(defvar-local xref--window nil
412 "ACTION argument to call `display-buffer' with.")
390 413
391(defun xref-goto-xref () 414(defun xref-goto-xref ()
392 "Jump to the xref on the current line and bury the xref buffer." 415 "Jump to the xref on the current line and bury the xref buffer."
@@ -395,35 +418,50 @@ WINDOW controls how the buffer is displayed:
395 (let ((loc (or (xref--location-at-point) 418 (let ((loc (or (xref--location-at-point)
396 (user-error "No reference at point"))) 419 (user-error "No reference at point")))
397 (window xref--window)) 420 (window xref--window))
398 (xref--quit) 421 (xref-quit)
399 (xref--pop-to-location loc window))) 422 (xref--pop-to-location loc window)))
400 423
401(define-derived-mode xref--xref-buffer-mode fundamental-mode "XREF" 424(defvar xref--xref-buffer-mode-map
425 (let ((map (make-sparse-keymap)))
426 (define-key map [remap quit-window] #'xref-quit)
427 (define-key map (kbd "n") #'xref-next-line)
428 (define-key map (kbd "p") #'xref-prev-line)
429 (define-key map (kbd "RET") #'xref-goto-xref)
430 (define-key map (kbd "C-o") #'xref-show-location-at-point)
431 ;; suggested by Johan Claesson "to further reduce finger movement":
432 (define-key map (kbd ".") #'xref-next-line)
433 (define-key map (kbd ",") #'xref-prev-line)
434 map))
435
436(define-derived-mode xref--xref-buffer-mode special-mode "XREF"
402 "Mode for displaying cross-references." 437 "Mode for displaying cross-references."
403 (setq buffer-read-only t)) 438 (setq buffer-read-only t))
404 439
405(let ((map xref--xref-buffer-mode-map)) 440(defun xref-quit (&optional kill)
406 (define-key map (kbd "q") #'xref--quit) 441 "Perform cleanup, then quit the current window.
407 (define-key map (kbd "n") #'xref-next-line) 442The cleanup consists of burying all temporarily displayed
408 (define-key map (kbd "p") #'xref-prev-line) 443buffers, and if KILL is non-nil, of killing all buffers that were
409 (define-key map (kbd "RET") #'xref-goto-xref) 444created in the process of showing xrefs.
410 (define-key map (kbd "C-o") #'xref-show-location-at-point)
411
412 ;; suggested by Johan Claesson "to further reduce finger movement":
413 (define-key map (kbd ".") #'xref-next-line)
414 (define-key map (kbd ",") #'xref-prev-line))
415 445
416(defun xref--quit () 446Exceptions are made for buffers switched to by the user in the
417 "Quit all windows in `xref--display-history', then quit current window." 447meantime, and other window configuration changes. These are
418 (interactive) 448preserved."
449 (interactive "P")
419 (let ((window (selected-window)) 450 (let ((window (selected-window))
420 (history xref--display-history)) 451 (history xref--display-history))
421 (setq xref--display-history nil) 452 (setq xref--display-history nil)
453 (when kill
454 (let ((xref--inhibit-mark-selected t)
455 kill-buffer-query-functions)
456 (dolist (buf xref--temporary-buffers)
457 (unless (buffer-local-value 'xref--selected buf)
458 (kill-buffer buf)))
459 (setq xref--temporary-buffers nil)))
422 (pcase-dolist (`(,buf . ,win) history) 460 (pcase-dolist (`(,buf . ,win) history)
423 (when (and (window-live-p win) 461 (when (and (window-live-p win)
424 (eq buf (window-buffer win))) 462 (eq buf (window-buffer win)))
425 (quit-window nil win))) 463 (quit-window nil win)))
426 (quit-window nil window))) 464 (quit-window kill window)))
427 465
428(defconst xref-buffer-name "*xref*" 466(defconst xref-buffer-name "*xref*"
429 "The name of the buffer to show xrefs.") 467 "The name of the buffer to show xrefs.")
@@ -471,7 +509,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
471 (xref-location-group (xref--xref-location x))) 509 (xref-location-group (xref--xref-location x)))
472 #'equal)) 510 #'equal))
473 511
474(defun xref--show-xref-buffer (xrefs window) 512(defun xref--show-xref-buffer (xrefs alist)
475 (let ((xref-alist (xref--analyze xrefs))) 513 (let ((xref-alist (xref--analyze xrefs)))
476 (with-current-buffer (get-buffer-create xref-buffer-name) 514 (with-current-buffer (get-buffer-create xref-buffer-name)
477 (let ((inhibit-read-only t)) 515 (let ((inhibit-read-only t))
@@ -480,7 +518,11 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
480 (xref--xref-buffer-mode) 518 (xref--xref-buffer-mode)
481 (pop-to-buffer (current-buffer)) 519 (pop-to-buffer (current-buffer))
482 (goto-char (point-min)) 520 (goto-char (point-min))
483 (setq xref--window window) 521 (setq xref--window (assoc-default 'window alist))
522 (setq xref--temporary-buffers (assoc-default 'temporary-buffers alist))
523 (dolist (buf xref--temporary-buffers)
524 (with-current-buffer buf
525 (add-hook 'buffer-list-update-hook #'xref--mark-selected nil t)))
484 (current-buffer))))) 526 (current-buffer)))))
485 527
486 528
@@ -493,16 +535,21 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
493(defvar xref-show-xrefs-function 'xref--show-xref-buffer 535(defvar xref-show-xrefs-function 'xref--show-xref-buffer
494 "Function to display a list of xrefs.") 536 "Function to display a list of xrefs.")
495 537
496(defun xref--show-xrefs (id kind xrefs window) 538(defun xref--show-xrefs (input kind arg window)
497 (cond 539 (let* ((bl (buffer-list))
498 ((null xrefs) 540 (xrefs (funcall xref-find-function kind arg))
499 (user-error "No known %s for: %s" kind id)) 541 (tb (cl-set-difference (buffer-list) bl)))
500 ((not (cdr xrefs)) 542 (cond
501 (xref-push-marker-stack) 543 ((null xrefs)
502 (xref--pop-to-location (xref--xref-location (car xrefs)) window)) 544 (user-error "No known %s for: %s" (symbol-name kind) input))
503 (t 545 ((not (cdr xrefs))
504 (xref-push-marker-stack) 546 (xref-push-marker-stack)
505 (funcall xref-show-xrefs-function xrefs window)))) 547 (xref--pop-to-location (xref--xref-location (car xrefs)) window))
548 (t
549 (xref-push-marker-stack)
550 (funcall xref-show-xrefs-function xrefs
551 `((window . ,window)
552 (temporary-buffers . ,tb)))))))
506 553
507(defun xref--read-identifier (prompt) 554(defun xref--read-identifier (prompt)
508 "Return the identifier at point or read it from the minibuffer." 555 "Return the identifier at point or read it from the minibuffer."
@@ -517,9 +564,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
517;;; Commands 564;;; Commands
518 565
519(defun xref--find-definitions (id window) 566(defun xref--find-definitions (id window)
520 (xref--show-xrefs id "definitions" 567 (xref--show-xrefs id 'definitions id window))
521 (funcall xref-find-function 'definitions id)
522 window))
523 568
524;;;###autoload 569;;;###autoload
525(defun xref-find-definitions (identifier) 570(defun xref-find-definitions (identifier)
@@ -546,9 +591,7 @@ prompt for it."
546 "Find references to the identifier at point. 591 "Find references to the identifier at point.
547With prefix argument, prompt for the identifier." 592With prefix argument, prompt for the identifier."
548 (interactive (list (xref--read-identifier "Find references of: "))) 593 (interactive (list (xref--read-identifier "Find references of: ")))
549 (xref--show-xrefs identifier "references" 594 (xref--show-xrefs identifier 'references identifier nil))
550 (funcall xref-find-function 'references identifier)
551 nil))
552 595
553;;;###autoload 596;;;###autoload
554(defun xref-find-apropos (pattern) 597(defun xref-find-apropos (pattern)
@@ -557,14 +600,13 @@ The argument has the same meaning as in `apropos'."
557 (interactive (list (read-from-minibuffer 600 (interactive (list (read-from-minibuffer
558 "Search for pattern (word list or regexp): "))) 601 "Search for pattern (word list or regexp): ")))
559 (require 'apropos) 602 (require 'apropos)
560 (xref--show-xrefs pattern "apropos" 603 (xref--show-xrefs pattern 'apropos
561 (funcall xref-find-function 'apropos 604 (apropos-parse-pattern
562 (apropos-parse-pattern 605 (if (string-equal (regexp-quote pattern) pattern)
563 (if (string-equal (regexp-quote pattern) pattern) 606 ;; Split into words
564 ;; Split into words 607 (or (split-string pattern "[ \t]+" t)
565 (or (split-string pattern "[ \t]+" t) 608 (user-error "No word list given"))
566 (user-error "No word list given")) 609 pattern))
567 pattern)))
568 nil)) 610 nil))
569 611
570 612
diff --git a/test/ChangeLog b/test/ChangeLog
index dcce0bf3c39..d63a561953d 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,7 +1,12 @@
12015-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * automated/cl-generic-tests.el (setf cl--generic-2): Make sure
4 the setf can be used already in the body of the method.
5
12015-01-20 Jorgen Schaefer <contact@jorgenschaefer.de> 62015-01-20 Jorgen Schaefer <contact@jorgenschaefer.de>
2 7
3 * automated/package-test.el (package-test-install-prioritized): 8 * automated/package-test.el (package-test-install-prioritized):
4 Removed test due to unreproducable failures. 9 Remove test due to unreproducable failures.
5 10
62015-01-20 Michal Nazarewicz <mina86@mina86.com> 112015-01-20 Michal Nazarewicz <mina86@mina86.com>
7 12
@@ -15,8 +20,8 @@
15 A new helper function for testing `tildify-double-space-undos' 20 A new helper function for testing `tildify-double-space-undos'
16 behaviour in the `tildify-space' function. 21 behaviour in the `tildify-space' function.
17 (tildify-space-undo-test-html, tildify-space-undo-test-html-nbsp) 22 (tildify-space-undo-test-html, tildify-space-undo-test-html-nbsp)
18 (tildify-space-undo-test-xml, tildify-space-undo-test-tex): New 23 (tildify-space-undo-test-xml, tildify-space-undo-test-tex):
19 tests for `tildify-doule-space-undos' behaviour. 24 New tests for `tildify-doule-space-undos' behaviour.
20 25
21 * automated/tildify-tests.el (tildify-space-test--test): 26 * automated/tildify-tests.el (tildify-space-test--test):
22 A new helper function for testing `tildify-space' function. 27 A new helper function for testing `tildify-space' function.
diff --git a/test/automated/cl-generic-tests.el b/test/automated/cl-generic-tests.el
index 1c01d9b164b..bc9a1ece423 100644
--- a/test/automated/cl-generic-tests.el
+++ b/test/automated/cl-generic-tests.el
@@ -73,6 +73,11 @@
73 (should (equal (cl--generic-1 (make-cl-generic-struct-child11) nil) 73 (should (equal (cl--generic-1 (make-cl-generic-struct-child11) nil)
74 '("child11" "around""child1" "parent" a)))) 74 '("child11" "around""child1" "parent" a))))
75 75
76;; I don't know how to put this inside an `ert-test'. This tests that `setf'
77;; can be used directly inside the body of the setf method.
78(cl-defmethod (setf cl--generic-2) (v (y integer) z)
79 (setf (cl--generic-2 (nth y z) z) v))
80
76(ert-deftest cl-generic-test-03-setf () 81(ert-deftest cl-generic-test-03-setf ()
77 (cl-defmethod (setf cl--generic-1) (v (y t) z) (list v y z)) 82 (cl-defmethod (setf cl--generic-1) (v (y t) z) (list v y z))
78 (cl-defmethod (setf cl--generic-1) (v (_y (eql 4)) z) (list v "four" z)) 83 (cl-defmethod (setf cl--generic-1) (v (_y (eql 4)) z) (list v "four" z))
diff --git a/test/automated/eieio-test-methodinvoke.el b/test/automated/eieio-test-methodinvoke.el
index 3918fb904fe..da5f59a4654 100644
--- a/test/automated/eieio-test-methodinvoke.el
+++ b/test/automated/eieio-test-methodinvoke.el
@@ -292,6 +292,7 @@
292 292
293(defmethod initialize-instance :after ((this eitest-Ja) &rest slots) 293(defmethod initialize-instance :after ((this eitest-Ja) &rest slots)
294 ;(message "+Ja") 294 ;(message "+Ja")
295 ;; FIXME: Using next-method-p in an after-method is invalid!
295 (when (next-method-p) 296 (when (next-method-p)
296 (call-next-method)) 297 (call-next-method))
297 ;(message "-Ja") 298 ;(message "-Ja")
@@ -302,6 +303,7 @@
302 303
303(defmethod initialize-instance :after ((this eitest-Jb) &rest slots) 304(defmethod initialize-instance :after ((this eitest-Jb) &rest slots)
304 ;(message "+Jb") 305 ;(message "+Jb")
306 ;; FIXME: Using next-method-p in an after-method is invalid!
305 (when (next-method-p) 307 (when (next-method-p)
306 (call-next-method)) 308 (call-next-method))
307 ;(message "-Jb") 309 ;(message "-Jb")