Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Util;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
Expand Down Expand Up @@ -44,7 +44,7 @@ internal sealed partial class RootSymbolTreeItemSourceProvider : AttachedCollect
/// of that file through that project.
/// </summary>
/// <remarks>Lock this instance when reading/writing as it is used over different threads.</remarks>
private readonly MultiDictionary<string, RootSymbolTreeItemCollectionSource> _filePathToCollectionSources = new(
private readonly Dictionary<string, List<RootSymbolTreeItemCollectionSource>> _filePathToCollectionSources = new(
StringComparer.OrdinalIgnoreCase);

/// <summary>
Expand Down Expand Up @@ -166,7 +166,9 @@ await source.UpdateIfEverExpandedAsync(cancellationToken)

var source = new RootSymbolTreeItemCollectionSource(this, item);
lock (_filePathToCollectionSources)
_filePathToCollectionSources.Add(currentFilePath, source);
{
AddToDictionary(currentFilePath, source);
}

// Register to hear about if this hierarchy is disposed. We'll stop watching it if so.
item.PropertyChanged += OnItemPropertyChanged;
Expand All @@ -181,7 +183,7 @@ void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
// event for the IsDisposed property. When this fires, we remove the filePath->sourcce mapping we're holding.
lock (_filePathToCollectionSources)
{
_filePathToCollectionSources.Remove(currentFilePath, source);
RemoveFromDictionary(currentFilePath, source);
}

item.PropertyChanged -= OnItemPropertyChanged;
Expand All @@ -195,8 +197,8 @@ void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{

// Unlink the oldPath->source mapping, and add a new line for the newPath->source.
_filePathToCollectionSources.Remove(currentFilePath, source);
_filePathToCollectionSources.Add(newPath, source);
RemoveFromDictionary(currentFilePath, source);
AddToDictionary(newPath, source);

// Keep track of the 'newPath'.
currentFilePath = newPath;
Expand All @@ -211,5 +213,29 @@ void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
}
}
}

void AddToDictionary(string currentFilePath, RootSymbolTreeItemCollectionSource source)
Copy link
Member

@jasonmalinowski jasonmalinowski Jun 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know for the future, thanks.

{
if (!_filePathToCollectionSources.TryGetValue(currentFilePath, out var sources))
{
sources = [];
_filePathToCollectionSources[currentFilePath] = sources;
}

sources.Add(source);
}

void RemoveFromDictionary(string currentFilePath, RootSymbolTreeItemCollectionSource source)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(feel free to ignore since this is impacting RPS)

...and MultiRemove from the same file as above.

{
if (_filePathToCollectionSources.TryGetValue(currentFilePath, out var sources))
{
sources.Remove(source);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should probably remove the key as well if there are no more sources. Otherwise on renames we're going to be leaving old file paths around in the dictionary.

Looks like the multidictionary previously removed the key as well - https://github.com/icsharpcode/ILSpy/blob/master/ICSharpCode.Decompiler/Util/MultiDictionary.cs#L59


if (sources.Count == 0)
{
_filePathToCollectionSources.Remove(currentFilePath);
}
}
}
}
}
Loading