fixes the responsiveness optimization disabled in

c8bee5acf7
This commit is contained in:
Robby Findler 2013-01-29 18:09:07 -06:00
parent ffb4b34494
commit f0450d716b
7 changed files with 207 additions and 113 deletions

View File

@ -11,6 +11,9 @@
(or/c path-string? #f)
(values (->* (syntax?) ((-> syntax? void?)) void?)
(-> void?)))]
[current-max-to-send-at-once
(parameter/c (or/c +inf.0 (and/c exact-integer? (>=/c 2))))]
[syncheck-annotations<%>
interface?]
[current-annotations
@ -25,7 +28,7 @@
syncheck:add-background-color
syncheck:add-require-open-menu
syncheck:add-docs-menu
syncheck:add-rename-menu
syncheck:add-id-set
syncheck:add-arrow
syncheck:add-tail-arrow
syncheck:add-mouse-over-status

View File

@ -38,6 +38,7 @@ If the namespace does not, they are colored the unbound color.
framework
net/url
browser/external
data/union-find
(for-syntax racket/base)
(only-in ffi/unsafe register-finalizer)
"../../syncheck-drracket-button.rkt"
@ -219,11 +220,15 @@ If the namespace does not, they are colored the unbound color.
(define-struct tooltip-info (text pos-left pos-right msg) #:transparent)
;; set : (uf-set (list/c source position span))
;; name-dup? : symbol? -> boolean?
(define-struct identifier-location-set (set name-dup?) #:transparent)
;; color : string
;; text: text:basic<%>
;; start, fin: number
;; used to represent regions to highlight when passing the mouse over the syncheck window
(define-struct colored-region (color text start fin))
(define-struct colored-region (color text start fin) #:transparent)
;; id : symbol -- the nominal-source-id from identifier-binding
;; filename : path
@ -355,11 +360,30 @@ If the namespace does not, they are colored the unbound color.
;; - tail-link
;; - arrow
;; - string
;; - colored-region
;; - identifier-location-set
(define/private (get-arrow-record table text)
(unless (object? text)
(error 'get-arrow-record "expected a text as the second argument, got ~e" text))
(hash-ref! table text (lambda () (make-interval-map))))
(define arrow-records #f)
(define/public (dump-arrow-records)
(cond
[arrow-records
(for ([(k v) (in-hash arrow-records)])
(printf "\n\n~s:\n" k)
(let loop ([it (interval-map-iterate-first v)])
(when it
(printf "~s =>\n" (interval-map-iterate-key v it))
(for ([v (in-list (interval-map-iterate-value v it))])
(printf " ~s\n" v))
(printf "\n")
(loop (interval-map-iterate-next v it)))))]
[else
(printf "arrow-records empty\n")]))
;; cleanup-texts : (or/c #f (listof text))
(define cleanup-texts #f)
@ -612,17 +636,23 @@ If the namespace does not, they are colored the unbound color.
(λ (x y)
(visit-docs-url)))))))
(define/public (syncheck:add-rename-menu id-as-sym to-be-renamed/poss name-dup?)
(define (make-menu menu)
(let ([name-to-offer (format "~a" id-as-sym)])
(new menu-item%
[parent menu]
[label (fw:gui-utils:format-literal-label (string-constant cs-rename-var) name-to-offer)]
[callback
(λ (x y)
(let ([frame-parent (find-menu-parent menu)])
(rename-callback name-to-offer
frame-parent)))])))
(define/public (syncheck:add-id-set to-be-renamed/poss name-dup?)
(add-identifier-to-range to-be-renamed/poss name-dup?))
(define/private (make-rename-menu menu an-identifier-location-set)
(define example-lst (set-first (uf-find (identifier-location-set-set an-identifier-location-set))))
(define name-to-offer (send (list-ref example-lst 0) get-text
(list-ref example-lst 1)
(list-ref example-lst 2)))
(new menu-item%
[parent menu]
[label (fw:gui-utils:format-literal-label (string-constant cs-rename-var) name-to-offer)]
[callback
(λ (x y)
(let ([frame-parent (find-menu-parent menu)])
(rename-menu-callback frame-parent
name-to-offer
an-identifier-location-set)))]))
;; rename-callback : string
;; (and/c syncheck-text<%> definitions-text<%>)
@ -631,61 +661,63 @@ If the namespace does not, they are colored the unbound color.
;; (union #f (is-a?/c top-level-window<%>))
;; -> void
;; callback for the rename popup menu item
(define (rename-callback name-to-offer parent)
(let ([new-str
(fw:keymap:call/text-keymap-initializer
(λ ()
(get-text-from-user
(string-constant cs-rename-id)
(fw:gui-utils:format-literal-label (string-constant cs-rename-var-to) name-to-offer)
parent
name-to-offer
#:dialog-mixin frame:focus-table-mixin)))])
(when new-str
(define new-sym (format "~s" (string->symbol new-str)))
(define dup-name? (name-dup? new-sym))
(define do-renaming?
(or (not dup-name?)
(equal?
(message-box/custom
(string-constant check-syntax)
(fw:gui-utils:format-literal-label (string-constant cs-name-duplication-error)
new-sym)
(string-constant cs-rename-anyway)
(string-constant cancel)
#f
parent
'(stop default=2)
#:dialog-mixin frame:focus-table-mixin)
1)))
(when do-renaming?
(unless (null? to-be-renamed/poss)
(let ([txts (list this)])
(define positions-to-rename
(remove-duplicates
(sort to-be-renamed/poss
>
#:key cadr)))
(begin-edit-sequence)
(for ([info (in-list positions-to-rename)])
(define source-editor (list-ref info 0))
(define start (list-ref info 1))
(define end (list-ref info 2))
(when (is-a? source-editor text%)
(unless (memq source-editor txts)
(send source-editor begin-edit-sequence)
(set! txts (cons source-editor txts)))
(send source-editor delete start end #f)
(send source-editor insert new-sym start start #f)))
(invalidate-bitmap-cache)
(for ([txt (in-list txts)])
(send txt end-edit-sequence))))))))
(define/private (rename-menu-callback parent name-to-offer an-identifier-location-set)
(define name-dup? (identifier-location-set-name-dup? an-identifier-location-set))
(let ([new-str
(fw:keymap:call/text-keymap-initializer
(λ ()
(get-text-from-user
(string-constant cs-rename-id)
(fw:gui-utils:format-literal-label (string-constant cs-rename-var-to) name-to-offer)
parent
name-to-offer
#:dialog-mixin frame:focus-table-mixin)))])
(when new-str
(define new-sym (format "~s" (string->symbol new-str)))
(define dup-name? (name-dup? new-sym))
(define do-renaming?
(or (not dup-name?)
(equal?
(message-box/custom
(string-constant check-syntax)
(fw:gui-utils:format-literal-label (string-constant cs-name-duplication-error)
new-sym)
(string-constant cs-rename-anyway)
(string-constant cancel)
#f
parent
'(stop default=2)
#:dialog-mixin frame:focus-table-mixin)
1)))
(when do-renaming?
(let ([txts (list this)])
(define positions-to-rename
(remove-duplicates
(sort (set->list (uf-find
(identifier-location-set-set
an-identifier-location-set)))
>
#:key cadr)))
(begin-edit-sequence)
(for ([info (in-list positions-to-rename)])
(define source-editor (list-ref info 0))
(define start (list-ref info 1))
(define end (list-ref info 2))
(when (is-a? source-editor text%)
(unless (memq source-editor txts)
(send source-editor begin-edit-sequence)
(set! txts (cons source-editor txts)))
(send source-editor delete start end #f)
(send source-editor insert new-sym start start #f)))
(invalidate-bitmap-cache)
(for ([txt (in-list txts)])
(send txt end-edit-sequence)))))))
;; find-parent : menu-item-container<%> -> (union #f (is-a?/c top-level-window<%>)
(define (find-menu-parent menu)
(define/private (find-menu-parent menu)
(let loop ([menu menu])
(cond
[(is-a? menu menu-bar%) (send menu get-frame)]
@ -701,13 +733,7 @@ If the namespace does not, they are colored the unbound color.
[else #f]))]
[(is-a? menu menu-item<%>) (loop (send menu get-parent))]
[else #f])))
(for ([loc (in-list to-be-renamed/poss)])
(define source (list-ref loc 0))
(define start (list-ref loc 1))
(define fin (list-ref loc 2))
(syncheck:add-menu source start fin id-as-sym make-menu)))
(define/private (syncheck:add-menu text start-pos end-pos key make-menu)
(when arrow-records
(when (<= 0 start-pos end-pos (last-position))
@ -792,6 +818,31 @@ If the namespace does not, they are colored the unbound color.
start (add1 end)
to-add null)])))
(define/private (add-identifier-to-range text/start/ends name-dup?)
(define id-set (apply set text/start/ends))
(define fresh-uf (uf-new id-set))
(define new-il-set (identifier-location-set fresh-uf name-dup?))
(for ([text/start/span (in-list text/start/ends)])
(define arrow-record (get-arrow-record arrow-records (list-ref text/start/span 0)))
(define start (list-ref text/start/span 1))
(define end (list-ref text/start/span 2))
(interval-map-update*! arrow-record
start (add1 end)
(lambda (curr-val)
(define this-uf-set
(for/or ([thing (in-list curr-val)])
(and (identifier-location-set? thing)
(identifier-location-set-set thing))))
(cond
[this-uf-set
(set! id-set (set-union (uf-find this-uf-set) id-set))
(uf-union! fresh-uf this-uf-set)
(uf-set-canonical! this-uf-set id-set)
curr-val]
[else
(cons new-il-set curr-val)]))
'())))
(inherit get-top-level-window)
(define/augment (on-change)
@ -1092,6 +1143,10 @@ If the namespace does not, they are colored the unbound color.
(define var-arrows (filter var-arrow? arrows))
(define add-menus (append (map cdr (filter pair? vec-ents))
(filter procedure? vec-ents)))
(define identifier-location-set/f
(for/or ([x (in-list vec-ents)])
(and (identifier-location-set? x)
x)))
(unless (null? arrows)
(add-sep)
(make-object menu-item%
@ -1149,7 +1204,10 @@ If the namespace does not, they are colored the unbound color.
arrow-record
start-selection
end-selection))))
(for-each (λ (f) (f menu)) add-menus))))
(for-each (λ (f) (f menu)) add-menus)
(when identifier-location-set/f
(make-rename-menu menu identifier-location-set/f))
(void))))
(define tooltip-frame #f)
(define/private (update-tooltip-frame)
@ -1635,7 +1693,7 @@ If the namespace does not, they are colored the unbound color.
(send defs-text syncheck:add-require-open-menu defs-text start-pos end-pos file)]
[`#(syncheck:add-docs-menu,start-pos ,end-pos ,key ,the-label ,path ,definition-tag ,tag)
(send defs-text syncheck:add-docs-menu defs-text start-pos end-pos key the-label path definition-tag tag)]
[`#(syncheck:add-rename-menu ,id-as-sym ,to-be-renamed/poss ,name-dup-pc ,name-dup-id)
[`#(syncheck:add-id-set ,to-be-renamed/poss ,name-dup-pc ,name-dup-id)
(define other-side-dead? #f)
(define (name-dup? name)
(cond
@ -1654,8 +1712,7 @@ If the namespace does not, they are colored the unbound color.
(define to-be-renamed/poss/fixed
(for/list ([lst (in-list to-be-renamed/poss)])
(list defs-text (list-ref lst 0) (list-ref lst 1))))
(send defs-text syncheck:add-rename-menu id-as-sym to-be-renamed/poss/fixed
name-dup?)]))
(send defs-text syncheck:add-id-set to-be-renamed/poss/fixed name-dup?)]))
(define/augment (enable-evaluation)
(send check-syntax-button enable #t)

View File

@ -8,7 +8,7 @@
syncheck:add-background-color
syncheck:add-require-open-menu
syncheck:add-docs-menu
syncheck:add-rename-menu
syncheck:add-id-set
syncheck:add-arrow
syncheck:add-tail-arrow
syncheck:add-mouse-over-status
@ -36,7 +36,7 @@
(define/public (syncheck:find-source-object stx) #f)
(define/public (syncheck:add-background-color source start end color) (void))
(define/public (syncheck:add-require-open-menu source start end key) (void))
(define/public (syncheck:add-rename-menu id all-ids new-name-intereferes?) (void))
(define/public (syncheck:add-id-set id all-ids new-name-intereferes?) (void))
(define/public (syncheck:add-docs-menu text start-pos end-pos key the-label path definition-tag tag) (void))
(define/public (syncheck:add-arrow start-text start-pos-left start-pos-right
end-text end-pos-left end-pos-right

View File

@ -13,7 +13,7 @@
syncheck:add-docs-menu
syncheck:color-range
syncheck:add-require-open-menu
syncheck:add-rename-menu
syncheck:add-id-set
syncheck:add-arrow
syncheck:add-tail-arrow
syncheck:add-mouse-over-status

View File

@ -56,10 +56,10 @@
(log syncheck:add-jump-to-definition _text start end id filename)
(log syncheck:add-require-open-menu _text start-pos end-pos file)
(log syncheck:add-docs-menu _text start-pos end-pos key the-label path definition-tag tag)
(define/override (syncheck:add-rename-menu id-as-sym to-be-renamed/poss dup-name?)
(define/override (syncheck:add-id-set to-be-renamed/poss dup-name?)
(define id (hash-count table))
(hash-set! table id dup-name?)
(add-to-trace (vector 'syncheck:add-rename-menu id-as-sym (map cdr to-be-renamed/poss) remote id)))
(add-to-trace (vector 'syncheck:add-id-set (map cdr to-be-renamed/poss) remote id)))
(define/public (get-trace) (reverse trace))
(define/private (add-to-trace thing)
@ -67,23 +67,24 @@
(super-new)))
(define (go expanded path the-source orig-cust)
(with-handlers ((exn:fail? (λ (x)
(printf "~a\n" (exn-message x))
(printf "---\n")
(for ([x (in-list
(continuation-mark-set->context
(exn-continuation-marks
x)))])
(printf " ~s\n" x))
(printf "===\n")
(raise x))))
(define obj (new obj%
[src the-source]
[orig-cust orig-cust]))
(define-values (expanded-expression expansion-completed)
(make-traversal (current-namespace)
(get-init-dir path)))
(parameterize ([current-annotations obj])
(expanded-expression expanded)
(expansion-completed))
(send obj get-trace)))
(parameterize ([current-max-to-send-at-once 50])
(with-handlers ((exn:fail? (λ (x)
(printf "~a\n" (exn-message x))
(printf "---\n")
(for ([x (in-list
(continuation-mark-set->context
(exn-continuation-marks
x)))])
(printf " ~s\n" x))
(printf "===\n")
(raise x))))
(define obj (new obj%
[src the-source]
[orig-cust orig-cust]))
(define-values (expanded-expression expansion-completed)
(make-traversal (current-namespace)
(get-init-dir path)))
(parameterize ([current-annotations obj])
(expanded-expression expanded)
(expansion-completed))
(send obj get-trace))))

View File

@ -12,11 +12,15 @@
racket/set
racket/class
racket/list
racket/contract
syntax/boundmap
framework/preferences
scribble/manual-struct)
(provide make-traversal)
(provide make-traversal
current-max-to-send-at-once)
(define current-max-to-send-at-once (make-parameter +inf.0))
;
@ -1134,10 +1138,23 @@
(for/or ([(level id-set) (in-hash phase-to-map)])
(get-ids id-set new-id))))))))
#t))
(send defs-text syncheck:add-rename-menu
id-as-sym
loc-lst
name-dup?)))))))
(define max-to-send-at-once (current-max-to-send-at-once))
(let loop ([loc-lst loc-lst]
[len (length loc-lst)])
(cond
[(<= len max-to-send-at-once)
(send defs-text syncheck:add-id-set
loc-lst
name-dup?)]
[else
(send defs-text syncheck:add-id-set
(take loc-lst max-to-send-at-once)
name-dup?)
;; drop one fewer so that we're sure that the
;; sets get unioned properly
(loop (drop loc-lst (- max-to-send-at-once 1))
(- len (- max-to-send-at-once 1)))]))))))))
;; remove-duplicates-stx : (listof syntax[original]) -> (listof syntax[original])
;; removes duplicates, based on the source locations of the identifiers

View File

@ -650,6 +650,10 @@ Check Syntax is a part of the DrRacket collection, but is implemented via the to
from @racket[make-traversal].
}
@defparam[current-max-to-send-at-once m (or/c +inf.0 (and/c exact-integer? (>=/c 2)))]{
See @xmethod[syncheck-annotations<%> syncheck:add-id-set].
}
@definterface[syncheck-annotations<%> ()]{
Classes implementing this interface are
@ -708,14 +712,26 @@ Check Syntax is a part of the DrRacket collection, but is implemented via the to
be longer than 200 characters).
}
@defmethod[(syncheck:add-rename-menu [id symbol?]
[all-ids (listof (list/c (not/c #f) exact-nonnegative-integer? exact-nonnegative-integer?))]
[new-name-interferes? (-> symbol boolean?)])
@defmethod[(syncheck:add-id-set [all-ids (listof (list/c (not/c #f)
exact-nonnegative-integer?
exact-nonnegative-integer?))]
[new-name-interferes? (-> symbol boolean?)])
void?]{
Called to indicate that there is a variable that can be renamed. The
identifier's name is @racket[id] and all of the occurrences of the identifier are given in the
list @racket[all-ids]. The @racket[new-name-interferes?] procedure determines if a potential name would
interfere with the existing bindings.
Called to indicate that all of the locations in the @racket[all-ids] list
refer to the same identifier.
The @racket[new-name-interferes?] procedure determines if a potential new name
at one of the corresponding places would interfere with the existing bindings
in the program.
Usually, this method is called with maximal sets in @racket[all-ids], in the
sense that, for a given call, either a source location is in the list, or
the location it does not contain a identifier that refers to one of the ones
in @racket[all-ids]. If, however, @racket[current-max-to-send-at-once] is not
@racket[+inf.0], then this set might not contain all of the source locations
for a given identifier and multiple calls are made. In the case that multiple
calls are made, the intersection of the @racket[all-ids] lists (on those
multiple calls) is non-empty.
}
@defmethod[(syncheck:add-arrow [start-source-obj (not/c #f)]