Forge
csharp4405de34
1#nullable enable
2
3using CascadeIDE.Models.Intercom;
4using CascadeIDE.Services;
5
6namespace CascadeIDE.Services.Intercom;
7
8/// <summary>
9/// Пересчёт <see cref="AttachmentAnchor.ResolveOutcome"/> и строк после смены workspace/solution
10/// (маркеры в ленте; reveal делает то же при клике — ADR 0128).
11/// </summary>
12public static class IntercomAttachmentAnchorRefresher
13{
14 public static bool NeedsRefresh(AttachmentAnchor anchor)
15 {
16 var outcome = anchor.ResolveOutcome?.Trim();
17 if (string.Equals(outcome, IntercomAttachmentRevealPlan.OutcomeMemberNotFound, StringComparison.OrdinalIgnoreCase)
18 || string.Equals(outcome, IntercomAttachmentRevealPlan.OutcomeFileMissing, StringComparison.OrdinalIgnoreCase))
19 {
20 return true;
21 }
22
23 var hasMember = !string.IsNullOrWhiteSpace(anchor.MemberKey);
24 AttachmentSyntaxScope.TryParse(anchor.SyntaxScope, out var syntaxScope);
25 var hasScope = syntaxScope is not null;
26 if (!hasMember && !hasScope)
27 return false;
28
29 if (string.IsNullOrWhiteSpace(outcome))
30 return true;
31
32 return string.Equals(outcome, IntercomAttachmentRevealPlan.OutcomeExcerptOnly, StringComparison.OrdinalIgnoreCase);
33 }
34
35 public static AttachmentAnchor Refresh(
36 AttachmentAnchor anchor,
37 string? workspaceRoot,
38 string? solutionPath)
39 {
40 if (!NeedsRefresh(anchor))
41 return anchor;
42
43 var plan = IntercomAttachmentRevealPlan.Create(anchor, workspaceRoot, solutionPath);
44 var updated = anchor with { ResolveOutcome = plan.ResolveOutcome };
45
46 if (plan.Lines is { } lines)
47 {
48 updated = updated with
49 {
50 LineStart = lines.Start.Value,
51 LineEnd = lines.End.Value,
52 };
53 }
54
55 if (string.Equals(plan.ResolveOutcome, IntercomAttachmentRevealPlan.OutcomeResolved, StringComparison.OrdinalIgnoreCase))
56 {
57 updated = updated with
58 {
59 ResolvedAtUtc = DateTimeOffset.UtcNow.ToString("O"),
60 };
61 }
62
63 return updated;
64 }
65
66 public static bool TryRefreshList(
67 IReadOnlyList<AttachmentAnchor> anchors,
68 string? workspaceRoot,
69 string? solutionPath,
70 out IReadOnlyList<AttachmentAnchor>? refreshed)
71 {
72 refreshed = null;
73 if (anchors.Count == 0)
74 return false;
75
76 var list = new List<AttachmentAnchor>(anchors.Count);
77 var changed = false;
78 foreach (var anchor in anchors)
79 {
80 var next = Refresh(anchor, workspaceRoot, solutionPath);
81 list.Add(next);
82 if (!anchor.Equals(next))
83 changed = true;
84 }
85
86 if (!changed)
87 return false;
88
89 refreshed = list;
90 return true;
91 }
92}
93
View only · write via MCP/CIDE