Пример #1
0
        public async Task <ProjectFixResult> FixProjectAsync(Project project, CancellationToken cancellationToken = default)
        {
            (ImmutableArray <DiagnosticAnalyzer> analyzers, ImmutableArray <CodeFixProvider> fixers) = CodeAnalysisHelpers.GetAnalyzersAndFixers(
                project: project,
                analyzerAssemblies: _analyzerAssemblies,
                analyzerReferences: _analyzerReferences,
                options: Options);

            ProjectFixResult fixResult = await FixProjectAsync(project, analyzers, fixers, cancellationToken).ConfigureAwait(false);

            Compilation compilation = await CurrentSolution.GetProject(project.Id).GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            Dictionary <string, ImmutableArray <CodeFixProvider> > fixersById = fixers
                                                                                .SelectMany(f => f.FixableDiagnosticIds.Select(id => (id, fixer: f)))
                                                                                .GroupBy(f => f.id)
                                                                                .ToDictionary(f => f.Key, g => g.Select(f => f.fixer).Distinct().ToImmutableArray());

            ImmutableArray <Diagnostic> unfixableDiagnostics = await GetDiagnosticsAsync(
                analyzers,
                fixResult.FixedDiagnostics,
                compilation,
                f => !fixersById.TryGetValue(f.id, out ImmutableArray <CodeFixProvider> fixers2),
                cancellationToken)
                                                               .ConfigureAwait(false);

            ImmutableArray <Diagnostic> unfixedDiagnostics = await GetDiagnosticsAsync(
                analyzers,
                fixResult.FixedDiagnostics.Concat(unfixableDiagnostics),
                compilation,
                f => fixersById.TryGetValue(f.id, out ImmutableArray <CodeFixProvider> fixers2),
                cancellationToken)
                                                             .ConfigureAwait(false);

            int numberOfAddedFileBanners = 0;

            if (Options.FileBannerLines.Any())
            {
                numberOfAddedFileBanners = await AddFileBannerAsync(CurrentSolution.GetProject(project.Id), Options.FileBannerLines, cancellationToken).ConfigureAwait(false);
            }

            ImmutableArray <DocumentId> formattedDocuments = ImmutableArray <DocumentId> .Empty;

            if (Options.Format)
            {
                formattedDocuments = await FormatProjectAsync(CurrentSolution.GetProject(project.Id), cancellationToken).ConfigureAwait(false);
            }

            return(new ProjectFixResult(
                       kind: fixResult.Kind,
                       fixedDiagnostics: fixResult.FixedDiagnostics,
                       unfixedDiagnostics: unfixedDiagnostics,
                       unfixableDiagnostics: unfixableDiagnostics,
                       analyzers: fixResult.Analyzers,
                       fixers: fixResult.Fixers,
                       numberOfFormattedDocuments: formattedDocuments.Length,
                       numberOfAddedFileBanners: numberOfAddedFileBanners));
        }
Пример #2
0
        public async Task <ImmutableArray <ProjectFixResult> > FixSolutionAsync(Func <Project, bool> predicate, CancellationToken cancellationToken = default)
        {
            ImmutableArray <ProjectId> projects = CurrentSolution
                                                  .GetProjectDependencyGraph()
                                                  .GetTopologicallySortedProjects(cancellationToken)
                                                  .ToImmutableArray();

            var results = new List <ProjectFixResult>();

            Stopwatch stopwatch = Stopwatch.StartNew();

            TimeSpan lastElapsed = TimeSpan.Zero;

            for (int i = 0; i < projects.Length; i++)
            {
                cancellationToken.ThrowIfCancellationRequested();

                Project project = CurrentSolution.GetProject(projects[i]);

                if (predicate == null || predicate(project))
                {
                    WriteLine($"Fix '{project.Name}' {$"{i + 1}/{projects.Length}"}", ConsoleColor.Cyan, Verbosity.Minimal);

                    ProjectFixResult result = await FixProjectAsync(project, cancellationToken).ConfigureAwait(false);

                    results.Add(result);

                    if (result.Kind == ProjectFixKind.CompilerError)
                    {
                        break;
                    }
                }
                else
                {
                    WriteLine($"Skip '{project.Name}' {$"{i + 1}/{projects.Length}"}", ConsoleColor.DarkGray, Verbosity.Minimal);

                    results.Add(ProjectFixResult.Skipped);
                }

                TimeSpan elapsed = stopwatch.Elapsed;

                WriteLine($"Done fixing '{project.Name}' in {elapsed - lastElapsed:mm\\:ss\\.ff}", Verbosity.Normal);

                lastElapsed = elapsed;
            }

            stopwatch.Stop();

            WriteLine($"Done fixing solution '{CurrentSolution.FilePath}' in {stopwatch.Elapsed:mm\\:ss\\.ff}", Verbosity.Minimal);

            LogHelpers.WriteProjectFixResults(results, Options, FormatProvider);

            return(results.ToImmutableArray());
        }
Пример #3
0
        public async Task FixSolutionAsync(CancellationToken cancellationToken = default)
        {
            foreach (string id in Options.IgnoredCompilerDiagnosticIds.OrderBy(f => f))
            {
                WriteLine($"Ignore compiler diagnostic '{id}'", Verbosity.Diagnostic);
            }

            foreach (string id in Options.IgnoredDiagnosticIds.OrderBy(f => f))
            {
                WriteLine($"Ignore diagnostic '{id}'", Verbosity.Diagnostic);
            }

            ImmutableArray <ProjectId> projects = CurrentSolution
                                                  .GetProjectDependencyGraph()
                                                  .GetTopologicallySortedProjects(cancellationToken)
                                                  .ToImmutableArray();

            var results = new List <ProjectFixResult>();

            Stopwatch stopwatch = Stopwatch.StartNew();

            TimeSpan lastElapsed = TimeSpan.Zero;

            for (int i = 0; i < projects.Length; i++)
            {
                cancellationToken.ThrowIfCancellationRequested();

                Project project = CurrentSolution.GetProject(projects[i]);

                if (Options.IsSupportedProject(project))
                {
                    WriteLine($"Fix '{project.Name}' {$"{i + 1}/{projects.Length}"}", ConsoleColor.Cyan, Verbosity.Minimal);

                    ProjectFixResult result = await FixProjectAsync(project, cancellationToken).ConfigureAwait(false);

                    results.Add(result);

                    WriteFixSummary(
                        result.FixedDiagnostics,
                        result.UnfixedDiagnostics,
                        result.UnfixableDiagnostics,
                        indent: "  ",
                        formatProvider: FormatProvider,
                        verbosity: Verbosity.Detailed);

                    if (result.Kind == ProjectFixKind.CompilerError)
                    {
                        break;
                    }
                }
                else
                {
                    WriteLine($"Skip '{project.Name}' {$"{i + 1}/{projects.Length}"}", ConsoleColor.DarkGray, Verbosity.Minimal);

                    results.Add(ProjectFixResult.Skipped);
                }

                TimeSpan elapsed = stopwatch.Elapsed;

                WriteLine($"Done fixing '{project.Name}' in {elapsed - lastElapsed:mm\\:ss\\.ff}", Verbosity.Normal);

                lastElapsed = elapsed;
            }

            stopwatch.Stop();

            WriteProjectFixResults(results, Options, FormatProvider);

            WriteLine($"Done fixing solution '{CurrentSolution.FilePath}' in {stopwatch.Elapsed:mm\\:ss\\.ff}", Verbosity.Minimal);
        }
Пример #4
0
        public async Task <ProjectFixResult> FixProjectAsync(Project project, CancellationToken cancellationToken = default)
        {
            (ImmutableArray <DiagnosticAnalyzer> analyzers, ImmutableArray <CodeFixProvider> fixers) = _analyzerLoader.GetAnalyzersAndFixers(project: project);

            FixResult fixResult = await FixProjectAsync(project, analyzers, fixers, cancellationToken).ConfigureAwait(false);

            project = CurrentSolution.GetProject(project.Id);

            Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            Dictionary <string, ImmutableArray <CodeFixProvider> > fixersById = fixers
                                                                                .SelectMany(f => f.FixableDiagnosticIds.Select(id => (id, fixer: f)))
                                                                                .GroupBy(f => f.id)
                                                                                .ToDictionary(f => f.Key, g => g.Select(f => f.fixer).Distinct().ToImmutableArray());

            ImmutableArray <Diagnostic> unfixableDiagnostics = await GetDiagnosticsAsync(
                analyzers,
                fixResult.FixedDiagnostics,
                compilation,
                project.AnalyzerOptions,
                f => !fixersById.ContainsKey(f.id),
                cancellationToken)
                                                               .ConfigureAwait(false);

            ImmutableArray <Diagnostic> unfixedDiagnostics = await GetDiagnosticsAsync(
                analyzers,
                fixResult.FixedDiagnostics.Concat(unfixableDiagnostics),
                compilation,
                project.AnalyzerOptions,
                f => fixersById.ContainsKey(f.id),
                cancellationToken)
                                                             .ConfigureAwait(false);

            int numberOfAddedFileBanners = 0;

            if (Options.FileBannerLines.Any())
            {
                numberOfAddedFileBanners = await AddFileBannerAsync(CurrentSolution.GetProject(project.Id), Options.FileBannerLines, cancellationToken).ConfigureAwait(false);
            }

            ImmutableArray <DocumentId> formattedDocuments = ImmutableArray <DocumentId> .Empty;

            if (Options.Format)
            {
                formattedDocuments = await FormatProjectAsync(CurrentSolution.GetProject(project.Id), cancellationToken).ConfigureAwait(false);
            }

            var result = new ProjectFixResult(
                kind: fixResult.Kind,
                fixedDiagnostics: fixResult.FixedDiagnostics.Select(f => DiagnosticInfo.Create(f)),
                unfixedDiagnostics: unfixedDiagnostics.Select(f => DiagnosticInfo.Create(f)),
                unfixableDiagnostics: unfixableDiagnostics.Select(f => DiagnosticInfo.Create(f)),
                numberOfFormattedDocuments: (Options.FileBannerLines.Any()) ? formattedDocuments.Length : -1,
                numberOfAddedFileBanners: (Options.Format) ? numberOfAddedFileBanners : -1);

            LogHelpers.WriteFixSummary(
                fixResult.FixedDiagnostics,
                unfixedDiagnostics,
                unfixableDiagnostics,
                baseDirectoryPath: Path.GetDirectoryName(project.FilePath),
                indentation: "  ",
                formatProvider: FormatProvider,
                verbosity: Verbosity.Detailed);

            return(result);
        }