racket-langserver
racket-langserver copied to clipboard
Cross-file goto references
The current racket-langserver supporting goto references in the same file, but references in others file won't be listed.
A reimagined version looks like this:
#lang racket
;; 3 symbol levels
;; 1. workspace level
;; it's defined in a module and used by other modules,
;; identified by (list module name) or (list module location)
;; 2. file level
;; it's a top level symbol in a module,
;; identified by (list module name) or (list module location)
;; 3. local level
;; it's a local symbol, identified by (list module location)
;; module -> location -> (listof location)
(define (goto-reference mod pos)
(define symbol-info (get-symbol-info-at pos))
(if (imported? symbol-info)
(get-workspace-refs (source-mod symbol-info) (source-name symbol-info))
(get-local-refs mod pos)))
;; module -> symbol -> (listof location)
;; get cross files locations
(define (get-workspace-refs mod name)
(for*/list ([mod (get-all-used-mods mod name)]
[refs (get-file-refs mod name)]
[ref refs])
ref))
;; TODO: module -> location -> (listof location)
(define (get-local-refs mod pos) #f)
;; TODO: module -> symbol -> (listof module)
(define (get-all-used-mods mod name) #f)
;; TODO: info -> module
(define (source-mod info) #f)
;; TODO: info -> symbol
(define (source-name info) #f)
;; TODO: module -> symbol -> (listof location)
(define (get-file-refs mod name) #f)
;; TODO: position -> info
(define (get-symbol-info-at pos) #f)
;; TODO: info -> boolean
(define (imported? info) #f)
I think maintain a dependency graph will help, since the changes to the graph usually small (add/delete a file)
The considered help case is: only seek usage in user modules of current file.
I think so
An over simple test about using concurrency vs parallelism for file checking, one can pick arbitrary test-dir, I use racket-langserver itself as target.
- Sequential: ~8.5sec
- Concurrency: ~10.9sec (racket thread)
- Parallelism: ~4.2sec (racket place)
Main file
(require drracket/check-syntax)
(require racket/place/dynamic)
(time
(for ([x (in-directory "test-dir")])
(when (path-has-extension? x #".rkt")
(show-content x)))
)
; cpu time: 8355 real time: 8519 gc time: 1488
(time
(define ts (for/list ([x (in-directory "test-dir")])
(thread
(lambda ()
(when (path-has-extension? x #".rkt")
(show-content x))))))
(for ([t ts])
(thread-wait t))
)
; cpu time: 10755 real time: 10981 gc time: 3128
(time
(let ([pls (for/list ([_ (in-range 8)])
(dynamic-place "worker.rkt" 'place-main))]
[xs (in-directory "test-dir")])
(for ([x xs]
#:when (path-has-extension? x #".rkt")
[i (in-range (length (sequence->list xs)))])
(define idx (modulo i 8))
(define p (list-ref pls idx))
(place-channel-put p x)
)
(map place-wait pls))
)
; cpu time: 22968 real time: 4244 gc time: 7687
worker.rkt
(provide place-main)
(require drracket/check-syntax)
(define (place-main pch)
(show-content (place-channel-get pch))
(place-channel-put pch 'done))