private async Task <ImmutableDictionary <ProjectId, ImmutableHashSet <string> > > GetProjectDiagnosticsAsync( Solution solution, ImmutableDictionary <ProjectId, ImmutableArray <DiagnosticAnalyzer> > projectAnalyzers, ImmutableHashSet <string> formattablePaths, FormatOptions options, DiagnosticSeverity severity, ImmutableHashSet <string> fixableCompilerDiagnostics, ILogger logger, List <FormattedFile> formattedFiles, CancellationToken cancellationToken) { var result = new CodeAnalysisResult(); var projects = options.WorkspaceType == WorkspaceType.Solution ? solution.Projects : solution.Projects.Where(project => project.FilePath == options.WorkspaceFilePath); foreach (var project in projects) { var analyzers = projectAnalyzers[project.Id]; if (analyzers.IsEmpty) { continue; } // Run all the filtered analyzers to determine which are reporting diagnostic. await _runner.RunCodeAnalysisAsync(result, analyzers, project, formattablePaths, severity, fixableCompilerDiagnostics, logger, cancellationToken).ConfigureAwait(false); } LogDiagnosticLocations(solution, result.Diagnostics.SelectMany(kvp => kvp.Value), options.SaveFormattedFiles, options.ChangesAreErrors, logger, options.LogLevel, formattedFiles); return(result.Diagnostics.ToImmutableDictionary(kvp => kvp.Key.Id, kvp => kvp.Value.Select(diagnostic => diagnostic.Id).ToImmutableHashSet()));
public Task RunCodeAnalysisAsync( CodeAnalysisResult result, DiagnosticAnalyzer analyzers, Project project, ImmutableHashSet <string> formattableDocumentPaths, DiagnosticSeverity severity, ILogger logger, CancellationToken cancellationToken) => RunCodeAnalysisAsync(result, ImmutableArray.Create(analyzers), project, formattableDocumentPaths, severity, logger, cancellationToken);
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 async Task <Solution> ApplyCodeFixesAsync( Solution solution, CodeAnalysisResult result, CodeFixProvider codeFix, string diagnosticId, ILogger logger, CancellationToken cancellationToken) { var fixAllProvider = codeFix.GetFixAllProvider(); if (fixAllProvider?.GetSupportedFixAllScopes()?.Contains(FixAllScope.Solution) != true) { logger.LogWarning(Resources.Unable_to_fix_0_Code_fix_1_doesnt_support_Fix_All_in_Solution, diagnosticId, codeFix.GetType().Name); return(solution); } var project = solution.Projects.FirstOrDefault(); if (project == null) { throw new InvalidOperationException(string.Format(Resources.Solution_0_has__no_projects, solution)); } var fixAllContext = new FixAllContext( project: project, codeFixProvider: codeFix, scope: FixAllScope.Solution, codeActionEquivalenceKey: null, diagnosticIds: codeFix.FixableDiagnosticIds, fixAllDiagnosticProvider: new DiagnosticProvider(result), cancellationToken: cancellationToken); try { var action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); var operations = action != null ? await action.GetOperationsAsync(cancellationToken).ConfigureAwait(false) : ImmutableArray <CodeActionOperation> .Empty; var applyChangesOperation = operations.OfType <ApplyChangesOperation>().SingleOrDefault(); return(applyChangesOperation?.ChangedSolution ?? solution); } catch (Exception ex) { logger.LogWarning(Resources.Failed_to_apply_code_fix_0_for_1_2, codeFix?.GetType().Name, diagnosticId, ex.Message); return(solution); } }
internal DiagnosticProvider(CodeAnalysisResult analysisResult) { _diagnosticsByProject = analysisResult.Diagnostics; }
public async Task <Solution> ApplyCodeFixesAsync( Solution solution, CodeAnalysisResult result, CodeFixProvider codeFix, string diagnosticId, ILogger logger, CancellationToken cancellationToken) { var fixAllProvider = codeFix.GetFixAllProvider(); if (fixAllProvider?.GetSupportedFixAllScopes()?.Contains(FixAllScope.Solution) != true) { logger.LogWarning(Resources.Unable_to_fix_0_Code_fix_1_doesnt_support_Fix_All_in_Solution, diagnosticId, codeFix.GetType().Name); return(solution); } var document = result.Diagnostics .SelectMany(kvp => kvp.Value) .Select(diagnostic => solution.GetDocument(diagnostic.Location.SourceTree)) .FirstOrDefault(); if (document is null) { return(solution); } var fixAllContext = new FixAllContext( document: document, codeFixProvider: codeFix, scope: FixAllScope.Solution, codeActionEquivalenceKey: null, diagnosticIds: new[] { diagnosticId }, fixAllDiagnosticProvider: new DiagnosticProvider(result), cancellationToken: cancellationToken); try { var action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); if (action is null) { logger.LogWarning(Resources.Unable_to_fix_0_Code_fix_1_didnt_return_a_Fix_All_action, diagnosticId, codeFix.GetType().Name); return(solution); } var operations = await action.GetOperationsAsync(cancellationToken).ConfigureAwait(false); var applyChangesOperation = operations.OfType <ApplyChangesOperation>().SingleOrDefault(); if (action is null) { logger.LogWarning(Resources.Unable_to_fix_0_Code_fix_1_returned_an_unexpected_operation, diagnosticId, codeFix.GetType().Name); return(solution); } return(applyChangesOperation.ChangedSolution); } catch (Exception ex) { logger.LogWarning(Resources.Failed_to_apply_code_fix_0_for_1_2, codeFix?.GetType().Name, diagnosticId, ex.Message); return(solution); } }
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;