diff --git a/drracket-tool-text-lib/drracket/private/syncheck/annotate.rkt b/drracket-tool-text-lib/drracket/private/syncheck/annotate.rkt index a1d88c470..6c51cb2c5 100644 --- a/drracket-tool-text-lib/drracket/private/syncheck/annotate.rkt +++ b/drracket-tool-text-lib/drracket/private/syncheck/annotate.rkt @@ -11,12 +11,11 @@ ;; color : syntax[original] str -> void ;; colors the syntax with style-name's style (define (color stx style-name) - (let ([source (find-source-editor stx)]) - (when (and (syntax-position stx) - (syntax-span stx)) - (let ([pos (- (syntax-position stx) 1)] - [span (syntax-span stx)]) - (color-range source pos (+ pos span) style-name))))) + (define source (find-source-editor stx)) + (when (and (syntax-position stx) (syntax-span stx)) + (let ([pos (- (syntax-position stx) 1)] + [span (syntax-span stx)]) + (color-range source pos (+ pos span) style-name)))) ;; color-range : text start finish style-name ;; colors a range in the text based on `style-name' @@ -55,9 +54,8 @@ ;; find-source-editor : stx -> editor or false (define (find-source-editor stx) - (let ([defs-text (current-annotations)]) - (and defs-text - (find-source-editor/defs stx defs-text)))) + (define defs-text (current-annotations)) + (and defs-text (find-source-editor/defs stx defs-text))) ;; find-source-editor : stx text -> editor or false (define (find-source-editor/defs stx defs-text) diff --git a/drracket-tool-text-lib/drracket/private/syncheck/contract-traversal.rkt b/drracket-tool-text-lib/drracket/private/syncheck/contract-traversal.rkt index 3fe3db832..aad09cf07 100644 --- a/drracket-tool-text-lib/drracket/private/syncheck/contract-traversal.rkt +++ b/drracket-tool-text-lib/drracket/private/syncheck/contract-traversal.rkt @@ -29,24 +29,32 @@ [_ (void)])) ;; fill in the coloring-plans table for boundary contracts - (for ([(start-k start-val) (in-hash boundary-start-map)]) - (for ([start-stx (in-list start-val)]) - (do-contract-traversal start-stx #t - coloring-plans already-jumped-ids - low-binders binding-inits - domain-map range-map - #t - binder+mods-binder))) + (for* ([(start-k start-val) (in-hash boundary-start-map)] + [start-stx (in-list start-val)]) + (do-contract-traversal start-stx + #t + coloring-plans + already-jumped-ids + low-binders + binding-inits + domain-map + range-map + #t + binder+mods-binder)) ;; fill in the coloring-plans table for internal contracts - (for ([(start-k start-val) (in-hash internal-start-map)]) - (for ([start-stx (in-list start-val)]) - (do-contract-traversal start-stx #f - coloring-plans already-jumped-ids - low-binders binding-inits - domain-map range-map - #f - binder+mods-binder))) + (for* ([(start-k start-val) (in-hash internal-start-map)] + [start-stx (in-list start-val)]) + (do-contract-traversal start-stx + #f + coloring-plans + already-jumped-ids + low-binders + binding-inits + domain-map + range-map + #f + binder+mods-binder)) ;; enact the coloring plans (for ([(stx colors) (in-hash coloring-plans)]) @@ -210,7 +218,7 @@ (let loop ([val (syntax-property stx prop)]) (cond [(symbol? val) - (hash-set! map val (cons stx (hash-ref map val '())))] + (hash-update! map val (λ (v) (cons stx v)) '())] [(pair? val) (loop (car val)) (loop (cdr val))]))) @@ -221,11 +229,11 @@ ;; approximate this by just asking 'did this identifier come from the core?' (which is known ;; to not bind any contracts (I hope)) (define (known-predicate? id) - (let ([ib (identifier-binding id)]) - (and (list? ib) - (let ([src (list-ref ib 0)]) - (let-values ([(base rel) (module-path-index-split src)]) - (member base '('#%kernel '#%runtime racket racket/base scheme scheme/base))))))) + (define ib (identifier-binding id)) + (and (list? ib) + (let ([src (list-ref ib 0)]) + (let-values ([(base rel) (module-path-index-split src)]) + (member base '('#%kernel '#%runtime racket racket/base scheme scheme/base)))))) (define (give-up stx boundary-contract? coloring-plans) (let loop ([stx stx]) @@ -253,11 +261,7 @@ (make-a-coloring-plan stx unk-obligation-style-name coloring-plans)) (define (make-a-coloring-plan stx plan coloring-plans) - (hash-set! coloring-plans - stx - (cons - plan - (hash-ref coloring-plans stx '())))) + (hash-update! coloring-plans stx (λ (v) (cons plan v)) '())) (module+ test (let () diff --git a/drracket-tool-text-lib/drracket/private/syncheck/traversals.rkt b/drracket-tool-text-lib/drracket/private/syncheck/traversals.rkt index 4a52e9b1f..69e23564b 100644 --- a/drracket-tool-text-lib/drracket/private/syncheck/traversals.rkt +++ b/drracket-tool-text-lib/drracket/private/syncheck/traversals.rkt @@ -48,76 +48,81 @@ (λ (sexp [ignored void]) (parameterize ([current-directory (or user-directory (current-directory))] [current-load-relative-directory user-directory]) - (let ([is-module? (syntax-case sexp (module) - [(module . rest) #t] - [_ #f])]) - (cond - [is-module? - (let ([phase-to-binders (make-hash)] - [phase-to-varrefs (make-hash)] - [phase-to-varsets (make-hash)] - [phase-to-tops (make-hash)] - [phase-to-requires (make-hash)] - [binding-inits (make-hash)] - [templrefs (make-id-set 0)] - [module-lang-requires (make-hash)] - [requires (make-hash)] - [require-for-syntaxes (make-hash)] - [require-for-templates (make-hash)] - [require-for-labels (make-hash)] - [sub-identifier-binding-directives (make-hash)]) - (annotate-basic sexp - user-namespace user-directory - phase-to-binders - phase-to-varrefs - phase-to-varsets - phase-to-tops - binding-inits - templrefs - module-lang-requires - phase-to-requires - sub-identifier-binding-directives) - (annotate-variables user-namespace - user-directory - phase-to-binders - phase-to-varrefs - phase-to-varsets - phase-to-tops - templrefs - module-lang-requires - phase-to-requires - sub-identifier-binding-directives) - (annotate-contracts sexp - (hash-ref phase-to-binders 0 (λ () (make-id-set 0))) - (hash-ref binding-inits 0 (λ () (make-id-set 0))) - binder+mods-binder) - (when print-extra-info? - (print-extra-info (list (list 'phase-to-binders phase-to-binders) - (list 'phase-to-varrefs phase-to-varrefs) - (list 'phase-to-varsets phase-to-varsets) - (list 'phase-to-tops phase-to-tops) - (list 'phase-to-requires phase-to-requires) - (list 'binding-inits binding-inits) - (list 'templrefs templrefs) - (list 'module-lang-requires module-lang-requires) - (list 'requires requires) - (list 'require-for-syntaxes require-for-syntaxes) - (list 'require-for-templates require-for-templates) - (list 'require-for-labels require-for-labels) - (list 'sub-identifier-binding-directives - sub-identifier-binding-directives)))))] - [else + (define is-module? + (syntax-case sexp (module) + [(module . rest + ) + #t] + [_ #f])) + (cond + [is-module? + (let ([phase-to-binders (make-hash)] + [phase-to-varrefs (make-hash)] + [phase-to-varsets (make-hash)] + [phase-to-tops (make-hash)] + [phase-to-requires (make-hash)] + [binding-inits (make-hash)] + [templrefs (make-id-set 0)] + [module-lang-requires (make-hash)] + [requires (make-hash)] + [require-for-syntaxes (make-hash)] + [require-for-templates (make-hash)] + [require-for-labels (make-hash)] + [sub-identifier-binding-directives (make-hash)]) (annotate-basic sexp - user-namespace user-directory - tl-phase-to-binders - tl-phase-to-varrefs - tl-phase-to-varsets - tl-phase-to-tops - tl-binding-inits - tl-templrefs - tl-module-lang-requires - tl-phase-to-requires - tl-sub-identifier-binding-directives)]))))] + user-namespace + user-directory + phase-to-binders + phase-to-varrefs + phase-to-varsets + phase-to-tops + binding-inits + templrefs + module-lang-requires + phase-to-requires + sub-identifier-binding-directives) + (annotate-variables user-namespace + user-directory + phase-to-binders + phase-to-varrefs + phase-to-varsets + phase-to-tops + templrefs + module-lang-requires + phase-to-requires + sub-identifier-binding-directives) + (annotate-contracts sexp + (hash-ref phase-to-binders 0 (λ () (make-id-set 0))) + (hash-ref binding-inits 0 (λ () (make-id-set 0))) + binder+mods-binder) + (when print-extra-info? + (print-extra-info (list (list 'phase-to-binders phase-to-binders) + (list 'phase-to-varrefs phase-to-varrefs) + (list 'phase-to-varsets phase-to-varsets) + (list 'phase-to-tops phase-to-tops) + (list 'phase-to-requires phase-to-requires) + (list 'binding-inits binding-inits) + (list 'templrefs templrefs) + (list 'module-lang-requires module-lang-requires) + (list 'requires requires) + (list 'require-for-syntaxes require-for-syntaxes) + (list 'require-for-templates require-for-templates) + (list 'require-for-labels require-for-labels) + (list 'sub-identifier-binding-directives + sub-identifier-binding-directives)))))] + [else + (annotate-basic sexp + user-namespace + user-directory + tl-phase-to-binders + tl-phase-to-varrefs + tl-phase-to-varsets + tl-phase-to-tops + tl-binding-inits + tl-templrefs + tl-module-lang-requires + tl-phase-to-requires + tl-sub-identifier-binding-directives)])))] [expansion-completed (λ () (parameterize ([current-directory (or user-directory (current-directory))] @@ -681,10 +686,7 @@ (vector-ref the-vec 8) (vector-ref the-vec 9))) (define key (list level mods)) - (hash-set! sub-identifier-binding-directives - key - (cons new-entry - (hash-ref sub-identifier-binding-directives key '())))] + (hash-update! sub-identifier-binding-directives key (λ (v) (cons new-entry v)) '())] [(vector? prop) (log-check-syntax-debug "found a vector in a 'sub-range-binders property that is ill-formed ~s" @@ -710,32 +712,41 @@ ;; add-disappeared-bindings : syntax id-set integer -> void (define (add-disappeared-bindings stx binders sub-identifier-binding-directives disappeared-uses level level-of-enclosing-module mods) - (let ([prop (syntax-property stx 'disappeared-binding)]) - (when prop - (let loop ([prop prop]) - (cond - [(pair? prop) - (loop (car prop)) - (loop (cdr prop))] - [(identifier? prop) - (add-origins prop disappeared-uses level-of-enclosing-module) - (add-binders prop binders #f #f level level-of-enclosing-module - sub-identifier-binding-directives mods)]))))) + (define prop (syntax-property stx 'disappeared-binding)) + (when prop + (let loop ([prop prop]) + (cond + [(pair? prop) + (loop (car prop)) + (loop (cdr prop))] + [(identifier? prop) + (add-origins prop disappeared-uses level-of-enclosing-module) + (add-binders prop + binders + #f + #f + level + level-of-enclosing-module + sub-identifier-binding-directives + mods)])))) ;; add-disappeared-uses : syntax id-set integer -> void (define (add-disappeared-uses stx id-set sub-identifier-binding-directives level level-of-enclosing-module mods) - (let ([prop (syntax-property stx 'disappeared-use)]) - (when prop - (let loop ([prop prop]) - (cond - [(pair? prop) - (loop (car prop)) - (loop (cdr prop))] - [(identifier? prop) - (add-sub-range-binders prop sub-identifier-binding-directives - level level-of-enclosing-module mods) - (add-id id-set prop level-of-enclosing-module)]))))) + (define prop (syntax-property stx 'disappeared-use)) + (when prop + (let loop ([prop prop]) + (cond + [(pair? prop) + (loop (car prop)) + (loop (cdr prop))] + [(identifier? prop) + (add-sub-range-binders prop + sub-identifier-binding-directives + level + level-of-enclosing-module + mods) + (add-id id-set prop level-of-enclosing-module)])))) ;; annotate-variables : namespace directory string id-set[four of them] ;; (listof syntax) (listof syntax) @@ -768,13 +779,13 @@ (for ([(k v) (in-hash requires)]) (hash-set! new-hash k #t))) - (for ([(level binders) (in-hash phase-to-binders)]) - (for ([(_ binder+modss) (in-dict binders)]) - (for ([binder+mods (in-list binder+modss)]) - (define var (binder+mods-binder binder+mods)) - (define varset (lookup-phase-to-mapping phase-to-varsets level)) - (color-variable var level varset) - (document-variable var level)))) + (for* ([(level binders) (in-hash phase-to-binders)] + [(_ binder+modss) (in-dict binders)] + [binder+mods (in-list binder+modss)]) + (define var (binder+mods-binder binder+mods)) + (define varset (lookup-phase-to-mapping phase-to-varsets level)) + (color-variable var level varset) + (document-variable var level)) (for ([(level+mods varrefs) (in-hash phase-to-varrefs)]) (define level (list-ref level+mods 0)) @@ -782,21 +793,21 @@ (define binders (lookup-phase-to-mapping phase-to-binders level)) (define varsets (lookup-phase-to-mapping phase-to-varsets level)) (initialize-binder-connections binders connections) - (for ([vars (in-list (get-idss varrefs))]) - (for ([var (in-list vars)]) - (color-variable var level varsets) - (document-variable var level) - (connect-identifier var - mods - binders - unused/phases - phase-to-requires - level - user-namespace - user-directory - #t - connections - module-lang-requires)))) + (for* ([vars (in-list (get-idss varrefs))] + [var (in-list vars)]) + (color-variable var level varsets) + (document-variable var level) + (connect-identifier var + mods + binders + unused/phases + phase-to-requires + level + user-namespace + user-directory + #t + connections + module-lang-requires))) ;; build a set of all of the known phases @@ -832,10 +843,9 @@ (for ([(level tops) (in-hash phase-to-tops)]) (define binders (lookup-phase-to-mapping phase-to-binders level)) - (for ([vars (in-list (get-idss tops))]) - (for ([var (in-list vars)]) - (color/connect-top user-namespace user-directory binders var connections - module-lang-requires)))) + (for* ([vars (in-list (get-idss tops))] + [var (in-list vars)]) + (color/connect-top user-namespace user-directory binders var connections module-lang-requires))) (for ([(phase+mods require-hash) (in-hash phase-to-requires)]) ;; don't mark for-label requires as unused until we can properly handle them @@ -903,8 +913,8 @@ (color-range source start end unused-require-style-name)) (define (self-module? mpi) - (let-values ([(a b) (module-path-index-split mpi)]) - (and (not a) (not b)))) + (define-values (a b) (module-path-index-split mpi)) + (and (not a) (not b))) ;; connect-identifier : syntax ;; (or/c #f (listof symbol)) -- name of enclosing sub-modules @@ -969,7 +979,7 @@ (define source-id (list-ref source-req-path/pr 1)) (define req-phase+space-shift (list-ref req-path/pr 3)) (define req-phase-level (if (pair? req-phase+space-shift) (car req-phase+space-shift) req-phase+space-shift)) - (define req-space (if (pair? req-phase+space-shift) (cdr req-phase+space-shift) #f)) + (define req-space (and (pair? req-phase+space-shift) (cdr req-phase+space-shift))) (define require-hash-key (list req-phase-level mods)) (define require-ht (hash-ref phase-to-requires require-hash-key #f)) (when id @@ -1071,7 +1081,7 @@ (define phase-shift (if (pair? phase+space-shift) (car phase+space-shift) phase+space-shift)) (define phase+space (list-ref binding 6)) (define phase (if (pair? phase+space) (car phase+space) phase+space)) - (define space (if (pair? phase+space) (cdr phase+space) #f)) + (define space (and (pair? phase+space) (cdr phase+space))) (when (and (number? phase-level) (not (= phase-level (+ phase-shift @@ -1095,20 +1105,28 @@ ;; color/connect-top : namespace directory id-set syntax connections[see defn for ctc] -> void (define (color/connect-top user-namespace user-directory binders var connections module-lang-requires) - (let ([top-bound? - (or (get-ids binders var) - (parameterize ([current-namespace user-namespace]) - (let/ec k - (namespace-variable-value (syntax-e var) #t (λ () (k #f))) - #t)))]) - (cond - [top-bound? - (color var lexically-bound-variable-style-name)] - [else - (add-mouse-over var (format "~s is a free variable" (syntax-e var))) - (color var free-variable-style-name)]) - (connect-identifier var #f binders #f #f 0 user-namespace user-directory #t connections - module-lang-requires))) + (define top-bound? + (or (get-ids binders var) + (parameterize ([current-namespace user-namespace]) + (let/ec k + (namespace-variable-value (syntax-e var) #t (λ () (k #f))) + #t)))) + (cond + [top-bound? (color var lexically-bound-variable-style-name)] + [else + (add-mouse-over var (format "~s is a free variable" (syntax-e var))) + (color var free-variable-style-name)]) + (connect-identifier var + #f + binders + #f + #f + 0 + user-namespace + user-directory + #t + connections + module-lang-requires)) ;; annotate-counts : connections[see defn] -> void ;; this function doesn't try to show the number of uses at @@ -1126,39 +1144,39 @@ ;; records the src locs of each 'end' position of each arrow) ;; to do this, but maybe lets leave that for another day. (define (annotate-counts connections) - (for ([(key val) (in-hash connections)]) - (when (list? val) - (define start (first val)) - (define end (second val)) - (define color? (third val)) - (define (show-starts) - (when (zero? start) - (define defs-text (current-annotations)) - (when defs-text - (send defs-text syncheck:unused-binder - (list-ref key 0) (list-ref key 1) (list-ref key 2)))) - (add-mouse-over/loc (list-ref key 0) (list-ref key 1) (list-ref key 2) - (cond - [(zero? start) - (string-constant cs-zero-varrefs)] - [(= 1 start) - (string-constant cs-one-varref)] - [else - (format (string-constant cs-n-varrefs) start)]))) - (define (show-ends) - (unless (= 1 end) - (add-mouse-over/loc (list-ref key 0) (list-ref key 1) (list-ref key 2) - (format (string-constant cs-binder-count) end)))) - (cond - [(zero? end) ;; assume this is a binder, show uses - #;(when (and color? (zero? start)) - (color-unused-binder (list-ref key 0) (list-ref key 1) (list-ref key 2))) - (show-starts)] - [(zero? start) ;; assume this is a use, show bindings (usually just one, so do nothing) - (show-ends)] - [else ;; crazyness, show both - (show-starts) - (show-ends)])))) + (for ([(key val) (in-hash connections)] + #:when (list? val)) + (define start (first val)) + (define end (second val)) + (define color? (third val)) + (define (show-starts) + (when (zero? start) + (define defs-text (current-annotations)) + (when defs-text + (send defs-text syncheck:unused-binder (list-ref key 0) (list-ref key 1) (list-ref key 2)))) + (add-mouse-over/loc (list-ref key 0) + (list-ref key 1) + (list-ref key 2) + (cond + [(zero? start) (string-constant cs-zero-varrefs)] + [(= 1 start) (string-constant cs-one-varref)] + [else (format (string-constant cs-n-varrefs) start)]))) + (define (show-ends) + (unless (= 1 end) + (add-mouse-over/loc (list-ref key 0) + (list-ref key 1) + (list-ref key 2) + (format (string-constant cs-binder-count) end)))) + (cond + ;; assume this is a binder, show uses + #;(when (and color? (zero? start)) + (color-unused-binder (list-ref key 0) (list-ref key 1) (list-ref key 2))) + [(zero? end) (show-starts)] + ;; assume this is a use, show bindings (usually just one, so do nothing) + [(zero? start) (show-ends)] + [else ;; crazyness, show both + (show-starts) + (show-ends)]))) ;; color-variable : syntax phase-level identifier-mapping -> void (define (color-variable var phase-level varsets) @@ -1272,22 +1290,19 @@ ;; popup menu in this area allows the programmer to jump ;; to the definition of the id. (define (add-jump-to-definition stx id filename submods phase-level+space) - (let ([source (find-source-editor stx)] - [defs-text (current-annotations)]) - (when (and source - defs-text - (syntax-position stx) - (syntax-span stx)) - (let* ([pos-left (- (syntax-position stx) 1)] - [pos-right (+ pos-left (syntax-span stx))]) - (send defs-text syncheck:add-jump-to-definition/phase-level+space - source - pos-left - pos-right - id - filename - submods - phase-level+space))))) + (define source (find-source-editor stx)) + (define defs-text (current-annotations)) + (when (and source defs-text (syntax-position stx) (syntax-span stx)) + (let* ([pos-left (- (syntax-position stx) 1)] + [pos-right (+ pos-left (syntax-span stx))]) + (send defs-text syncheck:add-jump-to-definition/phase-level+space + source + pos-left + pos-right + id + filename + submods + phase-level+space)))) ;; annotate-require-open : namespace string -> (stx -> void) ;; relies on current-module-name-resolver, which in turn depends on