▼ |  | Dr Racket Plugins

1 | Implementing Dr Racket Plugins
2 | Adding Languages to Dr Racket
3 | Creating New Kinds of Dr Racket Frames
4 | Extending the Existing Dr Racket Classes
5 | Expanding the User’s Program Text and Breaking
6 | Editor Modes
7 | Language-Specific Capabilities
8 | Check Syntax
9 | Teaching Languages
10 | drracket: get/ extend
11 | drracket: unit
12 | drracket: language
13 | drracket: language-configuration
14 | drracket: debug
15 | drracket: rep
16 | drracket: frame
17 | drracket: help-desk
18 | drracket: eval
19 | drracket: modes
20 | drracket: module-language-tools
21 | drracket: module-language
22 | Backwards Compatibility
| Index

► | 8 | Check Syntax

8.1 | Accessing Check Syntax Programmatically
8.2 | Check Syntax Button
8.3 | Disappeared Uses and Bindings

On this page:

8.1`` Accessing Check Syntax Programmatically
make-traversal
current-annotations
current-max-to-send-at-once
syncheck-annotations<%>
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-tail-arrow
syncheck: add-mouse-over-status
syncheck: add-jump-to-definition
syncheck: add-definition-target
syncheck: color-range
syncheck: add-rename-menu
annotations-mixin
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-tail-arrow
syncheck: add-mouse-over-status
syncheck: add-jump-to-definition
syncheck: add-id-set
syncheck: color-range
8.2`` Check Syntax Button
syncheck-drracket-button
syncheck: button-callback
syncheck-bitmap
8.3`` Disappeared Uses and Bindings

top ← prev up next →

### 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

(require drracket/check-syntax)

> > procedure

> > (make-traversal namespace path)

> > →

> > (->* (syntax?)
> > ((-> any/c void?))
> > void?)

> > (-> void?)

> namespace : namespace?
> path : (or/c #f path-string?)

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.

> > parameter

> > (current-annotations)

> → (or/c #f (is-a?/c syncheck-annotations<%>))
> (current-annotations ca) → void?
> ca : (or/c #f (is-a?/c syncheck-annotations<%>))

The methods of the value of this parameter are invoked by the functions returned from make-traversal.

> > parameter

> > (current-max-to-send-at-once)

> → (or/c +inf.0 (and/c exact-integer? (>=/c 2)))
> (current-max-to-send-at-once m) → void?
> m : (or/c +inf.0 (and/c exact-integer? (>=/c 2)))

See syncheck:add-id-set in syncheck-annotations<%>.

> interface

> syncheck-annotations<%> : interface?

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.

> > > method

> > > (send a-syncheck-annotations syncheck:find-source-object stx)

> > → (or/c #f (not/c #f))
> > stx : syntax?

> 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.

> > > method

> > > (send a-syncheck-annotations syncheck:add-background-color |
> > > |  | source-obj |
> > > |  | start |
> > > |  | end |
> > > |  | color) |

> > → void?
> > source-obj : (not/c #f)
> > start : exact-nonnegative-integer?
> > end : exact-nonnegative-integer?
> > color : string?

> 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.

> > > method

> > > (send a-syncheck-annotations syncheck:add-require-open-menu |
> > > |  | source-obj |
> > > |  | start |
> > > |  | end |
> > > |  | file) |

> > → void?
> > source-obj : (not/c #f)
> > start : exact-nonnegative-integer?
> > end : exact-nonnegative-integer?
> > file : path-string?

> 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.

> > > method

> > > (send a-syncheck-annotations syncheck:add-docs-menu |
> > > |  | source-obj |
> > > |  | start |
> > > |  | end |
> > > |  | id |
> > > |  | label |
> > > |  | path |
> > > |  | tag) |

> > → void?
> > source-obj : (not/c #f)
> > start : exact-nonnegative-integer?
> > end : exact-nonnegative-integer?
> > id : symbol?
> > label : any/c
> > path : any/c
> > tag : any/c

> 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).

> > > method

> > > (send a-syncheck-annotations syncheck:add-id-set |
> > > |  | all-ids |
> > > |  | new-name-interferes?) |

> > → void?

> > all-ids

> > :

> > (listof (list/c (not/c #f)
> > exact-nonnegative-integer?
> > exact-nonnegative-integer?))

> > new-name-interferes? : (-> symbol boolean?)

> Called to indicate that all of the locations in the all-ids list refer to the same identifier.

> The 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 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 all-ids. If, however, current-max-to-send-at-once is not +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 all-ids lists (on those multiple calls) is non-empty.

> > > method

> > > (send a-syncheck-annotations syncheck:add-arrow |
> > > |  | start-source-obj |
> > > |  | start-left |
> > > |  | start-right |
> > > |  | end-source-obj |
> > > |  | end-left |
> > > |  | end-right |
> > > |  | actual? |
> > > |  | phase-level) |

> > → void?
> > 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)

> 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).

> > > method

> > > (send a-syncheck-annotations syncheck:add-tail-arrow |
> > > |  | from-source-obj |
> > > |  | from-pos |
> > > |  | to-source-obj |
> > > |  | to-pos) |

> > → void?
> > from-source-obj : (not/c #f)
> > from-pos : exact-nonnegative-integer?
> > to-source-obj : (not/c #f)
> > to-pos : exact-nonnegative-integer?

> 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.

> > > method

> > > (send a-syncheck-annotations syncheck:add-mouse-over-status |
> > > |  | source-obj |
> > > |  | pos-left |
> > > |  | pos-right |
> > > |  | str) |

> > → void?
> > source-obj : (not/c #f)
> > pos-left : exact-nonnegative-integer?
> > pos-right : exact-nonnegative-integer?
> > str : string?

> Called to indicate that the message in str should be shown when the mouse passes over the given position.

> > > method

> > > (send a-syncheck-annotations syncheck:add-jump-to-definition |
> > > |  | source-obj |
> > > |  | start |
> > > |  | end |
> > > |  | id |
> > > |  | filename |
> > > |  | submods) |

> > → void?
> > source-obj : (not/c #f)
> > start : exact-nonnegative-integer?
> > end : exact-nonnegative-integer?
> > id : any/c
> > filename : path-string?
> > submods : (listof symbol?)

> 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).

> > > method

> > > (send a-syncheck-annotations syncheck:add-definition-target |
> > > |  | source-obj |
> > > |  | start |
> > > |  | finish |
> > > |  | style-name) |

> > → void?
> > source-obj : (not/c #f)
> > start : exact-nonnegative-integer?
> > finish : exact-nonnegative-integer?
> > style-name : any/c

> > > method

> > > (send a-syncheck-annotations syncheck:color-range |  | source-obj |
> > > |  | start |
> > > |  | finish |
> > > |  | style-name |
> > > |  | mode) |

> > → void?
> > source-obj : (not/c #f)
> > start : exact-nonnegative-integer?
> > finish : exact-nonnegative-integer?
> > style-name : any/c
> > mode : any/c

> 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).

> > > method

> > > (send a-syncheck-annotations syncheck:add-rename-menu |
> > > |  | id |
> > > |  | all-ids |
> > > |  | new-name-interferes?) |

> > → void?
> > id : symbol?

> > all-ids

> > :

> > (listof (list/c (not/c #f)
> > exact-nonnegative-integer?
> > exact-nonnegative-integer?))

> > new-name-interferes? : (-> symbol boolean?)

> This method is listed only for backwards compatibility. It is not called directly by check syntax, but it is called by the default implementation of syncheck:add-rename-menu in annotations-mixin.

> mixin

> annotations-mixin : (class? . -> . class?)

result implements: | syncheck-annotations<%>

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.

By default:

- The syncheck:find-source-object method ignores its arguments and returns #f;

- the syncheck:add-id-set manufactures a symbol and then passes that and its arguments to syncheck:add-rename-menu (this is for backwards compatibility – the syncheck:add-rename-menu is not called directly by Check Syntax anymore; the syncheck:add-id-set calls it instead); and

- all of the other methods ignore their arguments and return (void).

Here is an example showing how use this library to extract all of the arrows that Check Syntax would draw from various expressions:

> > (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 start-source-obj
> start-left
> start-right
> end-source-obj
> end-left
> end-right
> actual?
> phase-level)
> (set! arrows
> (cons (list start-source-obj end-source-obj)
> arrows)))
> (define arrows '())
> (define/public (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 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)))
> '((#<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))
> '()

> > syntax

> > syncheck:find-source-object

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-background-color

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-require-open-menu

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-docs-menu

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-rename-menu

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-arrow

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-tail-arrow

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-mouse-over-status

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-jump-to-definition

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:add-id-set

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

> > syntax

> > syncheck:color-range

Bound to an identifier created with define-local-member-name that is used in syncheck-annotations<%>.

#### 8.2`` Check Syntax Button

(require drracket/syncheck-drracket-button)

> > value

> > syncheck-drracket-button

> > :

> > (list/c
> > string?
> > (is-a?/c bitmap%)
> > (-> (is-a?/c
> > top-level-window<%>)
> > any))

This is meant to be used with the 'drracket:toolbar-buttons argument to the info proc returned from read-language.

> > syntax

> > syncheck:button-callback

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.

> > value

> > syncheck-bitmap : (is-a?/c bitmap%)

The bitmap in the Check Syntax button on the DrRacket frame.

#### 8.3`` Disappeared Uses and Bindings

Check Syntax collects the values of the syntax-propertys named 'disappeared-use and 'disappeared-binding and uses them to add additional arrows to the program text. These properties are intended for use when a macro discards 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.

> (define-syntax (m stx)
> (syntax-case stx ()
> [(_ id1 id2)
> (and (identifier? #'id1) (identifier? #'id2))
> (syntax-property
> (syntax-property
> #'1
> 'disappeared-use (list (syntax-local-introduce #'id1)))
> 'disappeared-binding (list (syntax-local-introduce #'id2)))]))

See also current-recorded-disappeared-uses.

top ← prev up next →