Exemplo n.º 1
0
        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()));
Exemplo n.º 2
0
 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);
Exemplo n.º 3
0
        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);
                }
            }
        }
Exemplo n.º 4
0
        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);
            }
        }
Exemplo n.º 5
0
 internal DiagnosticProvider(CodeAnalysisResult analysisResult)
 {
     _diagnosticsByProject = analysisResult.Diagnostics;
 }
Exemplo n.º 6
0
        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);
            }
        }
Exemplo n.º 7
0
        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;