private ImmutableArray <Diagnostic> GetDiagnostics(string filePath, string csharpSource) { SyntaxTree tree = CSharpSyntaxTree.ParseText(csharpSource, path: filePath); CSharpCompilation compilation = CSharpCompilation.Create("target") .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)) .AddSyntaxTrees(tree); ImmutableArray <Diagnostic> parseDiagnostics = compilation.GetParseDiagnostics(); Assembly stylecopAnalyzersAssembly = Assembly.LoadFile(GetPathToFile(@"StyleCop.Analyzers.dll")); ImmutableArray <DiagnosticAnalyzer> analyzers = stylecopAnalyzersAssembly.GetTypes() .Where(t => t.IsAbstract == false && typeof(DiagnosticAnalyzer).IsAssignableFrom(t)) .Select(t => Activator.CreateInstance(t) as DiagnosticAnalyzer) .ToImmutableArray(); CompilationWithAnalyzersOptions options = new CompilationWithAnalyzersOptions( new AnalyzerOptions(default(ImmutableArray <AdditionalText>)), OnAnalyzerException, false, false); CompilationWithAnalyzers compilationWithAnalyzers = new CompilationWithAnalyzers(compilation, analyzers, options); Task <ImmutableArray <Diagnostic> > analyzerDiagnosticsTask = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(); analyzerDiagnosticsTask.Wait(); ImmutableArray <Diagnostic> analyzerDiagnostics = analyzerDiagnosticsTask.Result; return(parseDiagnostics.Concat(analyzerDiagnostics).ToImmutableArray()); }
static async Task <CompilationWithAnalyzers> CreateCompilationWithAnalyzerAsync( Project project, ImmutableArray <DiagnosticAnalyzer> analyzers, CancellationToken cancellationToken) { // Always run analyzers concurrently in OOP const bool concurrentAnalysis = true; // Get original compilation var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); // Fork compilation with concurrent build. this is okay since WithAnalyzers will fork compilation // anyway to attach event queue. This should make compiling compilation concurrent and make things // faster compilation = compilation.WithOptions(compilation.Options.WithConcurrentBuild(concurrentAnalysis)); // Run analyzers concurrently, with performance logging and reporting suppressed diagnostics. // This allows all client requests with or without performance data and/or suppressed diagnostics to be satisfied. // TODO: can we support analyzerExceptionFilter in remote host? // right now, host doesn't support watson, we might try to use new NonFatal watson API? var analyzerOptions = new CompilationWithAnalyzersOptions( options: new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project), onAnalyzerException: null, analyzerExceptionFilter: null, concurrentAnalysis: concurrentAnalysis, logAnalyzerExecutionTime: true, reportSuppressedDiagnostics: true); return(compilation.WithAnalyzers(analyzers, analyzerOptions)); }
private static void ExecuteAnalyzers( PreviewWorkspace previewWorkspace, ImmutableArray <DiagnosticAnalyzer> analyzers ) { var analyzerOptions = new AnalyzerOptions( additionalFiles: ImmutableArray <AdditionalText> .Empty ); var workspaceAnalyzerOptions = new WorkspaceAnalyzerOptions( analyzerOptions, previewWorkspace.CurrentSolution ); var compilationWithAnalyzersOptions = new CompilationWithAnalyzersOptions( workspaceAnalyzerOptions, onAnalyzerException: null, concurrentAnalysis: false, logAnalyzerExecutionTime: false ); var project = previewWorkspace.CurrentSolution.Projects.Single(); var compilation = project.GetRequiredCompilationAsync(CancellationToken.None).Result; var compilationWithAnalyzers = new CompilationWithAnalyzers( compilation, analyzers, compilationWithAnalyzersOptions ); var result = compilationWithAnalyzers.GetAnalysisResultAsync(CancellationToken.None).Result; Assert.Equal(1, result.CompilationDiagnostics.Count); }
internal CompilationWithAnalyzers GetCompilationWithAnalyzers(Project project, Compilation compilation, bool concurrentAnalysis, bool reportSuppressedDiagnostics) { Contract.ThrowIfFalse(project.SupportsCompilation); Contract.ThrowIfNull(compilation); var analysisOptions = new CompilationWithAnalyzersOptions( new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Workspace), GetOnAnalyzerException(project.Id), concurrentAnalysis, logAnalyzerExecutionTime: true, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var analyzers = _stateManager.GetAnalyzers(project); var filteredAnalyzers = analyzers .Where(a => !CompilationWithAnalyzers.IsDiagnosticAnalyzerSuppressed(a, compilation.Options, analysisOptions.OnAnalyzerException)) .Distinct() .ToImmutableArray(); if (filteredAnalyzers.IsEmpty) { return(null); } return(new CompilationWithAnalyzers(compilation, filteredAnalyzers, analysisOptions)); }
public static ImmutableArray <Diagnostic> GetAnalyzerDiagnostics <TCompilation>( this TCompilation c, DiagnosticAnalyzer[] analyzers, TestValidationMode validationMode, AnalyzerOptions options = null) where TCompilation : Compilation { var compilationWithAnalyzerOptions = new CompilationWithAnalyzersOptions(options, OnAnalyzerException, concurrentAnalysis: c.Options.ConcurrentBuild, logAnalyzerExecutionTime: false); var compilationWithAnalyzers = c.WithAnalyzers(analyzers.ToImmutableArray(), compilationWithAnalyzerOptions); var diagnostics = c.GetDiagnostics(); if (validationMode != TestValidationMode.AllowCompileErrors) { CompilationUtils.ValidateNoCompileErrors(diagnostics); } var diagnosticDescriptors = analyzers.SelectMany(analyzer => analyzer.SupportedDiagnostics); var analyzerDiagnosticIds = diagnosticDescriptors.Select(diagnosticDescriptor => diagnosticDescriptor.Id); var allDiagnosticIds = new HashSet <string>(analyzerDiagnosticIds, StringComparer.Ordinal) { "AD0001" // Failures caught by the Analyzer Driver. }; var allDiagnostics = compilationWithAnalyzers.GetAllDiagnosticsAsync().Result; var resultDiagnostics = allDiagnostics.Where(diagnostic => allDiagnosticIds.Contains(diagnostic.Id)); return(resultDiagnostics.ToImmutableArray()); }
internal static async Task <ImmutableArray <Diagnostic> > GetDiagnostics(Project project, List <DiagnosticAnalyzer> providers, CancellationToken token) { var analyzers = ImmutableArray <DiagnosticAnalyzer> .Empty.AddRange(providers); try { var compilation = await project.GetCompilationAsync(token).ConfigureAwait(false); CompilationWithAnalyzers compilationWithAnalyzer; var options = new CompilationWithAnalyzersOptions( null, delegate(Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diag) { LoggingService.LogError("Exception in diagnostic analyzer " + diag.Id + ":" + diag.GetMessage(), exception); }, null, true, false ); compilationWithAnalyzer = compilation.WithAnalyzers(analyzers, options); if (token.IsCancellationRequested) { return(ImmutableArray <Diagnostic> .Empty); } return(await compilationWithAnalyzer.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false)); } catch (Exception) { return(ImmutableArray <Diagnostic> .Empty); } finally { CompilationWithAnalyzers.ClearAnalyzerState(analyzers); } }
static async Task <ImmutableArray <Diagnostic> > GetDiagnosticsForDocument(ImmutableArray <DiagnosticAnalyzer> analyzers, Microsoft.CodeAnalysis.Document doc, ImmutableHashSet <string> diagnostics, CancellationToken token) { var sol = doc.Project.Solution; var options = new CompilationWithAnalyzersOptions( new WorkspaceAnalyzerOptions( new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty), sol.Options, sol), delegate(Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diag) { LoggingService.LogError("Exception in diagnostic analyzer " + diag.Id + ":" + diag.GetMessage(), exception); }, true, false ); var model = await doc.GetSemanticModelAsync(token).ConfigureAwait(false); var compilationWithAnalyzer = model.Compilation.WithAnalyzers(analyzers, options); var diagnosticList = new List <Diagnostic> (); diagnosticList.AddRange(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, token).ConfigureAwait(false)); diagnosticList.AddRange(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, token).ConfigureAwait(false)); return(diagnosticList.ToImmutableArray()); }
private async Task <DiagnosticAnalysisResultMap <string, DiagnosticAnalysisResultBuilder> > AnalyzeAsync( BidirectionalMap <string, DiagnosticAnalyzer> analyzerMap, ImmutableArray <DiagnosticAnalyzer> analyzers, OptionSet options, bool reportSuppressedDiagnostics, bool logAnalyzerExecutionTime, CancellationToken cancellationToken) { // flag that controls concurrency var useConcurrent = true; // get original compilation var compilation = await _project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); // fork compilation with concurrent build. this is okay since WithAnalyzers will fork compilation // anyway to attach event queue. this should make compiling compilation concurrent and make things // faster compilation = compilation.WithOptions(compilation.Options.WithConcurrentBuild(useConcurrent)); // We need this to fork soluton, otherwise, option is cached at document. // all this can go away once we do this - https://github.com/dotnet/roslyn/issues/19284 var temporaryWorksapce = new TemporaryWorkspace(_project.Solution); // TODO: can we support analyzerExceptionFilter in remote host? // right now, host doesn't support watson, we might try to use new NonFatal watson API? var analyzerOptions = new CompilationWithAnalyzersOptions( options: new WorkspaceAnalyzerOptions(_project.AnalyzerOptions, MergeOptions(_project.Solution.Options, options), temporaryWorksapce.CurrentSolution), onAnalyzerException: OnAnalyzerException, analyzerExceptionFilter: null, concurrentAnalysis: useConcurrent, logAnalyzerExecutionTime: logAnalyzerExecutionTime, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var analyzerDriver = compilation.WithAnalyzers(analyzers, analyzerOptions); // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API. var analysisResult = await analyzerDriver.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); // REVIEW: the design of current analyzer engine is that, information/states in CompilationWithAnalyzer (more specifically AnalyzerManager singleton) // will live forever until analyzer references (analyzers), which is given to CompilationWithAnalyzer, go away. // that is not suitable for OOP since OOP will create new workspace // for each analysis but share all resources including analyzer references. // until, we address this issue, OOP will clear state every time analysis is done. // // * NOTE * this only works for now since we don't run analysis on multiple threads. // // best way to fix this is doing this - https://github.com/dotnet/roslyn/issues/2830 // host should control lifetime of all information related to analyzer reference explicitly CompilationWithAnalyzers.ClearAnalyzerState(analyzers); var builderMap = analysisResult.ToResultBuilderMap(_project, VersionStamp.Default, compilation, analysisResult.Analyzers, cancellationToken); return(DiagnosticAnalysisResultMap.Create( builderMap.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value), analysisResult.AnalyzerTelemetryInfo.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value), _exceptions.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value.ToImmutableArray()))); }
public async Task RunCodeAnalysisAsync( CodeAnalysisResult result, ImmutableArray <DiagnosticAnalyzer> analyzers, Project project, ImmutableHashSet <string> formattableDocumentPaths, DiagnosticSeverity severity, ILogger logger, CancellationToken cancellationToken) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); if (compilation is null) { return; } // If are not running any analyzers and are not reporting compiler diagnostics, then there is // nothing to report. if (analyzers.IsEmpty && !_includeComplilerDiagnostics) { return; } ImmutableArray <Diagnostic> diagnostics; if (analyzers.IsEmpty) { diagnostics = compilation.GetDiagnostics(cancellationToken); } else { var analyzerOptions = new CompilationWithAnalyzersOptions( project.AnalyzerOptions, onAnalyzerException: null, concurrentAnalysis: true, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: false); var analyzerCompilation = compilation.WithAnalyzers(analyzers, analyzerOptions); diagnostics = _includeComplilerDiagnostics ? await analyzerCompilation.GetAllDiagnosticsAsync(cancellationToken).ConfigureAwait(false) : await analyzerCompilation.GetAnalyzerDiagnosticsAsync(cancellationToken).ConfigureAwait(false); } // filter diagnostics foreach (var diagnostic in diagnostics) { if (!diagnostic.IsSuppressed && diagnostic.Severity >= severity && diagnostic.Location.IsInSource && diagnostic.Location.SourceTree != null && formattableDocumentPaths.Contains(diagnostic.Location.SourceTree.FilePath)) { result.AddDiagnostic(project, diagnostic); } } }
public static Task <ImmutableArray <Diagnostic> > GetAnalyzerDiagnosticsAsync( this Compilation compilation, ImmutableArray <DiagnosticAnalyzer> analyzers, CompilationWithAnalyzersOptions analysisOptions, CancellationToken cancellationToken = default) { var compilationWithAnalyzers = new CompilationWithAnalyzers(compilation, analyzers, analysisOptions); return(compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(cancellationToken)); }
private async Task <DiagnosticAnalysisResultMap <string, DiagnosticAnalysisResultBuilder> > AnalyzeAsync( BidirectionalMap <string, DiagnosticAnalyzer> analyzerMap, ImmutableArray <DiagnosticAnalyzer> analyzers, OptionSet options, bool reportSuppressedDiagnostics, bool logAnalyzerExecutionTime, CancellationToken cancellationToken) { // flag that controls concurrency var useConcurrent = true; // get original compilation var compilation = await _project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); // fork compilation with concurrent build. this is okay since WithAnalyzers will fork compilation // anyway to attach event queue. this should make compiling compilation concurrent and make things // faster compilation = compilation.WithOptions(compilation.Options.WithConcurrentBuild(useConcurrent)); // We need this to fork soluton, otherwise, option is cached at document. // all this can go away once we do this - https://github.com/dotnet/roslyn/issues/19284 using (var temporaryWorksapce = new TemporaryWorkspace(_project.Solution)) { // TODO: can we support analyzerExceptionFilter in remote host? // right now, host doesn't support watson, we might try to use new NonFatal watson API? var analyzerOptions = new CompilationWithAnalyzersOptions( options: new WorkspaceAnalyzerOptions(_project.AnalyzerOptions, MergeOptions(_project.Solution.Options, options), temporaryWorksapce.CurrentSolution), onAnalyzerException: OnAnalyzerException, analyzerExceptionFilter: null, concurrentAnalysis: useConcurrent, logAnalyzerExecutionTime: logAnalyzerExecutionTime, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var analyzerDriver = compilation.WithAnalyzers(analyzers, analyzerOptions); // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API. var analysisResult = await analyzerDriver.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); // record performance if tracker is available if (_performanceTracker != null) { // +1 to include project itself _performanceTracker.AddSnapshot(analysisResult.AnalyzerTelemetryInfo.ToAnalyzerPerformanceInfo(), _project.DocumentIds.Count + 1); } var builderMap = analysisResult.ToResultBuilderMap(_project, VersionStamp.Default, compilation, analysisResult.Analyzers, cancellationToken); return(DiagnosticAnalysisResultMap.Create( builderMap.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value), analysisResult.AnalyzerTelemetryInfo.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value), _exceptions.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value.ToImmutableArray()))); } }
public CSharpCompiler() { whitelist = new Whitelist(); parseOptions = CreateParseOptions(); compilationOptions = CreateCompilationOptions(); analyzerOptions = CreateAnalyzerOptions(); doubleOptions = CreateCompilationWithAnalyzersOptions(analyzerOptions); var analyzer = new CSharpDiagnosticAnalyser(); immutableanalyzers = ImmutableArray <DiagnosticAnalyzer> .Empty.Add(analyzer); descriptors = new diagnosticdescriptors(); }
public void Execute(GeneratorExecutionContext context) { if (context.SyntaxReceiver is not AggregatedSyntaxCapture asc) { return; } // Ensure no analyzer has failed using var scope = asc.ServiceProvider.CreateScope(); var scopeService = scope.ServiceProvider; // Setup the service. var option = new CompilationWithAnalyzersOptions(null, null, concurrentAnalysis: false, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: true, analyzerExceptionFilter: null); try { var analyzers = context.Compilation.WithAnalyzers(scopeService.GetServices <DiagnosticAnalyzer>().ToImmutableArray(), option); var hasFailed = false; foreach (var result in analyzers.GetAnalyzerDiagnosticsAsync(context.CancellationToken).GetAwaiter().GetResult()) { context.ReportDiagnostic(result); hasFailed |= result.Severity == DiagnosticSeverity.Error; } if (hasFailed) { return; } var capturedSyntaxes = scopeService.GetService <PredicateSyntaxCapture>()?.CapturedSyntaxes.ToImmutableArray() ?? default; var contextAccessor = scopeService.GetRequiredService <SourceContextAccessor>(); { contextAccessor.OnOperationCanceled = context.CancellationToken; contextAccessor.SourceCompilation = context.Compilation; contextAccessor.AnalyzerConfigOptions = context.AnalyzerConfigOptions; contextAccessor.AdditionalFiles = context.AdditionalFiles; contextAccessor.ParseOptions = context.ParseOptions; contextAccessor.AddSource = context.AddSource; } foreach (var generator in scopeService.GetServices <SourcebergGenerator>()) { generator.CommonContext = contextAccessor; generator.RunGeneration(capturedSyntaxes, context.CancellationToken); } } catch (Exception exception) { context.ReportDiagnostic(Diagnostic.Create(UnexpectedExceptionDescriptor, Location.None, exception.GetType(), GeneratorGroupType, exception)); } }
public async Task <DiagnosticAnalysisResultMap <string, DiagnosticAnalysisResultBuilder> > GetDiagnosticsAsync( IEnumerable <AnalyzerReference> hostAnalyzers, IEnumerable <string> analyzerIds, bool reportSuppressedDiagnostics, bool logAnalyzerExecutionTime, CancellationToken cancellationToken) { var analyzerMap = CreateAnalyzerMap(hostAnalyzers, _project); var analyzers = GetAnalyzers(analyzerMap, analyzerIds); if (analyzers.Length == 0) { return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <string, DiagnosticAnalysisResultBuilder> .Empty, ImmutableDictionary <string, AnalyzerTelemetryInfo> .Empty)); } var compilation = await _project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); // TODO: can we support analyzerExceptionFilter in remote host? // right now, host doesn't support watson, we might try to use new NonFatal watson API? var analyzerOptions = new CompilationWithAnalyzersOptions( options: _project.AnalyzerOptions, onAnalyzerException: OnAnalyzerException, analyzerExceptionFilter: null, concurrentAnalysis: true, logAnalyzerExecutionTime: logAnalyzerExecutionTime, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var analyzerDriver = compilation.WithAnalyzers(analyzers, analyzerOptions); // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API. var analysisResult = await analyzerDriver.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); // REVIEW: the design of current analyzer engine is that, information/states in CompilationWithAnalyzer (more specifically AnalyzerManager singleton) // will live forever until analyzer references (analyzers), which is given to CompilationWithAnalyzer, go away. // that is not suitable for OOP since OOP will create new workspace // for each analysis but share all resources including analyzer references. // until, we address this issue, OOP will clear state every time analysis is done. // // * NOTE * this only works for now since we don't run analysis on multiple threads. // // best way to fix this is doing this - https://github.com/dotnet/roslyn/issues/2830 // host should control lifetime of all information related to analyzer reference explicitly CompilationWithAnalyzers.ClearAnalyzerState(analyzers); var builderMap = analysisResult.ToResultBuilderMap(_project, VersionStamp.Default, compilation, analysisResult.Analyzers, cancellationToken); return(DiagnosticAnalysisResultMap.Create(builderMap.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value), analysisResult.AnalyzerTelemetryInfo.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value), _exceptions.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value.ToImmutableArray()))); }
public DiagnosticAnalyzerDriver( Project project, DiagnosticIncrementalAnalyzer owner, CancellationToken cancellationToken) { _project = project; _owner = owner; _cancellationToken = cancellationToken; _analysisOptions = new CompilationWithAnalyzersOptions( new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Workspace), owner.GetOnAnalyzerException(project.Id), concurrentAnalysis: false, logAnalyzerExecutionTime: true); }
public DiagnosticAnalyzerDriver( Project project, DiagnosticIncrementalAnalyzer owner, CancellationToken cancellationToken) { _project = project; _owner = owner; _cancellationToken = cancellationToken; _analysisOptions = new CompilationWithAnalyzersOptions( new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Workspace), owner.GetOnAnalyzerException(project.Id), concurrentAnalysis: false, logAnalyzerExecutionTime: true); }
private async Task <DiagnosticAnalysisResultMap <string, DiagnosticAnalysisResultBuilder> > AnalyzeAsync( BidirectionalMap <string, DiagnosticAnalyzer> analyzerMap, ImmutableArray <DiagnosticAnalyzer> analyzers, SkippedHostAnalyzersInfo skippedAnalyzersInfo, bool reportSuppressedDiagnostics, bool logAnalyzerExecutionTime, CancellationToken cancellationToken) { // flag that controls concurrency var useConcurrent = true; // get original compilation var compilation = await _project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); // fork compilation with concurrent build. this is okay since WithAnalyzers will fork compilation // anyway to attach event queue. this should make compiling compilation concurrent and make things // faster compilation = compilation.WithOptions(compilation.Options.WithConcurrentBuild(useConcurrent)); // TODO: can we support analyzerExceptionFilter in remote host? // right now, host doesn't support watson, we might try to use new NonFatal watson API? var analyzerOptions = new CompilationWithAnalyzersOptions( options: new WorkspaceAnalyzerOptions(_project.AnalyzerOptions, _project.Solution), onAnalyzerException: null, analyzerExceptionFilter: null, concurrentAnalysis: useConcurrent, logAnalyzerExecutionTime: logAnalyzerExecutionTime, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var analyzerDriver = compilation.WithAnalyzers(analyzers, analyzerOptions); // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API. var(analysisResult, additionalPragmaSuppressionDiagnostics) = await analyzerDriver.GetAnalysisResultAsync(_project, _analyzerInfoCache, cancellationToken).ConfigureAwait(false); // record performance if tracker is available if (_performanceTracker != null) { // +1 to include project itself _performanceTracker.AddSnapshot(analysisResult.AnalyzerTelemetryInfo.ToAnalyzerPerformanceInfo(_analyzerInfoCache), _project.DocumentIds.Count + 1); } var builderMap = analysisResult.ToResultBuilderMap(additionalPragmaSuppressionDiagnostics, _project, VersionStamp.Default, compilation, analysisResult.Analyzers, skippedAnalyzersInfo, cancellationToken); return(DiagnosticAnalysisResultMap.Create( builderMap.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value), analysisResult.AnalyzerTelemetryInfo.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value))); }
private static async Task <ImmutableArray <Diagnostic> > GetDiagnosticsAsync( Project project, ImmutableArray <DiagnosticAnalyzer> diagnosticAnalyzers, CancellationToken cancellationToken) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); RoslynDebug.AssertNotNull(compilation); var analyzerOptions = new CompilationWithAnalyzersOptions( project.AnalyzerOptions, onAnalyzerException: null, concurrentAnalysis: true, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: false); var analyzerCompilation = compilation.WithAnalyzers(diagnosticAnalyzers, analyzerOptions); return(await analyzerCompilation.GetAnalyzerDiagnosticsAsync(cancellationToken).ConfigureAwait(false)); }
public static async Task <IEnumerable <Diagnostic> > GetAnalyzerDiagnostics(this Compilation compilation, DiagnosticAnalyzer analyzer, CancellationToken cancellationToken = default) { var exceptions = new List <Exception>(); var analysisOptions = new CompilationWithAnalyzersOptions( new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty), (exception, _, __) => exceptions.Add(exception), concurrentAnalysis: false, logAnalyzerExecutionTime: false); var diagnostics = await compilation .WithAnalyzers(ImmutableArray.Create(analyzer), analysisOptions) .GetAnalyzerDiagnosticsAsync(cancellationToken); if (exceptions.Any()) { throw new AggregateException(exceptions); } return(diagnostics .OrderBy(diagnostic => diagnostic.Location.SourceSpan) .ThenBy(diagnostic => diagnostic.Id)); }
public async Task <IEnumerable <ISymbol> > GetSymbolsAsync( Project project, RenameScope scope, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var compilationWithAnalyzersOptions = new CompilationWithAnalyzersOptions( options: default(AnalyzerOptions), onAnalyzerException: default(Action <Exception, DiagnosticAnalyzer, Diagnostic>), concurrentAnalysis: true, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: false); Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <SymbolKind> symbolKinds = scope switch { RenameScope.Type => ImmutableArray.Create(SymbolKind.NamedType), RenameScope.Member => ImmutableArray.Create(SymbolKind.Field, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property), RenameScope.Local => ImmutableArray.Create(SymbolKind.Field, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property), _ => throw new InvalidOperationException(), }; var analyzer = new Analyzer( symbolKinds, IncludeGeneratedCode); var compilationWithAnalyzers = new CompilationWithAnalyzers( compilation, ImmutableArray.Create((DiagnosticAnalyzer)analyzer), compilationWithAnalyzersOptions); ImmutableArray <Diagnostic> _ = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(cancellationToken).ConfigureAwait(false); return(analyzer.Symbols); }
internal CompilationWithAnalyzers GetCompilationWithAnalyzers(Project project, Compilation compilation, bool concurrentAnalysis, bool reportSuppressedDiagnostics) { Contract.ThrowIfFalse(project.SupportsCompilation); Contract.ThrowIfNull(compilation); Func <Exception, bool> analyzerExceptionFilter = ex => { if (project.Solution.Workspace.Options.GetOption(InternalDiagnosticsOptions.CrashOnAnalyzerException)) { // if option is on, crash the host to get crash dump. FatalError.ReportUnlessCanceled(ex); } return(true); }; var analysisOptions = new CompilationWithAnalyzersOptions( new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Workspace), GetOnAnalyzerException(project.Id), analyzerExceptionFilter, concurrentAnalysis, logAnalyzerExecutionTime: true, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var analyzers = _stateManager.GetAnalyzers(project); var filteredAnalyzers = analyzers .Where(a => !CompilationWithAnalyzers.IsDiagnosticAnalyzerSuppressed(a, compilation.Options, analysisOptions.OnAnalyzerException)) .Distinct() .ToImmutableArray(); if (filteredAnalyzers.IsEmpty) { return(null); } return(new CompilationWithAnalyzers(compilation, filteredAnalyzers, analysisOptions)); }
private ImmutableArray <Diagnostic> GetDiagnostics(Document document) { var analyzers = ImmutableArray.Create(CreateAnalyzer()); var compilation = document.Project.GetCompilationAsync(CancellationToken.None).Result; List <Exception> exceptions = new List <Exception>(); var options = new CompilationWithAnalyzersOptions( options: new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty), onAnalyzerException: (exception, analyzer, arg3) => exceptions.Add(exception), concurrentAnalysis: true, logAnalyzerExecutionTime: false); var compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, options); var discarded = compilation.GetDiagnostics(CancellationToken.None); var tree = document.GetSyntaxTreeAsync(CancellationToken.None).Result; var builder = ImmutableArray.CreateBuilder <Diagnostic>(); foreach (var diagnostic in compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result) { var location = diagnostic.Location; if (location.IsInSource && location.SourceTree == tree) { builder.Add(diagnostic); } } if (exceptions.Count != 0) { Assert.Fail($"Unhandled exception occurred during analysis: \r\n{string.Join("\r\n", exceptions)}"); } return(builder.ToImmutable()); }
public async Task <ImmutableArray <SpellingFixResult> > FixProjectAsync( Project project, CancellationToken cancellationToken = default) { project = CurrentSolution.GetProject(project.Id); ISpellingService service = MefWorkspaceServices.Default.GetService <ISpellingService>(project.Language); if (service == null) { return(ImmutableArray <SpellingFixResult> .Empty); } ImmutableArray <Diagnostic> previousDiagnostics = ImmutableArray <Diagnostic> .Empty; ImmutableArray <Diagnostic> previousPreviousDiagnostics = ImmutableArray <Diagnostic> .Empty; ImmutableArray <SpellingFixResult> .Builder results = ImmutableArray.CreateBuilder <SpellingFixResult>(); bool nonSymbolsFixed = (Options.ScopeFilter & (SpellingScopeFilter.NonSymbol)) == 0; while (true) { cancellationToken.ThrowIfCancellationRequested(); var compilationWithAnalyzersOptions = new CompilationWithAnalyzersOptions( options: default(AnalyzerOptions), onAnalyzerException: default(Action <Exception, DiagnosticAnalyzer, Diagnostic>), concurrentAnalysis: true, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: false); Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); DiagnosticAnalyzer analyzer = service.CreateAnalyzer(SpellingData, Options); var compilationWithAnalyzers = new CompilationWithAnalyzers( compilation, ImmutableArray.Create(analyzer), compilationWithAnalyzersOptions); ImmutableArray <Diagnostic> diagnostics = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(cancellationToken).ConfigureAwait(false); #if DEBUG foreach (IGrouping <Diagnostic, Diagnostic> grouping in diagnostics .GroupBy(f => f, DiagnosticDeepEqualityComparer.Instance)) { using (IEnumerator <Diagnostic> en = grouping.GetEnumerator()) { if (en.MoveNext() && en.MoveNext()) { Debug.Fail(DiagnosticFormatter.FormatDiagnostic(en.Current)); } } } #endif int length = diagnostics.Length; if (length == 0) { break; } if (length == previousDiagnostics.Length && !diagnostics.Except(previousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any()) { break; } if (length == previousPreviousDiagnostics.Length && !diagnostics.Except(previousPreviousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any()) { LogHelpers.WriteInfiniteLoopSummary(diagnostics, previousDiagnostics, project, FormatProvider); break; } var spellingDiagnostics = new List <SpellingDiagnostic>(); foreach (Diagnostic diagnostic in diagnostics) { Debug.Assert(diagnostic.Id == CommonDiagnosticIdentifiers.PossibleMisspellingOrTypo, diagnostic.Id); if (diagnostic.Id != CommonDiagnosticIdentifiers.PossibleMisspellingOrTypo) { if (diagnostic.IsAnalyzerExceptionDiagnostic()) { LogHelpers.WriteDiagnostic(diagnostic, baseDirectoryPath: Path.GetDirectoryName(project.FilePath), formatProvider: FormatProvider, indentation: " ", verbosity: Verbosity.Detailed); } continue; } SpellingDiagnostic spellingDiagnostic = service.CreateSpellingDiagnostic(diagnostic); spellingDiagnostics.Add(spellingDiagnostic); } if (!nonSymbolsFixed) { List <SpellingFixResult> commentResults = await FixCommentsAsync(project, spellingDiagnostics, cancellationToken).ConfigureAwait(false); results.AddRange(commentResults); nonSymbolsFixed = true; } if ((Options.ScopeFilter & SpellingScopeFilter.Symbol) == 0) { break; } (List <SpellingFixResult> symbolResults, bool allIgnored) = await FixSymbolsAsync( project, spellingDiagnostics, service.SyntaxFacts, cancellationToken) .ConfigureAwait(false); results.AddRange(symbolResults); if (allIgnored) { break; } if (Options.DryRun) { break; } project = CurrentSolution.GetProject(project.Id); previousPreviousDiagnostics = previousDiagnostics; previousDiagnostics = diagnostics; } return(results.ToImmutableArray()); }
internal CompilationWithAnalyzers GetCompilationWithAnalyzers(Project project, Compilation compilation, bool concurrentAnalysis, bool reportSuppressedDiagnostics) { Contract.ThrowIfFalse(project.SupportsCompilation); Contract.ThrowIfNull(compilation); var analysisOptions = new CompilationWithAnalyzersOptions( new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Workspace), GetOnAnalyzerException(project.Id), concurrentAnalysis, logAnalyzerExecutionTime: true, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var analyzers = _stateManager.GetAnalyzers(project); var filteredAnalyzers = analyzers .Where(a => !CompilationWithAnalyzers.IsDiagnosticAnalyzerSuppressed(a, compilation.Options, analysisOptions.OnAnalyzerException)) .Distinct() .ToImmutableArray(); if (filteredAnalyzers.IsEmpty) { return null; } return new CompilationWithAnalyzers(compilation, filteredAnalyzers, analysisOptions); }
protected async Task <Diagnostic[]> GetSortedDiagnosticsFromDocumentsAsync(AnalyzerVerificationContext context, DiagnosticAnalyzer analyzer, Document[] documents, params DiagnosticResult[] expected) { var projects = new HashSet <Project>(); foreach (var document in documents) { projects.Add(document.Project); } var diagnostics = new List <Diagnostic>(); foreach (var project in projects) { var analyzers = ImmutableArray.Create(analyzer) .AddRange(GetRelatedAnalyzers(analyzer)); var compilation = await project.GetCompilationAsync(); Assert.NotNull(compilation); var optionsProvider = new AnalyzerOptionsProvider(context.Options); var options = new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty, optionsProvider); var analyzerOptions = new CompilationWithAnalyzersOptions(options, null, true, true, true); var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, reportSuppressedDiagnostics: true); var specificDiagnosticOptions = compilationOptions.SpecificDiagnosticOptions; // Force all tested diagnostics to be enabled foreach (var descriptor in analyzer.SupportedDiagnostics) { specificDiagnosticOptions = specificDiagnosticOptions.SetItem(descriptor.Id, ReportDiagnostic.Info); } var compilationWithAnalyzers = compilation .WithOptions(compilationOptions.WithSpecificDiagnosticOptions(specificDiagnosticOptions)) .WithAnalyzers(analyzers, analyzerOptions); var allDiagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync(); var errors = allDiagnostics.Where(d => d.Severity == DiagnosticSeverity.Error).ToList(); foreach (var error in errors) { Assert.True(false, $"Line {error.Location.GetLineSpan().StartLinePosition.Line}: {error.GetMessage()}"); } var diags = allDiagnostics .Except(errors) .Where(d => d.Location.IsInSource); //only keep diagnostics related to a source location foreach (var diag in diags) { // We should not hit this anymore, but keep in case we change the previous filter if (diag.Location == Location.None || diag.Location.IsInMetadata) { diagnostics.Add(diag); } else { foreach (var document in documents) { var tree = await document.GetSyntaxTreeAsync(); if (tree == diag.Location.SourceTree) { diagnostics.Add(diag); } } } } } var results = SortDiagnostics(FilterDiagnostics(diagnostics, context.Filters)); diagnostics.Clear(); return(results); }
public async Task RunCodeAnalysisAsync( CodeAnalysisResult result, ImmutableArray <DiagnosticAnalyzer> analyzers, Project project, ImmutableHashSet <string> formattableDocumentPaths, DiagnosticSeverity severity, bool includeCompilerDiagnostics, ILogger logger, CancellationToken cancellationToken) { // If are not running any analyzers and are not reporting compiler diagnostics, then there is // nothing to report. if (analyzers.IsEmpty && includeCompilerDiagnostics) { return; } // For projects targeting NetStandard, the Runtime references are resolved from the project.assets.json. // This file is generated during a `dotnet restore`. if (!AllReferencedProjectsLoaded(project)) { logger.LogWarning(Resources.Required_references_did_not_load_for_0_or_referenced_project_Run_dotnet_restore_prior_to_formatting, project.Name); return; } var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); if (compilation is null) { return; } ImmutableArray <Diagnostic> diagnostics; if (analyzers.IsEmpty) { diagnostics = compilation.GetDiagnostics(cancellationToken); } else { logger.LogDebug(Resources.Running_0_analyzers_on_1, analyzers.Length, project.Name); var analyzerOptions = new CompilationWithAnalyzersOptions( project.AnalyzerOptions, onAnalyzerException: null, concurrentAnalysis: true, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: false); var analyzerCompilation = compilation.WithAnalyzers(analyzers, analyzerOptions); diagnostics = includeCompilerDiagnostics ? await analyzerCompilation.GetAllDiagnosticsAsync(cancellationToken).ConfigureAwait(false) : await analyzerCompilation.GetAnalyzerDiagnosticsAsync(cancellationToken).ConfigureAwait(false); } // filter diagnostics foreach (var diagnostic in diagnostics) { if (!diagnostic.IsSuppressed && diagnostic.Severity >= severity && diagnostic.Location.IsInSource && diagnostic.Location.SourceTree != null && formattableDocumentPaths.Contains(diagnostic.Location.SourceTree.FilePath)) { result.AddDiagnostic(project, diagnostic); } } return;
internal CompilationWithAnalyzers GetCompilationWithAnalyzers( Project project, IEnumerable<DiagnosticAnalyzer> analyzers, Compilation compilation, bool concurrentAnalysis, bool reportSuppressedDiagnostics) { Contract.ThrowIfFalse(project.SupportsCompilation); Contract.ThrowIfNull(compilation); Func<Exception, bool> analyzerExceptionFilter = ex => { if (project.Solution.Workspace.Options.GetOption(InternalDiagnosticsOptions.CrashOnAnalyzerException)) { // if option is on, crash the host to get crash dump. FatalError.ReportUnlessCanceled(ex); } return true; }; var analysisOptions = new CompilationWithAnalyzersOptions( new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Workspace), GetOnAnalyzerException(project.Id), analyzerExceptionFilter: analyzerExceptionFilter, concurrentAnalysis: concurrentAnalysis, logAnalyzerExecutionTime: true, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var filteredAnalyzers = analyzers .Where(a => !CompilationWithAnalyzers.IsDiagnosticAnalyzerSuppressed(a, compilation.Options, analysisOptions.OnAnalyzerException)) .Distinct() .ToImmutableArray(); if (filteredAnalyzers.IsEmpty) { return null; } return new CompilationWithAnalyzers(compilation, filteredAnalyzers, analysisOptions); }
protected async Task <Diagnostic[]> GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer analyzer, Document[] documents, bool allowCompilationErrors) { if (documents == null) { throw new ArgumentNullException(nameof(documents)); } var projects = new HashSet <Project>(); foreach (var document in documents) { projects.Add(document.Project); } var diagnostics = new List <Diagnostic>(); var analyzerExceptions = new List <Exception>(); foreach (var project in projects) { var options = new CompilationWithAnalyzersOptions( new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty), (exception, diagnosticAnalyzer, diagnostic) => analyzerExceptions.Add(exception), false, true); var compilationWithAnalyzers = (await project.GetCompilationAsync()) .WithAnalyzers(ImmutableArray.Create(analyzer), options); if (!allowCompilationErrors) { AssertThatCompilationSucceeded(compilationWithAnalyzers); } var diags = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(); if (analyzerExceptions.Any()) { if (analyzerExceptions.Count == 1) { ExceptionDispatchInfo.Capture(analyzerExceptions[0]).Throw(); } else { throw new AggregateException("Multiple exceptions thrown during analysis", analyzerExceptions); } } foreach (var diag in diags) { if (diag.Location == Location.None || diag.Location.IsInMetadata) { diagnostics.Add(diag); } else { for (int i = 0; i < documents.Length; i++) { var document = documents[i]; var tree = await document.GetSyntaxTreeAsync(); if (tree == diag.Location.SourceTree) { diagnostics.Add(diag); } } } } } var results = SortDiagnostics(diagnostics); diagnostics.Clear(); return(results); }
private async Task <ProjectAnalysisResult> AnalyzeProjectCoreAsync(Project project, ImmutableArray <DiagnosticAnalyzer> analyzers, CancellationToken cancellationToken = default) { LogHelpers.WriteUsedAnalyzers(analyzers, null, Options, ConsoleColors.DarkGray, Verbosity.Diagnostic); cancellationToken.ThrowIfCancellationRequested(); Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = (Options.IgnoreCompilerDiagnostics) ? ImmutableArray <Diagnostic> .Empty : compilation.GetDiagnostics(cancellationToken); compilerDiagnostics = FilterDiagnostics(compilerDiagnostics, project, cancellationToken).ToImmutableArray(); ImmutableArray <Diagnostic> diagnostics = ImmutableArray <Diagnostic> .Empty; ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> telemetry = ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty; if (analyzers.Any()) { var compilationWithAnalyzersOptions = new CompilationWithAnalyzersOptions( options: project.AnalyzerOptions, onAnalyzerException: default(Action <Exception, DiagnosticAnalyzer, Diagnostic>), concurrentAnalysis: Options.ConcurrentAnalysis, logAnalyzerExecutionTime: Options.LogAnalyzerExecutionTime, reportSuppressedDiagnostics: Options.ReportSuppressedDiagnostics); var compilationWithAnalyzers = new CompilationWithAnalyzers(compilation, analyzers, compilationWithAnalyzersOptions); if (Options.LogAnalyzerExecutionTime) { AnalysisResult analysisResult = await compilationWithAnalyzers.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); diagnostics = analysisResult.GetAllDiagnostics(); telemetry = analysisResult.AnalyzerTelemetryInfo; } else { diagnostics = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(cancellationToken).ConfigureAwait(false); } } string projectDirectoryPath = Path.GetDirectoryName(project.FilePath); LogHelpers.WriteDiagnostics(FilterDiagnostics(diagnostics.Where(f => f.IsAnalyzerExceptionDiagnostic()), project, cancellationToken).ToImmutableArray(), baseDirectoryPath: projectDirectoryPath, formatProvider: FormatProvider, indentation: " ", verbosity: Verbosity.Detailed); #if DEBUG if (ConsoleOut.Verbosity >= Verbosity.Detailed && diagnostics.Any(f => f.IsAnalyzerExceptionDiagnostic())) { Console.Write("Stop (Y/N)? "); if (char.ToUpperInvariant((char)Console.Read()) == 'Y') { throw new OperationCanceledException(); } } #endif diagnostics = FilterDiagnostics(diagnostics.Where(f => !f.IsAnalyzerExceptionDiagnostic()), project, cancellationToken).ToImmutableArray(); LogHelpers.WriteDiagnostics(compilerDiagnostics, baseDirectoryPath: projectDirectoryPath, formatProvider: FormatProvider, indentation: " ", verbosity: Verbosity.Normal); LogHelpers.WriteDiagnostics(diagnostics, baseDirectoryPath: projectDirectoryPath, formatProvider: FormatProvider, indentation: " ", verbosity: Verbosity.Normal); return(ProjectAnalysisResult.Create(project, compilerDiagnostics, diagnostics, telemetry)); }
public static async Task <IEnumerable <Result> > Check(AnalysisDocument analysisDocument, CancellationToken cancellationToken) { var input = analysisDocument.DocumentContext; if (!AnalysisOptions.EnableFancyFeatures || input.Project == null || !input.IsCompileableInProject || input.AnalysisDocument == null) { return(Enumerable.Empty <Result> ()); } if (SkipContext(input)) { return(Enumerable.Empty <Result> ()); } try { var model = await analysisDocument.DocumentContext.AnalysisDocument.GetSemanticModelAsync(cancellationToken); if (model == null) { return(Enumerable.Empty <Result> ()); } var compilation = model.Compilation; var language = CodeRefactoringService.MimeTypeToLanguage(analysisDocument.Editor.MimeType); var providers = new List <DiagnosticAnalyzer> (); var alreadyAdded = new HashSet <Type>(); if (diagnostics == null) { diagnostics = await CodeRefactoringService.GetCodeDiagnosticsAsync(analysisDocument.DocumentContext, language, cancellationToken); } var diagnosticTable = new Dictionary <string, CodeDiagnosticDescriptor> (); foreach (var diagnostic in diagnostics) { if (alreadyAdded.Contains(diagnostic.DiagnosticAnalyzerType)) { continue; } if (!diagnostic.IsEnabled) { continue; } alreadyAdded.Add(diagnostic.DiagnosticAnalyzerType); var provider = diagnostic.GetProvider(); if (provider == null) { continue; } foreach (var diag in provider.SupportedDiagnostics) { diagnosticTable [diag.Id] = diagnostic; } providers.Add(provider); } if (providers.Count == 0 || cancellationToken.IsCancellationRequested) { return(Enumerable.Empty <Result> ()); } #if DEBUG Debug.Listeners.Add(consoleTraceListener); #endif CompilationWithAnalyzers compilationWithAnalyzer; var analyzers = ImmutableArray <DiagnosticAnalyzer> .Empty.AddRange(providers); var diagnosticList = new List <Diagnostic> (); try { var sol = analysisDocument.DocumentContext.AnalysisDocument.Project.Solution; var options = new CompilationWithAnalyzersOptions( new WorkspaceAnalyzerOptions( new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty), sol.Options, sol), delegate(Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diag) { LoggingService.LogError("Exception in diagnostic analyzer " + diag.Id + ":" + diag.GetMessage(), exception); }, false, false ); compilationWithAnalyzer = compilation.WithAnalyzers(analyzers, options); if (input.ParsedDocument == null || cancellationToken.IsCancellationRequested) { return(Enumerable.Empty <Result> ()); } diagnosticList.AddRange(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, cancellationToken).ConfigureAwait(false)); diagnosticList.AddRange(await compilationWithAnalyzer.GetAnalyzerSyntaxDiagnosticsAsync(model.SyntaxTree, cancellationToken).ConfigureAwait(false)); } catch (OperationCanceledException) { } catch (AggregateException ae) { ae.Flatten().Handle(ix => ix is OperationCanceledException); } catch (Exception ex) { LoggingService.LogError("Error creating analyzer compilation", ex); return(Enumerable.Empty <Result> ()); } finally { #if DEBUG Debug.Listeners.Remove(consoleTraceListener); #endif CompilationWithAnalyzers.ClearAnalyzerState(analyzers); } return(diagnosticList .Where(d => !d.Id.StartsWith("CS", StringComparison.Ordinal)) .Where(d => diagnosticTable[d.Id].GetIsEnabled(d.Descriptor)) .Select(diagnostic => { var res = new DiagnosticResult(diagnostic); // var line = analysisDocument.Editor.GetLineByOffset (res.Region.Start); // Console.WriteLine (diagnostic.Id + "/" + res.Region +"/" + analysisDocument.Editor.GetTextAt (line)); return res; })); } catch (OperationCanceledException) { return(Enumerable.Empty <Result> ()); } catch (AggregateException ae) { ae.Flatten().Handle(ix => ix is OperationCanceledException); return(Enumerable.Empty <Result> ()); } catch (Exception e) { LoggingService.LogError("Error while running diagnostics.", e); return(Enumerable.Empty <Result> ()); } }