diff --git a/Src/Compilers/Core/Desktop/AnalyzerFileReference.cs b/Src/Compilers/Core/Desktop/AnalyzerFileReference.cs index 20fe4e9778ce898c81480fe38d08e2565c8c7fd3..24a28825403af7eac255adada73339bfac9a9bac 100644 --- a/Src/Compilers/Core/Desktop/AnalyzerFileReference.cs +++ b/Src/Compilers/Core/Desktop/AnalyzerFileReference.cs @@ -8,9 +8,8 @@ using System.Reflection; using System.Reflection.Metadata; using System.Security; -using Roslyn.Utilities; -using System.Collections.Concurrent; using System.Threading; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics { @@ -32,7 +31,7 @@ public sealed partial class AnalyzerFileReference : AnalyzerReference private string lazyDisplayName; private ImmutableArray lazyAllAnalyzers; private ImmutableArray lazyLanguageAgnosticAnalyzers; - private ConcurrentDictionary> lazyAnalyzersPerLanguage; + private ImmutableDictionary> lazyAnalyzersPerLanguage; private Assembly lazyAssembly; private ImmutableDictionary> lazyAnalyzerTypeNameMap; @@ -79,7 +78,7 @@ public AnalyzerFileReference(string fullPath, Func getAssembly this.lazyAllAnalyzers = default(ImmutableArray); this.lazyLanguageAgnosticAnalyzers = default(ImmutableArray); - this.lazyAnalyzersPerLanguage = null; + this.lazyAnalyzersPerLanguage = ImmutableDictionary>.Empty; this.getAssembly = getAssembly; } @@ -88,7 +87,7 @@ public override ImmutableArray GetAnalyzersForAllLanguages( if (lazyAllAnalyzers.IsDefault) { var allAnalyzers = MetadataCache.GetOrCreateAnalyzersFromFile(this); - ImmutableInterlocked.InterlockedCompareExchange(ref this.lazyAllAnalyzers, allAnalyzers, default(ImmutableArray)); + ImmutableInterlocked.InterlockedInitialize(ref this.lazyAllAnalyzers, allAnalyzers); } return lazyAllAnalyzers; @@ -101,23 +100,12 @@ public override ImmutableArray GetAnalyzers(string language throw new ArgumentException("language"); } - ImmutableArray analyzers; - if (this.lazyAnalyzersPerLanguage == null) - { - Interlocked.CompareExchange(ref this.lazyAnalyzersPerLanguage, new ConcurrentDictionary>(), null); - } - else if (this.lazyAnalyzersPerLanguage.TryGetValue(language, out analyzers)) - { - return analyzers; - } - - analyzers = MetadataCache.GetOrCreateAnalyzersFromFile(this, language); - if (!this.lazyAnalyzersPerLanguage.TryAdd(language, analyzers)) - { - return this.lazyAnalyzersPerLanguage[language]; - } + return ImmutableInterlocked.GetOrAdd(ref this.lazyAnalyzersPerLanguage, language, CreateLanguageSpecificAnalyzers, this); + } - return analyzers; + private static ImmutableArray CreateLanguageSpecificAnalyzers(string language, AnalyzerFileReference @this) + { + return MetadataCache.GetOrCreateAnalyzersFromFile(@this, language); } public override string FullPath @@ -173,7 +161,7 @@ private ImmutableArray GetLanguageAgnosticAnalyzers(Immutab analyzers = GetAnalyzersForTypeNames(analyzerAssembly, analyzerTypeNames).ToImmutableArrayOrEmpty(); } - ImmutableInterlocked.InterlockedCompareExchange(ref this.lazyLanguageAgnosticAnalyzers, analyzers, default(ImmutableArray)); + ImmutableInterlocked.InterlockedInitialize(ref this.lazyLanguageAgnosticAnalyzers, analyzers); } return this.lazyLanguageAgnosticAnalyzers; @@ -299,7 +287,7 @@ private IEnumerable GetAnalyzersForTypeNames(Assembly analy /// private static ImmutableDictionary> GetAnalyzerTypeNameMap(string fullPath) { - var typeNameMap = new Dictionary>(); + var typeNameMap = ImmutableDictionary.CreateBuilder>(); var diagnosticNamespaceName = string.Format("{0}.{1}.{2}", nameof(Microsoft), nameof(CodeAnalysis), nameof(Diagnostics)); var supportedLanguageNames = new HashSet(); @@ -367,7 +355,7 @@ private IEnumerable GetAnalyzersForTypeNames(Assembly analy } } - return typeNameMap.ToImmutableDictionary(); + return typeNameMap.ToImmutable(); } private static string GetFullyQualifiedTypeName(TypeDefinition typeDef, PEModule peModule) diff --git a/Src/Compilers/Core/Desktop/MetadataCache.cs b/Src/Compilers/Core/Desktop/MetadataCache.cs index 092cee8add2d77f43db5f6415894bbed9d1a8bf5..6f11b54f0160a1ebb5a3a96fc56804500f1ddb28 100644 --- a/Src/Compilers/Core/Desktop/MetadataCache.cs +++ b/Src/Compilers/Core/Desktop/MetadataCache.cs @@ -122,7 +122,7 @@ internal struct CachedAnalyzers public readonly WeakReference Analyzers; public readonly string Language; - public CachedAnalyzers(ImmutableArray analyzers, string language) + public CachedAnalyzers(object analyzers, string language) { Debug.Assert(analyzers != null); diff --git a/Src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs b/Src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs index f1abf4e6e3a75c12c681c3f40d82f2701089bf00..852dd15ccbc90eae24e13f1a6db0a5979567b6f8 100644 --- a/Src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs +++ b/Src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs @@ -44,12 +44,12 @@ public virtual bool IsUnresolved /// In most instances, either the analyzer reference is associated with a project or is being queried for analyzers in a particular language context. /// If so, use method. /// - /// public abstract ImmutableArray GetAnalyzersForAllLanguages(); /// /// Gets all the diagnostic analyzers defined in this assembly reference for the given . /// + /// Language name. public abstract ImmutableArray GetAnalyzers(string language); } } \ No newline at end of file diff --git a/Src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs b/Src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs index 671285f69feffd4aff52f5320ea632b3948fa41b..c4dfde3b92b0c642d2438ed835478f0a8228af05 100644 --- a/Src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs +++ b/Src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs @@ -369,7 +369,7 @@ public void TestProjectDiagnosticAnalyzers() var actualAnalyzerReferences = newSolution.Projects.Single().AnalyzerReferences; Assert.Equal(1, actualAnalyzerReferences.Count); Assert.Equal(analyzerReference, actualAnalyzerReferences[0]); - var actualAnalyzers = actualAnalyzerReferences[0].GetAnalyzersForAllLanguages().ToImmutableArray(); + var actualAnalyzers = actualAnalyzerReferences[0].GetAnalyzersForAllLanguages(); Assert.Equal(1, actualAnalyzers.Length); Assert.Equal(analyzer, actualAnalyzers[0]);