8 Check Syntax
Check Syntax is a part of the DrRacket collection, but is implemented via the tools API.
8.1 Accessing Check Syntax Programmatically
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 define-values, define-syntaxes,
and define-values-for-syntax.
During the dynamic extent of the call to the two result functions, the value
of the 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.
The methods of the value of this parameter are invoked by the functions returned
from
make-traversal.
No longer used.
Classes implementing this interface are
accceptors of information about a traversal
of syntax objects. See
make-traversal.
Do not implement this interface directly, as it
is liable to change without warning. Instead, use
the
annotations-mixin and override
the methods you’re interested in. The
annotations-mixin will keep in sync
with this interface, providing methods that
ignore their arguments.
This should return #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-#f)
value that will then be passed to one of the other methods below as
a source-obj argument.
Called to indicate that the color 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.
Called to indicate that there is a
require at the location from
start to
end,
and that it corresponds to
file. Check Syntax adds a popup menu.
Called to indicate that there is something that has documentation between the range
start and end. The documented identifier’s name is given by id
and the docs are found in the html file path at the html tag tag.
The label argument describes the binding for use in the menu item (although it may
be longer than 200 characters).
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
syncheck:add-arrow/name-dup.
This method is invoked by the default implementation of
syncheck:add-arrow/name-dup in
annotations-mixin.
Called to indicate that there should be an arrow between the locations described by the first
six arguments.
The phase-level argument indicates the phase of the binding and the
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 require-arrow? argument indicates if this arrow points from
an imported identifier to its corresponding require.
The name-dup? predicate returns #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).
Called to indicate that there are two expressions, beginning at
from-pos and to-pos
that are in tail position with respect to each other.
Called to indicate that the message in str should be shown when the mouse
passes over the given position.
Called to indicate that there is some identifier at the given location (named id) that
is defined in the submods of the file filename (where an empty list in
submods means that the identifier is defined at the top-level module).
Called to indicate that the given location should be colored according to the
style style-name when in mode. The mode either indicates regular
check syntax or is used indicate blame for potential contract violations
(and still experimental).
This method is listed only for backwards compatibility. It is not called
by Check Syntax anymore.
Supplies all of the methods in
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.
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
syntax-original?;
the code below manages this by copying the properties from
an identifier that is
syntax-original? in the
call to
datum->syntax.
> (require drracket/check-syntax racket/class) |
|
|
|
|
|
|
|
> (arrows `(λ (,(make-id 'x 1 #t)) ,(make-id 'x 2 #t))) |
'((#<syntax::1 x> #<syntax::2 x>)) |
> (arrows `(λ (x) x)) |
'() |
> (arrows `(λ (,(make-id 'x 1 #f)) ,(make-id 'x 2 #t))) |
'() |
> (arrows `(λ (,(make-id 'x 1 #t)) x)) |
'() |
8.2 Check Syntax Button
This is meant to be used with the
'drracket:toolbar-buttons
argument to the info proc returned
from
read-language.
This is defined with
define-local-member-name and
is bound to a method of no arguments of the DrRacket frame that runs Check
Syntax.
The bitmap in the Check Syntax button on the DrRacket frame.
8.3 Syntax Properties that Check Syntax Looks For
Check Syntax collects the values of the
syntax-propertys named
'disappeared-use,
'disappeared-binding, and
'sub-range-binders, and uses them to add
additional arrows to the program text. These properties are
intended for use when a macro discards or manufactures identifiers that,
from the programmers perspective, should be binding each other.
For example, here is a macro that discards its arguments, but
adds properties to the result syntax object so the arguments
are treated as a binding/bound pair by Check Syntax.
See also current-recorded-disappeared-uses.
The value of the
'sub-range-binders property is expected
to be a tree of
cons pairs (in any configuration) whose leaves
are either ignored or are vectors of the shape
.
If the leaf is a vector, the first syntax object is expected to be an identifier whose
bound occurrences should have arrows that point to the syntax object in the fourth
position in the vector. The numbers indicate the starting point and the range inside
the corresponding identifier to consider as the location of the end of the arrow.
Here’s an example:
After putting this code in the DrRacket window, mouse over the words “big” and
“generator” to see arrows pointing to the individual pieces of the identifier
big-generator.
Finally, Check Syntax only draws arrows between identifiers that are syntax-original?
or that have the syntax-property 'original-for-check-syntax
set to #t.