~ chicken-core (chicken-5) dab1eb671bbe208dbe0bbbaba9f29a247573ebe3
commit dab1eb671bbe208dbe0bbbaba9f29a247573ebe3 Author: Evan Hanson <evhan@foldling.org> AuthorDate: Sat Sep 26 15:22:25 2015 +0200 Commit: Evan Hanson <evhan@foldling.org> CommitDate: Sat Sep 26 15:22:25 2015 +0200 Warn when users try to import nonexistent identifiers from modules Adds a warning when a nonexistent identifier is specified in an import form using (only ...), (rename ...) or (except ...). Thanks to Kristian Lein-Mathisen for helping with the patch. diff --git a/modules.scm b/modules.scm index 38b34da8..3867fce0 100644 --- a/modules.scm +++ b/modules.scm @@ -585,6 +585,8 @@ (%srfi (r 'srfi))) (define (resolve sym) (or (lookup sym '()) sym)) ;XXX really empty se? + (define (warn msg mod id) + (##sys#warn (sprintf msg mod id))) (define (tostr x) (cond ((string? x) x) ((keyword? x) (##sys#string-append (##sys#symbol->string x) ":")) ; hack @@ -595,8 +597,9 @@ (let* ((mod (##sys#find-module/import-library (chicken.expand#strip-syntax spec) 'import)) (vexp (module-vexports mod)) (sexp (module-sexports mod)) - (iexp (module-iexports mod))) - (values (module-name mod) vexp sexp iexp))) + (iexp (module-iexports mod)) + (name (module-name mod))) + (values name name vexp sexp iexp))) (define (import-spec spec) (cond ((symbol? spec) (import-name spec)) ((or (not (list? spec)) (< (length spec) 2)) @@ -608,58 +611,72 @@ (else (let ((head (car spec)) (imports (cddr spec))) - (let-values (((form impv imps impi) (import-spec (cadr spec)))) + (let-values (((name form impv imps impi) (import-spec (cadr spec)))) (cond ((c %only head) (##sys#check-syntax loc spec '(_ _ . #(symbol 0))) (let ((ids (map resolve imports))) - (let loop ((ids ids) (v '()) (s '())) + (let loop ((ids ids) (v '()) (s '()) (missing '())) (cond ((null? ids) - (values `(,head ,form ,@imports) v s impi)) + (for-each + (lambda (id) + (warn "imported identifier doesn't exist in module ~s: ~s" name id)) + missing) + (values name `(,head ,form ,@imports) v s impi)) ((assq (car ids) impv) => - (lambda (a) - (loop (cdr ids) (cons a v) s))) + (lambda (a) + (loop (cdr ids) (cons a v) s missing))) ((assq (car ids) imps) => - (lambda (a) - (loop (cdr ids) v (cons a s)))) - (else (loop (cdr ids) v s)))))) + (lambda (a) + (loop (cdr ids) v (cons a s) missing))) + (else + (loop (cdr ids) v s (cons (car ids) missing))))))) ((c %except head) (##sys#check-syntax loc spec '(_ _ . #(symbol 0))) (let ((ids (map resolve imports))) - (let loop ((impv impv) (v '())) + (let loop ((impv impv) (v '()) (ids imports)) (cond ((null? impv) - (let loop ((imps imps) (s '())) + (let loop ((imps imps) (s '()) (ids ids)) (cond ((null? imps) - (values `(,head ,form ,@imports) v s impi)) - ((memq (caar imps) ids) (loop (cdr imps) s)) - (else (loop (cdr imps) (cons (car imps) s)))))) - ((memq (caar impv) ids) (loop (cdr impv) v)) - (else (loop (cdr impv) (cons (car impv) v))))))) + (for-each + (lambda (id) + (warn "excluded identifier doesn't exist in module ~s: ~s" name id)) + ids) + (values name `(,head ,form ,@imports) v s impi)) + ((memq (caar imps) ids) => + (lambda (id) + (loop (cdr imps) s (delete (car id) ids eq?)))) + (else + (loop (cdr imps) (cons (car imps) s) ids))))) + ((memq (caar impv) ids) => + (lambda (id) + (loop (cdr impv) v (delete (car id) ids eq?)))) + (else + (loop (cdr impv) (cons (car impv) v) ids)))))) ((c %rename head) (##sys#check-syntax loc spec '(_ _ . #((symbol symbol) 0))) - (let loop ((impv impv) (imps imps) (v '()) (s '()) (ids imports)) - (cond ((null? impv) - (cond ((null? imps) - (for-each - (lambda (id) - (##sys#warn "renamed identifier not imported" id) ) - ids) - (values `(,head ,form ,@imports) v s impi)) - ((assq (caar imps) ids) => - (lambda (a) - (loop impv (cdr imps) - v - (cons (cons (cadr a) (cdar imps)) s) - (delete a ids eq?)))) - (else (loop impv (cdr imps) v (cons (car imps) s) ids)))) + (let loop ((impv impv) (v '()) (ids imports)) + (cond ((null? impv) + (let loop ((imps imps) (s '()) (ids ids)) + (cond ((null? imps) + (for-each + (lambda (id) + (warn "renamed identifier doesn't exist in module ~s: ~s" name id)) + (map car ids)) + (values name `(,head ,form ,@imports) v s impi)) + ((assq (caar imps) ids) => + (lambda (a) + (loop (cdr imps) + (cons (cons (cadr a) (cdar imps)) s) + (delete a ids eq?)))) + (else + (loop (cdr imps) (cons (car imps) s) ids))))) ((assq (caar impv) ids) => (lambda (a) - (loop (cdr impv) imps + (loop (cdr impv) (cons (cons (cadr a) (cdar impv)) v) - s (delete a ids eq?)))) - (else (loop (cdr impv) imps - (cons (car impv) v) - s ids))))) + (else + (loop (cdr impv) (cons (car impv) v) ids))))) ((c %prefix head) (##sys#check-syntax loc spec '(_ _ _)) (let ((pref (caddr spec))) @@ -668,13 +685,13 @@ (##sys#string->symbol (##sys#string-append (tostr pref) (##sys#symbol->string (car imp)))) (cdr imp) ) ) - (values (list head form pref) (map ren impv) (map ren imps) impi))) + (values name `(,head ,form ,pref) (map ren impv) (map ren imps) impi))) (else (##sys#syntax-error-hook loc "invalid import specification" spec)))))))) (##sys#check-syntax loc x '(_ . #(_ 1))) (let ((cm (##sys#current-module))) (for-each (lambda (spec) - (let-values (((form vsv vss vsi) (import-spec spec))) + (let-values (((name form vsv vss vsi) (import-spec spec))) (when cm ; save import form (if meta? (set-module-meta-import-forms!Trap