Forge
csharpdeeb25a2
1#nullable enable
2
3using CascadeIDE.Features.Workspace;
4using CascadeIDE.Services;
5using CascadeIDE.Services.Intercom;
6
7namespace CascadeIDE.Features.WorkspaceNavigation.Application;
8
9/// <summary><c>[[workspace.correspondence.code_anchors]]</c> → explicit reverse entries.</summary>
10public static class WorkspaceCorrespondenceCodeAnchorsLoader
11{
12 public const string DefaultKind = "documents";
13
14 public static IReadOnlyList<WorkspaceExplicitCodeAnchor> LoadFromWorkspaceToml(
15 RepositoryWorkspaceToml? workspaceToml,
16 string workspaceRoot)
17 {
18 var entries = workspaceToml?.Workspace?.Correspondence?.CodeAnchors;
19 if (entries is not { Count: > 0 })
20 return [];
21
22 var root = workspaceRoot.Trim();
23 var list = new List<WorkspaceExplicitCodeAnchor>();
24
25 foreach (var row in entries)
26 {
27 if (!TryToExplicit(row, out var explicitAnchor))
28 continue;
29
30 list.Add(explicitAnchor with { DocPath = NormalizeDoc(explicitAnchor.DocPath) });
31 }
32
33 return list;
34 }
35
36 private static bool TryToExplicit(RepositoryCorrespondenceCodeAnchorToml row, out WorkspaceExplicitCodeAnchor explicitAnchor)
37 {
38 explicitAnchor = new WorkspaceExplicitCodeAnchor("", new CodeAnchor(""), DefaultKind, DocReverseAnchorResolver.ProvenanceWorkspaceToml);
39
40 var doc = (row.Doc ?? "").Trim();
41 if (doc.Length == 0)
42 return false;
43
44 var kind = string.IsNullOrWhiteSpace(row.Kind) ? DefaultKind : row.Kind.Trim();
45
46 if (!string.IsNullOrWhiteSpace(row.Bracket))
47 {
48 if (!BracketCodeReferenceParser.TryParse(row.Bracket, out var reference, out _)
49 || string.IsNullOrWhiteSpace(reference.File))
50 return false;
51
52 explicitAnchor = new WorkspaceExplicitCodeAnchor(
53 doc,
54 new CodeAnchor(
55 reference.File!.Replace('\\', '/'),
56 reference.LineStart ?? row.LineStart,
57 reference.LineEnd ?? row.LineEnd,
58 reference.MemberKey ?? row.MemberKey,
59 reference.ScopeKind is null ? null : $"{reference.ScopeKind}:{reference.ScopeIndexInParent}"),
60 kind,
61 DocReverseAnchorResolver.ProvenanceWorkspaceToml);
62 return true;
63 }
64
65 var file = (row.File ?? "").Trim();
66 if (file.Length == 0)
67 return false;
68
69 explicitAnchor = new WorkspaceExplicitCodeAnchor(
70 doc,
71 new CodeAnchor(
72 file.Replace('\\', '/'),
73 row.LineStart,
74 row.LineEnd,
75 string.IsNullOrWhiteSpace(row.MemberKey) ? null : row.MemberKey.Trim()),
76 kind,
77 DocReverseAnchorResolver.ProvenanceWorkspaceToml);
78 return true;
79 }
80
81 private static string NormalizeDoc(string doc) =>
82 doc.Replace('\\', '/').Trim().TrimStart('/');
83}
84
View only · write via MCP/CIDE