diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.CompilationData.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.CompilationData.cs index d73148946933439f7d83af7c351dff072f126fd2..af1c98fd18c40071c280cc940f7738ea1d158157 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.CompilationData.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.CompilationData.cs @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics { internal abstract partial class AnalyzerDriver : IDisposable { - protected static readonly ConditionalWeakTable s_compilationDataCache = new ConditionalWeakTable(); + private static readonly WeakReference s_cachedCompilationData = new WeakReference(null); internal class CompilationData { @@ -28,12 +28,18 @@ internal class CompilationData public CompilationData(Compilation comp) { + this.Compilation = comp; _semanticModelsMap = new Dictionary(); _symbolDeclarationsMap = new Dictionary>(); this.SuppressMessageAttributeState = new SuppressMessageAttributeState(comp); this.DeclarationAnalysisDataMap = new Dictionary(); } + /// + /// Compilation whose data is cached. + /// + public readonly Compilation Compilation; + public SuppressMessageAttributeState SuppressMessageAttributeState { get; } public Dictionary DeclarationAnalysisDataMap { get; } @@ -146,12 +152,29 @@ public void Free() internal static CompilationData GetOrCreateCachedCompilationData(Compilation compilation) { - return s_compilationDataCache.GetValue(compilation, c => new CompilationData(c)); + CompilationData data; + if (!s_cachedCompilationData.TryGetTarget(out data) || data == null || data.Compilation != compilation) + { + data = new CompilationData(compilation); + s_cachedCompilationData.SetTarget(data); + } + + return data; + } + + internal static bool TryGetCachedCompilationData(Compilation compilation, out CompilationData compilationData) + { + return s_cachedCompilationData.TryGetTarget(out compilationData) && + compilationData?.Compilation == compilation; } - internal static bool RemoveCachedCompilationData(Compilation compilation) + internal static void RemoveCachedCompilationData(Compilation compilation) { - return s_compilationDataCache.Remove(compilation); + CompilationData compilationData; + if (TryGetCachedCompilationData(compilation, out compilationData)) + { + s_cachedCompilationData.SetTarget(null); + } } public static SemanticModel GetOrCreateCachedSemanticModel(SyntaxTree tree, Compilation compilation, CancellationToken cancellationToken) @@ -160,11 +183,13 @@ public static SemanticModel GetOrCreateCachedSemanticModel(SyntaxTree tree, Comp return compilationData.GetOrCreateCachedSemanticModel(tree, compilation, cancellationToken); } - public static bool RemoveCachedSemanticModel(SyntaxTree tree, Compilation compilation) + public static void RemoveCachedSemanticModel(SyntaxTree tree, Compilation compilation) { CompilationData compilationData; - return s_compilationDataCache.TryGetValue(compilation, out compilationData) && + if (TryGetCachedCompilationData(compilation, out compilationData)) + { compilationData.RemoveCachedSemanticModel(tree); + } } public static bool TryGetCachedDeclaringReferences(ISymbol symbol, Compilation compilation, out ImmutableArray declaringReferences) @@ -179,11 +204,13 @@ public static void CacheDeclaringReferences(ISymbol symbol, Compilation compilat compilationData.CacheDeclaringReferences(symbol, declaringReferences); } - public static bool RemoveCachedDeclaringReferences(ISymbol symbol, Compilation compilation) + public static void RemoveCachedDeclaringReferences(ISymbol symbol, Compilation compilation) { CompilationData compilationData; - return s_compilationDataCache.TryGetValue(compilation, out compilationData) && + if (TryGetCachedCompilationData(compilation, out compilationData)) + { compilationData.RemoveCachedDeclaringReferences(symbol); + } } } } \ No newline at end of file diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs index e2bfcb2f1f567c4db8fb519bfd94f4a285ef2d13..df90678f5c80bfc8a6ff42cdfa8d0e0bb6dc7514 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs @@ -1137,7 +1137,7 @@ private void ClearCachedAnalysisDataIfAnalyzed(SyntaxReference declaration, Synt Debug.Assert(analysisState != null); CompilationData compilationData; - if (!s_compilationDataCache.TryGetValue(compilation, out compilationData) || + if (!TryGetCachedCompilationData(compilation, out compilationData) || !analysisState.IsDeclarationComplete(node)) { return;