Skip to content

Commit 6319104

Browse files
authored
simplify sln-remove implementation (#45797)
1 parent 0c58854 commit 6319104

File tree

1 file changed

+33
-36
lines changed
  • src/Cli/dotnet/commands/dotnet-sln/remove

1 file changed

+33
-36
lines changed

src/Cli/dotnet/commands/dotnet-sln/remove/Program.cs

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,6 @@ internal class RemoveProjectFromSolutionCommand : CommandBase
1919
private readonly string _fileOrDirectory;
2020
private readonly IReadOnlyCollection<string> _projects;
2121

22-
private int CountNonFolderDescendants(
23-
SolutionModel solution,
24-
SolutionFolderModel item,
25-
Dictionary<SolutionFolderModel, SolutionItemModel[]> solutionItemsGroupedByParent,
26-
Dictionary<SolutionFolderModel, int> cached)
27-
{
28-
if (cached.ContainsKey(item))
29-
{
30-
return cached[item];
31-
}
32-
int count = item.Files?.Count ?? 0;
33-
var children = solutionItemsGroupedByParent.TryGetValue(item, out var items) ? items : Array.Empty<SolutionItemModel>();
34-
foreach (var child in children)
35-
{
36-
count += child is SolutionFolderModel folderModel
37-
? CountNonFolderDescendants(solution, folderModel, solutionItemsGroupedByParent, cached)
38-
: 1;
39-
}
40-
cached.Add(item, count);
41-
return count;
42-
}
43-
4422
public RemoveProjectFromSolutionCommand(ParseResult parseResult) : base(parseResult)
4523
{
4624
_fileOrDirectory = parseResult.GetValue(SlnCommandParser.SlnArgument);
@@ -91,7 +69,7 @@ private async Task RemoveProjectsAsync(string solutionFileFullPath, IEnumerable<
9169
ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath);
9270
SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken);
9371

94-
// set UTF8 BOM encoding for .sln
72+
// set UTF-8 BOM encoding for .sln
9573
if (serializer is ISolutionSerializer<SlnV12SerializerSettings> v12Serializer)
9674
{
9775
solution.SerializerExtension = v12Serializer.CreateModelExtension(new()
@@ -114,21 +92,40 @@ private async Task RemoveProjectsAsync(string solutionFileFullPath, IEnumerable<
11492
}
11593
}
11694

117-
Dictionary<SolutionFolderModel, SolutionItemModel[]> solutionItemsGroupedByParent = solution.SolutionItems
118-
.Where(i => i.Parent != null)
119-
.GroupBy(i => i.Parent)
120-
.ToDictionary(g => g.Key, g => g.ToArray());
121-
122-
Dictionary<SolutionFolderModel, int> nonFolderDescendantsCount = new();
123-
foreach (var item in solution.SolutionFolders)
95+
for (int i = 0; i < solution.SolutionFolders.Count; i++)
12496
{
125-
CountNonFolderDescendants(solution, item, solutionItemsGroupedByParent, nonFolderDescendantsCount);
126-
}
97+
var folder = solution.SolutionFolders[i];
98+
int nonFolderDescendants = 0;
99+
Stack<SolutionFolderModel> stack = new();
100+
stack.Push(folder);
127101

128-
var emptyFolders = nonFolderDescendantsCount.Where(i => i.Value == 0).Select(i => i.Key);
129-
foreach (var folder in emptyFolders)
130-
{
131-
solution.RemoveFolder(folder);
102+
while (stack.Count > 0)
103+
{
104+
var current = stack.Pop();
105+
106+
nonFolderDescendants += current.Files?.Count ?? 0;
107+
foreach (var child in solution.SolutionItems)
108+
{
109+
if (child is { Parent: var parent } && parent == current)
110+
{
111+
if (child is SolutionFolderModel childFolder)
112+
{
113+
stack.Push(childFolder);
114+
}
115+
else
116+
{
117+
nonFolderDescendants++;
118+
}
119+
}
120+
}
121+
}
122+
123+
if (nonFolderDescendants == 0)
124+
{
125+
solution.RemoveFolder(folder);
126+
// After removal, adjust index and continue to avoid skipping folders after removal
127+
i--;
128+
}
132129
}
133130

134131
await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken);

0 commit comments

Comments
 (0)