racket/collects/syntax/location.rkt

93 lines
3.1 KiB
Racket

#lang racket/base
(require syntax/srcloc
(for-syntax racket/base syntax/srcloc setup/path-to-relative))
(provide (protect-out module-name-fixup)
quote-srcloc
quote-source-file
quote-line-number
quote-column-number
quote-character-position
quote-character-span
quote-module-path
quote-module-name)
(define-syntax (quote-srcloc stx)
(syntax-case stx ()
[(_) #`(quote-srcloc #,stx)]
[(_ loc)
(let* ([src (build-source-location #'loc)])
(cond
[(and (path-string? (srcloc-source src))
(path->relative-string/library (srcloc-source src) #f))
=>
(lambda (rel)
(with-syntax ([src rel]
[line (srcloc-line src)]
[col (srcloc-column src)]
[pos (srcloc-position src)]
[span (srcloc-span src)])
#'(make-srcloc 'src 'line 'col 'pos 'span)))]
[else (with-syntax ([loc (identifier-prune-to-source-module
(datum->syntax #'loc 'loc #'loc #'loc))])
#'(build-source-location (quote-syntax loc)))]))]))
(define-syntax-rule (define-quote-srcloc-accessors [name accessor] ...)
(define-syntaxes [ name ... ]
(values
(lambda (stx)
(syntax-case stx ()
[(_) #`(name #,stx)]
[(_ loc) #`(accessor (quote-srcloc loc))]))
...)))
(define-quote-srcloc-accessors
[quote-source-file source-location-source]
[quote-line-number source-location-line]
[quote-column-number source-location-column]
[quote-character-position source-location-position]
[quote-character-span source-location-span])
(define-syntax-rule (module-source)
(variable-reference->module-source
(#%variable-reference)))
(define-syntax (quote-module-name stx)
(syntax-case stx ()
[(_) #'(module-name-fixup (module-source) null)]
[(_ "." path ...) #'(module-name-fixup (module-source) (list path ...))]
[(_ ".." path ...) #'(module-name-fixup (module-source) (list ".." path ...))]
[(_ path ...) #'(module-name-fixup null (list path ...))]))
(define (module-name-fixup src path)
(or
(cond
[(null? path) src]
[(list? src) (append src path)]
[else (append (list src) path)])
'top-level))
(define-syntax (quote-module-path stx)
(syntax-case stx ()
[(_) #'(module-path-fixup (module-source) null)]
[(_ "." path ...) #'(module-path-fixup (module-source) (list path ...))]
[(_ ".." path ...) #'(module-path-fixup (module-source) (list ".." path ...))]
[(_ path ...) #'(module-path-fixup null (list path ...))]))
(define (module-path-fixup src path)
(define (map-path->string l)
(for/list ([i l])
(cond
[(path? i) (path->bytes i)]
[else i])))
(define (last-pass src)
(cond
[(path? src) `(file ,(path->bytes src))]
[(symbol? src) `(quote ,src)]
[(list? src) (map-path->string `(submod ,@src))]
[else 'top-level]))
(last-pass
(cond
[(null? path) src]
[(list? src) (append src path)]
[else (append (list src) path)])))