fix(claude-do): merge preview_merge_set: don't report a symbol as removed when the
ClaudeDo-Task: 4882c459-374c-4afe-a60d-2b25b8cce407
This commit is contained in:
+50
-8
@@ -744,7 +744,7 @@ public sealed class MergeMcpTools
|
||||
// One line of a unified diff, tagged with the file it belongs to ('-'/'+' only; context lines
|
||||
// are dropped). File is set from the `diff --git a/<path> b/<path>` header, which (unlike
|
||||
// `+++ b/...`) is present and names the real path even for a deleted file (`+++ /dev/null`).
|
||||
private readonly record struct DiffLine(string? File, char Sign, string Text);
|
||||
internal readonly record struct DiffLine(string? File, char Sign, string Text);
|
||||
|
||||
private static List<DiffLine> ParseDiffLines(string diff)
|
||||
{
|
||||
@@ -783,22 +783,64 @@ public sealed class MergeMcpTools
|
||||
@"|[\w<>\[\],.?]+\??\s+(?<name>[A-Za-z_]\w*)\s*(?:\(|\{|=>|;|=))",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
private static List<RemovedSymbolDto> ExtractRemovedSymbols(List<DiffLine> diffLines)
|
||||
private static bool IsScannedFile(string? file)
|
||||
=> file is not null &&
|
||||
!file.EndsWith(".axaml", StringComparison.OrdinalIgnoreCase) &&
|
||||
!file.EndsWith(".json", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
// Names this diff declares on '+' lines, per file. A [ObservableProperty] field `_camelName` /
|
||||
// `camelName` generates `CamelName`, so it counts as declaring that; the attribute may sit on its
|
||||
// own '+' line(s) directly above the field.
|
||||
private static HashSet<(string Name, string File)> ExtractAddedDeclarations(List<DiffLine> diffLines)
|
||||
{
|
||||
var added = new HashSet<(string Name, string File)>();
|
||||
var observablePending = false;
|
||||
foreach (var line in diffLines)
|
||||
{
|
||||
if (line.Sign != '+' || !IsScannedFile(line.File)) { observablePending = false; continue; }
|
||||
|
||||
var trimmed = line.Text.Trim();
|
||||
var isObservable = trimmed.Contains("[ObservableProperty", StringComparison.Ordinal);
|
||||
if (trimmed.StartsWith('[') && trimmed.EndsWith(']'))
|
||||
{
|
||||
observablePending |= isObservable;
|
||||
continue;
|
||||
}
|
||||
|
||||
var match = RemovedDeclarationRegex.Match(line.Text);
|
||||
if (match.Success)
|
||||
{
|
||||
var name = match.Groups["name"].Value;
|
||||
added.Add((name, line.File!));
|
||||
if (isObservable || observablePending)
|
||||
{
|
||||
var bare = name.TrimStart('_');
|
||||
if (bare.Length > 0)
|
||||
added.Add((char.ToUpperInvariant(bare[0]) + bare[1..], line.File!));
|
||||
}
|
||||
}
|
||||
observablePending = false;
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
internal static List<RemovedSymbolDto> ExtractRemovedSymbols(List<DiffLine> diffLines)
|
||||
{
|
||||
var added = ExtractAddedDeclarations(diffLines);
|
||||
var seen = new HashSet<(string Name, string File)>();
|
||||
var result = new List<RemovedSymbolDto>();
|
||||
foreach (var line in diffLines)
|
||||
{
|
||||
if (line.Sign != '-' || line.File is null) continue;
|
||||
if (line.File.EndsWith(".axaml", StringComparison.OrdinalIgnoreCase) ||
|
||||
line.File.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
if (line.Sign != '-' || !IsScannedFile(line.File)) continue;
|
||||
|
||||
var match = RemovedDeclarationRegex.Match(line.Text);
|
||||
if (!match.Success) continue;
|
||||
|
||||
if (seen.Add((match.Groups["name"].Value, line.File)))
|
||||
result.Add(new RemovedSymbolDto(match.Groups["name"].Value, line.File));
|
||||
var key = (match.Groups["name"].Value, line.File!);
|
||||
if (added.Contains(key)) continue;
|
||||
|
||||
if (seen.Add(key))
|
||||
result.Add(new RemovedSymbolDto(key.Item1, key.Item2));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user