From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: EIEIO with lexical scoping Date: Mon, 13 May 2013 17:25:34 -0400 Message-ID: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1368480348 11788 80.91.229.3 (13 May 2013 21:25:48 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 13 May 2013 21:25:48 +0000 (UTC) Cc: emacs-devel@gnu.org To: Eric M. Ludlam Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon May 13 23:25:47 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Uc0Fd-0003Vk-N2 for ged-emacs-devel@m.gmane.org; Mon, 13 May 2013 23:25:46 +0200 Original-Received: from localhost ([::1]:47887 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uc0Fc-0008KO-Vl for ged-emacs-devel@m.gmane.org; Mon, 13 May 2013 17:25:45 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:58484) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uc0FX-0008KG-25 for emacs-devel@gnu.org; Mon, 13 May 2013 17:25:41 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uc0FU-0001rK-Hn for emacs-devel@gnu.org; Mon, 13 May 2013 17:25:38 -0400 Original-Received: from ironport2-out.teksavvy.com ([206.248.154.182]:7111) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uc0FU-0001rB-87; Mon, 13 May 2013 17:25:36 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArMHABK/CFG4rwb8/2dsb2JhbABBA7cREYQTg1kXc4J7I08mGA0kiCTBLY1cgy4DklqSIIFegxOBTCQ X-IPAS-Result: ArMHABK/CFG4rwb8/2dsb2JhbABBA7cREYQTg1kXc4J7I08mGA0kiCTBLY1cgy4DklqSIIFegxOBTCQ X-IronPort-AV: E=Sophos;i="4.84,565,1355115600"; d="scan'208";a="11943539" Original-Received: from 184-175-6-252.dsl.teksavvy.com (HELO pastel.home) ([184.175.6.252]) by ironport2-out.teksavvy.com with ESMTP/TLS/ADH-AES256-SHA; 13 May 2013 17:25:30 -0400 Original-Received: by pastel.home (Postfix, from userid 20848) id 4F94267B0D; Mon, 13 May 2013 17:25:34 -0400 (EDT) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 206.248.154.182 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:159549 Archived-At: I'm trying to compile eieio.el using lexical-binding but am bumping into a problem that requires too much internal knowledge of eieio for me. I'm using the patch appended below for now, which seems to work to some extent, but when I then try to compile CEDET using it, I get the following backtrace: Debugger entered--Lisp error: (invalid-slot-name "#" tables) signal(invalid-slot-name ("#" tables)) eieio-default-superclass([object semanticdb-project-database default-cach= e-object unbound semanticdb-table nil nil] tables oref-default) apply(eieio-default-superclass ([object semanticdb-project-database defau= lt-cache-object unbound semanticdb-table nil nil] tables oref-default)) eieio-generic-call-primary-only(slot-missing ([object semanticdb-project-= database default-cache-object unbound semanticdb-table nil nil] tables oref= -default)) slot-missing([object semanticdb-project-database default-cache-object unb= ound semanticdb-table nil nil] tables oref-default) eieio-oref-default([object semanticdb-project-database default-cache-obje= ct unbound semanticdb-table nil nil] tables) eieio-set-defaults([object semanticdb-project-database default-cache-obje= ct unbound semanticdb-table nil nil] t) eieio-defclass(semanticdb-project-database (eieio-instance-tracker) ((tra= cking-symbol :initform semanticdb-database-list) (reference-directory :type= string :documentation "Directory this database refers to.\nWhen a cache di= rectory is specified, then this refers to the directory\nthis database cont= ains symbols for.") (new-table-class :initform semanticdb-table :type class= :documentation "New tables created for this database are of this class.") = (cache :type list :initform nil :documentation "List of cache information f= or tools.\nAny particular tool can cache data to a database at runtime\nwit= h `semanticdb-cache-get'.\n\nUsing a semanticdb cache does not save any inf= ormation to a file,\nso your cache will need to be recalculated at runtime.= \n\nNote: This index will not be saved in a persistent file.") (tables :ini= targ :tables :type semanticdb-abstract-table-list :accessor semanticdb-get-= database-tables :protection :protected :documentation "List of `semantic-db= -table' objects.")) ("Database of file tables.")) (progn (eieio-defclass 'semanticdb-project-database '(eieio-instance-trac= ker) '((tracking-symbol :initform semanticdb-database-list) (reference-dire= ctory :type string :documentation "Directory this database refers to.\nWhen= a cache directory is specified, then this refers to the directory\nthis da= tabase contains symbols for.") (new-table-class :initform semanticdb-table = :type class :documentation "New tables created for this database are of thi= s class.") (cache :type list :initform nil :documentation "List of cache in= formation for tools.\nAny particular tool can cache data to a database at r= untime\nwith `semanticdb-cache-get'.\n\nUsing a semanticdb cache does not s= ave any information to a file,\nso your cache will need to be recalculated = at runtime.\n\nNote: This index will not be saved in a persistent file.") (= tables :initarg :tables :type semanticdb-abstract-table-list :accessor sema= nticdb-get-database-tables :protection :protected :documentation "List of `= semantic-db-table' objects.")) '("Database of file tables."))) eval((progn (eieio-defclass 'semanticdb-project-database '(eieio-instance= -tracker) '((tracking-symbol :initform semanticdb-database-list) (reference= -directory :type string :documentation "Directory this database refers to.\= nWhen a cache directory is specified, then this refers to the directory\nth= is database contains symbols for.") (new-table-class :initform semanticdb-t= able :type class :documentation "New tables created for this database are o= f this class.") (cache :type list :initform nil :documentation "List of cac= he information for tools.\nAny particular tool can cache data to a database= at runtime\nwith `semanticdb-cache-get'.\n\nUsing a semanticdb cache does = not save any information to a file,\nso your cache will need to be recalcul= ated at runtime.\n\nNote: This index will not be saved in a persistent file= .") (tables :initarg :tables :type semanticdb-abstract-table-list :accessor= semanticdb-get-database-tables :protection :protected :documentation "List= of `semantic-db-table' objects.")) '("Database of file tables."))) nil) #[128 "\301\302\303B\"D\207" [lexical-binding quote eval progn] 5 "\n\n(= fn &rest BODY)"]((eieio-defclass 'semanticdb-project-database '(eieio-insta= nce-tracker) '((tracking-symbol :initform semanticdb-database-list) (refere= nce-directory :type string :documentation "Directory this database refers t= o.\nWhen a cache directory is specified, then this refers to the directory\= nthis database contains symbols for.") (new-table-class :initform semanticd= b-table :type class :documentation "New tables created for this database ar= e of this class.") (cache :type list :initform nil :documentation "List of = cache information for tools.\nAny particular tool can cache data to a datab= ase at runtime\nwith `semanticdb-cache-get'.\n\nUsing a semanticdb cache do= es not save any information to a file,\nso your cache will need to be recal= culated at runtime.\n\nNote: This index will not be saved in a persistent f= ile.") (tables :initarg :tables :type semanticdb-abstract-table-list :acces= sor semanticdb-get-database-tables :protection :protected :documentation "L= ist of `semantic-db-table' objects.")) '("Database of file tables."))) (eval-and-compile (eieio-defclass 'semanticdb-project-database '(eieio-in= stance-tracker) '((tracking-symbol :initform semanticdb-database-list) (ref= erence-directory :type string :documentation "Directory this database refer= s to.\nWhen a cache directory is specified, then this refers to the directo= ry\nthis database contains symbols for.") (new-table-class :initform semant= icdb-table :type class :documentation "New tables created for this database= are of this class.") (cache :type list :initform nil :documentation "List = of cache information for tools.\nAny particular tool can cache data to a da= tabase at runtime\nwith `semanticdb-cache-get'.\n\nUsing a semanticdb cache= does not save any information to a file,\nso your cache will need to be re= calculated at runtime.\n\nNote: This index will not be saved in a persisten= t file.") (tables :initarg :tables :type semanticdb-abstract-table-list :ac= cessor semanticdb-get-database-tables :protection :protected :documentation= "List of `semantic-db-table' objects.")) '("Database of file tables."))) (defclass semanticdb-project-database (eieio-instance-tracker) ((tracking= -symbol :initform semanticdb-database-list) (reference-directory :type stri= ng :documentation "Directory this database refers to.\nWhen a cache directo= ry is specified, then this refers to the directory\nthis database contains = symbols for.") (new-table-class :initform semanticdb-table :type class :doc= umentation "New tables created for this database are of this class.") (cach= e :type list :initform nil :documentation "List of cache information for to= ols.\nAny particular tool can cache data to a database at runtime\nwith `se= manticdb-cache-get'.\n\nUsing a semanticdb cache does not save any informat= ion to a file,\nso your cache will need to be recalculated at runtime.\n\nN= ote: This index will not be saved in a persistent file.") (tables :initarg = :tables :type semanticdb-abstract-table-list :accessor semanticdb-get-datab= ase-tables :protection :protected :documentation "List of `semantic-db-tabl= e' objects.")) "Database of file tables.") eval-buffer(# nil "/home/monnier/src/emacs/work/li= sp/cedet/semantic/db.el" nil t) ; Reading at buffer position 12358662 load-with-code-conversion("/home/monnier/src/emacs/work/lisp/cedet/semant= ic/db.el" "/home/monnier/src/emacs/work/lisp/cedet/semantic/db.el" nil t) require(semantic/db) eval-buffer(# nil "/home/monnier/src/emacs/work/li= sp/cedet/semantic/db-find.el" nil t) ; Reading at buffer position 12350271 load-with-code-conversion("/home/monnier/src/emacs/work/lisp/cedet/semant= ic/db-find.el" "/home/monnier/src/emacs/work/lisp/cedet/semantic/db-find.el= " nil t) require(semantic/db-find) (progn (require 'semantic/db-find) (require 'semantic/find)) eval((progn (require 'semantic/db-find) (require 'semantic/find)) nil) #[128 "\301\302\303B\"D\207" [lexical-binding quote eval progn] 5 "\n\n(= fn &rest BODY)"]((require 'semantic/db-find) (require 'semantic/find)) (eval-when-compile (require 'semantic/db-find) (require 'semantic/find)) eval-buffer(# nil "/home/monnier/src/emacs/work/lisp= /cedet/semantic/util.el" nil t) ; Reading at buffer position 12346843 load-with-code-conversion("/home/monnier/src/emacs/work/lisp/cedet/semant= ic/util.el" "/home/monnier/src/emacs/work/lisp/cedet/semantic/util.el" nil = t) require(semantic/util) eval-buffer(# nil "/home/monnier/src/emacs/work/li= sp/cedet/semantic.el" nil t) ; Reading at buffer position 12395975 load-with-code-conversion("/home/monnier/src/emacs/work/lisp/cedet/semant= ic.el" "/home/monnier/src/emacs/work/lisp/cedet/semantic.el" nil t) require(semantic) eval-buffer(# nil "/home/monnier/src/emacs/work/lisp/cede= t/semantic/util.el" nil t) ; Reading at buffer position 12346651 load-with-code-conversion("/home/monnier/src/emacs/work/lisp/cedet/semant= ic/util.el" "/home/monnier/src/emacs/work/lisp/cedet/semantic/util.el" nil = t) require(semantic/util) apply(require semantic/util) byte-compile-file-form-require((require 'semantic/util)) byte-compile-file-form((require 'semantic/util)) byte-compile-toplevel-file-form((require 'semantic/util)) #[0 "r\300q\210 \203=00\306 \n\"\210eb\210\307\310\307w\210\311\312!\203\= "\313y\210\202=00m\204B`\f\307=13\314\300!=13\2039\315\316!\210\317!)\266\2= 02=00\320 \210d\321 )\210 \205Wr\nq\210\322 !)\207" [# byte-compile-current-file byte-compile--outbuffer byte-compile-unreso= lved-functions byte-compile-read-position byte-compile-last-position byte-c= ompile-insert-header nil " \n\f" looking-at ";" 1 read byte-compile-warn "= !! The file uses old-style backquotes !!\nThis functionality has been obsol= ete for more than 10 years already\nand will be removed soon. See (elisp)B= ackquote in the manual." byte-compile-toplevel-file-form byte-compile-flush= -pending byte-compile-warn-about-unresolved-functions byte-compile-fix-head= er old-style-backquotes] 3 "\n\n(fn)"]() byte-compile-from-buffer(#) byte-compile-file("/home/monnier/src/emacs/work/lisp/cedet/semantic.el") Can you help me figure out what's going on? Stefan =3D=3D=3D modified file 'lisp/emacs-lisp/eieio.el' --- lisp/emacs-lisp/eieio.el 2013-02-27 04:09:50 +0000 +++ lisp/emacs-lisp/eieio.el 2013-05-13 21:22:02 +0000 @@ -1,4 +1,4 @@ -;;; eieio.el --- Enhanced Implementation of Emacs Interpreted Objects +;;; eieio.el --- Enhanced Implementation of Emacs Interpreted Objects -*-= lexical-binding:t -*- ;;; or maybe Eric's Implementation of Emacs Interpreted Objec= ts =20 ;; Copyright (C) 1995-1996, 1998-2013 Free Software Foundation, Inc. @@ -193,32 +193,31 @@ ;; No check: If eieio gets this far, it's probably been checked already. `(get ,class 'eieio-class-definition)) =20 -(defmacro class-p (class) +(defsubst class-p (class) "Return t if CLASS is a valid class vector. CLASS is a symbol." ;; this new method is faster since it doesn't waste time checking lots of ;; things. - `(condition-case nil - (eq (aref (class-v ,class) 0) 'defclass) + (condition-case nil + (eq (aref (class-v class) 0) 'defclass) (error nil))) =20 -(defmacro eieio-object-p (obj) +(defsubst eieio-object-p (obj) "Return non-nil if OBJ is an EIEIO object." - `(let ((tobj ,obj)) - (and (vectorp tobj) - (eq (aref tobj 0) 'object) - (class-p (eieio--object-class tobj))))) + (and (vectorp obj) + (eq (aref obj 0) 'object) + (class-p (eieio--object-class obj)))) (defalias 'object-p 'eieio-object-p) =20 (defmacro class-constructor (class) "Return the symbol representing the constructor of CLASS." `(eieio--class-symbol (class-v ,class))) =20 -(defmacro generic-p (method) +(defsubst generic-p (method) "Return t if symbol METHOD is a generic function. Only methods have the symbol `eieio-method-obarray' as a property \(which contains a list of all bindings to that method type.)" - `(and (fboundp ,method) (get ,method 'eieio-method-obarray))) + (and (fboundp method) (get method 'eieio-method-obarray))) =20 (defun generic-primary-only-p (method) "Return t if symbol METHOD is a generic function with only primary metho= ds. @@ -261,10 +260,10 @@ Return nil if that option doesn't exist." `(class-option-assoc (eieio--class-options (class-v ,class)) ',option)) =20 -(defmacro class-abstract-p (class) +(defsubst class-abstract-p (class) "Return non-nil if CLASS is abstract. Abstract classes cannot be instantiated." - `(class-option ,class :abstract)) + (class-option class :abstract)) =20 (defmacro class-method-invocation-order (class) "Return the invocation order of CLASS. @@ -501,7 +500,7 @@ (setf (eieio--class-children (class-v (car pname))) (cons cname (eieio--class-children (class-v (car pname)))))) ;; Get custom groups, and store them into our local copy. - (mapc (lambda (g) (add-to-list 'groups g)) + (mapc (lambda (g) (pushnew g groups :test #'equal)) (class-option (car pname) :custom-groups)) ;; save parent in child (setf (eieio--class-parent newc) (cons (car pname) (eieio--class-paren= t newc)))) @@ -680,7 +679,7 @@ prot initarg alloc 'defaultoverride skip-nil) =20 ;; We need to id the group, and store them in a group list attribute. - (mapc (lambda (cg) (add-to-list 'groups cg)) customg) + (mapc (lambda (cg) (pushnew cg groups :test #'equal)) customg) =20 ;; Anyone can have an accessor function. This creates a function ;; of the specified name, and also performs a `defsetf' if applicable @@ -824,7 +823,7 @@ =20 ;; We have a list of custom groups. Store them into the options. (let ((g (class-option-assoc options :custom-groups))) - (mapc (lambda (cg) (add-to-list 'g cg)) groups) + (mapc (lambda (cg) (pushnew cg g :test #'equal)) groups) (if (memq :custom-groups options) (setcar (cdr (memq :custom-groups options)) g) (setq options (cons :custom-groups (cons g options))))) @@ -856,10 +855,10 @@ (defun eieio-perform-slot-validation-for-default (slot spec value skipnil) "For SLOT, signal if SPEC does not match VALUE. If SKIPNIL is non-nil, then if VALUE is nil return t instead." - (if (and (not (eieio-eval-default-p value)) - (not eieio-skip-typecheck) - (not (and skipnil (null value))) - (not (eieio-perform-slot-validation spec value))) + (if (not (or (eieio-eval-default-p value) + eieio-skip-typecheck + (and skipnil (null value)) + (eieio-perform-slot-validation spec value))) (signal 'invalid-slot-type (list slot spec value)))) =20 (defun eieio-add-new-slot (newc a d doc type cust label custg print prot i= nit alloc @@ -1425,10 +1424,8 @@ (t (let* ((name (symbol-name type)) (namep (intern (concat name "p")))) - (if (fboundp namep) - (funcall `(lambda () (,namep val))) - (funcall `(lambda () - (,(intern (concat name "-p")) val))))))) + (funcall (if (fboundp namep) namep (intern (concat name "-p"))) + val)))) (cond ((get (car type) 'cl-deftype-handler) (eieio--typep val (apply (get (car type) 'cl-deftype-handler) (cdr type)))) @@ -1450,7 +1447,7 @@ ((memq (car type) '(member member*)) (memql val (cdr type))) ((eq (car type) 'satisfies) - (funcall `(lambda () (,(cadr type) val)))) + (funcall (cadr type) val)) (t (error "Bad type spec: %s" type))))) =20 (defun eieio-perform-slot-validation (spec value) @@ -1799,9 +1796,9 @@ `(car (eieio-class-parents ,class))) (define-obsolete-function-alias 'class-parent #'eieio-class-parent "24.4") =20 -(defmacro same-class-fast-p (obj class) +(defsubst same-class-fast-p (obj class) "Return t if OBJ is of class-type CLASS with no error checking." - `(eq (eieio--object-class ,obj) ,class)) + (eq (eieio--object-class obj) class)) =20 (defun same-class-p (obj class) "Return t if OBJ is of class-type CLASS." (eieio--check-type class-p class) @@ -2459,11 +2456,10 @@ buffer-file-name)) loc) (when fname - (when (string-match "\\.elc$" fname) + (when (string-match "\\.elc\\'" fname) (setq fname (substring fname 0 (1- (length fname))))) (setq loc (get method-name 'method-locations)) - (add-to-list 'loc - (list class fname)) + (pushnew (list class fname) loc :test #'equal) (put method-name 'method-locations loc))) ;; Now optimize the entire obarray (if (< key method-num-lists)