Skip to content

Commit 7c8a399

Browse files
Copilotjackfirth
andcommitted
Add source-syntax-paths function to filter syntax paths by line ranges
Co-authored-by: jackfirth <[email protected]>
1 parent 64f3cd1 commit 7c8a399

File tree

1 file changed

+46
-1
lines changed

1 file changed

+46
-1
lines changed

private/source.rkt

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
[source-can-expand? (-> source? boolean?)]
2020
[source-text-of (-> source? syntax? immutable-string?)]
2121
[source-comment-locations (-> source? immutable-range-set?)]
22+
[source-syntax-paths (->* (source?) (range-set?) sorted-set?)]
2223
[file-source? (-> any/c boolean?)]
2324
[file-source (-> path-string? file-source?)]
2425
[file-source-path (-> file-source? path?)]
@@ -37,11 +38,14 @@
3738
racket/path
3839
racket/port
3940
rebellion/base/immutable-string
41+
resyntax/private/linemap
4042
resyntax/private/syntax-neighbors
43+
resyntax/private/syntax-path
4144
syntax/modread
4245
rebellion/base/comparator
4346
rebellion/base/range
4447
rebellion/collection/range-set
48+
rebellion/collection/sorted-set
4549
rebellion/collection/vector/builder
4650
rebellion/streaming/transducer
4751
syntax-color/lexer-contract
@@ -149,7 +153,32 @@
149153
(define valid-mod (modified-source orig "#lang racket/base\n(define foo 43)"))
150154
(define invalid-mod (modified-source orig "#lang racket/base\n(if)"))
151155
(check-true (source-can-expand? valid-mod))
152-
(check-false (source-can-expand? invalid-mod))))
156+
(check-false (source-can-expand? invalid-mod)))
157+
158+
(test-case "source-syntax-paths"
159+
;; Test with all lines (unbounded range)
160+
(define test-source (string-source "#lang racket/base\n(define x 42)\n(define y 99)"))
161+
(define all-paths (source-syntax-paths test-source))
162+
(check-true (sorted-set? all-paths))
163+
;; Should have multiple paths since there are multiple forms
164+
(check-true (> (sorted-set-size all-paths) 0))
165+
166+
;; Test with specific line range - just line 2 which has (define x 42)
167+
(define line2-range (range-set (closed-range 2 2 #:comparator natural<=>)))
168+
(define line2-paths (source-syntax-paths test-source line2-range))
169+
(check-true (sorted-set? line2-paths))
170+
;; Should have fewer paths than all-paths
171+
(check-true (< (sorted-set-size line2-paths) (sorted-set-size all-paths)))
172+
173+
;; Test with a line range that includes multiple forms
174+
(define lines23-range (range-set (closed-range 2 3 #:comparator natural<=>)))
175+
(define lines23-paths (source-syntax-paths test-source lines23-range))
176+
(check-true (>= (sorted-set-size lines23-paths) (sorted-set-size line2-paths)))
177+
178+
;; Test with no overlapping lines (e.g., line 100)
179+
(define no-overlap-range (range-set (closed-range 100 100 #:comparator natural<=>)))
180+
(define no-overlap-paths (source-syntax-paths test-source no-overlap-range))
181+
(check-equal? (sorted-set-size no-overlap-paths) 0)))
153182

154183

155184
(define (source-expand code)
@@ -195,6 +224,22 @@
195224
#:into (into-range-set natural<=>)))
196225

197226

227+
(define (source-syntax-paths src [lines (range-set (unbounded-range #:comparator natural<=>))])
228+
(define program-stx (source-read-syntax src))
229+
(define linemap (string-linemap (source->string src)))
230+
(sorted-set->immutable-sorted-set
231+
(transduce (in-syntax-paths program-stx)
232+
(filtering
233+
(λ (path)
234+
(define stx (syntax-ref program-stx path))
235+
;; Only include paths with source location information
236+
(and (syntax-position stx)
237+
(syntax-span stx)
238+
(let ([stx-lines (syntax-line-range stx #:linemap linemap)])
239+
(range-set-overlaps? lines stx-lines)))))
240+
#:into (into-sorted-set syntax-path<=>))))
241+
242+
198243
(struct lexical-token (text start end type delimiter-kind attributes) #:transparent)
199244

200245

0 commit comments

Comments
 (0)