start the drracket-tools pkg
pull out the drracket/check-syntax library into this pkg
This commit is contained in:
parent
994c54c722
commit
43ffd4b6ce
|
@ -1057,8 +1057,7 @@
|
|||
("red" imported)
|
||||
(")" default-color))
|
||||
'(((26 29) (47 50))
|
||||
((6 17) (19 25)))
|
||||
#:extra-info? #t)
|
||||
((6 17) (19 25))))
|
||||
|
||||
(build-test "#lang racket/base\n(require '#%kernel)\npair?"
|
||||
'(("#lang racket/base\n(" default-color)
|
||||
|
@ -1689,24 +1688,6 @@
|
|||
(define (click-check-syntax-button drs extra-info?)
|
||||
(test:run-one (lambda () (send drs syncheck:button-callback #:print-extra-info? extra-info?))))
|
||||
|
||||
(let ()
|
||||
(define ns (make-base-namespace))
|
||||
(define stx
|
||||
(parameterize ([current-namespace ns])
|
||||
(expand #'(module m racket/base
|
||||
(define red 1)
|
||||
(module+ tests red)))))
|
||||
(define ids '())
|
||||
(let loop ([stx stx])
|
||||
(cond
|
||||
[(pair? stx) (loop (car stx)) (loop (cdr stx))]
|
||||
[(identifier? stx)
|
||||
(when (equal? (syntax-e stx) 'red) (set! ids (cons stx ids)))]
|
||||
[(syntax? stx) (loop (syntax-e stx))]))
|
||||
(for ([x (in-list ids)])
|
||||
(for ([y (in-list ids)])
|
||||
(printf " ~s\n ~s\n ~s\n\n" x y (free-identifier=? x y)))))
|
||||
|
||||
(main)
|
||||
|
||||
(module+ test
|
||||
|
|
12
pkgs/drracket-pkgs/drracket-tool-doc/info.rkt
Normal file
12
pkgs/drracket-pkgs/drracket-tool-doc/info.rkt
Normal file
|
@ -0,0 +1,12 @@
|
|||
#lang info
|
||||
|
||||
(define collection 'multi)
|
||||
|
||||
(define deps '("base" "scribble-lib" "drracket-tool-lib"))
|
||||
(define build-deps '("racket-doc"))
|
||||
|
||||
(define pkg-desc "Docs for the programmatic interface to some IDE tools that DrRacket supports")
|
||||
|
||||
(define pkg-authors '(robby))
|
||||
|
||||
(define version "1.0")
|
|
@ -0,0 +1,298 @@
|
|||
#lang scribble/manual
|
||||
@(require scribble/eval
|
||||
(for-label drracket/check-syntax
|
||||
racket))
|
||||
|
||||
@title{DrRacket Tools}
|
||||
|
||||
This manual describes portions of DrRacket's functionality
|
||||
that are exposed via Racket APIs to be used with other editors.
|
||||
|
||||
@section{Accessing Check Syntax Programmatically}
|
||||
|
||||
@defmodule[drracket/check-syntax]
|
||||
|
||||
@defproc[(make-traversal [namespace namespace?]
|
||||
[path (or/c #f path-string?)])
|
||||
(values (->* (syntax?)
|
||||
((-> any/c void?))
|
||||
void?)
|
||||
(-> void?))]{
|
||||
This function creates some local state about a traversal of syntax objects
|
||||
and returns two functions. The first one should be called with each of the
|
||||
(fully expanded) syntax objects that make up a program (there will be only
|
||||
one if the program is a module) and then the second one should be called to
|
||||
indicate there are no more.
|
||||
|
||||
The optional argument to the first function is ignored.
|
||||
It is left there for historical reasons. In the past it
|
||||
was called for each sequence
|
||||
of binding identifiers encountered in @racket[define-values], @racket[define-syntaxes],
|
||||
and @racket[define-values-for-syntax].
|
||||
|
||||
During the dynamic extent of the call to the two result functions, the value
|
||||
of the @racket[current-annotations] parameter is consulted and various
|
||||
methods are invoked in the corresponding object (if any), to indicate
|
||||
what has been found in the syntax object. These methods will only be called
|
||||
if the syntax objects have source locations.
|
||||
}
|
||||
|
||||
@defparam[current-annotations ca (or/c #f (is-a?/c syncheck-annotations<%>))]{
|
||||
The methods of the value of this parameter are invoked by the functions returned
|
||||
from @racket[make-traversal].
|
||||
}
|
||||
|
||||
@defparam[current-max-to-send-at-once m (or/c +inf.0 (and/c exact-integer? (>=/c 2)))]{
|
||||
No longer used.
|
||||
}
|
||||
|
||||
@definterface[syncheck-annotations<%> ()]{
|
||||
|
||||
Classes implementing this interface are
|
||||
accceptors of information about a traversal
|
||||
of syntax objects. See @racket[make-traversal].
|
||||
|
||||
Do not implement this interface directly, as it
|
||||
is liable to change without warning. Instead, use
|
||||
the @racket[annotations-mixin] and override
|
||||
the methods you're interested in. The
|
||||
@racket[annotations-mixin] will keep in sync
|
||||
with this interface, providing methods that
|
||||
ignore their arguments.
|
||||
|
||||
@defmethod[(syncheck:find-source-object [stx syntax?]) (or/c #f (not/c #f))]{
|
||||
This should return @racket[#f] if the source of this syntax object is
|
||||
uninteresting for annotations (if, for example, the only interesting
|
||||
annotations are those in the original file and this is a syntax object
|
||||
introduced by a macro and thus has a source location from some other file).
|
||||
|
||||
Otherwise, it should return some (non-@racket[#f])
|
||||
value that will then be passed to one of the other methods below as
|
||||
a @racket[_source-obj] argument.
|
||||
}
|
||||
|
||||
@defmethod[(syncheck:add-background-color [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[end exact-nonnegative-integer?]
|
||||
[color string?])
|
||||
void?]{
|
||||
Called to indicate that the color @racket[color] should be drawn on the background of
|
||||
the given range in the editor, when the mouse moves over it. This method is typically
|
||||
called in conjuction with some other method that provides some other annotation
|
||||
on the source.
|
||||
}
|
||||
@defmethod[(syncheck:add-require-open-menu [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[end exact-nonnegative-integer?]
|
||||
[file path-string?])
|
||||
void?]{
|
||||
Called to indicate that there is a @racket[require] at the location from
|
||||
@racket[start] to @racket[end],
|
||||
and that it corresponds to @racket[file]. Check Syntax adds a popup menu.
|
||||
}
|
||||
|
||||
@defmethod[(syncheck:add-docs-menu [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[end exact-nonnegative-integer?]
|
||||
[id symbol?]
|
||||
[label any/c]
|
||||
[path any/c]
|
||||
[tag any/c])
|
||||
void?]{
|
||||
Called to indicate that there is something that has documentation between the range
|
||||
@racket[start] and @racket[end]. The documented identifier's name is given by @racket[id]
|
||||
and the docs are found in the html file @racket[path] at the html tag @racket[tag].
|
||||
The @racket[label] argument describes the binding for use in the menu item (although it may
|
||||
be longer than 200 characters).
|
||||
}
|
||||
|
||||
@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?]{This method is no longer called by Check Syntax. It is here
|
||||
for backwards compatibility only. The information it provided
|
||||
must now be synthesized from the information supplied to
|
||||
@method[syncheck-annotations<%> syncheck:add-arrow/name-dup].}
|
||||
|
||||
@defmethod[(syncheck:add-arrow [start-source-obj (not/c #f)]
|
||||
[start-left exact-nonnegative-integer?]
|
||||
[start-right exact-nonnegative-integer?]
|
||||
[end-source-obj (not/c #f)]
|
||||
[end-left exact-nonnegative-integer?]
|
||||
[end-right exact-nonnegative-integer?]
|
||||
[actual? boolean?]
|
||||
[phase-level (or/c exact-nonnegative-integer? #f)])
|
||||
void?]{
|
||||
This function is not called directly anymore by Check Syntax. Instead
|
||||
@method[syncheck-annotations<%> syncheck:add-arrow/name-dup] is.
|
||||
|
||||
This method is invoked by the default implementation of
|
||||
@racket[_syncheck:add-arrow/name-dup] in
|
||||
@racket[annotations-mixin].
|
||||
}
|
||||
@defmethod[(syncheck:add-arrow/name-dup [start-source-obj (not/c #f)]
|
||||
[start-left exact-nonnegative-integer?]
|
||||
[start-right exact-nonnegative-integer?]
|
||||
[end-source-obj (not/c #f)]
|
||||
[end-left exact-nonnegative-integer?]
|
||||
[end-right exact-nonnegative-integer?]
|
||||
[actual? boolean?]
|
||||
[phase-level (or/c exact-nonnegative-integer? #f)]
|
||||
[require-arrow? boolean?]
|
||||
[name-dup? (-> string? boolean?)])
|
||||
void?]{
|
||||
Called to indicate that there should be an arrow between the locations described by the first
|
||||
six arguments.
|
||||
|
||||
The @racket[phase-level] argument indicates the phase of the binding and the
|
||||
@racket[actual?] argument indicates if the binding is a real one, or a predicted one from
|
||||
a syntax template (predicted bindings are drawn with question marks in Check Syntax).
|
||||
|
||||
The @racket[require-arrow?] argument indicates if this arrow points from
|
||||
an imported identifier to its corresponding @racket[require].
|
||||
|
||||
The @racket[name-dup?] predicate returns @racket[#t]
|
||||
in case that this variable (either the start or end), when replaced with the given string, would
|
||||
shadow some other binding (or otherwise interfere with the binding structure of the program at
|
||||
the time the program was expanded).
|
||||
}
|
||||
@defmethod[(syncheck:add-tail-arrow [from-source-obj (not/c #f)]
|
||||
[from-pos exact-nonnegative-integer?]
|
||||
[to-source-obj (not/c #f)]
|
||||
[to-pos exact-nonnegative-integer?])
|
||||
void?]{
|
||||
Called to indicate that there are two expressions, beginning at
|
||||
@racket[from-pos] and @racket[to-pos]
|
||||
that are in tail position with respect to each other.
|
||||
}
|
||||
@defmethod[(syncheck:add-mouse-over-status [source-obj (not/c #f)]
|
||||
[pos-left exact-nonnegative-integer?]
|
||||
[pos-right exact-nonnegative-integer?]
|
||||
[str string?])
|
||||
void?]{
|
||||
Called to indicate that the message in @racket[str] should be shown when the mouse
|
||||
passes over the given position.
|
||||
}
|
||||
@defmethod[(syncheck:add-jump-to-definition [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[end exact-nonnegative-integer?]
|
||||
[id any/c]
|
||||
[filename path-string?]
|
||||
[submods (listof symbol?)])
|
||||
void?]{
|
||||
Called to indicate that there is some identifier at the given location (named @racket[id]) that
|
||||
is defined in the @racket[submods] of the file @racket[filename] (where an empty list in
|
||||
@racket[submods] means that the identifier is defined at the top-level module).
|
||||
}
|
||||
|
||||
@defmethod[(syncheck:add-definition-target [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[finish exact-nonnegative-integer?]
|
||||
[style-name any/c]) void?]{
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(syncheck:color-range [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[finish exact-nonnegative-integer?]
|
||||
[style-name any/c]
|
||||
[mode any/c])
|
||||
void?]{
|
||||
Called to indicate that the given location should be colored according to the
|
||||
style @racket[style-name] when in @racket[mode]. The mode either indicates regular
|
||||
check syntax or is used indicate blame for potential contract violations
|
||||
(and still experimental).
|
||||
}
|
||||
@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?)])
|
||||
void?]{
|
||||
This method is listed only for backwards compatibility. It is not called
|
||||
by Check Syntax anymore.
|
||||
}
|
||||
}
|
||||
|
||||
@(define syncheck-example-eval (make-base-eval))
|
||||
|
||||
@defmixin[annotations-mixin () (syncheck-annotations<%>)]{
|
||||
Supplies all of the methods in @racket[syncheck-annotations<%>]
|
||||
with default behavior. Be sure to use this mixin to future-proof
|
||||
your code and then override the methods you're interested in.
|
||||
|
||||
By default:
|
||||
@itemlist[@item{The @method[syncheck-annotations<%> syncheck:find-source-object]
|
||||
method ignores its arguments and returns @racket[#f];}
|
||||
@item{the @method[syncheck-annotations<%> syncheck:add-arrow/name-dup] method drops the
|
||||
@racket[_require-arrow?] and @racket[_name-dup?] arguments and calls
|
||||
@method[syncheck-annotations<%> syncheck:add-arrow]; and}
|
||||
@item{all of the other methods ignore their arguments and return @racket[(void)].}]
|
||||
|
||||
Here is an example showing how use this library to extract all
|
||||
of the arrows that Check Syntax would draw from various
|
||||
expressions. One subtle point: arrows are only included when
|
||||
the corresponding identifiers are @racket[syntax-original?];
|
||||
the code below manages this by copying the properties from
|
||||
an identifier that is @racket[syntax-original?] in the
|
||||
call to @racket[datum->syntax].
|
||||
@interaction[#:eval
|
||||
syncheck-example-eval
|
||||
(require drracket/check-syntax racket/class)
|
||||
(define arrows-collector%
|
||||
(class (annotations-mixin object%)
|
||||
(super-new)
|
||||
(define/override (syncheck:find-source-object stx)
|
||||
stx)
|
||||
(define/override (syncheck:add-arrow/name-dup
|
||||
start-source-obj start-left start-right
|
||||
end-source-obj end-left end-right
|
||||
actual? phase-level require-arrow? name-dup?)
|
||||
(set! arrows
|
||||
(cons (list start-source-obj end-source-obj)
|
||||
arrows)))
|
||||
(define arrows '())
|
||||
(define/public (get-collected-arrows) arrows)))
|
||||
(define (arrows form)
|
||||
(define base-namespace (make-base-namespace))
|
||||
(define-values (add-syntax done)
|
||||
(make-traversal base-namespace #f))
|
||||
(define collector (new arrows-collector%))
|
||||
(parameterize ([current-annotations collector]
|
||||
[current-namespace base-namespace])
|
||||
(add-syntax (expand form))
|
||||
(done))
|
||||
(send collector get-collected-arrows))
|
||||
(define (make-id name pos orig?)
|
||||
(datum->syntax
|
||||
#f
|
||||
name
|
||||
(list #f #f #f pos (string-length (symbol->string name)))
|
||||
(and orig? #'is-orig)))
|
||||
(arrows `(λ (,(make-id 'x 1 #t)) ,(make-id 'x 2 #t)))
|
||||
(arrows `(λ (x) x))
|
||||
(arrows `(λ (,(make-id 'x 1 #f)) ,(make-id 'x 2 #t)))
|
||||
(arrows `(λ (,(make-id 'x 1 #t)) x))]
|
||||
}
|
||||
|
||||
@(close-eval syncheck-example-eval)
|
||||
|
||||
@(define-syntax-rule
|
||||
(syncheck-method-id x ...)
|
||||
(begin @defidform[x]{Bound to an identifier created with
|
||||
@racket[define-local-member-name]
|
||||
that is used in @racket[syncheck-annotations<%>].}
|
||||
...))
|
||||
@syncheck-method-id[syncheck:find-source-object
|
||||
syncheck:add-background-color
|
||||
syncheck:add-require-open-menu
|
||||
syncheck:add-docs-menu
|
||||
syncheck:add-rename-menu
|
||||
syncheck:add-arrow
|
||||
syncheck:add-arrow/name-dup
|
||||
syncheck:add-tail-arrow
|
||||
syncheck:add-mouse-over-status
|
||||
syncheck:add-jump-to-definition
|
||||
syncheck:add-id-set
|
||||
syncheck:color-range]
|
|
@ -0,0 +1,3 @@
|
|||
#lang info
|
||||
|
||||
(define scribblings '(("drracket-tools.scrbl" (multi-page) (tool -200))))
|
|
@ -2,8 +2,8 @@
|
|||
(require racket/contract
|
||||
racket/class
|
||||
"private/syncheck/traversals.rkt"
|
||||
"private/syncheck/intf.rkt"
|
||||
"private/syncheck/local-member-names.rkt")
|
||||
"private/syncheck/syncheck-intf.rkt"
|
||||
"private/syncheck/syncheck-local-member-names.rkt")
|
||||
|
||||
(provide/contract
|
||||
[make-traversal
|
||||
|
@ -36,6 +36,3 @@
|
|||
syncheck:add-mouse-over-status
|
||||
syncheck:add-jump-to-definition
|
||||
syncheck:color-range)
|
||||
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#lang racket/base
|
||||
(require racket/class
|
||||
"intf.rkt"
|
||||
"local-member-names.rkt")
|
||||
"syncheck-intf.rkt"
|
||||
"syncheck-local-member-names.rkt")
|
||||
(provide color color-range
|
||||
find-source-editor
|
||||
find-source-editor/defs
|
|
@ -1,6 +1,6 @@
|
|||
#lang racket/base
|
||||
(require "intf.rkt"
|
||||
"local-member-names.rkt"
|
||||
(require "syncheck-intf.rkt"
|
||||
"syncheck-local-member-names.rkt"
|
||||
"annotate.rkt"
|
||||
"colors.rkt"
|
||||
syntax/boundmap
|
|
@ -0,0 +1,60 @@
|
|||
#lang racket/base
|
||||
(require racket/class
|
||||
"syncheck-local-member-names.rkt")
|
||||
|
||||
(define syncheck-annotations<%>
|
||||
(interface ()
|
||||
syncheck:find-source-object
|
||||
syncheck:add-background-color
|
||||
syncheck:add-require-open-menu
|
||||
syncheck:add-docs-menu
|
||||
syncheck:add-id-set
|
||||
syncheck:add-arrow
|
||||
syncheck:add-arrow/name-dup
|
||||
syncheck:add-tail-arrow
|
||||
syncheck:add-mouse-over-status
|
||||
syncheck:add-jump-to-definition
|
||||
syncheck:add-definition-target
|
||||
syncheck:color-range
|
||||
|
||||
syncheck:add-rename-menu))
|
||||
|
||||
;; use this to communicate the frame being
|
||||
;; syntax checked w/out having to add new
|
||||
;; parameters to all of the functions
|
||||
(define current-annotations (make-parameter #f))
|
||||
|
||||
(define annotations-mixin
|
||||
(mixin () (syncheck-annotations<%>)
|
||||
(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-id-set all-ids new-name-intereferes?) (void))
|
||||
(define/public (syncheck:add-rename-menu sym 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
|
||||
actual? level)
|
||||
(void))
|
||||
(define/public (syncheck:add-arrow/name-dup start-text start-pos-left start-pos-right
|
||||
end-text end-pos-left end-pos-right
|
||||
actual? level require-arrow? name-dup?)
|
||||
(syncheck:add-arrow start-text start-pos-left start-pos-right
|
||||
end-text end-pos-left end-pos-right
|
||||
actual? level))
|
||||
(define/public (syncheck:add-tail-arrow from-text from-pos to-text to-pos) (void))
|
||||
(define/public (syncheck:add-mouse-over-status text pos-left pos-right str) (void))
|
||||
(define/public (syncheck:add-jump-to-definition text start end id filename submods) (void))
|
||||
(define/public (syncheck:add-definition-target source pos-left pos-right id mods) (void))
|
||||
(define/public (syncheck:color-range source start finish style-name) (void))
|
||||
(super-new)))
|
||||
|
||||
(provide syncheck-annotations<%>
|
||||
current-annotations
|
||||
annotations-mixin)
|
|
@ -0,0 +1,17 @@
|
|||
#lang racket/base
|
||||
(require racket/class)
|
||||
(provide (all-defined-out))
|
||||
|
||||
(define-local-member-name
|
||||
syncheck:find-source-object
|
||||
syncheck:add-background-color
|
||||
syncheck:add-docs-menu
|
||||
syncheck:color-range
|
||||
syncheck:add-require-open-menu
|
||||
syncheck:add-id-set
|
||||
syncheck:add-arrow
|
||||
syncheck:add-arrow/name-dup
|
||||
syncheck:add-rename-menu
|
||||
syncheck:add-tail-arrow
|
||||
syncheck:add-mouse-over-status
|
||||
syncheck:add-jump-to-definition)
|
|
@ -1,8 +1,8 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "colors.rkt"
|
||||
"intf.rkt"
|
||||
"local-member-names.rkt"
|
||||
"syncheck-intf.rkt"
|
||||
"syncheck-local-member-names.rkt"
|
||||
"annotate.rkt"
|
||||
"contract-traversal.rkt"
|
||||
"xref.rkt"
|
||||
|
@ -875,7 +875,6 @@
|
|||
(when (pair? val)
|
||||
(define start (car val))
|
||||
(define end (cdr val))
|
||||
(define (get-str) (send (list-ref key 0) get-text (list-ref key 1) (list-ref key 2)))
|
||||
(define (show-starts)
|
||||
(add-mouse-over/loc (list-ref key 0) (list-ref key 1) (list-ref key 2)
|
||||
(cond
|
16
pkgs/drracket-pkgs/drracket-tool-lib/info.rkt
Normal file
16
pkgs/drracket-pkgs/drracket-tool-lib/info.rkt
Normal file
|
@ -0,0 +1,16 @@
|
|||
#lang info
|
||||
|
||||
(define collection 'multi)
|
||||
|
||||
(define deps '("base"
|
||||
"scribble-lib"
|
||||
"string-constants-lib"
|
||||
"scribble-lib"
|
||||
"racket-index"))
|
||||
(define build-deps '("at-exp-lib"))
|
||||
|
||||
(define pkg-desc "Code implementing programmatic interfaces to some IDE tools that DrRacket supports")
|
||||
|
||||
(define pkg-authors '(robby))
|
||||
|
||||
(define version "1.0")
|
14
pkgs/drracket-pkgs/drracket-tool-test/info.rkt
Normal file
14
pkgs/drracket-pkgs/drracket-tool-test/info.rkt
Normal file
|
@ -0,0 +1,14 @@
|
|||
#lang info
|
||||
|
||||
(define collection 'multi)
|
||||
|
||||
(define deps '("base"
|
||||
"rackunit-lib"
|
||||
"drracket-tool-lib"))
|
||||
(define build-deps '())
|
||||
|
||||
(define pkg-desc "Tests for IDE tools that DrRacket supports")
|
||||
|
||||
(define pkg-authors '(robby))
|
||||
|
||||
(define version "1.0")
|
12
pkgs/drracket-pkgs/drracket-tool/info.rkt
Normal file
12
pkgs/drracket-pkgs/drracket-tool/info.rkt
Normal file
|
@ -0,0 +1,12 @@
|
|||
#lang info
|
||||
|
||||
(define collection 'multi)
|
||||
|
||||
(define deps '("drracket-tool-lib"
|
||||
"drracket-tool-doc"))
|
||||
(define implies '("drracket-tool-lib"
|
||||
"drracket-tool-doc"))
|
||||
|
||||
(define pkg-desc "Programmatic interface to some IDE tools that DrRacket supports")
|
||||
|
||||
(define pkg-authors '(robby))
|
|
@ -43,11 +43,12 @@ If the namespace does not, they are colored the unbound color.
|
|||
"../../private/eval-helpers-and-pref-init.rkt"
|
||||
"intf.rkt"
|
||||
"local-member-names.rkt"
|
||||
"colors.rkt"
|
||||
"traversals.rkt"
|
||||
"annotate.rkt"
|
||||
"../tooltip.rkt"
|
||||
"blueboxes-gui.rkt"
|
||||
drracket/private/syncheck/syncheck-intf
|
||||
drracket/private/syncheck/colors
|
||||
drracket/private/syncheck/traversals
|
||||
drracket/private/syncheck/annotate
|
||||
framework/private/logging-timer)
|
||||
(provide tool@)
|
||||
|
||||
|
|
|
@ -1,24 +1,9 @@
|
|||
#lang racket/base
|
||||
(require racket/class
|
||||
(provide syncheck-text<%>)
|
||||
(require racket/class
|
||||
drracket/private/syncheck/syncheck-intf
|
||||
"local-member-names.rkt")
|
||||
|
||||
(define syncheck-annotations<%>
|
||||
(interface ()
|
||||
syncheck:find-source-object
|
||||
syncheck:add-background-color
|
||||
syncheck:add-require-open-menu
|
||||
syncheck:add-docs-menu
|
||||
syncheck:add-id-set
|
||||
syncheck:add-arrow
|
||||
syncheck:add-arrow/name-dup
|
||||
syncheck:add-tail-arrow
|
||||
syncheck:add-mouse-over-status
|
||||
syncheck:add-jump-to-definition
|
||||
syncheck:add-definition-target
|
||||
syncheck:color-range
|
||||
|
||||
syncheck:add-rename-menu))
|
||||
|
||||
(define syncheck-text<%>
|
||||
(interface (syncheck-annotations<%>)
|
||||
syncheck:init-arrows
|
||||
|
@ -29,39 +14,4 @@
|
|||
syncheck:jump-to-binding-occurrence
|
||||
syncheck:jump-to-definition
|
||||
syncheck:rename-identifier
|
||||
syncheck:tack/untack-arrows))
|
||||
|
||||
;; use this to communicate the frame being
|
||||
;; syntax checked w/out having to add new
|
||||
;; parameters to all of the functions
|
||||
(define current-annotations (make-parameter #f))
|
||||
|
||||
(define annotations-mixin
|
||||
(mixin () (syncheck-annotations<%>)
|
||||
(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-id-set all-ids new-name-intereferes?) (void))
|
||||
(define/public (syncheck:add-rename-menu sym 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
|
||||
actual? level)
|
||||
(void))
|
||||
(define/public (syncheck:add-arrow/name-dup start-text start-pos-left start-pos-right
|
||||
end-text end-pos-left end-pos-right
|
||||
actual? level require-arrow? name-dup?)
|
||||
(syncheck:add-arrow start-text start-pos-left start-pos-right
|
||||
end-text end-pos-left end-pos-right
|
||||
actual? level))
|
||||
(define/public (syncheck:add-tail-arrow from-text from-pos to-text to-pos) (void))
|
||||
(define/public (syncheck:add-mouse-over-status text pos-left pos-right str) (void))
|
||||
(define/public (syncheck:add-jump-to-definition text start end id filename submods) (void))
|
||||
(define/public (syncheck:add-definition-target source pos-left pos-right id mods) (void))
|
||||
(define/public (syncheck:color-range source start finish style-name) (void))
|
||||
(super-new)))
|
||||
|
||||
(provide syncheck-text<%>
|
||||
syncheck-annotations<%>
|
||||
current-annotations
|
||||
annotations-mixin)
|
||||
syncheck:tack/untack-arrows))
|
|
@ -1,6 +1,8 @@
|
|||
#lang racket/base
|
||||
(require racket/class)
|
||||
(provide (all-defined-out))
|
||||
(require racket/class
|
||||
drracket/private/syncheck/syncheck-local-member-names)
|
||||
(provide (all-defined-out)
|
||||
(all-from-out drracket/private/syncheck/syncheck-local-member-names))
|
||||
|
||||
(define-local-member-name
|
||||
syncheck:init-arrows
|
||||
|
@ -8,19 +10,6 @@
|
|||
syncheck:clear-coloring
|
||||
syncheck:arrows-visible?
|
||||
|
||||
syncheck:find-source-object
|
||||
syncheck:add-background-color
|
||||
syncheck:add-docs-menu
|
||||
syncheck:color-range
|
||||
syncheck:add-require-open-menu
|
||||
syncheck:add-id-set
|
||||
syncheck:add-arrow
|
||||
syncheck:add-arrow/name-dup
|
||||
syncheck:add-rename-menu
|
||||
syncheck:add-tail-arrow
|
||||
syncheck:add-mouse-over-status
|
||||
syncheck:add-jump-to-definition
|
||||
|
||||
syncheck:jump-to-next-bound-occurrence
|
||||
syncheck:jump-to-binding-occurrence
|
||||
syncheck:jump-to-definition
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
racket/match
|
||||
racket/contract
|
||||
(for-syntax racket/base)
|
||||
drracket/private/syncheck/traversals
|
||||
drracket/private/syncheck/syncheck-intf
|
||||
drracket/private/syncheck/xref
|
||||
"../../private/eval-helpers-and-pref-init.rkt"
|
||||
"traversals.rkt"
|
||||
"local-member-names.rkt"
|
||||
"intf.rkt"
|
||||
"xref.rkt")
|
||||
"local-member-names.rkt")
|
||||
|
||||
(provide go monitor)
|
||||
|
||||
|
|
|
@ -37,7 +37,9 @@
|
|||
"tex-table"
|
||||
"unstable-lib"
|
||||
"drracket-plugin-lib"
|
||||
"gui-pkg-manager-lib"))
|
||||
"gui-pkg-manager-lib"
|
||||
"drracket-tool-lib"
|
||||
"drracket-tool-doc"))
|
||||
(define build-deps '("mzscheme-doc"
|
||||
"net-doc"
|
||||
"planet-doc"
|
||||
|
@ -52,7 +54,10 @@
|
|||
"at-exp-lib"
|
||||
"rackunit-lib"))
|
||||
|
||||
(define implies '("drracket-plugin-lib"))
|
||||
;; implies drracket-tool-lib so that others dependencies don't break
|
||||
;; (redex, in particular, used to depend on drracket but it really
|
||||
;; needs only the parts in drracket-tool-lib)
|
||||
(define implies '("drracket-plugin-lib" "drracket-tool-lib"))
|
||||
|
||||
(define pkg-desc "The DrRacket programming environment")
|
||||
|
||||
|
|
|
@ -643,296 +643,8 @@ for a list of the capabilities registered by default.
|
|||
|
||||
@section{Check Syntax}
|
||||
|
||||
Check Syntax is a part of the DrRacket collection, but is implemented via the tools API.
|
||||
|
||||
@subsection{Accessing Check Syntax Programmatically}
|
||||
|
||||
@defmodule[drracket/check-syntax]
|
||||
|
||||
@defproc[(make-traversal [namespace namespace?]
|
||||
[path (or/c #f path-string?)])
|
||||
(values (->* (syntax?)
|
||||
((-> any/c void?))
|
||||
void?)
|
||||
(-> void?))]{
|
||||
This function creates some local state about a traversal of syntax objects
|
||||
and returns two functions. The first one should be called with each of the
|
||||
(fully expanded) syntax objects that make up a program (there will be only
|
||||
one if the program is a module) and then the second one should be called to
|
||||
indicate there are no more.
|
||||
|
||||
The optional argument to the first function is ignored.
|
||||
It is left there for historical reasons. In the past it
|
||||
was called for each sequence
|
||||
of binding identifiers encountered in @racket[define-values], @racket[define-syntaxes],
|
||||
and @racket[define-values-for-syntax].
|
||||
|
||||
During the dynamic extent of the call to the two result functions, the value
|
||||
of the @racket[current-annotations] parameter is consulted and various
|
||||
methods are invoked in the corresponding object (if any), to indicate
|
||||
what has been found in the syntax object. These methods will only be called
|
||||
if the syntax objects have source locations.
|
||||
}
|
||||
|
||||
@defparam[current-annotations ca (or/c #f (is-a?/c syncheck-annotations<%>))]{
|
||||
The methods of the value of this parameter are invoked by the functions returned
|
||||
from @racket[make-traversal].
|
||||
}
|
||||
|
||||
@defparam[current-max-to-send-at-once m (or/c +inf.0 (and/c exact-integer? (>=/c 2)))]{
|
||||
No longer used.
|
||||
}
|
||||
|
||||
@definterface[syncheck-annotations<%> ()]{
|
||||
|
||||
Classes implementing this interface are
|
||||
accceptors of information about a traversal
|
||||
of syntax objects. See @racket[make-traversal].
|
||||
|
||||
Do not implement this interface directly, as it
|
||||
is liable to change without warning. Instead, use
|
||||
the @racket[annotations-mixin] and override
|
||||
the methods you're interested in. The
|
||||
@racket[annotations-mixin] will keep in sync
|
||||
with this interface, providing methods that
|
||||
ignore their arguments.
|
||||
|
||||
@defmethod[(syncheck:find-source-object [stx syntax?]) (or/c #f (not/c #f))]{
|
||||
This should return @racket[#f] if the source of this syntax object is
|
||||
uninteresting for annotations (if, for example, the only interesting
|
||||
annotations are those in the original file and this is a syntax object
|
||||
introduced by a macro and thus has a source location from some other file).
|
||||
|
||||
Otherwise, it should return some (non-@racket[#f])
|
||||
value that will then be passed to one of the other methods below as
|
||||
a @racket[_source-obj] argument.
|
||||
}
|
||||
|
||||
@defmethod[(syncheck:add-background-color [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[end exact-nonnegative-integer?]
|
||||
[color string?])
|
||||
void?]{
|
||||
Called to indicate that the color @racket[color] should be drawn on the background of
|
||||
the given range in the editor, when the mouse moves over it. This method is typically
|
||||
called in conjuction with some other method that provides some other annotation
|
||||
on the source.
|
||||
}
|
||||
@defmethod[(syncheck:add-require-open-menu [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[end exact-nonnegative-integer?]
|
||||
[file path-string?])
|
||||
void?]{
|
||||
Called to indicate that there is a @racket[require] at the location from
|
||||
@racket[start] to @racket[end],
|
||||
and that it corresponds to @racket[file]. Check Syntax adds a popup menu.
|
||||
}
|
||||
|
||||
@defmethod[(syncheck:add-docs-menu [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[end exact-nonnegative-integer?]
|
||||
[id symbol?]
|
||||
[label any/c]
|
||||
[path any/c]
|
||||
[tag any/c])
|
||||
void?]{
|
||||
Called to indicate that there is something that has documentation between the range
|
||||
@racket[start] and @racket[end]. The documented identifier's name is given by @racket[id]
|
||||
and the docs are found in the html file @racket[path] at the html tag @racket[tag].
|
||||
The @racket[label] argument describes the binding for use in the menu item (although it may
|
||||
be longer than 200 characters).
|
||||
}
|
||||
|
||||
@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?]{This method is no longer called by Check Syntax. It is here
|
||||
for backwards compatibility only. The information it provided
|
||||
must now be synthesized from the information supplied to
|
||||
@method[syncheck-annotations<%> syncheck:add-arrow/name-dup].}
|
||||
|
||||
@defmethod[(syncheck:add-arrow [start-source-obj (not/c #f)]
|
||||
[start-left exact-nonnegative-integer?]
|
||||
[start-right exact-nonnegative-integer?]
|
||||
[end-source-obj (not/c #f)]
|
||||
[end-left exact-nonnegative-integer?]
|
||||
[end-right exact-nonnegative-integer?]
|
||||
[actual? boolean?]
|
||||
[phase-level (or/c exact-nonnegative-integer? #f)])
|
||||
void?]{
|
||||
This function is not called directly anymore by Check Syntax. Instead
|
||||
@method[syncheck-annotations<%> syncheck:add-arrow/name-dup] is.
|
||||
|
||||
This method is invoked by the default implementation of
|
||||
@racket[_syncheck:add-arrow/name-dup] in
|
||||
@racket[annotations-mixin].
|
||||
}
|
||||
@defmethod[(syncheck:add-arrow/name-dup [start-source-obj (not/c #f)]
|
||||
[start-left exact-nonnegative-integer?]
|
||||
[start-right exact-nonnegative-integer?]
|
||||
[end-source-obj (not/c #f)]
|
||||
[end-left exact-nonnegative-integer?]
|
||||
[end-right exact-nonnegative-integer?]
|
||||
[actual? boolean?]
|
||||
[phase-level (or/c exact-nonnegative-integer? #f)]
|
||||
[require-arrow? boolean?]
|
||||
[name-dup? (-> string? boolean?)])
|
||||
void?]{
|
||||
Called to indicate that there should be an arrow between the locations described by the first
|
||||
six arguments.
|
||||
|
||||
The @racket[phase-level] argument indicates the phase of the binding and the
|
||||
@racket[actual?] argument indicates if the binding is a real one, or a predicted one from
|
||||
a syntax template (predicted bindings are drawn with question marks in Check Syntax).
|
||||
|
||||
The @racket[require-arrow?] argument indicates if this arrow points from
|
||||
an imported identifier to its corresponding @racket[require].
|
||||
|
||||
The @racket[name-dup?] predicate returns @racket[#t]
|
||||
in case that this variable (either the start or end), when replaced with the given string, would
|
||||
shadow some other binding (or otherwise interfere with the binding structure of the program at
|
||||
the time the program was expanded).
|
||||
}
|
||||
@defmethod[(syncheck:add-tail-arrow [from-source-obj (not/c #f)]
|
||||
[from-pos exact-nonnegative-integer?]
|
||||
[to-source-obj (not/c #f)]
|
||||
[to-pos exact-nonnegative-integer?])
|
||||
void?]{
|
||||
Called to indicate that there are two expressions, beginning at
|
||||
@racket[from-pos] and @racket[to-pos]
|
||||
that are in tail position with respect to each other.
|
||||
}
|
||||
@defmethod[(syncheck:add-mouse-over-status [source-obj (not/c #f)]
|
||||
[pos-left exact-nonnegative-integer?]
|
||||
[pos-right exact-nonnegative-integer?]
|
||||
[str string?])
|
||||
void?]{
|
||||
Called to indicate that the message in @racket[str] should be shown when the mouse
|
||||
passes over the given position.
|
||||
}
|
||||
@defmethod[(syncheck:add-jump-to-definition [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[end exact-nonnegative-integer?]
|
||||
[id any/c]
|
||||
[filename path-string?]
|
||||
[submods (listof symbol?)])
|
||||
void?]{
|
||||
Called to indicate that there is some identifier at the given location (named @racket[id]) that
|
||||
is defined in the @racket[submods] of the file @racket[filename] (where an empty list in
|
||||
@racket[submods] means that the identifier is defined at the top-level module).
|
||||
}
|
||||
|
||||
@defmethod[(syncheck:add-definition-target [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[finish exact-nonnegative-integer?]
|
||||
[style-name any/c]) void?]{
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(syncheck:color-range [source-obj (not/c #f)]
|
||||
[start exact-nonnegative-integer?]
|
||||
[finish exact-nonnegative-integer?]
|
||||
[style-name any/c]
|
||||
[mode any/c])
|
||||
void?]{
|
||||
Called to indicate that the given location should be colored according to the
|
||||
style @racket[style-name] when in @racket[mode]. The mode either indicates regular
|
||||
check syntax or is used indicate blame for potential contract violations
|
||||
(and still experimental).
|
||||
}
|
||||
@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?)])
|
||||
void?]{
|
||||
This method is listed only for backwards compatibility. It is not called
|
||||
by Check Syntax anymore.
|
||||
}
|
||||
}
|
||||
|
||||
@(define syncheck-example-eval (make-base-eval))
|
||||
|
||||
@defmixin[annotations-mixin () (syncheck-annotations<%>)]{
|
||||
Supplies all of the methods in @racket[syncheck-annotations<%>]
|
||||
with default behavior. Be sure to use this mixin to future-proof
|
||||
your code and then override the methods you're interested in.
|
||||
|
||||
By default:
|
||||
@itemlist[@item{The @method[syncheck-annotations<%> syncheck:find-source-object]
|
||||
method ignores its arguments and returns @racket[#f];}
|
||||
@item{the @method[syncheck-annotations<%> syncheck:add-arrow/name-dup] method drops the
|
||||
@racket[_require-arrow?] and @racket[_name-dup?] arguments and calls
|
||||
@method[syncheck-annotations<%> syncheck:add-arrow]; and}
|
||||
@item{all of the other methods ignore their arguments and return @racket[(void)].}]
|
||||
|
||||
Here is an example showing how use this library to extract all
|
||||
of the arrows that Check Syntax would draw from various
|
||||
expressions. One subtle point: arrows are only included when
|
||||
the corresponding identifiers are @racket[syntax-original?];
|
||||
the code below manages this by copying the properties from
|
||||
an identifier that is @racket[syntax-original?] in the
|
||||
call to @racket[datum->syntax].
|
||||
@interaction[#:eval
|
||||
syncheck-example-eval
|
||||
(require drracket/check-syntax racket/class)
|
||||
(define arrows-collector%
|
||||
(class (annotations-mixin object%)
|
||||
(super-new)
|
||||
(define/override (syncheck:find-source-object stx)
|
||||
stx)
|
||||
(define/override (syncheck:add-arrow/name-dup
|
||||
start-source-obj start-left start-right
|
||||
end-source-obj end-left end-right
|
||||
actual? phase-level require-arrow? name-dup?)
|
||||
(set! arrows
|
||||
(cons (list start-source-obj end-source-obj)
|
||||
arrows)))
|
||||
(define arrows '())
|
||||
(define/public (get-collected-arrows) arrows)))
|
||||
(define (arrows form)
|
||||
(define base-namespace (make-base-namespace))
|
||||
(define-values (add-syntax done)
|
||||
(make-traversal base-namespace #f))
|
||||
(define collector (new arrows-collector%))
|
||||
(parameterize ([current-annotations collector]
|
||||
[current-namespace base-namespace])
|
||||
(add-syntax (expand form))
|
||||
(done))
|
||||
(send collector get-collected-arrows))
|
||||
(define (make-id name pos orig?)
|
||||
(datum->syntax
|
||||
#f
|
||||
name
|
||||
(list #f #f #f pos (string-length (symbol->string name)))
|
||||
(and orig? #'is-orig)))
|
||||
(arrows `(λ (,(make-id 'x 1 #t)) ,(make-id 'x 2 #t)))
|
||||
(arrows `(λ (x) x))
|
||||
(arrows `(λ (,(make-id 'x 1 #f)) ,(make-id 'x 2 #t)))
|
||||
(arrows `(λ (,(make-id 'x 1 #t)) x))]
|
||||
}
|
||||
|
||||
@(close-eval syncheck-example-eval)
|
||||
|
||||
@(define-syntax-rule
|
||||
(syncheck-method-id x ...)
|
||||
(begin @defidform[x]{Bound to an identifier created with
|
||||
@racket[define-local-member-name]
|
||||
that is used in @racket[syncheck-annotations<%>].}
|
||||
...))
|
||||
@syncheck-method-id[syncheck:find-source-object
|
||||
syncheck:add-background-color
|
||||
syncheck:add-require-open-menu
|
||||
syncheck:add-docs-menu
|
||||
syncheck:add-rename-menu
|
||||
syncheck:add-arrow
|
||||
syncheck:add-arrow/name-dup
|
||||
syncheck:add-tail-arrow
|
||||
syncheck:add-mouse-over-status
|
||||
syncheck:add-jump-to-definition
|
||||
syncheck:add-id-set
|
||||
syncheck:color-range]
|
||||
Check Syntax is a part of the DrRacket collection, but is implemented via the
|
||||
plugin API. See also @racketmodname[drracket/check-syntax].
|
||||
|
||||
@subsection{Check Syntax Button}
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
"images-test"
|
||||
"plot-test"
|
||||
"math-test"
|
||||
"racket-benchmarks"))
|
||||
"racket-benchmarks"
|
||||
"drracket-tool-test"))
|
||||
|
||||
(define pkg-desc "tests for \"main-distribution\"")
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"draw-doc"
|
||||
"draw-lib"
|
||||
"drracket"
|
||||
"drracket-tool"
|
||||
"eopl"
|
||||
"errortrace"
|
||||
"frtime"
|
||||
|
|
Loading…
Reference in New Issue
Block a user