stx-patching-srcloc.scrbl (3655B)
1 #lang scribble/manual 2 @require[racket/require 3 "utils.rkt" 4 @for-label[phc-toolkit/stx]] 5 6 @(def-orig typed [phc-toolkit/stx] 7 stx-assoc 8 identifier->string 9 identifier→string 10 quasisyntax/top-loc 11 syntax/top-loc 12 quasisyntax/whole-loc 13 syntax/whole-loc) 14 15 @title{Patching source locations} 16 17 @(declare-exporting phc-toolkit/stx 18 #:use-sources 19 [(lib "phc-toolkit/stx/fold.rkt")]) 20 21 @defform[(quasisyntax/top-loc stx-expr quasitemplate)]{ 22 Like @racket[(quasisyntax/loc stx-expr quasitemplate)], but the source 23 location for all "top" parts of the resulting syntax object are updated, so 24 long as their source location is the same as the source location for the 25 topmost part of the @racket[quasitemplate]. 26 27 In other words, this does a traversal of the syntax object and updates the 28 source location of the traversed parts, but the traversal does not go within a 29 part whose source file differs from that of the @racket[quasitemplate]. 30 31 For example, in the following code, the source location of parts within 32 @racket[user-code] will not be updated (unless @racket[user-code] originates 33 from the same file as @racket[quasitemplate]), but the source location of all 34 other parts will be updated, including the @racket[begin] identifier and its 35 surrounding form (its surrounding "pair of parentheses"). In contrast, 36 @racket[quasisyntax/loc] would have updated only the topmost syntax object, 37 i.e. the outermost "pair of parentheses" of the @racket[let] form. 38 39 @racketblock[(λ (stx) 40 (syntax-case stx () 41 [(_ . user-code) 42 (with-syntax ([bg #'(begin . user-code)]) 43 (quasisyntax/top-loc stx (let () bg)))]))]} 44 45 @defform[(syntax/top-loc stx-expr quasitemplate)]{ 46 Like @racket[(syntax/loc stx-expr quasitemplate)], but the source location 47 for all "top" parts of the resulting syntax object are updated, like is done 48 by @racket[quasisyntax/top-loc].} 49 50 51 @defform[(quasisyntax/whole-loc stx-expr quasitemplate)]{ 52 53 Like @racket[(quasisyntax/top-loc stx-expr quasitemplate)], but the source 54 location for all parts of the resulting syntax object are updated if they 55 belong to the same source file as the @racket[quasitemplate], not only the 56 "top" ones. 57 58 In the following example, all parts of the syntax object which source file is 59 the same as the macro will be updated, including those within 60 @racket[user-code] (e.g. if the @racket[user-code] contains code generated by 61 other macros from the same file. 62 63 @racketblock[(λ (stx) 64 (syntax-case stx () 65 [(_ . user-code) 66 (with-syntax ([bg #'(begin . user-code)]) 67 (quasisyntax/whole-loc stx (let () bg)))]))] 68 69 This is usually not needed, as @racket[quasisyntax/top-loc] would have 70 updated the source location of @racket[1], @racket[2] and @racket[3] and their 71 surrounding syntax list (the "pair of parentheses" around them), since their 72 surrounding syntax list comes from the same file as the macro: 73 74 @racketblock[(λ (stx) 75 (syntax-case stx () 76 [(_ . user-function) 77 (quasisyntax/top-loc stx 78 (user-function 1 2 3))]))]} 79 80 @defform[(syntax/whole-loc stx-expr quasitemplate)]{ 81 Like @racket[(syntax/top-loc stx-expr quasitemplate)], but the source 82 location for all parts of the resulting syntax object are updated if they 83 belong to the same source file as the @racket[quasitemplate], not only the 84 "top" ones, like is done by @racket[quasisyntax/whole-loc].}