Skip to content

Instantly share code, notes, and snippets.

@greghendershott
Last active January 30, 2020 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save greghendershott/5dd59c00f8daa2ce0987ad343244489e to your computer and use it in GitHub Desktop.
Save greghendershott/5dd59c00f8daa2ce0987ad343244489e to your computer and use it in GitHub Desktop.

I am seeing a problem where drracket/check-syntax show-content returns bad pathnames in syncheck:add-jump-to-definition items. It seems to happen only requires of relative path names.

Given a.rkt and b.rkt in the same dir:

#lang racket/base
(require "b.rkt")
provided-by-b
#lang racket/base
(define provided-by-b 42)
(provide provided-by-b)

And check.rkt:

#lang racket/base
(require drracket/check-syntax)
(show-content "/tmp/a.rkt")

Then doing `racket check.rkt`will print a list of syncheck: items that are fine, except one which is not – the path should be /tmp/b.rkt not /tmp/a.rkt/b.rkt:

#(syncheck:add-jump-to-definition 36 49 provided-by-b #<path:/tmp/a.rkt/b.rkt> ())

Huh?

Next, I temporarily hack drracket/private/syncheck/traversals.rkt to println its local variables:

;; get-require-filename : sexp-or-module-path-index namespace string[directory] -> filename or #f
;; finds the filename corresponding to the require in stx
(define (get-require-filename datum user-namespace user-directory)
  (parameterize ([current-namespace user-namespace]
                 [current-directory (or user-directory (current-directory))]
                 [current-load-relative-directory user-directory])
    (define mpi
      (with-handlers ([exn:fail? (λ (x) #f)])
        (cond
          [(module-path-index? datum)
           (module-path-index-resolve datum)]
          [else
           ((current-module-name-resolver) datum #f #f #t)])))
    (define rkt-path/mod-path (and mpi (resolved-module-path-name mpi)))
    (define rkt-path/f (cond
                         [(path? rkt-path/mod-path) rkt-path/mod-path]
                         [(and (pair? rkt-path/mod-path)
                               (path? (car rkt-path/mod-path)))
                          (car rkt-path/mod-path)]
                         [else #f]))
    (define rkt-submods (cond
                          [(not rkt-path/mod-path) #f]
                          [(or (symbol? rkt-path/mod-path) (path? rkt-path/mod-path)) '()]
                          [(pair? rkt-path/mod-path) (cdr rkt-path/mod-path)]))
    (define cleaned-up-path
      (let/ec k
        (unless (path? rkt-path/f) (k rkt-path/f))
        (when (file-exists? rkt-path/f) (k rkt-path/f))
        (let* ([bts (path->bytes rkt-path/f)]
               [len (bytes-length bts)])
          (unless (and (len . >= . 4) 
                       (bytes=? #".rkt" (subbytes bts (- len 4))))
            (k rkt-path/f))
          (let ([ss-path (bytes->path (bytes-append (subbytes bts 0 (- len 4)) #".ss"))])
            (unless (file-exists? ss-path)
              (k rkt-path/f))
            ss-path))))
    ;;;;;;;;;;;;;;;;;;;;;;; HACK ;;;;;;;;;;;;;;;;
    (println (list (current-module-name-resolver) (current-directory) (current-load-relative-directory) datum mpi rkt-path/mod-path rkt-path/f cleaned-up-path))
    ;;;;;;;;;;;;;;;;;;;;;;; HACK ;;;;;;;;;;;;;;;;
    (values cleaned-up-path rkt-submods)))

And again do racket check.rkt, it prints:

'(#<procedure:standard-module-name-resolver> #<path:/tmp/a.rkt/> #<path:/tmp/a.rkt> racket/base #<resolved-module-path:"/home/greg/racket/7.3/collects/racket/base.rkt"> #<path:/home/greg/racket/7.3/collects/racket/base.rkt> #<path:/home/greg/racket/7.3/collects/racket/base.rkt> #<path:/home/greg/racket/7.3/collects/racket/base.rkt>)

'(#<procedure:standard-module-name-resolver> #<path:/tmp/a.rkt/> #<path:/tmp/a.rkt> "b.rkt" #f #f #f #f)

;; Here is the item where it seems to go wrong:
'(#<procedure:standard-module-name-resolver>
  #<path:/tmp/a.rkt/>
  #<path:/tmp/a.rkt>
  #<module-path-index:"b.rkt" + '|expanded module|> ;datum
  #<resolved-module-path:"/tmp/a.rkt/b.rkt">        ;mpi
  #<path:/tmp/a.rkt/b.rkt>
  #<path:/tmp/a.rkt/b.rkt>
  #<path:/tmp/a.rkt/b.rkt>)

'(#<procedure:standard-module-name-resolver> #<path:/tmp/a.rkt/> #<path:/tmp/a.rkt> #<module-path-index:"reqprov.rkt" "pre-base.rkt" "private/base.rkt" racket/base> #<resolved-module-path:"/home/greg/racket/7.3/collects/racket/private/reqprov.rkt"> #<path:/home/greg/racket/7.3/collects/racket/private/reqprov.rkt> #<path:/home/greg/racket/7.3/collects/racket/private/reqprov.rkt> #<path:/home/greg/racket/7.3/collects/racket/private/reqprov.rkt>)

Interestingly, when I try a.rkt and b.rkt in DrRacket, it jumps to /tmp/b.rkt correctly! IIUC it uses the same code in traversals.rkt. So, this seems to be a problem not in traversals.rkt, per se, but in how the drracket/check-syntax “wrapper” sets it up to be used. I think??

Any ideas what is going on?

What does #<module-path-index:"b.rkt" + '|expanded module|> mean, and how/why does that result in #<resolved-module-path:"/tmp/a.rkt/b.rkt">?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment