diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2021-09-07 21:19:11 +0200 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2021-09-13 12:31:10 +0200 |
| commit | 8531997d2a1e10d574a6e9ab70bc86ade6af4733 (patch) | |
| tree | 5c1cdaff85b4cba539fe84ba5c3c87fb9217408e | |
| parent | 10c981b1355df694b277a812cd8beb7cd60d1ea6 (diff) | |
packages: Add 'package-definition-location'.
Suggested by Maxime Devos <maximedevos@telenet.be>.
* guix/packages.scm (current-definition-location): New syntax parameter.
(define-public*): New macro.
(<package>)[definition-location]: New field.
(package-definition-location): New procedure.
* tests/packages.scm ("package-definition-location"): New test.
| -rw-r--r-- | guix/packages.scm | 48 | ||||
| -rw-r--r-- | tests/packages.scm | 11 |
2 files changed, 58 insertions, 1 deletions
diff --git a/guix/packages.scm b/guix/packages.scm index 01de50ebd73..ad7937b4fb7 100644 --- a/guix/packages.scm +++ b/guix/packages.scm | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #:re-export (%current-system | 52 | #:re-export (%current-system |
| 53 | %current-target-system | 53 | %current-target-system |
| 54 | search-path-specification) ;for convenience | 54 | search-path-specification) ;for convenience |
| 55 | #:replace ((define-public* . define-public)) | ||
| 55 | #:export (content-hash | 56 | #:export (content-hash |
| 56 | content-hash? | 57 | content-hash? |
| 57 | content-hash-algorithm | 58 | content-hash-algorithm |
| @@ -99,6 +100,7 @@ | |||
| 99 | package-supported-systems | 100 | package-supported-systems |
| 100 | package-properties | 101 | package-properties |
| 101 | package-location | 102 | package-location |
| 103 | package-definition-location | ||
| 102 | hidden-package | 104 | hidden-package |
| 103 | hidden-package? | 105 | hidden-package? |
| 104 | package-superseded | 106 | package-superseded |
| @@ -385,6 +387,35 @@ one-indexed line numbers." | |||
| 385 | (location-line loc) | 387 | (location-line loc) |
| 386 | (location-column loc))))) | 388 | (location-column loc))))) |
| 387 | 389 | ||
| 390 | (define-syntax-parameter current-definition-location | ||
| 391 | ;; Location of the encompassing 'define-public'. | ||
| 392 | (const #f)) | ||
| 393 | |||
| 394 | (define-syntax define-public* | ||
| 395 | (lambda (s) | ||
| 396 | "Like 'define-public' but set 'current-definition-location' for the | ||
| 397 | lexical scope of its body." | ||
| 398 | (define location | ||
| 399 | (match (syntax-source s) | ||
| 400 | (#f #f) | ||
| 401 | (properties | ||
| 402 | (let ((line (assq-ref properties 'line)) | ||
| 403 | (column (assq-ref properties 'column))) | ||
| 404 | ;; Don't repeat the file name since it's redundant with 'location'. | ||
| 405 | ;; Encode the whole thing so that it fits in a fixnum on 32-bit | ||
| 406 | ;; platforms, which leaves us 29 bits: 7 bits for COLUMN (which is | ||
| 407 | ;; almost always zero), and 22 bits for LINE. | ||
| 408 | (and line column | ||
| 409 | (logior (ash (logand #x7f column) 22) | ||
| 410 | (logand (- (expt 2 22) 1) (+ 1 line)))))))) | ||
| 411 | |||
| 412 | (syntax-case s () | ||
| 413 | ((_ prototype body ...) | ||
| 414 | #`(define-public prototype | ||
| 415 | (syntax-parameterize ((current-definition-location | ||
| 416 | (lambda (s) #,location))) | ||
| 417 | body ...)))))) | ||
| 418 | |||
| 388 | ;; A package. | 419 | ;; A package. |
| 389 | (define-record-type* <package> | 420 | (define-record-type* <package> |
| 390 | package make-package | 421 | package make-package |
| @@ -430,7 +461,10 @@ one-indexed line numbers." | |||
| 430 | 461 | ||
| 431 | (location package-location-vector | 462 | (location package-location-vector |
| 432 | (default (current-location-vector)) | 463 | (default (current-location-vector)) |
| 433 | (innate) (sanitize sanitize-location))) | 464 | (innate) (sanitize sanitize-location)) |
| 465 | (definition-location package-definition-location-code | ||
| 466 | (default (current-definition-location)) | ||
| 467 | (innate))) | ||
| 434 | 468 | ||
| 435 | (set-record-type-printer! <package> | 469 | (set-record-type-printer! <package> |
| 436 | (lambda (package port) | 470 | (lambda (package port) |
| @@ -455,6 +489,18 @@ it is not known." | |||
| 455 | (#f #f) | 489 | (#f #f) |
| 456 | (#(file line column) (location file line column)))) | 490 | (#(file line column) (location file line column)))) |
| 457 | 491 | ||
| 492 | (define (package-definition-location package) | ||
| 493 | "Like 'package-location', but return the location of the definition | ||
| 494 | itself--i.e., that of the enclosing 'define-public' form, if any, or #f." | ||
| 495 | (match (package-definition-location-code package) | ||
| 496 | (#f #f) | ||
| 497 | (code | ||
| 498 | (let ((column (bit-extract code 22 29)) | ||
| 499 | (line (bit-extract code 0 21))) | ||
| 500 | (match (package-location-vector package) | ||
| 501 | (#f #f) | ||
| 502 | (#(file _ _) (location file line column))))))) | ||
| 503 | |||
| 458 | (define-syntax-rule (package/inherit p overrides ...) | 504 | (define-syntax-rule (package/inherit p overrides ...) |
| 459 | "Like (package (inherit P) OVERRIDES ...), except that the same | 505 | "Like (package (inherit P) OVERRIDES ...), except that the same |
| 460 | transformation is done to the package P's replacement, if any. P must be a bare | 506 | transformation is done to the package P's replacement, if any. P must be a bare |
diff --git a/tests/packages.scm b/tests/packages.scm index 2a290bc3539..3756877270e 100644 --- a/tests/packages.scm +++ b/tests/packages.scm | |||
| @@ -236,6 +236,17 @@ | |||
| 236 | (eq? item new))) | 236 | (eq? item new))) |
| 237 | (null? (manifest-transaction-remove tx))))))) | 237 | (null? (manifest-transaction-remove tx))))))) |
| 238 | 238 | ||
| 239 | (test-assert "package-definition-location" | ||
| 240 | (let ((location (package-location hello)) | ||
| 241 | (definition (package-definition-location hello))) | ||
| 242 | ;; Check for the usual layout of (define-public hello (package ...)). | ||
| 243 | (and (string=? (location-file location) | ||
| 244 | (location-file definition)) | ||
| 245 | (= 0 (location-column definition)) | ||
| 246 | (= 2 (location-column location)) | ||
| 247 | (= (location-line definition) | ||
| 248 | (- (location-line location) 1))))) | ||
| 249 | |||
| 239 | (test-assert "package-field-location" | 250 | (test-assert "package-field-location" |
| 240 | (let () | 251 | (let () |
| 241 | (define (goto port line column) | 252 | (define (goto port line column) |
