[racket] identifier-binding source-id vs. nominal-source-id

From: Greg Hendershott (greghendershott at gmail.com)
Date: Tue Jul 22 15:50:57 EDT 2014

So for racket-mode I have a visit-definition feature. It takes you to
the definition of the symbol at point.

I'm using identifier-binding to find the file and name, then I
read-syntax the file and use syntax-case* to find the identifier, and
use its syntax srcloc.

The only issue I'm experiencing is what seems to be inconsistency (for
my purposes) in what identifier-binding reports. Code below.
Paraphrase:

For a plain provide, source-id = nominal-source-id. Great.

For a rename-out, the original definition name is source-id, and
nominal-source-id is the rename. Great.

For a define/contract, plus plain provide, same thing.

So far it seems like source-id is the definition name. Cool!

For (provide (contract-out)) --- bzzzzzt.  Now source-id is the name
of the wrapped thing (e.g. 'provide/contract-id-pc.9), and
nominal-source-id is the original definition name.  Huh?? This seems
backwards.

And worst of all is (provide (contract-out rename old new contract))
-- both a contract and a rename. In this case source-id is the
contract wrapper, nominal-source-id is the rename, and the original
definition name is... absent.  (Well, I have it -- maybe -- from the
user's symbol at point in the Emacs buffer.)

I have a sad.

I suppose I could try all 3 possibilities -- source-id,
nominal-source-id, and the symbol at point from the Emacs buffer --
until one (or none) succeeds. Is that my least-worst option?


-=-=-=-=-=-=-=-

;;; provide.rkt
#lang racket

(define (f)
  0)
(provide f)

(define (-r)
  0)
(provide (rename-out [-r r]))

(define/contract (dc)
  (-> any)
  0)
(provide dc)

(define (pc)
  0)
(provide (contract-out [pc (-> any)]))

(define (-pcr)
  0)
(provide (contract-out [rename -pcr pcr (-> any)]))

;;; some-other-file.rkt
#lang racket
(require "provide.rkt")
(pretty-print
 (for/list ([sym '(f r dc pc pcr)])
   (match (identifier-binding (namespace-symbol->identifier sym))
     [(list source-mpi source-id
            nominal-source-mpi nominal-source-id
            source-phase import-phase nominal-export-phase)
      (list sym "source" source-id "nominal" nominal-source-id)])))

;; ==>
;; '((f "source" f "nominal" f)
;;   (r "source" -r "nominal" r)
;;   (dc "source" dc "nominal" dc)
;;   (pc "source" provide/contract-id-pc.9 "nominal" pc)
;;   (pcr "source" provide/contract-id-pcr.13 "nominal" pcr))

-=-=-=-=-=-=-=-

p.s. This is re https://github.com/greghendershott/racket-mode/issues/39

Posted on the users mailing list.