Severity: low — noisy logs and a degenerate map key, but no functional regression today.
Symptom
ServerImpl.textDocumentReferencesOp does:
defResult <- IO.interruptible(pc.definition(offsetParams))
pcSymbol = defResult.symbol()
targetId = index.SymbolId.fromSemanticDb(pcSymbol)
When the cursor is on whitespace, a keyword, or an unresolved identifier, defResult.symbol() returns "". fromSemanticDb("") returns SymbolId(Nil, Nil, "", None) — a term id with an empty name. The lookup runs unguarded and the log line says
…which is misleading. Worse, if anything else in the index also produces an empty-name id (the TastyIndexer NonFatal fallback at line 348 returns <unknown> — close but not empty; issue ##8 — but other code paths could leak empty-name ids in the future), this lookup would silently match them.
Fix
Guard at the call site:
defResult <- IO.interruptible(pc.definition(offsetParams))
pcSymbol = defResult.symbol()
result <- if pcSymbol.isEmpty then IO.pure(lsp.TextDocumentReferencesOpOutput(None))
else {
val targetId = index.SymbolId.fromSemanticDb(pcSymbol)
symbolIndex.getReferences(targetId).map(...)
}
Acceptance criteria
- Unit test:
pcSymbol = "" returns TextDocumentReferencesOpOutput(None) without an index lookup
Severity: low — noisy logs and a degenerate map key, but no functional regression today.
Symptom
ServerImpl.textDocumentReferencesOpdoes:When the cursor is on whitespace, a keyword, or an unresolved identifier,
defResult.symbol()returns"".fromSemanticDb("")returnsSymbolId(Nil, Nil, "", None)— a term id with an empty name. The lookup runs unguarded and the log line says…which is misleading. Worse, if anything else in the index also produces an empty-name id (the TastyIndexer
NonFatalfallback at line 348 returns<unknown>— close but not empty; issue ##8 — but other code paths could leak empty-name ids in the future), this lookup would silently match them.Fix
Guard at the call site:
Acceptance criteria
pcSymbol = ""returnsTextDocumentReferencesOpOutput(None)without an index lookup