Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -844,7 +844,7 @@ internal static AnalyzerDriver CreateAndAttachToCompilation(
{
AnalyzerDriver analyzerDriver = compilation.CreateAnalyzerDriver(analyzers, analyzerManager, severityFilter);
newCompilation = compilation
.WithSemanticModelProvider(new CachingSemanticModelProvider())
.WithSemanticModelProvider(CachingSemanticModelProvider.Instance)
.WithEventQueue(new AsyncQueue<CompilationEvent>());

var categorizeDiagnostics = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,31 @@ namespace Microsoft.CodeAnalysis.Diagnostics
/// </summary>
internal sealed class CachingSemanticModelProvider : SemanticModelProvider
{
public static CachingSemanticModelProvider Instance { get; } = new CachingSemanticModelProvider();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider adding a comment linking to the CWT issue so someone doesn't unintentionally undo this change in the future.


private static readonly ConditionalWeakTable<Compilation, PerCompilationProvider>.CreateValueCallback s_createProviderCallback
= new ConditionalWeakTable<Compilation, PerCompilationProvider>.CreateValueCallback(compilation => new PerCompilationProvider(compilation));

private readonly ConditionalWeakTable<Compilation, PerCompilationProvider> _providerCache;
private static readonly ConditionalWeakTable<Compilation, PerCompilationProvider> s_providerCache = new ConditionalWeakTable<Compilation, PerCompilationProvider>();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why was this made static? Couldn't it remain an instance field with the same effect since the owner is a singleton now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The general guidance per @DustinCampbell is that CWT declarations should be static if possible to remove the cyclic leak possibility. But yes, it doesn't need to be static now that the owner is a singleton, but I figured it was best to do so.


public CachingSemanticModelProvider()
private CachingSemanticModelProvider()
{
_providerCache = new ConditionalWeakTable<Compilation, PerCompilationProvider>();
}

public override SemanticModel GetSemanticModel(SyntaxTree tree, Compilation compilation, SemanticModelOptions options = default)
=> _providerCache.GetValue(compilation, s_createProviderCallback).GetSemanticModel(tree, options);
=> s_providerCache.GetValue(compilation, s_createProviderCallback).GetSemanticModel(tree, options);

internal void ClearCache(SyntaxTree tree, Compilation compilation)
{
if (_providerCache.TryGetValue(compilation, out var provider))
if (s_providerCache.TryGetValue(compilation, out var provider))
{
provider.ClearCachedSemanticModel(tree);
}
}

internal void ClearCache(Compilation compilation)
{
_providerCache.Remove(compilation);
s_providerCache.Remove(compilation);
}

private sealed class PerCompilationProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public CompilationWithAnalyzers(Compilation compilation, ImmutableArray<Diagnost

compilation = compilation
.WithOptions(compilation.Options.WithReportSuppressedDiagnostics(analysisOptions.ReportSuppressedDiagnostics))
.WithSemanticModelProvider(new CachingSemanticModelProvider())
.WithSemanticModelProvider(CachingSemanticModelProvider.Instance)
.WithEventQueue(new AsyncQueue<CompilationEvent>());
_compilation = compilation;
_analyzers = analyzers;
Expand Down Expand Up @@ -723,7 +723,7 @@ private async Task ComputeAnalyzerDiagnosticsAsync(AnalysisScope? analysisScope,
// subsequently discard this compilation.
var compilation = analysisScope.IsSingleFileAnalysisForCompilerAnalyzer
? _compilation
: _compilation.WithSemanticModelProvider(new CachingSemanticModelProvider()).WithEventQueue(new AsyncQueue<CompilationEvent>());
: _compilation.WithSemanticModelProvider(CachingSemanticModelProvider.Instance).WithEventQueue(new AsyncQueue<CompilationEvent>());

// Get the analyzer driver to execute analysis.
using var driver = await CreateAndInitializeDriverAsync(compilation, _analysisOptions, analysisScope, _suppressors, categorizeDiagnostics: true, cancellationToken).ConfigureAwait(false);
Expand Down Expand Up @@ -1188,7 +1188,7 @@ private static IEnumerable<Diagnostic> GetEffectiveDiagnosticsImpl(ImmutableArra

if (compilation.SemanticModelProvider == null)
{
compilation = compilation.WithSemanticModelProvider(new CachingSemanticModelProvider());
compilation = compilation.WithSemanticModelProvider(CachingSemanticModelProvider.Instance);
}

var suppressMessageState = new SuppressMessageAttributeState(compilation);
Expand Down