]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/check-declare.el
Add classes as run-time descriptors of cl-structs.
[gnu-emacs] / lisp / emacs-lisp / check-declare.el
index c027f31f3aaf0ef0ec02ad0db4b61388fc65fbc4..8fc299d7e938d07a8944c1eef624992c71ebfca6 100644 (file)
@@ -1,6 +1,6 @@
 ;;; check-declare.el --- Check declare-function statements
 
-;; Copyright (C) 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
+;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
 
 ;; Author: Glenn Morris <rgm@gnu.org>
 ;; Keywords: lisp, tools, maint
@@ -28,7 +28,7 @@
 ;; checks that all such statements in a file or directory are accurate.
 ;; The entry points are `check-declare-file' and `check-declare-directory'.
 
-;; For more information, see Info node `elisp(Declaring Functions)'.
+;; For more information, see Info node `(elisp)Declaring Functions'.
 
 ;;; TODO:
 
@@ -88,9 +88,11 @@ don't know how to recognize (e.g. some macros)."
       ;; FIXME we could theoretically be inside a string.
       (while (re-search-forward "^[ \t]*\\((declare-function\\)[ \t\n]" nil t)
         (goto-char (match-beginning 1))
-        (if (and (setq form (ignore-errors (read (current-buffer)))
-                       len (length form))
-                 (> len 2) (< len 6)
+        (if (and (setq form (ignore-errors (read (current-buffer))))
+                 ;; Exclude element of byte-compile-initial-macro-environment.
+                 (or (listp (cdr form)) (setq form nil))
+                 (> (setq len (length form)) 2)
+                 (< len 6)
                  (symbolp (setq fn (cadr form)))
                  (setq fn (symbol-name fn)) ; later we use as a search string
                  (stringp (setq fnfile (nth 2 form)))
@@ -104,7 +106,7 @@ don't know how to recognize (e.g. some macros)."
                  (symbolp (setq fileonly (nth 4 form))))
             (setq alist (cons (list fnfile fn arglist fileonly) alist))
           ;; FIXME make this more noticeable.
-          (message "Malformed declaration for `%s'" (cadr form)))))
+          (if form (message "Malformed declaration for `%s'" (cadr form))))))
     (message "%sdone" m)
     alist))
 
@@ -123,6 +125,14 @@ With optional argument FULL, sums the number of elements in each element."
 
 (autoload 'byte-compile-arglist-signature "bytecomp")
 
+(defgroup check-declare nil
+  "Check declare-function statements."
+  :group 'tools)
+
+(defcustom check-declare-ext-errors nil
+  "When non-nil, warn about functions not found in :ext."
+  :type 'boolean)
+
 (defun check-declare-verify (fnfile fnlist)
   "Check that FNFILE contains function definitions matching FNLIST.
 Each element of FNLIST has the form (FILE FN ARGLIST FILEONLY), where
@@ -224,7 +234,8 @@ method\\|class\\)\\|fset\\)\\>" type)
       (when type
         (setq errlist (cons (list (car e) (cadr e) type) errlist))))
     (message "%s%s" m
-             (if (or re (not ext))
+             (if (or re (or check-declare-ext-errors
+                            (not ext)))
                  (check-declare-errmsg errlist)
                (progn
                  (setq errlist nil)
@@ -249,12 +260,29 @@ Returned list has elements FNFILE (FILE ...)."
   "Warn that FILE made a false claim about FN in FNFILE.
 TYPE is a string giving the nature of the error.  Warning is displayed in
 `check-declare-warning-buffer'."
-  (display-warning 'check-declare
-                   (format "%s said `%s' was defined in %s: %s"
-                           (file-name-nondirectory file) fn
-                           (file-name-nondirectory fnfile)
-                           type)
-                   nil check-declare-warning-buffer))
+  (let ((warning-prefix-function
+         (lambda (level entry)
+           (let ((line 0)
+                 (col 0))
+             (insert
+              (with-current-buffer (find-file-noselect file)
+                (goto-char (point-min))
+                (when (re-search-forward
+                       (format "(declare-function[ \t\n]+%s" fn) nil t)
+                  (goto-char (match-beginning 0))
+                  (setq line (line-number-at-pos))
+                  (setq col (1+ (current-column))))
+                (format "%s:%d:%d:"
+                        (file-name-nondirectory file)
+                        line col))))
+           entry))
+        (warning-fill-prefix "    "))
+    (display-warning 'check-declare
+                     (format "%s said `%s' was defined in %s: %s"
+                             (file-name-nondirectory file) fn
+                             (file-name-nondirectory fnfile)
+                             type)
+                     nil check-declare-warning-buffer)))
 
 (defun check-declare-files (&rest files)
   "Check veracity of all `declare-function' statements in FILES.
@@ -267,13 +295,20 @@ Return a list of any errors found."
     (dolist (e (check-declare-sort alist))
       (if (setq err (check-declare-verify (car e) (cdr e)))
           (setq errlist (cons (cons (car e) err) errlist))))
+    (setq errlist (nreverse errlist))
     (if (get-buffer check-declare-warning-buffer)
         (kill-buffer check-declare-warning-buffer))
+    (with-current-buffer (get-buffer-create check-declare-warning-buffer)
+      (unless (derived-mode-p 'compilation-mode)
+        (compilation-mode))
+      (let ((inhibit-read-only t))
+        (insert "\f\n"))
+      (compilation-forget-errors))
     ;; Sort back again so that errors are ordered by the files
     ;; containing the declare-function statements.
     (dolist (e (check-declare-sort errlist))
-        (dolist (f (cdr e))
-          (check-declare-warn (car e) (cadr f) (car f) (nth 2 f))))
+      (dolist (f (cdr e))
+        (check-declare-warn (car e) (cadr f) (car f) (nth 2 f))))
     errlist))
 
 ;;;###autoload
@@ -314,5 +349,4 @@ Returns non-nil if any false statements are found."
 
 (provide 'check-declare)
 
-;; arch-tag: a4d6cdc4-deb7-4502-b327-0e4ef3d82d96
 ;;; check-declare.el ends here.