Пример #1
0
        public async Task VerifyFixAsync(
            string source,
            string expected,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (!FixProvider.FixableDiagnosticIds.Contains(DiagnosticId))
            {
                Assert.True(false, $"Code fix provider '{FixProvider.GetType().Name}' cannot fix diagnostic '{DiagnosticId}'.");
            }

            Document document = CreateDocument(source);

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

            ImmutableArray <Diagnostic> diagnostics = compilation.GetDiagnostics(cancellationToken: cancellationToken);

            diagnostics = diagnostics.Sort((x, y) => - DiagnosticComparer.SpanStart.Compare(x, y));

            bool fixRegistered = false;

            while (diagnostics.Length > 0)
            {
                cancellationToken.ThrowIfCancellationRequested();

                Diagnostic diagnostic = FindDiagnostic();

                if (diagnostic == null)
                {
                    break;
                }

                CodeAction action = null;

                var context = new CodeFixContext(
                    document,
                    diagnostic,
                    (a, d) =>
                {
                    if (action != null)
                    {
                        return;
                    }

                    if (!d.Contains(diagnostic))
                    {
                        return;
                    }

                    if (equivalenceKey != null &&
                        !string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal))
                    {
                        return;
                    }

                    action = a;
                },
                    CancellationToken.None);

                await FixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);

                if (action == null)
                {
                    break;
                }

                fixRegistered = true;

                document = await document.ApplyCodeActionAsync(action).ConfigureAwait(false);

                compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> newDiagnostics = compilation.GetDiagnostics(cancellationToken: cancellationToken);

                if (options == null)
                {
                    options = Options;
                }

                if (!options.AllowNewCompilerDiagnostics)
                {
                    VerifyNoNewCompilerDiagnostics(diagnostics, newDiagnostics, options);
                }

                diagnostics = newDiagnostics;
            }

            Assert.True(fixRegistered, "No code fix has been registered.");

            string actual = await document.ToFullStringAsync(simplify : true, format : true).ConfigureAwait(false);

            Assert.Equal(expected, actual);

            Diagnostic FindDiagnostic()
            {
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    if (string.Equals(diagnostic.Id, DiagnosticId, StringComparison.Ordinal))
                    {
                        return(diagnostic);
                    }
                }

                return(null);
            }
        }
Пример #2
0
        public async Task VerifyFixAsync(
            string source,
            string expected,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (!FixProvider.CanFixAny(Analyzer.SupportedDiagnostics))
            {
                Assert.True(false, $"Code fix provider '{FixProvider.GetType().Name}' cannot fix any diagnostic supported by analyzer '{Analyzer}'.");
            }

            Document document = CreateDocument(source);

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

            ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);

            if (options == null)
            {
                options = Options;
            }

            VerifyCompilerDiagnostics(compilerDiagnostics, options);

            if (options.EnableDiagnosticsDisabledByDefault)
            {
                compilation = compilation.EnableDiagnosticsDisabledByDefault(Analyzer);
            }

            ImmutableArray <Diagnostic> diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false);

            ImmutableArray <string> fixableDiagnosticIds = FixProvider.FixableDiagnosticIds;

            bool fixRegistered = false;

            while (diagnostics.Length > 0)
            {
                cancellationToken.ThrowIfCancellationRequested();

                Diagnostic diagnostic = FindFirstFixableDiagnostic();

                if (diagnostic == null)
                {
                    break;
                }

                CodeAction action = null;

                var context = new CodeFixContext(
                    document,
                    diagnostic,
                    (a, d) =>
                {
                    if (d.Contains(diagnostic) &&
                        action == null)
                    {
                        action = a;
                    }
                },
                    CancellationToken.None);

                await FixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);

                if (action == null)
                {
                    break;
                }

                fixRegistered = true;

                document = await document.ApplyCodeActionAsync(action).ConfigureAwait(false);

                compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> newCompilerDiagnostics = compilation.GetDiagnostics(cancellationToken);

                VerifyCompilerDiagnostics(newCompilerDiagnostics, options);

                if (!options.AllowNewCompilerDiagnostics)
                {
                    VerifyNoNewCompilerDiagnostics(compilerDiagnostics, newCompilerDiagnostics, options);
                }

                if (options.EnableDiagnosticsDisabledByDefault)
                {
                    compilation = compilation.EnableDiagnosticsDisabledByDefault(Analyzer);
                }

                diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false);
            }

            Assert.True(fixRegistered, "No code fix has been registered.");

            string actual = await document.ToFullStringAsync(simplify : true, format : true).ConfigureAwait(false);

            Assert.Equal(expected, actual);

            Diagnostic FindFirstFixableDiagnostic()
            {
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    if (fixableDiagnosticIds.Contains(diagnostic.Id))
                    {
                        return(diagnostic);
                    }
                }

                return(null);
            }
        }