aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2022-08-02 02:09:50 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2022-09-18 22:53:57 +0200
commit41f2bafcb672f449c082ca9128f46adbd31289ca (patch)
treec10851ec15c50baf6422d6e856189d8c26805d0f
parentMove get-forms to module static-util. (diff)
downloadcalp-41f2bafcb672f449c082ca9128f46adbd31289ca.tar.gz
calp-41f2bafcb672f449c082ca9128f46adbd31289ca.tar.xz
Add library for staticly figuring out module deps.
-rw-r--r--scripts/module-uses.scm66
1 files changed, 66 insertions, 0 deletions
diff --git a/scripts/module-uses.scm b/scripts/module-uses.scm
new file mode 100644
index 00000000..220843b6
--- /dev/null
+++ b/scripts/module-uses.scm
@@ -0,0 +1,66 @@
+(define-module (module-uses)
+ :use-module (ice-9 match)
+ :export (module-uses*))
+
+;;; Commentary:
+;;; Static analyze version of guile's built in module-uses.
+;;; Will give a less accurate result, but in turn doesn't
+;;; require that the target module compiles.
+;;; Code:
+
+(define (parse-interface-specification interface-specification)
+ (match interface-specification
+ ;; matches `((srfi srfi-1) :select (something))
+ (((parts ...) args ...)
+ parts)
+ ;; matches `(srfi srfi-1)
+ ((parts ...)
+ parts)
+ (_ (error "Bad module declaration"))))
+
+;; Finds all define-module forms, and returns what they
+;; pull in (including autoloads)
+(define (module-declaration-uses forms)
+ (match forms
+ (('define-module module-name directives ...)
+ (let loop ((directives directives))
+ (cond ((null? directives) '())
+ ((memv (car directives) '(#:use-module #{:use-module}#))
+ (cons (parse-interface-specification (cadr directives))
+ (loop (cddr directives))))
+ ((memv (car directives) '(#:autoload #{:autoload}#))
+ (cons (cadr directives)
+ (loop (cdddr directives))))
+ (else (loop (cdr directives))))))
+ ((form forms ...)
+ (append (module-declaration-uses form)
+ (module-declaration-uses forms)))
+ (_ '())))
+
+;; find all use-modules forms, and return what they pull in
+(define (module-use-module-uses forms)
+ (match forms
+ (('use-modules modules ...)
+ (map parse-interface-specification modules))
+ ((form forms ...)
+ (append (module-use-module-uses form)
+ (module-use-module-uses forms)))
+ (_ '())))
+
+;; find all explicit module references (e.g.
+;; (@ (module) var) and (@@ (module) private-var)),
+;; and return those modules
+(define (module-refer-uses forms)
+ (match forms
+ (((or '@ '@@) module _) (list module))
+ ((form forms ...)
+ (append (module-refer-uses form)
+ (module-refer-uses forms)))
+ (_ '())))
+
+;; List of all modules pulled in in any of forms
+(define (module-uses* forms)
+ (append
+ (module-declaration-uses forms)
+ (module-use-module-uses forms)
+ (module-refer-uses forms)))