lsp: project-wide find-references + revive the LSP test suite
find-references only searched documents the editor had open, so asking for references to a field from a file whose users were all closed returned just the definition. Load every .sx under the workspace root before matching so uses in unopened files are found too. The LSP server's own tests were dormant: nested under the `lsp` struct in root.zig, refAllDecls never reached them, and they had bit-rotted (stale DocumentStore.init arity, an unaligned dummy io, fake /test/ paths that no longer resolve). Reference the lsp files directly so their tests run, give the doc-store tests a real Threaded io with bare paths, and fix the stale extractIdentAtOffset expectation. Extract referencesPayload from the transport so it is unit-testable, and add tests covering cross-document field references, includeDeclaration, the for-loop capture inlay hint, and workspace file loading.
This commit is contained in:
@@ -103,6 +103,32 @@ pub const DocumentStore = struct {
|
||||
return file_paths.toOwnedSlice(self.allocator) catch null;
|
||||
}
|
||||
|
||||
/// Recursively load and analyse every `.sx` file under the workspace root so
|
||||
/// cross-file features (find-references) see uses in files the editor never
|
||||
/// opened. Already-loaded documents keep their in-editor content.
|
||||
pub fn loadWorkspaceFiles(self: *DocumentStore) void {
|
||||
const root = self.rootPathOpt() orelse return;
|
||||
self.loadDirRecursive(root, 0);
|
||||
}
|
||||
|
||||
fn loadDirRecursive(self: *DocumentStore, dir_path: []const u8, depth: u32) void {
|
||||
if (depth > 16) return;
|
||||
const dir = std.Io.Dir.openDir(.cwd(), self.io, dir_path, .{ .iterate = true }) catch return;
|
||||
defer dir.close(self.io);
|
||||
var it = dir.iterate();
|
||||
while (it.next(self.io) catch null) |entry| {
|
||||
if (entry.name.len == 0 or entry.name[0] == '.') continue;
|
||||
const full = std.fmt.allocPrint(self.allocator, "{s}/{s}", .{ dir_path, entry.name }) catch continue;
|
||||
defer self.allocator.free(full);
|
||||
if (entry.kind == .directory) {
|
||||
self.loadDirRecursive(full, depth + 1);
|
||||
} else if (entry.kind == .file and std.mem.endsWith(u8, entry.name, ".sx")) {
|
||||
const doc = self.getOrLoad(full) catch continue;
|
||||
if (doc.sema == null) self.analyzeDocument(doc) catch {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create or update a document with editor-provided source (for didOpen/didChange).
|
||||
pub fn openOrUpdate(self: *DocumentStore, path: []const u8, source: [:0]const u8, version: i64) !*Document {
|
||||
if (self.by_path.get(path)) |doc| {
|
||||
|
||||
Reference in New Issue
Block a user