emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bytecomp.el warnings for simplifications


From: Kevin Ryde
Subject: bytecomp.el warnings for simplifications
Date: Mon, 21 Sep 2009 11:43:07 +1000
User-agent: Gnus/5.110011 (No Gnus v0.11) Emacs/23.1 (gnu/linux)

I lately realized I'd written quite a few

    (kill-buffer (current-buffer))

which can of course be

    (kill-buffer nil)

I thought maybe the byte compiler could warn me about that.  I don't
think I want it actually changed by the optimizer, just a hint/reminder
there's a simpler way.

I got to the few lines below.  It finds some kill-buffers like above
within emacs itself, and some re-search-forward of constant strings too.

Does this look promising?  The alternative would be something in
elint.el, but I get the impression that's not greatly used.  If this is
a bit outside the scope of the core byte compiler I might work it up as
an add-on, though it may be tricky with normal byte compiles done "emacs
-Q" and thus without a handy place to hook into ...


--- bytecomp.el.~2.263.~        2009-09-21 10:18:08.000000000 +1000
+++ bytecomp.el 2009-09-21 10:26:22.000000000 +1000
@@ -102,6 +102,7 @@
 ;;                             `make-local' (dubious calls to
 ;;                                           `make-variable-buffer-local')
 ;;                              `mapcar'     (mapcar called for effect)
+;;                              `simplify'   (possible simplifications)
 ;; byte-compile-compatibility  Whether the compiler should
 ;;                             generate .elc files which can be loaded into
 ;;                             generic emacs 18.
@@ -370,6 +371,7 @@
              commands that normally shouldn't be called from Lisp code.
   make-local  calls to make-variable-buffer-local that may be incorrect.
   mapcar      mapcar called for effect.
+  simplify    possible simplifications.
 
 If the list begins with `not', then the remaining elements specify warnings to
 suppress.  For example, (not mapcar) will suppress warnings about mapcar."
@@ -380,7 +382,8 @@
                      (const callargs) (const redefine)
                      (const obsolete) (const noruntime)
                      (const cl-functions) (const interactive-only)
-                     (const make-local) (const mapcar))))
+                     (const make-local) (const mapcar)
+                     (const simplify))))
 ;;;###autoload(put 'byte-compile-warnings 'safe-local-variable 
'byte-compile-warnings-safe-p)
 
 ;;;###autoload
@@ -1485,6 +1488,47 @@
                           func)))
   form)
 
+(defun byte-compile-regexp-fixed-p (regexp)
+  "Return non-nil if REGEXP matches only a fixed string."
+  ;; unspecified backslashes like \X match a literal X, but don't
+  ;; treat them as a fixed string match here in case they get new
+  ;; meanings in the future
+  (string-match (concat "\\`\\("
+                        "[^.*+?[^$\\]"     ;; not a special
+                        "\\|"              ;; OR
+                        "\\\\[.*+?[^$\\]"  ;; a special but backslashed
+                        "\\|"              ;; OR
+                        "\\[\\(.\\|\n\\)]" ;; a char-class of single character
+                        "\\)*\\'")
+                regexp))
+
+(defun byte-compile-simplify-warn (form)
+  (let ((fn (car-safe form)))
+
+    ;; (kill-buffer (current-buffer))
+    (and (equal form '(kill-buffer (current-buffer)))
+         (byte-compile-warn
+          "`(kill-buffer (current-buffer))' can be simplified to `(kill-buffer 
nil)'"))
+
+    ;; (re-search-forward "fixed string")
+    (and (memq fn '(re-search-forward
+                    re-search-backward))
+         (stringp (nth 1 form))
+         (byte-compile-regexp-fixed-p (nth 1 form))
+         (byte-compile-warn
+          "`%s' with fixed-string regexp can be simplified to `%s'"
+          fn (substring (symbol-name fn) 3)))
+
+    ;; (re-search-forward ... (point-max))
+    (let ((default (cdr (assq fn '((   search-forward . point-max)
+                                   (re-search-forward . point-max)
+                                   (   search-backward . point-min)
+                                   (re-search-backward . point-min))))))
+      (and default
+           (equal (nth 2 form) (list default))
+           (byte-compile-warn "`%s' argument %S can be simplified to `nil'"
+                              fn (nth 2 form))))))
+  
 (defun byte-compile-print-syms (str1 strn syms)
   (when syms
     (byte-compile-set-symbol-position (car syms) t))
@@ -3001,7 +3045,9 @@
                (funcall bytecomp-handler form)
             (byte-compile-normal-call form))
           (if (byte-compile-warning-enabled-p 'cl-functions)
-              (byte-compile-cl-warn form))))
+              (byte-compile-cl-warn form))
+          (if (byte-compile-warning-enabled-p 'simplify)
+               (byte-compile-simplify-warn form))))
        ((and (or (byte-code-function-p (car form))
                  (eq (car-safe (car form)) 'lambda))
              ;; if the form comes out the same way it went in, that's

reply via email to

[Prev in Thread] Current Thread [Next in Thread]