public InProcOrRemoteHostAnalyzerRunner( DiagnosticAnalyzerInfoCache analyzerInfoCache, IAsynchronousOperationListener?operationListener = null) { AnalyzerInfoCache = analyzerInfoCache; _asyncOperationListener = operationListener ?? AsynchronousOperationListenerProvider.NullListener; }
static bool ShouldIncludeHostAnalyzer( DiagnosticAnalyzer hostAnalyzer, ImmutableHashSet <string> idsReportedByProjectAnalyzers, DiagnosticAnalyzerInfoCache analyzerInfoCache, out ImmutableArray <string> skippedDiagnosticIdsForAnalyzer) { // Include only those host (VSIX) analyzers that report at least one unique diagnostic ID // which is not reported by any project (NuGet) analyzer. // See https://github.com/dotnet/roslyn/issues/18818. var shouldInclude = false; var descriptors = analyzerInfoCache.GetDiagnosticDescriptors(hostAnalyzer); var skippedDiagnosticIdsBuilder = ArrayBuilder <string> .GetInstance(); foreach (var descriptor in descriptors) { if (idsReportedByProjectAnalyzers.Contains(descriptor.Id)) { skippedDiagnosticIdsBuilder.Add(descriptor.Id); } else { shouldInclude = true; } } skippedDiagnosticIdsForAnalyzer = skippedDiagnosticIdsBuilder.ToImmutableAndFree(); return(shouldInclude); }
public SkippedHostAnalyzersInfo GetSkippedAnalyzersInfo( Project project, DiagnosticAnalyzerInfoCache infoCache ) { var box = _skippedHostAnalyzers.GetOrCreateValue(project.AnalyzerReferences); if (box.Value != null && box.Value.TryGetValue(project.Language, out var info)) { return(info); } lock (box) { box.Value ??= ImmutableDictionary <string, SkippedHostAnalyzersInfo> .Empty; if (!box.Value.TryGetValue(project.Language, out info)) { info = SkippedHostAnalyzersInfo.Create( this, project.AnalyzerReferences, project.Language, infoCache ); box.Value = box.Value.Add(project.Language, info); } return(info); } }
public DefaultDiagnosticAnalyzerService( IDiagnosticUpdateSourceRegistrationService registrationService ) { _analyzerInfoCache = new DiagnosticAnalyzerInfoCache(); registrationService.Register(this); }
> CreateDiagnosticDescriptorsPerReference( DiagnosticAnalyzerInfoCache infoCache, ImmutableDictionary <object, ImmutableArray <DiagnosticAnalyzer> > analyzersMap ) { var builder = ImmutableDictionary.CreateBuilder < object, ImmutableArray <DiagnosticDescriptor> >(); foreach (var(referenceId, analyzers) in analyzersMap) { var descriptors = ImmutableArray.CreateBuilder <DiagnosticDescriptor>(); foreach (var analyzer in analyzers) { // given map should be in good shape. no duplication. no null and etc descriptors.AddRange(infoCache.GetDiagnosticDescriptors(analyzer)); } // there can't be duplication since _hostAnalyzerReferenceMap is already de-duplicated. builder.Add(referenceId, descriptors.ToImmutable()); } return(builder.ToImmutable()); }
private TestDiagnosticAnalyzerService( DiagnosticAnalyzerInfoCache analyzerInfoCache, AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource, IDiagnosticUpdateSourceRegistrationService registrationService = null, IAsynchronousOperationListener listener = null) : base(analyzerInfoCache, hostDiagnosticUpdateSource, registrationService ?? new MockDiagnosticUpdateSourceRegistrationService(), listener) { }
public DefaultDiagnosticAnalyzerService( IDiagnosticUpdateSourceRegistrationService registrationService, IGlobalOptionService globalOptions) { _analyzerInfoCache = new DiagnosticAnalyzerInfoCache(); registrationService.Register(this); _globalOptions = globalOptions; }
public InProcOrRemoteHostAnalyzerRunner( DiagnosticAnalyzerInfoCache analyzerInfoCache, Workspace workspace, IAsynchronousOperationListener?operationListener = null) { AnalyzerInfoCache = analyzerInfoCache; _asyncOperationListener = operationListener ?? AsynchronousOperationListenerProvider.NullListener; _documentTrackingService = workspace.Services.GetService <IDocumentTrackingService>(); }
> GetDiagnosticDescriptorsPerReference(DiagnosticAnalyzerInfoCache infoCache) { return(ConvertReferenceIdentityToName( CreateDiagnosticDescriptorsPerReference( infoCache, _lazyHostDiagnosticAnalyzersPerReferenceMap.Value ), _hostAnalyzerReferencesMap )); }
protected DiagnosticAnalyzerService( DiagnosticAnalyzerInfoCache analyzerInfoCache, AbstractHostDiagnosticUpdateSource?hostDiagnosticUpdateSource, IDiagnosticUpdateSourceRegistrationService registrationService, IAsynchronousOperationListener?listener = null) : this(registrationService) { _analyzerInfoCache = analyzerInfoCache; _hostDiagnosticUpdateSource = hostDiagnosticUpdateSource; Listener = listener ?? AsynchronousOperationListenerProvider.NullListener; }
private TestDiagnosticAnalyzerService( DiagnosticAnalyzerInfoCache analyzerInfoCache, AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource, Action <Exception, DiagnosticAnalyzer, Diagnostic> onAnalyzerException, IDiagnosticUpdateSourceRegistrationService registrationService = null, IAsynchronousOperationListener listener = null) : base(analyzerInfoCache, hostDiagnosticUpdateSource, registrationService ?? new MockDiagnosticUpdateSourceRegistrationService(), listener) { _hostAnalyzerReferenceMap = analyzerInfoCache.CreateAnalyzerReferencesMap(project : null); _onAnalyzerException = onAnalyzerException; }
public static async Task <(AnalysisResult result, ImmutableArray <Diagnostic> additionalDiagnostics)> GetAnalysisResultAsync( this CompilationWithAnalyzers compilationWithAnalyzers, Project project, DiagnosticAnalyzerInfoCache analyzerInfoCache, CancellationToken cancellationToken) { var result = await compilationWithAnalyzers.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); var additionalDiagnostics = await compilationWithAnalyzers.GetPragmaSuppressionAnalyzerDiagnosticsAsync(project, analyzerInfoCache, cancellationToken).ConfigureAwait(false); return(result, additionalDiagnostics); }
private static async Task <ImmutableArray <Diagnostic> > GetPragmaSuppressionAnalyzerDiagnosticsAsync( this CompilationWithAnalyzers compilationWithAnalyzers, Project project, DiagnosticAnalyzerInfoCache analyzerInfoCache, CancellationToken cancellationToken) { var suppressionAnalyzer = compilationWithAnalyzers.Analyzers.OfType <IPragmaSuppressionsAnalyzer>().FirstOrDefault(); if (suppressionAnalyzer == null) { return(ImmutableArray <Diagnostic> .Empty); } if (compilationWithAnalyzers.AnalysisOptions.ConcurrentAnalysis) { var bag = new ConcurrentBag <Diagnostic>(); using var _ = ArrayBuilder <Task> .GetInstance(project.DocumentIds.Count, out var tasks); foreach (var document in project.Documents) { tasks.Add(AnalyzeDocumentAsync(suppressionAnalyzer, document, bag.Add)); } await Task.WhenAll(tasks).ConfigureAwait(false); return(bag.ToImmutableArray()); } else { using var _ = ArrayBuilder <Diagnostic> .GetInstance(out var diagnosticsBuilder); foreach (var document in project.Documents) { await AnalyzeDocumentAsync(suppressionAnalyzer, document, diagnosticsBuilder.Add).ConfigureAwait(false); } return(diagnosticsBuilder.ToImmutable()); } // Local functions. async Task AnalyzeDocumentAsync(IPragmaSuppressionsAnalyzer suppressionAnalyzer, Document document, Action <Diagnostic> reportDiagnostic) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); using var _ = ArrayBuilder <Diagnostic> .GetInstance(out var diagnostics); await suppressionAnalyzer.AnalyzeAsync(semanticModel, span : null, compilationWithAnalyzers, analyzerInfoCache.GetDiagnosticDescriptors, IsCompilationEndAnalyzer, reportDiagnostic, cancellationToken).ConfigureAwait(false); } bool IsCompilationEndAnalyzer(DiagnosticAnalyzer analyzer) => analyzerInfoCache.IsCompilationEndAnalyzer(analyzer, compilationWithAnalyzers.AnalysisOptions.Options !, compilationWithAnalyzers.Compilation) ?? true; }
private static IEnumerable <DiagnosticAnalyzer> GetAnalyzers(DiagnosticAnalyzerInfoCache analyzerInfoCache, Project project) { // C# or VB document that supports compiler var compilerAnalyzer = analyzerInfoCache.GetCompilerDiagnosticAnalyzer(project.Language); if (compilerAnalyzer != null) { return(SpecializedCollections.SingletonEnumerable(compilerAnalyzer)); } // document that doesn't support compiler diagnostics such as FSharp or TypeScript return(analyzerInfoCache.CreateDiagnosticAnalyzersPerReference(project).Values.SelectMany(v => v)); }
private static SkippedHostAnalyzersInfo Create( IEnumerable <DiagnosticAnalyzer> projectAnalyzers, IEnumerable <DiagnosticAnalyzer> hostAnalyzers, DiagnosticAnalyzerInfoCache analyzerInfoCache) { ComputeSkippedHostAnalyzers(projectAnalyzers, hostAnalyzers, analyzerInfoCache, out var fullySkippedHostAnalyzers, out var filteredDiagnosticIdsForAnalyzers); if (fullySkippedHostAnalyzers.IsEmpty && filteredDiagnosticIdsForAnalyzers.IsEmpty) { return(Default); } return(new SkippedHostAnalyzersInfo(fullySkippedHostAnalyzers, filteredDiagnosticIdsForAnalyzers));
static ImmutableHashSet <string> GetIdsReportedByProjectAnalyzers( IEnumerable <DiagnosticAnalyzer> projectAnalyzers, DiagnosticAnalyzerInfoCache analyzerInfoCache) { var builder = ImmutableHashSet.CreateBuilder <string>(); foreach (var analyzer in projectAnalyzers) { var descriptors = analyzerInfoCache.GetDiagnosticDescriptors(analyzer); builder.AddRange(descriptors.Select(d => d.Id)); } return(builder.ToImmutable()); }
static bool ShouldIncludeHostAnalyzer( DiagnosticAnalyzer hostAnalyzer, HashSet <string> projectAnalyzerDiagnosticIds, HashSet <string> projectSuppressedDiagnosticIds, DiagnosticAnalyzerInfoCache analyzerInfoCache, out ImmutableArray <string> skippedDiagnosticIdsForAnalyzer) { // Include only those host (VSIX) analyzers that report at least one unique diagnostic ID // which is not reported by any project (NuGet) analyzer. // See https://github.com/dotnet/roslyn/issues/18818. var shouldInclude = false; var descriptors = analyzerInfoCache.GetDiagnosticDescriptors(hostAnalyzer); var skippedDiagnosticIdsBuilder = ArrayBuilder <string> .GetInstance(); foreach (var descriptor in descriptors) { if (projectAnalyzerDiagnosticIds.Contains(descriptor.Id)) { skippedDiagnosticIdsBuilder.Add(descriptor.Id); } else { shouldInclude = true; } } if (hostAnalyzer is DiagnosticSuppressor suppressor) { skippedDiagnosticIdsForAnalyzer = ImmutableArray <string> .Empty; // Only execute host suppressor if it does not suppress any diagnostic ID reported by project analyzer // and does not share any suppression ID with a project suppressor. foreach (var descriptor in suppressor.SupportedSuppressions) { if (projectAnalyzerDiagnosticIds.Contains(descriptor.SuppressedDiagnosticId) || projectSuppressedDiagnosticIds.Contains(descriptor.SuppressedDiagnosticId)) { return(false); } } return(true); } skippedDiagnosticIdsForAnalyzer = skippedDiagnosticIdsBuilder.ToImmutableAndFree(); return(shouldInclude); }
public DiagnosticAnalyzerService( IDiagnosticUpdateSourceRegistrationService registrationService, IAsynchronousOperationListenerProvider listenerProvider) { AnalyzerInfoCache = new DiagnosticAnalyzerInfoCache(); Listener = listenerProvider.GetListener(FeatureAttribute.DiagnosticService); _map = new ConditionalWeakTable <Workspace, DiagnosticIncrementalAnalyzer>(); _createIncrementalAnalyzer = CreateIncrementalAnalyzerCallback; _eventMap = new EventMap(); _eventQueue = new TaskQueue(Listener, TaskScheduler.Default); registrationService.Register(this); }
public DocumentAnalysisExecutor( DocumentAnalysisScope analysisScope, CompilationWithAnalyzers?compilationWithAnalyzers, DiagnosticAnalyzerInfoCache analyzerInfoCache) { AnalysisScope = analysisScope; _compilationWithAnalyzers = compilationWithAnalyzers; _analyzerInfoCache = analyzerInfoCache; var compilationBasedAnalyzers = compilationWithAnalyzers?.Analyzers.ToImmutableHashSet(); _compilationBasedAnalyzersInAnalysisScope = compilationBasedAnalyzers != null ? analysisScope.Analyzers.WhereAsArray(compilationBasedAnalyzers.Contains) : ImmutableArray <DiagnosticAnalyzer> .Empty; }
> GetDiagnosticDescriptorsPerReference( DiagnosticAnalyzerInfoCache infoCache, Project project ) { var descriptorPerReference = CreateDiagnosticDescriptorsPerReference( infoCache, CreateDiagnosticAnalyzersPerReference(project) ); var map = _hostAnalyzerReferencesMap.AddRange( CreateProjectAnalyzerReferencesMap(project.AnalyzerReferences) ); return(ConvertReferenceIdentityToName(descriptorPerReference, map)); }
public static SkippedHostAnalyzersInfo Create( Project project, HostDiagnosticAnalyzers hostAnalyzers, DiagnosticAnalyzerInfoCache analyzerInfoCache) { var projectAnalyzers = hostAnalyzers.CreateProjectDiagnosticAnalyzersPerReference(project).SelectMany(v => v.Value); if (projectAnalyzers.IsEmpty()) { return(Default); } var hostAnalyzersPerReference = hostAnalyzers.GetOrCreateHostDiagnosticAnalyzersPerReference(project.Language).SelectMany(v => v.Value); return(Create(projectAnalyzers, hostAnalyzersPerReference, analyzerInfoCache)); }
public static SkippedHostAnalyzersInfo Create( Project project, IEnumerable <AnalyzerReference> hostAnalyzerReferences, DiagnosticAnalyzerInfoCache analyzerInfoCache) { var projectAnalyzers = project.AnalyzerReferences.SelectMany(p => p.GetAnalyzers(project.Language)); if (projectAnalyzers.IsEmpty()) { return(Default); } var hostAnalyzers = hostAnalyzerReferences.SelectMany(p => p.GetAnalyzers(project.Language)); return(Create(projectAnalyzers, hostAnalyzers, analyzerInfoCache)); }
protected DiagnosticAnalyzerService( IDiagnosticUpdateSourceRegistrationService registrationService, IAsynchronousOperationListener?listener) { AnalyzerInfoCache = new DiagnosticAnalyzerInfoCache(); Listener = listener ?? AsynchronousOperationListenerProvider.NullListener; _map = new ConditionalWeakTable <Workspace, DiagnosticIncrementalAnalyzer>(); _createIncrementalAnalyzer = CreateIncrementalAnalyzerCallback; _eventMap = new EventMap(); // use diagnostic event task scheduler so that we never flood async events queue with million of events. // queue itself can handle huge number of events but we are seeing OOM due to captured data in pending events. _eventQueue = new TaskQueue(Listener, s_eventScheduler); registrationService.Register(this); }
static void ComputeSkippedHostAnalyzers( IEnumerable <DiagnosticAnalyzer> projectAnalyzers, IEnumerable <DiagnosticAnalyzer> hostAnalyzers, DiagnosticAnalyzerInfoCache analyzerInfoCache, out ImmutableHashSet <DiagnosticAnalyzer> fullySkippedHostAnalyzers, out ImmutableDictionary <DiagnosticAnalyzer, ImmutableArray <string> > filteredDiagnosticIdsForAnalyzers) { var idsReportedByProjectAnalyzers = GetIdsReportedByProjectAnalyzers(projectAnalyzers, analyzerInfoCache); var fullySkippedHostAnalyzersBuilder = ImmutableHashSet.CreateBuilder <DiagnosticAnalyzer>(); var partiallySkippedHostAnalyzersBuilder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, ImmutableArray <string> >(); using var _ = PooledHashSet <DiagnosticAnalyzer> .GetInstance(out var projectAnalyzersSet); projectAnalyzersSet.AddRange(projectAnalyzers); foreach (var hostAnalyzer in hostAnalyzers) { if (projectAnalyzersSet.Contains(hostAnalyzer)) { // Duplicate project and host analyzer. // Do not mark this as a skipped host analyzer as that will also cause the project analyzer to be skipped. // We already perform the required host analyzer reference de-duping in the executor. continue; } if (!ShouldIncludeHostAnalyzer(hostAnalyzer, idsReportedByProjectAnalyzers, analyzerInfoCache, out var skippedIdsForAnalyzer)) { fullySkippedHostAnalyzersBuilder.Add(hostAnalyzer); } else if (skippedIdsForAnalyzer.Length > 0) { partiallySkippedHostAnalyzersBuilder.Add(hostAnalyzer, skippedIdsForAnalyzer); } } fullySkippedHostAnalyzers = fullySkippedHostAnalyzersBuilder.ToImmutable(); filteredDiagnosticIdsForAnalyzers = partiallySkippedHostAnalyzersBuilder.ToImmutable(); }
public static SkippedHostAnalyzersInfo Create( HostDiagnosticAnalyzers hostAnalyzers, IReadOnlyList <AnalyzerReference> projectAnalyzerReferences, string language, DiagnosticAnalyzerInfoCache analyzerInfoCache) { using var _1 = PooledHashSet <object> .GetInstance(out var projectAnalyzerIds); using var _2 = PooledHashSet <string> .GetInstance(out var projectAnalyzerDiagnosticIds); using var _3 = PooledHashSet <string> .GetInstance(out var projectSuppressedDiagnosticIds); foreach (var(analyzerId, analyzers) in hostAnalyzers.CreateProjectDiagnosticAnalyzersPerReference(projectAnalyzerReferences, language)) { projectAnalyzerIds.Add(analyzerId); foreach (var analyzer in analyzers) { foreach (var descriptor in analyzerInfoCache.GetDiagnosticDescriptors(analyzer)) { projectAnalyzerDiagnosticIds.Add(descriptor.Id); } if (analyzer is DiagnosticSuppressor suppressor) { foreach (var descriptor in suppressor.SupportedSuppressions) { projectSuppressedDiagnosticIds.Add(descriptor.SuppressedDiagnosticId); } } } } if (projectAnalyzerIds.Count == 0) { return(Empty); } var fullySkippedHostAnalyzersBuilder = ImmutableHashSet.CreateBuilder <DiagnosticAnalyzer>(); var partiallySkippedHostAnalyzersBuilder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, ImmutableArray <string> >(); foreach (var(hostAnalyzerId, analyzers) in hostAnalyzers.GetOrCreateHostDiagnosticAnalyzersPerReference(language)) { foreach (var hostAnalyzer in analyzers) { if (projectAnalyzerIds.Contains(hostAnalyzerId)) { // Duplicate project and host analyzer. // Do not mark this as a skipped host analyzer as that will also cause the project analyzer to be skipped. // We already perform the required host analyzer reference de-duping in the executor. continue; } if (!ShouldIncludeHostAnalyzer(hostAnalyzer, projectAnalyzerDiagnosticIds, projectSuppressedDiagnosticIds, analyzerInfoCache, out var skippedIdsForAnalyzer)) { fullySkippedHostAnalyzersBuilder.Add(hostAnalyzer); } else if (skippedIdsForAnalyzer.Length > 0) { partiallySkippedHostAnalyzersBuilder.Add(hostAnalyzer, skippedIdsForAnalyzer); } } } var fullySkippedHostAnalyzers = fullySkippedHostAnalyzersBuilder.ToImmutable(); var filteredDiagnosticIdsForAnalyzers = partiallySkippedHostAnalyzersBuilder.ToImmutable(); if (fullySkippedHostAnalyzers.IsEmpty && filteredDiagnosticIdsForAnalyzers.IsEmpty) { return(Empty); } return(new SkippedHostAnalyzersInfo(fullySkippedHostAnalyzers, filteredDiagnosticIdsForAnalyzers));
public ImmutableDictionary <string, ImmutableArray <DiagnosticDescriptor> > GetDiagnosticDescriptorsPerReference(DiagnosticAnalyzerInfoCache infoCache, Project project) { var descriptorPerReference = CreateDiagnosticDescriptorsPerReference(infoCache, CreateDiagnosticAnalyzersPerReference(project)); var map = _hostAnalyzerReferencesMap.Value.AddRange(CreateProjectAnalyzerReferencesMap(project)); return(ConvertReferenceIdentityToName(descriptorPerReference, map)); }
public ImmutableDictionary <string, ImmutableArray <DiagnosticDescriptor> > GetDiagnosticDescriptorsPerReference(DiagnosticAnalyzerInfoCache infoCache) { return(ConvertReferenceIdentityToName( CreateDiagnosticDescriptorsPerReference(infoCache, _lazyHostDiagnosticAnalyzersPerReferenceMap.Value), _hostAnalyzerReferencesMap.Value)); }