Skip to content
代码片段 群组 项目
未验证 提交 fc14a135 编辑于 作者: Rikki Gibson's avatar Rikki Gibson 提交者: GitHub
浏览文件

Port "Fix race condition in computing _hostAnalyzerStateMap" for 16.11 servicing (#58034)


* Fix merge conflicts

* Add parameter

Co-authored-by: default avatarJinu <jinuj@microsoft.com>
No related branches found
无相关合并请求
......@@ -15,15 +15,29 @@ internal partial class DiagnosticIncrementalAnalyzer
private partial class StateManager
{
public IEnumerable<StateSet> GetAllHostStateSets()
=> _hostAnalyzerStateMap.Values.SelectMany(v => v.OrderedStateSets);
{
var analyzerReferencesMap = _workspace.CurrentSolution.State.Analyzers.GetHostAnalyzerReferencesMap();
foreach (var (key, value) in _hostAnalyzerStateMap)
{
if (key.AnalyzerReferences == analyzerReferencesMap)
{
foreach (var stateSet in value.OrderedStateSets)
{
yield return stateSet;
}
}
}
}
private HostAnalyzerStateSets GetOrCreateHostStateSets(Project project, ProjectAnalyzerStateSets projectStateSets)
{
var hostStateSets = ImmutableInterlocked.GetOrAdd(ref _hostAnalyzerStateMap, project.Language, CreateLanguageSpecificAnalyzerMap, project.Solution.State.Analyzers);
var key = new HostAnalyzerStateSetKey(project.Language, project.Solution.State.Analyzers.GetHostAnalyzerReferencesMap());
var hostStateSets = ImmutableInterlocked.GetOrAdd(ref _hostAnalyzerStateMap, key, CreateLanguageSpecificAnalyzerMap, project.Solution.State.Analyzers);
return hostStateSets.WithExcludedAnalyzers(projectStateSets.SkippedAnalyzersInfo.SkippedAnalyzers);
static HostAnalyzerStateSets CreateLanguageSpecificAnalyzerMap(string language, HostDiagnosticAnalyzers hostAnalyzers)
static HostAnalyzerStateSets CreateLanguageSpecificAnalyzerMap(HostAnalyzerStateSetKey arg, HostDiagnosticAnalyzers hostAnalyzers)
{
var language = arg.Language;
var analyzersPerReference = hostAnalyzers.GetOrCreateHostDiagnosticAnalyzersPerReference(language);
var analyzerMap = CreateStateSetMap(language, analyzersPerReference.Values, includeFileContentLoadAnalyzer: true);
......
......@@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
......@@ -21,6 +22,7 @@ internal partial class DiagnosticIncrementalAnalyzer
/// </summary>
private partial class StateManager
{
private readonly Workspace _workspace;
private readonly IPersistentStorageService _persistentStorageService;
private readonly DiagnosticAnalyzerInfoCache _analyzerInfoCache;
......@@ -28,7 +30,7 @@ private partial class StateManager
/// Analyzers supplied by the host (IDE). These are built-in to the IDE, the compiler, or from an installed IDE extension (VSIX).
/// Maps language name to the analyzers and their state.
/// </summary>
private ImmutableDictionary<string, HostAnalyzerStateSets> _hostAnalyzerStateMap;
private ImmutableDictionary<HostAnalyzerStateSetKey, HostAnalyzerStateSets> _hostAnalyzerStateMap;
/// <summary>
/// Analyzers referenced by the project via a PackageReference.
......@@ -40,12 +42,13 @@ private partial class StateManager
/// </summary>
public event EventHandler<ProjectAnalyzerReferenceChangedEventArgs>? ProjectAnalyzerReferenceChanged;
public StateManager(IPersistentStorageService persistentStorageService, DiagnosticAnalyzerInfoCache analyzerInfoCache)
public StateManager(Workspace workspace, IPersistentStorageService persistentStorageService, DiagnosticAnalyzerInfoCache analyzerInfoCache)
{
_persistentStorageService = persistentStorageService;
_workspace = workspace;
_analyzerInfoCache = analyzerInfoCache;
_hostAnalyzerStateMap = ImmutableDictionary<string, HostAnalyzerStateSets>.Empty;
_hostAnalyzerStateMap = ImmutableDictionary<HostAnalyzerStateSetKey, HostAnalyzerStateSets>.Empty;
_projectAnalyzerStateMap = new ConcurrentDictionary<ProjectId, ProjectAnalyzerStateSets>(concurrencyLevel: 2, capacity: 10);
}
......@@ -311,6 +314,27 @@ private void VerifyProjectDiagnosticStates(IEnumerable<StateSet> stateSets)
VerifyUniqueStateNames(hostStates.Concat(stateSets));
}
private readonly struct HostAnalyzerStateSetKey : IEquatable<HostAnalyzerStateSetKey>
{
public HostAnalyzerStateSetKey(string language, ImmutableDictionary<object, AnalyzerReference> analyzerReferences)
{
Language = language;
AnalyzerReferences = analyzerReferences;
}
public string Language { get; }
public ImmutableDictionary<object, AnalyzerReference> AnalyzerReferences { get; }
public bool Equals(HostAnalyzerStateSetKey other)
=> Language == other.Language && AnalyzerReferences == other.AnalyzerReferences;
public override bool Equals(object? obj)
=> obj is HostAnalyzerStateSetKey key && Equals(key);
public override int GetHashCode()
=> Hash.Combine(Language.GetHashCode(), AnalyzerReferences.GetHashCode());
}
}
}
}
......@@ -56,7 +56,7 @@ public DiagnosticIncrementalAnalyzer(
_correlationId = correlationId;
_stateManager = new StateManager(PersistentStorageService, analyzerInfoCache);
_stateManager = new StateManager(workspace, PersistentStorageService, analyzerInfoCache);
_stateManager.ProjectAnalyzerReferenceChanged += OnProjectAnalyzerReferenceChanged;
_telemetry = new DiagnosticAnalyzerTelemetry();
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册