Mercurial > emacs
comparison lisp/emacs-lisp/elint.el @ 20014:2ecea967337d
(elint-check-defcustom-form): New function.
(elint-special-forms): Use it.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Thu, 02 Oct 1997 02:47:57 +0000 |
parents | ad26cf3804c3 |
children | b174db545cfd |
comparison
equal
deleted
inserted
replaced
20013:cc417f06a333 | 20014:2ecea967337d |
---|---|
143 ;; Tell the user we're finished. This is terribly klugy: we set | 143 ;; Tell the user we're finished. This is terribly klugy: we set |
144 ;; elint-top-form-logged so elint-log-message doesn't print the | 144 ;; elint-top-form-logged so elint-log-message doesn't print the |
145 ;; ** top form ** header... | 145 ;; ** top form ** header... |
146 (let ((elint-top-form-logged t)) | 146 (let ((elint-top-form-logged t)) |
147 (elint-log-message "\nLinting complete.\n"))) | 147 (elint-log-message "\nLinting complete.\n"))) |
148 | 148 |
149 (defun elint-defun () | 149 (defun elint-defun () |
150 "Lint the function at point." | 150 "Lint the function at point." |
151 (interactive) | 151 (interactive) |
152 (save-excursion | 152 (save-excursion |
153 (if (not (beginning-of-defun)) | 153 (if (not (beginning-of-defun)) |
191 (set (make-local-variable 'elint-buffer-forms) (elint-get-top-forms)) | 191 (set (make-local-variable 'elint-buffer-forms) (elint-get-top-forms)) |
192 (set (make-local-variable 'elint-buffer-env) | 192 (set (make-local-variable 'elint-buffer-env) |
193 (elint-init-env elint-buffer-forms)) | 193 (elint-init-env elint-buffer-forms)) |
194 (set (make-local-variable 'elint-last-env-time) (buffer-modified-tick)) | 194 (set (make-local-variable 'elint-last-env-time) (buffer-modified-tick)) |
195 elint-buffer-forms)) | 195 elint-buffer-forms)) |
196 | 196 |
197 (defun elint-get-top-forms () | 197 (defun elint-get-top-forms () |
198 "Collect all the top forms in the current buffer." | 198 "Collect all the top forms in the current buffer." |
199 (save-excursion | 199 (save-excursion |
200 (let ((tops nil)) | 200 (let ((tops nil)) |
201 (goto-char (point-min)) | 201 (goto-char (point-min)) |
269 (error "dummy error..."))) | 269 (error "dummy error..."))) |
270 (error | 270 (error |
271 (ding) | 271 (ding) |
272 (message "Can't get variables from require'd library %s" name))) | 272 (message "Can't get variables from require'd library %s" name))) |
273 env) | 273 env) |
274 | 274 |
275 (defun regexp-assoc (regexp alist) | 275 (defun regexp-assoc (regexp alist) |
276 "Search for a key matching REGEXP in ALIST." | 276 "Search for a key matching REGEXP in ALIST." |
277 (let ((res nil)) | 277 (let ((res nil)) |
278 (while (and alist (not res)) | 278 (while (and alist (not res)) |
279 (if (and (stringp (car (car alist))) | 279 (if (and (stringp (car (car alist))) |
310 (defun . elint-check-defun-form) | 310 (defun . elint-check-defun-form) |
311 (defsubst . elint-check-defun-form) | 311 (defsubst . elint-check-defun-form) |
312 (defmacro . elint-check-defun-form) | 312 (defmacro . elint-check-defun-form) |
313 (defvar . elint-check-defvar-form) | 313 (defvar . elint-check-defvar-form) |
314 (defconst . elint-check-defvar-form) | 314 (defconst . elint-check-defvar-form) |
315 (defcustom . elint-check-defvar-form) | 315 (defcustom . elint-check-defcustom-form) |
316 (macro . elint-check-macro-form) | 316 (macro . elint-check-macro-form) |
317 (condition-case . elint-check-condition-case-form)) | 317 (condition-case . elint-check-condition-case-form)) |
318 "Functions to call when some special form should be linted.") | 318 "Functions to call when some special form should be linted.") |
319 | 319 |
320 (defun elint-form (form env) | 320 (defun elint-form (form env) |
321 "Lint FORM in the environment ENV. | 321 "Lint FORM in the environment ENV. |
322 The environment created by the form is returned." | 322 The environment created by the form is returned." |
323 (cond | 323 (cond |
324 ((consp form) | 324 ((consp form) |
332 (argsok t)) | 332 (argsok t)) |
333 (cond | 333 (cond |
334 ((eq args 'undefined) | 334 ((eq args 'undefined) |
335 (setq argsok nil) | 335 (setq argsok nil) |
336 (elint-error "Call to undefined function: %s" form)) | 336 (elint-error "Call to undefined function: %s" form)) |
337 | 337 |
338 ((eq args 'unknown) nil) | 338 ((eq args 'unknown) nil) |
339 | 339 |
340 (t (setq argsok (elint-match-args form args)))) | 340 (t (setq argsok (elint-match-args form args)))) |
341 | 341 |
342 ;; Is this a macro? | 342 ;; Is this a macro? |
343 (if (elint-env-macrop env func) | 343 (if (elint-env-macrop env func) |
344 ;; Macro defined in buffer, expand it | 344 ;; Macro defined in buffer, expand it |
524 (elint-error "Setting non-symbol in setq: %s" sym)) | 524 (elint-error "Setting non-symbol in setq: %s" sym)) |
525 (elint-form val newenv) | 525 (elint-form val newenv) |
526 (if (symbolp sym) | 526 (if (symbolp sym) |
527 (setq newenv (elint-env-add-var newenv sym)))) | 527 (setq newenv (elint-env-add-var newenv sym)))) |
528 newenv)) | 528 newenv)) |
529 | 529 |
530 (defun elint-check-defvar-form (form env) | 530 (defun elint-check-defvar-form (form env) |
531 "Lint the defvar/defconst FORM in ENV." | 531 "Lint the defvar/defconst FORM in ENV." |
532 (if (or (= (length form) 2) | 532 (if (or (= (length form) 2) |
533 (= (length form) 3) | 533 (= (length form) 3) |
534 (and (= (length form) 4) (stringp (nth 3 form)))) | 534 (and (= (length form) 4) (stringp (nth 3 form)))) |
535 (elint-env-add-global-var (elint-form (nth 2 form) env) | 535 (elint-env-add-global-var (elint-form (nth 2 form) env) |
536 (car (cdr form))) | 536 (car (cdr form))) |
537 (elint-error "Malformed variable declaration: %s" form) | 537 (elint-error "Malformed variable declaration: %s" form) |
538 env)) | 538 env)) |
539 | 539 |
540 (defun elint-check-defcustom-form (form env) | |
541 "Lint the defcustom FORM in ENV." | |
542 (if (and (> (length form) 3) | |
543 (evenp (length form))) ; even no. of keyword/value args | |
544 (elint-env-add-global-var (elint-form (nth 2 form) env) | |
545 (car (cdr form))) | |
546 (elint-error "Malformed variable declaration: %s" form) | |
547 env)) | |
548 | |
540 (defun elint-check-function-form (form env) | 549 (defun elint-check-function-form (form env) |
541 "Lint the function FORM in ENV." | 550 "Lint the function FORM in ENV." |
542 (let ((func (car (cdr-safe form)))) | 551 (let ((func (car (cdr-safe form)))) |
543 (cond | 552 (cond |
544 ((symbolp func) | 553 ((symbolp func) |
589 ) | 598 ) |
590 (elint-forms (cdr (car errforms)) newenv) | 599 (elint-forms (cdr (car errforms)) newenv) |
591 (setq errforms (cdr errforms)) | 600 (setq errforms (cdr errforms)) |
592 ))) | 601 ))) |
593 resenv)) | 602 resenv)) |
594 | 603 |
595 ;;; | 604 ;;; |
596 ;;; Message functions | 605 ;;; Message functions |
597 ;;; | 606 ;;; |
598 | 607 |
599 ;; elint-error and elint-warning are identical, but they might change | 608 ;; elint-error and elint-warning are identical, but they might change |
603 "Report an linting error. | 612 "Report an linting error. |
604 STRING and ARGS are thrown on `format' to get the message." | 613 STRING and ARGS are thrown on `format' to get the message." |
605 (let ((errstr (apply 'format string args))) | 614 (let ((errstr (apply 'format string args))) |
606 (elint-log-message errstr) | 615 (elint-log-message errstr) |
607 )) | 616 )) |
608 | 617 |
609 (defun elint-warning (string &rest args) | 618 (defun elint-warning (string &rest args) |
610 "Report an linting warning. | 619 "Report an linting warning. |
611 STRING and ARGS are thrown on `format' to get the message." | 620 STRING and ARGS are thrown on `format' to get the message." |
612 (let ((errstr (apply 'format string args))) | 621 (let ((errstr (apply 'format string args))) |
613 (elint-log-message errstr) | 622 (elint-log-message errstr) |
666 (prog1 | 675 (prog1 |
667 (set-buffer (get-buffer-create elint-log-buffer)) | 676 (set-buffer (get-buffer-create elint-log-buffer)) |
668 (setq truncate-lines t) | 677 (setq truncate-lines t) |
669 (set-buffer oldbuf))) | 678 (set-buffer oldbuf))) |
670 ))) | 679 ))) |
671 | 680 |
672 ;;; | 681 ;;; |
673 ;;; Initializing code | 682 ;;; Initializing code |
674 ;;; | 683 ;;; |
675 | 684 |
676 ;;;###autoload | 685 ;;;###autoload |
677 (defun elint-initialize () | 686 (defun elint-initialize () |
678 "Initialize elint." | 687 "Initialize elint." |
679 (interactive) | 688 (interactive) |
680 (mapcar (function (lambda (x) | 689 (mapcar (function (lambda (x) |
731 mode-line-format mode-line-modified mode-line-process mode-name | 740 mode-line-format mode-line-modified mode-line-process mode-name |
732 overwrite-mode paragraph-separate paragraph-start | 741 overwrite-mode paragraph-separate paragraph-start |
733 point-before-scroll require-final-newline selective-display | 742 point-before-scroll require-final-newline selective-display |
734 selective-display-ellipses tab-width truncate-lines vc-mode) | 743 selective-display-ellipses tab-width truncate-lines vc-mode) |
735 "Standard buffer local vars.") | 744 "Standard buffer local vars.") |
736 | 745 |
737 (defconst elint-unknown-builtin-args | 746 (defconst elint-unknown-builtin-args |
738 '((while test &rest forms) | 747 '((while test &rest forms) |
739 (insert-before-markers-and-inherit &rest text) | 748 (insert-before-markers-and-inherit &rest text) |
740 (catch tag &rest body) | 749 (catch tag &rest body) |
741 (and &rest args) | 750 (and &rest args) |