diff --git a/doc-trace.rkt b/doc-trace.rkt index e4577c9..20f922f 100644 --- a/doc-trace.rkt +++ b/doc-trace.rkt @@ -9,6 +9,7 @@ "service/definition.rkt" "service/diagnostic.rkt" "service/declaration.rkt" + "service/project-references.rkt" "service/highlight.rkt") (define build-trace% @@ -21,6 +22,7 @@ (define definitions (new definition% [src src])) (define diag (new diag% [src src] [doc-text doc-text])) (define decls (new declaration%)) + (define project-references (new project-references% [src src])) (define semantic-tokens (new highlight% [src src] [doc-text doc-text])) (define services @@ -67,6 +69,7 @@ (define/public (get-definitions) (send definitions get)) (define/public (get-quickfixs) (cadr (send diag get))) (define/public (get-semantic-tokens) (send semantic-tokens get)) + (define/public (get-nonlocal-references uri symbol) (find-nonlocal-references uri symbol)) ;; Overrides (define/override (syncheck:find-source-object stx) diff --git a/service/declaration.rkt b/service/declaration.rkt index f0a4f2c..8523ba2 100644 --- a/service/declaration.rkt +++ b/service/declaration.rkt @@ -60,7 +60,8 @@ (define/override (syncheck:add-jump-to-definition _src-obj start end id filename _submods) (define decl (Decl filename id 0 0)) ;; NOTE start <= end. In some situations, it may be that start = end. - (interval-map-set! sym-bindings start (if (= start end) (add1 end) end) decl)) + (define end- (if (= start end) (add1 end) end)) + (interval-map-set! sym-bindings start end- decl)) (define/override (syncheck:add-arrow/name-dup _start-src-obj start-left start-right _end-src-obj end-left end-right diff --git a/service/project-references.rkt b/service/project-references.rkt new file mode 100644 index 0000000..d52bdf3 --- /dev/null +++ b/service/project-references.rkt @@ -0,0 +1,41 @@ +#lang racket/base + +(require "interface.rkt" + "../struct.rkt" + racket/class + racket/set + racket/file + racket/path + drracket/check-syntax) + +(provide project-references% + find-nonlocal-references) + +(define (project-files) + (define files (mutable-set)) + + ;; FIXME: use loaded sufficies + ;; FIXME: use workspace folders + (for ([path (find-files (lambda (path) (path-has-extension? path #".rkt")) (current-directory))]) + (set-add! files (path->complete-path path))) + + files) + +(define projectwise-references (make-hash)) +(define (find-nonlocal-references uri symbol) + (hash-ref projectwise-references (list uri symbol))) + +(define project-references% + (class base-service% + (init-field src) + (super-new) + + (define/override (syncheck:add-jump-to-definition _src-obj start end id filename _submods) + ;; NOTE start <= end. In some situations, it may be that start = end. + (define end- (if (= start end) (add1 end) end)) + (when (set-member? (project-files) filename) + (println "Reference to other file!") + (hash-update! projectwise-references + (list filename id) + (lambda (refs) (set-add refs (list src start end-))) + (set)))))) diff --git a/text-document.rkt b/text-document.rkt index 06ee2a0..74d10c0 100644 --- a/text-document.rkt +++ b/text-document.rkt @@ -404,10 +404,13 @@ (define doc-decls (send doc-trace get-sym-decls)) (match-define (Decl req? id left right) decl) + + (define nonlocal-refs (send doc-trace get-nonlocal-references uri id)) + (define-values (bind-start bind-end bindings) (interval-map-ref/bounds doc-decls left #f)) (if bindings - (for/list ([range (in-set bindings)]) + (for/list ([range (in-set (set-union bindings nonlocal-refs))]) (start/end->range doc (car range) (cdr range))) empty)))) diff --git a/workspace.rkt b/workspace.rkt index 1e73841..f8cc2f7 100644 --- a/workspace.rkt +++ b/workspace.rkt @@ -3,7 +3,8 @@ didChangeWorkspaceFolders didChangeWatchedFiles didChangeConfiguration - update-configuration) + update-configuration + workspace-folders) (require compiler/module-suffix) (require "json-util.rkt" "doc.rkt"