|
172 | 172 |
|
173 | 173 | ;; binder : syntax? |
174 | 174 | ;; mods : same contract as `mods` in level+tail+mod-loop |
175 | | -(struct binder+mods (binder mods)) |
| 175 | +(struct binder+mods (binder mods) #:transparent) |
| 176 | + |
| 177 | +;; ids : (listof syntax?) |
| 178 | +;; in? : boolean? -- indicates if `ids` are the only ones included (#t) or if they are excluded (#f) |
| 179 | +;; prefix : (or/c #f syntax?) |
| 180 | +;; b+m : binder+mods? |
| 181 | +;; -- INVARIANT: if prefix? is syntax?, then in? must be #f |
| 182 | +(struct require-context (ids in? prefix b+m) #:transparent) |
176 | 183 |
|
177 | 184 | ;; annotate-basic : |
178 | 185 | ;; stx-obj: syntax? |
|
448 | 455 | (hash-ref! phase-to-requires |
449 | 456 | (list (+ level level-of-enclosing-module) next-level-mods) |
450 | 457 | (λ () (make-hash)))) |
451 | | - (hash-cons! sub-requires (syntax->datum (syntax lang)) (binder+mods (syntax lang) this-submodule)) |
| 458 | + (hash-cons! sub-requires (syntax->datum #'lang) |
| 459 | + (require-context '() #f #f (binder+mods #'lang this-submodule))) |
452 | 460 | (for ([body (in-list (syntax->list (syntax (bodies ...))))]) |
453 | 461 | (mod-loop body this-submodule)))] |
454 | 462 | [(module* m-name lang (mb bodies ...)) |
|
463 | 471 | (hash-ref! phase-to-requires |
464 | 472 | (list (+ level level-of-enclosing-module) next-level-mods) |
465 | 473 | (λ () (make-hash)))) |
466 | | - (hash-cons! sub-requires (syntax->datum (syntax lang)) (binder+mods (syntax lang) this-submodule))) |
| 474 | + (hash-cons! sub-requires (syntax->datum #'lang) |
| 475 | + (require-context '() #f #f (binder+mods #'lang this-submodule)))) |
467 | 476 |
|
468 | 477 | (for ([body (in-list (syntax->list (syntax (bodies ...))))]) |
469 | 478 | (if (syntax-e #'lang) |
|
516 | 525 | (define require-ht (hash-ref! phase-to-requires |
517 | 526 | (list adjusted-level mods) |
518 | 527 | (λ () (make-hash)))) |
519 | | - (define raw-module-path |
520 | | - (phaseless-spec->raw-module-path |
| 528 | + (define require-context |
| 529 | + (phaseless-spec->require-context |
| 530 | + mods |
521 | 531 | stx |
522 | 532 | (λ (local-id) |
523 | 533 | (add-binders (list local-id) binders binding-inits #'b |
524 | 534 | level level-of-enclosing-module |
525 | 535 | sub-identifier-binding-directives mods)))) |
| 536 | + (define raw-module-path (binder+mods-binder (require-context-b+m require-context))) |
526 | 537 | (annotate-require-open user-namespace user-directory raw-module-path level stx) |
527 | 538 | (when (original-enough? raw-module-path) |
528 | 539 | (define key |
|
534 | 545 | `(submod "." ,m) |
535 | 546 | `',m)] |
536 | 547 | [rmp rmp])) |
537 | | - (hash-cons! require-ht key (binder+mods stx mods)))) |
| 548 | + (hash-cons! require-ht key require-context))) |
538 | 549 |
|
539 | 550 | (for ([spec (in-list (syntax->list #'(raw-require-specs ...)))]) |
540 | 551 | (handle-raw-require-spec spec)))] |
|
855 | 866 | ;; -> void |
856 | 867 | (define (color-unused requires unused module-lang-requires) |
857 | 868 | (for ([(k v) (in-hash unused)]) |
858 | | - (define requires-binder+modss |
| 869 | + (define require-contexts |
859 | 870 | (hash-ref requires k |
860 | 871 | (λ () |
861 | 872 | (error 'syncheck/traversals.rkt |
862 | 873 | "requires doesn't have a mapping for ~s" |
863 | 874 | k)))) |
864 | | - (for ([binder+mods (in-list requires-binder+modss)]) |
| 875 | + (for ([require-context (in-list require-contexts)]) |
| 876 | + (define binder+mods (require-context-b+m require-context)) |
865 | 877 | (define stx (binder+mods-binder binder+mods)) |
866 | 878 | (unless (hash-ref module-lang-requires (list (syntax-source stx) |
867 | 879 | (syntax-position stx) |
868 | 880 | (syntax-span stx)) #f) |
869 | | - ;; Use module path portion of syntax: Its more-specific |
870 | | - ;; location matters for e.g. combine-in and things that expand |
871 | | - ;; to it. See issue #110. |
872 | | - (define raw-mod-stx (phaseless-spec->raw-module-path stx)) |
873 | | - (define mod-stx (if (syntax-source raw-mod-stx) raw-mod-stx stx)) |
874 | 881 | (define defs-text (current-annotations)) |
875 | | - (define source-editor (find-source-editor mod-stx)) |
| 882 | + (define source-editor (find-source-editor stx)) |
876 | 883 | (when (and defs-text source-editor) |
877 | | - (define pos (syntax-position mod-stx)) |
878 | | - (define span (syntax-span mod-stx)) |
| 884 | + (define pos (syntax-position stx)) |
| 885 | + (define span (syntax-span stx)) |
879 | 886 | (when (and pos span) |
880 | 887 | (define start (- pos 1)) |
881 | 888 | (define fin (+ start span)) |
882 | 889 | (send defs-text syncheck:add-unused-require source-editor start fin) |
883 | 890 | (send defs-text syncheck:add-text-type |
884 | 891 | source-editor start fin 'unused-identifier))) |
885 | | - (color mod-stx unused-require-style-name))))) |
| 892 | + (color stx unused-require-style-name))))) |
886 | 893 |
|
887 | 894 | ;; color-unused-binder : source integer integer -> void |
888 | 895 | (define (color-unused-binder source start end) |
|
913 | 920 | (when binders |
914 | 921 | (for ([binder+mods (in-list binders)]) |
915 | 922 | (define binder (binder+mods-binder binder+mods)) |
916 | | - (define binder-is-outside-reference? |
917 | | - (or (not mods-where-var-is) |
918 | | - (not (binder+mods-mods binder+mods)) |
919 | | - (let loop ([mods-where-var-is (reverse mods-where-var-is)] |
920 | | - [mods-where-binder-is (reverse (binder+mods-mods binder+mods))]) |
921 | | - (cond |
922 | | - [(null? mods-where-binder-is) |
923 | | - (for/and ([mod (in-list mods-where-var-is)]) |
924 | | - (submodule-enclosing-bindings-visible? mod))] |
925 | | - [(null? mods-where-var-is) #f] |
926 | | - [else |
927 | | - (and (equal? (car mods-where-var-is) |
928 | | - (car mods-where-binder-is)) |
929 | | - (loop (cdr mods-where-var-is) |
930 | | - (cdr mods-where-binder-is)))])))) |
931 | | - (when binder-is-outside-reference? |
932 | | - (connect-syntaxes binder var actual? all-binders phase-level connections #f)))) |
| 923 | + (when (equal? (syntax->datum binder) (syntax->datum var)) |
| 924 | + (define binder-is-outside-reference? |
| 925 | + (or (not mods-where-var-is) |
| 926 | + (not (binder+mods-mods binder+mods)) |
| 927 | + (let loop ([mods-where-var-is (reverse mods-where-var-is)] |
| 928 | + [mods-where-binder-is (reverse (binder+mods-mods binder+mods))]) |
| 929 | + (cond |
| 930 | + [(null? mods-where-binder-is) |
| 931 | + (for/and ([mod (in-list mods-where-var-is)]) |
| 932 | + (submodule-enclosing-bindings-visible? mod))] |
| 933 | + [(null? mods-where-var-is) #f] |
| 934 | + [else |
| 935 | + (and (equal? (car mods-where-var-is) |
| 936 | + (car mods-where-binder-is)) |
| 937 | + (loop (cdr mods-where-var-is) |
| 938 | + (cdr mods-where-binder-is)))])))) |
| 939 | + (when binder-is-outside-reference? |
| 940 | + (connect-syntaxes binder var actual? all-binders phase-level connections #f))))) |
933 | 941 |
|
934 | 942 | (when (and unused/phases phase-to-requires) |
935 | 943 | (define req-path/pr (get-module-req-path var phase-level)) |
|
964 | 972 | (when req-binder+modss |
965 | 973 | (define unused (hash-ref unused/phases require-hash-key #f)) |
966 | 974 | (when unused (hash-remove! unused req-path)) |
967 | | - (for ([binder+mods (in-list req-binder+modss)]) |
| 975 | + (for ([require-context (in-list req-binder+modss)]) |
| 976 | + (define binder+mods (require-context-b+m require-context)) |
968 | 977 | (define req-stx (binder+mods-binder binder+mods)) |
969 | 978 | (define match/prefix |
970 | | - (id/require-match (syntax->datum var) id req-stx)) |
| 979 | + (id/require-match (syntax->datum var) id require-context)) |
971 | 980 | (when match/prefix |
972 | 981 | (when id |
973 | 982 | (define-values (filename submods) |
|
985 | 994 | (syntax-span match/prefix)) |
986 | 995 | (syntax-span match/prefix)] |
987 | 996 | [else 0])) |
988 | | - (define raw-module-path (phaseless-spec->raw-module-path req-stx)) |
| 997 | + (define require-context (phaseless-spec->require-context mods req-stx)) |
| 998 | + (define raw-module-path (binder+mods-binder (require-context-b+m require-context))) |
989 | 999 | (add-mouse-over var |
990 | 1000 | (format |
991 | 1001 | (string-constant cs-mouse-over-import/library-only) |
|
1018 | 1028 | 'module-lang |
1019 | 1029 | #t)))))))) |
1020 | 1030 |
|
1021 | | -(define (id/require-match var id req-stx) |
1022 | | - (syntax-case* req-stx (only prefix all-except prefix-all-except rename) |
1023 | | - symbolic-compare? |
1024 | | - [(only raw-mod-path . ids) |
1025 | | - (and (memq id (syntax->datum #'ids)) |
1026 | | - (eq? var id))] |
1027 | | - [(prefix the-prefix raw-mod-path) |
1028 | | - (and (equal? (format "~a~a" (syntax->datum #'the-prefix) id) |
1029 | | - (symbol->string var)) |
1030 | | - #'the-prefix)] |
1031 | | - [(all-except raw-mod-path . ids) |
1032 | | - (and (eq? var id) |
1033 | | - (not (member var (syntax->datum #'ids))))] |
1034 | | - [(prefix-all-except the-prefix raw-mod-path . rest) |
1035 | | - (and (not (memq id (syntax->datum #'rest))) |
1036 | | - (equal? (format "~a~a" (syntax->datum #'the-prefix) id) |
1037 | | - (symbol->string var)) |
1038 | | - #'the-prefix)] |
1039 | | - [(rename raw-mod-path local-id exported-id) |
1040 | | - (and (eq? (syntax->datum #'local-id) var))] |
1041 | | - [raw-mod-path |
1042 | | - (eq? var id)])) |
1043 | | - |
1044 | | -(define (phaseless-spec->raw-module-path stx [found-local-id void]) |
| 1031 | +(define (id/require-match var id require-context) |
| 1032 | + (define prefix (require-context-prefix require-context)) |
| 1033 | + (cond |
| 1034 | + [prefix |
| 1035 | + (and (equal? (format "~a~a" (syntax->datum prefix) id) (symbol->string var)) |
| 1036 | + (not (member var (map syntax-e (require-context-ids require-context)))) |
| 1037 | + prefix)] |
| 1038 | + [(require-context-in? require-context) |
| 1039 | + (member var (map syntax-e (require-context-ids require-context)))] |
| 1040 | + [else |
| 1041 | + (and (not (member var (map syntax-e (require-context-ids require-context)))) |
| 1042 | + (equal? var id))])) |
| 1043 | + |
| 1044 | +(define (phaseless-spec->require-context mods stx [found-local-id void]) |
1045 | 1045 | (syntax-case* stx (only prefix all-except prefix-all-except rename) symbolic-compare? |
1046 | | - [(only raw-module-path id ...) #'raw-module-path] |
1047 | | - [(prefix prefix-id raw-module-path) #'raw-module-path] |
1048 | | - [(all-except raw-module-path id ...) #'raw-module-path] |
1049 | | - [(prefix-all-except prefix-id raw-module-path id ...) #'raw-module-path] |
| 1046 | + [(only raw-module-path id ...) |
| 1047 | + (require-context (syntax->list #'(id ...)) #t #f (binder+mods #'raw-module-path mods))] |
| 1048 | + [(prefix prefix-id raw-module-path) |
| 1049 | + (require-context '() #f #'prefix-id (binder+mods #'raw-module-path mods))] |
| 1050 | + [(all-except raw-module-path id ...) |
| 1051 | + (require-context (syntax->list #'(id ...)) #f #f (binder+mods #'raw-module-path mods))] |
| 1052 | + [(prefix-all-except prefix-id raw-module-path id ...) |
| 1053 | + (require-context (syntax->list #'(id ...)) #t #'prefix-id (binder+mods #'raw-module-path mods))] |
1050 | 1054 | [(rename raw-module-path local-id exported-id) |
1051 | 1055 | (found-local-id #'local-id) |
1052 | | - #'raw-module-path] |
1053 | | - [_ stx])) |
1054 | | - |
| 1056 | + (require-context (list #'local-id) #t #f (binder+mods #'raw-module-path mods))] |
| 1057 | + [_ |
| 1058 | + (require-context '() #f #f (binder+mods stx mods))])) |
1055 | 1059 |
|
1056 | 1060 | ;; get-module-req-path : identifier number [#:nominal? boolean] |
1057 | 1061 | ;; -> (union #f (list require-sexp sym ?? module-path-index? phase+space?)) |
|
1391 | 1395 | [_ |
1392 | 1396 | null])) |
1393 | 1397 |
|
1394 | | -;; trim-require-prefix : syntax -> syntax |
1395 | | -(define (trim-require-prefix require-spec) |
1396 | | - (syntax-case* require-spec (only prefix all-except prefix-all-except rename) |
1397 | | - symbolic-compare? |
1398 | | - [(only module-name identifier ...) |
1399 | | - (syntax module-name)] |
1400 | | - [(prefix identifier module-name) |
1401 | | - (syntax module-name)] |
1402 | | - [(all-except module-name identifier ...) |
1403 | | - (syntax module-name)] |
1404 | | - [(prefix-all-except module-name identifier ...) |
1405 | | - (syntax module-name)] |
1406 | | - [(rename module-name local-identifier exported-identifier) |
1407 | | - (syntax module-name)] |
1408 | | - [_ require-spec])) |
1409 | | - |
1410 | 1398 | (define (symbolic-compare? x y) (eq? (syntax-e x) (syntax-e y))) |
1411 | 1399 |
|
1412 | 1400 | ;; add-binders : syntax id-set (or/c #f id-set) (or/c #f syntax) integer -> void |
|
0 commit comments