-
Notifications
You must be signed in to change notification settings - Fork 2
Fix duplicated completion candidates to solve #6 #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Well, I don't think you can use ordered-dedupe here... because the result of find-available-references is not ordered. |
Thank you for the valuable feedback. You're absolutely right that we need to focus on the root cause rather than applying temporary patches. After analyzing the Root Cause AnalysisThe core problem could be in For debug usage, I restructure the first case of the function [(document current-index-node)
(let* ([local (index-node-references-import-in-this-node current-index-node)]
[local-identifiers (map identifier-reference-identifier local)]
[exclude (index-node-excluded-references current-index-node)]
[parent-refs (if (null? (index-node-parent current-index-node))
(document-ordered-reference-list document)
(find-available-references-for document (index-node-parent current-index-node)))]
[filtered-parent-refs (filter
(lambda (reference)
(not (member (identifier-reference-identifier reference) local-identifiers)))
parent-refs)]
[combined-refs (append local filtered-parent-refs)])
(with-output-to-file "debug-ref-sources.log"
(lambda ()
(display "=== Reference Sources Debug ===\n")
(display (format "Local refs count: ~a\n" (length local)))
(display (format "Parent refs count: ~a\n" (length parent-refs)))
(display (format "Filtered parent refs count: ~a\n" (length filtered-parent-refs)))
(display (format "Combined refs count: ~a\n" (length combined-refs)))
(display (format "Final refs count after exclude filter: ~a\n"
(length (filter (lambda (reference) (not (member reference exclude))) combined-refs))))
(display "\nLocal ref identifiers (first 10):\n")
(let loop ([refs local] [count 0])
(if (and (not (null? refs)) (< count 10))
(begin
(display (format " ~a\n" (identifier-reference-identifier (car refs))))
(loop (cdr refs) (+ count 1)))))
(display "\nParent ref identifiers (first 10):\n")
(let loop ([refs parent-refs] [count 0])
(if (and (not (null? refs)) (< count 10))
(begin
(display (format " ~a\n" (identifier-reference-identifier (car refs))))
(loop (cdr refs) (+ count 1)))))
(display "\n"))
'append)
(filter
(lambda (reference) (not (member reference exclude)))
combined-refs))] Based on the log, I assume the following reasons: 1. Exponential Reference Multiplication
Evidence from Debug Log:
Results growing from ~1,575 → 2,265 → 10,412 references per call. Also, this could be the reason why the server repeatedly cancels/timeouts some requests of {"jsonrpc":"2.0","id":20,"method":"textDocument/documentSymbol","params":{"textDocument":{"uri":"file:///home/dez/scheme-langserver/test.ss"}}}
{"jsonrpc":"2.0","id":19,"result":[{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"
{"jsonrpc":"2.0","id":19,"error":{"code":-32800,"message":"textDocument\/documentSymbol"}}
{"jsonrpc":"2.0","method":"$/cancelRequest","params":{"id":20}} 2. Ineffective Deduplication Strategy
Evidence from Debug Log:
The analysis may not be correct and needs to be explored deeper, but this is what I can find out so far, and no ideal/effective fix yet. |
You should minimize your |
Fix: fix duplicated reference in one index-node
The original duplications appear both in Logs of showing {"jsonrpc":"2.0","id":20,"method":"textDocument/documentSymbol","params":{"textDocument":{"uri":"file:///home/dez/scheme-langserver/test.ss"}}}
{"jsonrpc":"2.0","id":19,"result":[{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}},{"name":"x","kind":13,"range":{"start":{"line":4,"character":16}," Logs of showing {"jsonrpc":"2.0","id":4,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///home/dez/scheme-langserver/test.ss"},"position":{"line":13,"character":12},"context":{"triggerKind":1}}}
{"jsonrpc":"2.0","id":4,"result":[{"label":"brobroken","insertText":"n","sortText":"brobroken"},{"label":"brobroken","insertText":"n","sortText":"brobroken"},{"label":"brobroken","insertText":"n","sortText":"brobroken"}]} The problem should be resolved by ending with {"jsonrpc":"2.0","id":3,"result":[{"label":"b","insertText":"","sortText":"b"},{"label":"base-exception-handler","insertText":"ase-exception-handler","sortText":"base-exception-handler"},{"label":"begin","insertText":"egin","sortText":"begin"},{"label":"bignum?","insertText":"ignum?","sortText":"bignum?"},{"label":"binary-port-input-buffer","insertText":"inary-port-input-buffer","sortText":"binary-port-input-buffer"},{"label":"binary-port-input-count","insertText":"inary-port-input-count","sortText":"binary-port-input-count"},{"label":"binary-port-input-index","insertText":"inary-port-input-index","sortText":"binary-port-input-index"},{"label":"binary-port-input-size","insertText":"inary-port-input-size","sortText":"binary-port-input-size"},{"label":"binary-port-output-buffer","insertText":"inary-port-output-buffer","sortText":"binary-port-output-buffer"},{"label":"binary-port-output-count","insertText":"inary-port-output-count","sortText":"binary-port-output-count"},{"label":"binary-port-output-index","insertText":"inary-port-output-index","sortText":"binary-port-output-index"},{"label":"binary-port-output-size","insertText":"inary-port-output-size","sortText":"binary-port-output-size"},{"label":"binary-port?","insertText":"inary-port?","sortText":"binary-port?"},{"label":"bitwise-and","insertText":"itwise-and","sortText":"bitwise-and"},{"label":"bitwise-arithmetic-shift","insertText":"itwise-arithmetic-shift","sortText":"bitwise-arithmetic-shift"},{"label":"bitwise-arithmetic-shift-left","insertText":"itwise-arithmetic-shift-left","sortText":"bitwise-arithmetic-shift-left"},{"label":"bitwise-arithmetic-shift-right","insertText":"itwise-arithmetic-shift-right","sortText":"bitwise-arithmetic-shift-right"},{"label":"bitwise-bit-count","insertText":"itwise-bit-count","sortText":"bitwise-bit-count"},{"label":"bitwise-bit-field","insertText":"itwise-bit-field","sortText":"bitwise-bit-field"},{"label":"bitwise-bit-set?","insertText":"itwise-bit-set?","sortText":"bitwise-bit-set?"},{"label":"bitwise-copy-bit","insertText":"itwise-copy-bit","sortText":"bitwise-copy-bit"},{"label":"bitwise-copy-bit-field","insertText":"itwise-copy-bit-field","sortText":"bitwise-copy-bit-field"},{"label":"bitwise-first-bit-set","insertText":"itwise-first-bit-set","sortText":"bitwise-first-bit-set"},{"label":"bitwise-if","insertText":"itwise-if","sortText":"bitwise-if"},{"label":"bitwise-ior","insertText":"itwise-ior","sortText":"bitwise-ior"},{"label":"bitwise-length","insertText":"itwise-length","sortText":"bitwise-length"},{"label":"bitwise-not","insertText":"itwise-not","sortText":"bitwise-not"},{"label":"bitwise-reverse-bit-field","insertText":"itwise-reverse-bit-field","sortText":"bitwise-reverse-bit-field"},{"label":"bitwise-rotate-bit-field","insertText":"itwise-rotate-bit-field","sortText":"bitwise-rotate-bit-field"},{"label":"bitwise-xor","insertText":"itwise-xor","sortText":"bitwise-xor"},{"label":"block-read","insertText":"lock-read","sortText":"block-read"},{"label":"block-write","insertText":"lock-write","sortText":"block-write"},{"label":"boolean=?","insertText":"oolean=?","sortText":"boolean=?"},{"label":"boolean?","insertText":"oolean?","sortText":"boolean?"},{"label":"bound-identifier=?","insertText":"ound-identifier=?","sortText":"bound-identifier=?"},{"label":"box","insertText":"ox","sortText":"box"},{"label":"box-cas!","insertText":"ox-cas!","sortText":"box-cas!"},{"label":"box-immutable","insertText":"ox-immutable","sortText":"box-immutable"},{"label":"box?","insertText":"ox?","sortText":"box?"},{"label":"break","insertText":"reak","sortText":"break"},{"label":"break-handler","insertText":"reak-handler","sortText":"break-handler"},{"label":"broken-function","insertText":"roken-function","sortText":"broken-function"},{"label":"buffer-mode","insertText":"uffer-mode","sortText":"buffer-mode"},{"label":"buffer-mode?","insertText":"uffer-mode?","sortText":"buffer-mode?"},{"label":"bwp-object?","insertText":"wp-object?","sortText":"bwp-object?"},{"label":"bytes-allocated","insertText":"ytes-allocated","sortText":"bytes-allocated"},{"label":"bytes-deallocated","insertText":"ytes-deallocated","sortText":"bytes-deallocated"},{"label":"bytevector","insertText":"ytevector","sortText":"bytevector"},{"label":"bytevector->immutable-bytevector","insertText":"ytevector->immutable-bytevector","sortText":"bytevector->immutable-bytevector"},{"label":"bytevector->s8-list","insertText":"ytevector->s8-list","sortText":"bytevector->s8-list"},{"label":"bytevector->sint-list","insertText":"ytevector->sint-list","sortText":"bytevector->sint-list"},{"label":"bytevector->string","insertText":"ytevector->string","sortText":"bytevector->string"},{"label":"bytevector->u8-list","insertText":"ytevector->u8-list","sortText":"bytevector->u8-list"},{"label":"bytevector->uint-list","insertText":"ytevector->uint-list","sortText":"bytevector->uint-list"},{"label":"bytevector-compress","insertText":"ytevector-compress","sortText":"bytevector-compress"},{"label":"bytevector-copy","insertText":"ytevector-copy","sortText":"bytevector-copy"},{"label":"bytevector-copy!","insertText":"ytevector-copy!","sortText":"bytevector-copy!"},{"label":"bytevector-fill!","insertText":"ytevector-fill!","sortText":"bytevector-fill!"},{"label":"bytevector-ieee-double-native-ref","insertText":"ytevector-ieee-double-native-ref","sortText":"bytevector-ieee-double-native-ref"},{"label":"bytevector-ieee-double-native-set!","insertText":"ytevector-ieee-double-native-set!","sortText":"bytevector-ieee-double-native-set!"},{"label":"bytevector-ieee-double-ref","insertText":"ytevector-ieee-double-ref","sortText":"bytevector-ieee-double-ref"},{"label":"bytevector-ieee-double-set!","insertText":"ytevector-ieee-double-set!","sortText":"bytevector-ieee-double-set!"},{"label":"bytevector-ieee-single-native-ref","insertText":"ytevector-ieee-single-native-ref","sortText":"bytevector-ieee-single-native-ref"},{"label":"bytevector-ieee-single-native-set!","insertText":"ytevector-ieee-single-native-set!","sortText":"bytevector-ieee-single-native-set!"},{"label":"bytevector-ieee-single-ref","insertText":"ytevector-ieee-single-ref","sortText":"bytevector-ieee-single-ref"},{"label":"bytevector-ieee-single-set!","insertText":"ytevector-ieee-single-set!","sortText":"bytevector-ieee-single-set!"},{"label":"bytevector-length","insertText":"ytevector-length","sortText":"bytevector-length"},{"label":"bytevector-s16-native-ref","insertText":"ytevector-s16-native-ref","sortText":"bytevector-s16-native-ref"},{"label":"bytevector-s16-native-set!","insertText":"ytevector-s16-native-set!","sortText":"bytevector-s16-native-set!"},{"label":"bytevector-s16-ref","insertText":"ytevector-s16-ref","sortText":"bytevector-s16-ref"},{"label":"bytevector-s16-set!","insertText":"ytevector-s16-set!","sortText":"bytevector-s16-set!"},{"label":"bytevector-s24-ref","insertText":"ytevector-s24-ref","sortText":"bytevector-s24-ref"},{"label":"bytevector-s24-set!","insertText":"ytevector-s24-set!","sortText":"bytevector-s24-set!"},{"label":"bytevector-s32-native-ref","insertText":"ytevector-s32-native-ref","sortText":"bytevector-s32-native-ref"},{"label":"bytevector-s32-native-set!","insertText":"ytevector-s32-native-set!","sortText":"bytevector-s32-native-set!"},{"label":"bytevector-s32-ref","insertText":"ytevector-s32-ref","sortText":"bytevector-s32-ref"},{"label":"bytevector-s32-set!","insertText":"ytevector-s32-set!","sortText":"bytevector-s32-set!"},{"label":"bytevector-s40-ref","insertText":"ytevector-s40-ref","sortText":"bytevector-s40-ref"},{"label":"bytevector-s40-set!","insertText":"ytevector-s40-set!","sortText":"bytevector-s40-set!"},{"label":"bytevector-s48-ref","insertText":"ytevector-s48-ref","sortText":"bytevector-s48-ref"},{"label":"bytevector-s48-set!","insertText":"ytevector-s48-set!","sortText":"bytevector-s48-set!"},{"label":"bytevector-s56-ref","insertText":"ytevector-s56-ref","sortText":"bytevector-s56-ref"},{"label":"bytevector-s56-set!","insertText":"ytevector-s56-set!","sortText":"bytevector-s56-set!"},{"label":"bytevector-s64-native-ref","insertText":"ytevector-s64-native-ref","sortText":"bytevector-s64-native-ref"},{"label":"bytevector-s64-native-set!","insertText":"ytevector-s64-native-set!","sortText":"bytevector-s64-native-set!"},{"label":"bytevector-s64-ref","insertText":"ytevector-s64-ref","sortText":"bytevector-s64-ref"},{"label":"bytevector-s64-set!","insertText":"ytevector-s64-set!","sortText":"bytevector-s64-set!"},{"label":"bytevector-s8-ref","insertText":"ytevector-s8-ref","sortText":"bytevector-s8-ref"},{"label":"bytevector-s8-set!","insertText":"ytevector-s8-set!","sortText":"bytevector-s8-set!"},{"label":"bytevector-sint-ref","insertText":"ytevector-sint-ref","sortText":"bytevector-sint-ref"},{"label":"bytevector-sint-set!","insertText":"ytevector-sint-set!","sortText":"bytevector-sint-set!"},{"label":"bytevector-truncate!","insertText":"ytevector-truncate!","sortText":"bytevector-truncate!"},{"label":"bytevector-u16-native-ref","insertText":"ytevector-u16-native-ref","sortText":"bytevector-u16-native-ref"},{"label":"bytevector-u16-native-set!","insertText":"ytevector-u16-native-set!","sortText":"bytevector-u16-native-set!"},{"label":"bytevector-u16-ref","insertText":"ytevector-u16-ref","sortText":"bytevector-u16-ref"},{"label":"bytevector-u16-set!","insertText":"ytevector-u16-set!","sortText":"bytevector-u16-set!"},{"label":"bytevector-u24-ref","insertText":"ytevector-u24-ref","sortText":"bytevector-u24-ref"},{"label":"bytevector-u24-set!","insertText":"ytevector-u24-set!","sortText":"bytevector-u24-set!"},{"label":"bytevector-u32-native-ref","insertText":"ytevector-u32-native-ref","sortText":"bytevector-u32-native-ref"},{"label":"bytevector-u32-native-set!","insertText":"ytevector-u32-native-set!","sortText":"bytevector-u32-native-set!"},{"label":"bytevector-u32-ref","insertText":"ytevector-u32-ref","sortText":"bytevector-u32-ref"},{"label":"bytevector-u32-set!","insertText":"ytevector-u32-set!","sortText":"bytevector-u32-set!"},{"label":"bytevector-u40-ref","insertText":"ytevector-u40-ref","sortText":"bytevector-u40-ref"},{"label":"bytevector-u40-set!","insertText":"ytevector-u40-set!","sortText":"bytevector-u40-set!"},{"label":"bytevector-u48-ref","insertText":"ytevector-u48-ref","sortText":"bytevector-u48-ref"},{"label":"bytevector-u48-set!","insertText":"ytevector-u48-set!","sortText":"bytevector-u48-set!"},{"label":"bytevector-u56-ref","insertText":"ytevector-u56-ref","sortText":"bytevector-u56-ref"},{"label":"bytevector-u56-set!","insertText":"ytevector-u56-set!","sortText":"bytevector-u56-set!"},{"label":"bytevector-u64-native-ref","insertText":"ytevector-u64-native-ref","sortText":"bytevector-u64-native-ref"},{"label":"bytevector-u64-native-set!","insertText":"ytevector-u64-native-set!","sortText":"bytevector-u64-native-set!"},{"label":"bytevector-u64-ref","insertText":"ytevector-u64-ref","sortText":"bytevector-u64-ref"},{"label":"bytevector-u64-set!","insertText":"ytevector-u64-set!","sortText":"bytevector-u64-set!"},{"label":"bytevector-u8-ref","insertText":"ytevector-u8-ref","sortText":"bytevector-u8-ref"},{"label":"bytevector-u8-set!","insertText":"ytevector-u8-set!","sortText":"bytevector-u8-set!"},{"label":"bytevector-uint-ref","insertText":"ytevector-uint-ref","sortText":"bytevector-uint-ref"},{"label":"bytevector-uint-set!","insertText":"ytevector-uint-set!","sortText":"bytevector-uint-set!"},{"label":"bytevector-uncompress","insertText":"ytevector-uncompress","sortText":"bytevector-uncompress"},{"label":"bytevector=?","insertText":"ytevector=?","sortText":"bytevector=?"},{"label":"bytevector?","insertText":"ytevector?","sortText":"bytevector?"}]}
{"jsonrpc":"2.0","id":6,"result":[{"label":"brok","insertText":"","sortText":"brok"},{"label":"broken-function","insertText":"en-function","sortText":"broken-function"}]}
{"jsonrpc":"2.0","id":7,"result":[{"name":"x","kind":13,"range":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}},"selectionRange":{"start":{"line":4,"character":16},"end":{"line":4,"character":17}}}]} The duplications both in |
Description
This PR fixes an issue where the language server would return duplicate completion items for the same identifier. The problem was particularly noticeable with identifiers like
broken-function
appearing multiple times in completion suggestions.Root Cause
The
find-available-references-for
function was collecting all references to an identifier without deduplication, resulting in multiple identical completion items when an identifier was defined in several places or imported from multiple sources.Solution
Applied
ordered-dedupe
to filter identifier references before converting them to completion items:eq?
equality predicate onidentifier-reference-identifier
to identify duplicatesImplementation
Benefits
Related Issues
Fixes #6