lsp: find-references for fields, methods, and enum variants
Members aren't symbols, so their uses were never recorded. Adds a member-reference list (declaration + uses) tracked during analysis: struct fields/methods and enum variants as declarations; field access, method calls, bare enum literals, qualified Type.variant, and match-arm patterns as uses. Spans are derived from the source-relative name slices; uses carry the owner type (via inferExprType, dereferencing pointers). find-references matches by (owner, name) across loaded documents, treating an unknown owner as a wildcard. Verified: references for a field (legal_moves), a method (clear_valid_targets), and a variant (promote_rook — decl + comparisons + case patterns + struct-literal values across 5 files).
This commit is contained in:
@@ -203,6 +203,30 @@ pub const Server = struct {
|
||||
}
|
||||
}
|
||||
|
||||
// A struct field / method / enum variant under the cursor — matched by
|
||||
// (owner type, name) across loaded documents.
|
||||
for (sema.member_refs) |mt| {
|
||||
if (offset < mt.span.start or offset >= mt.span.end) continue;
|
||||
var buf = std.ArrayList(u8).empty;
|
||||
defer buf.deinit(self.allocator);
|
||||
try buf.append(self.allocator, '[');
|
||||
var first = true;
|
||||
var dit = self.documents.by_path.iterator();
|
||||
while (dit.next()) |entry| {
|
||||
const odoc = entry.value_ptr.*;
|
||||
const osema = odoc.sema orelse continue;
|
||||
for (osema.member_refs) |mr| {
|
||||
if (!std.mem.eql(u8, mr.name, mt.name)) continue;
|
||||
// Owner must match, treating an unknown owner ("") as a wildcard.
|
||||
if (mr.owner.len != 0 and mt.owner.len != 0 and !std.mem.eql(u8, mr.owner, mt.owner)) continue;
|
||||
if (mr.is_def and !include_decl) continue;
|
||||
try self.appendRefLoc(&buf, &first, odoc, mr.span);
|
||||
}
|
||||
}
|
||||
try buf.append(self.allocator, ']');
|
||||
return try self.sendResponse(id_json, buf.items);
|
||||
}
|
||||
|
||||
// Resolve the target symbol: a reference at the cursor, or a definition.
|
||||
var target_idx: ?u32 = null;
|
||||
if (sx.sema.findReferenceAtOffset(sema.references, offset)) |ri| {
|
||||
|
||||
Reference in New Issue
Block a user