Used Imports
module->used-imports
multi-used-imports
8.12

Used Imports🔗ℹ

Laurent Orseau

This packages defines the raco command raco used-imports to analyze the provenance of identifiers within one or several modules. The API is also described below.

 (require used-imports) package: used-imports

Quick start: After installing, try on the command line:

raco used-imports syntax/parse

procedure

(module->used-imports mod)  hash?

  mod : module-path?
Returns a dictionary of symbols per imported module, where each symbol is used at least once in the module mod.

Suppose that file "mod1.rkt" contains the following code:
#lang racket/base
(require racket/string
         racket/format)
(string-split "abc def")
(~a 'abc)
Then (module->used-imports "mod1.rkt") returns:
(hash 'racket/base
      (set 'require 'quote)
 
      'racket/format
      (set '~a)
 
      'racket/string
      (set 'string-split))

Another example:
(module->used-imports 'syntax/parse)
; evaluates to:
(hash
 'racket/base
 (set 'syntax? 'for-syntax 'except-out 'identifier? 'symbol?
      'require 'provide 'string? 'begin-for-syntax)
 
 'racket/contract/base
 (set 'or/c 'struct-type-property/c 'any/c 'contract-out '->)
 
 'syntax/parse/private/pattern-expander
 (set 'pattern-expander)
 
 'syntax/parse/private/residual-ct
 (set
  'syntax-local-syntax-parse-pattern-introduce
  'prop:pattern-expander
  'prop:syntax-class
  'pattern-expander?)
 
 "parse/experimental/contract.rkt"
 (set 'expr/c)
 
 "parse/experimental/provide.rkt"
 (set 'provide-syntax-class/contract))

procedure

(multi-used-imports mods    
  [#:verbose? verbose?])  hash?
  mods : (listof module-path?)
  verbose? : boolean? = #f
For a list of modules (in the form of a file path or a module symbol like 'racket/string), returns a dictionary of dictionaries. The top level key is a module name that is imported by any of the modules mods (say, module A). The second level key is a module of mods (say, module B), and the values are the bindings (symbols) used in module B by module A.

If verbose? is true, information is displayed during the parsing of the files. The parsing (via check-syntax) can take a while, so it is useful to know if progress is being made.

Suppose that file "mod1.rkt" contains the following code:
#lang racket/base
(require racket/string
         racket/format)
(string-split "abc def")
(~a 'abc)
and that file "mod2.rkt" contains:
#lang racket/base
(require racket/string
         racket/list)
(string-split "abc def")
(first '(a b c))

Then (multi-used-imports '("mod1.rkt" "mod2.rkt")) evaluates to
(hash
'racket/base
(list (cons "mod2.rkt" (set 'require 'quote)) (cons "mod1.rkt" (set 'require 'quote)))
'racket/format
(list (cons "mod1.rkt" (set '~a)))
'racket/list
(list (cons "mod2.rkt" (set 'first)))
'racket/string
(list (cons "mod2.rkt" (set 'string-split)) (cons "mod1.rkt" (set 'string-split))))

The command

raco used-imports *.rkt

has the same effect, but the result is displayed in a more readable format.