public async Task VerifyNoRefactoringAsync(
            string source,
            IEnumerable <TextSpan> spans,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            Document document = CreateDocument(source);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

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

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

            VerifyCompilerDiagnostics(compilerDiagnostics, options);

            using (IEnumerator <TextSpan> en = spans.GetEnumerator())
            {
                if (!en.MoveNext())
                {
                    throw new InvalidOperationException($"'{nameof(spans)}' contains no elements.");
                }

                do
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var context = new CodeRefactoringContext(
                        document,
                        en.Current,
                        a =>
                    {
                        if (equivalenceKey == null ||
                            string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal))
                        {
                            Assert.True(false, "No code refactoring expected.");
                        }
                    },
                        CancellationToken.None);

                    await RefactoringProvider.ComputeRefactoringsAsync(context).ConfigureAwait(false);
                } while (en.MoveNext());
            }
        }
Exemple #2
0
        public async Task VerifyDiagnosticAsync(
            string source,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            TextParserResult result = TextParser.GetSpans(source);

            await VerifyDiagnosticAsync(
                result.Text,
                result.Spans.Select(f => CreateDiagnostic(f.Span, f.LineSpan)),
                additionalSources : null,
                options : options,
                cancellationToken).ConfigureAwait(false);
        }
        public async Task VerifyNoDiagnosticAsync(
            string theory,
            string fromData,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            (string source, TextSpan span) = TestSourceText.ReplaceSpan(theory, fromData);

            await VerifyNoDiagnosticAsync(
                source : source,
                additionalSources : null,
                options : options,
                cancellationToken).ConfigureAwait(false);
        }
Exemple #4
0
        public async Task VerifyNoDiagnosticAsync(
            string theory,
            string fromData,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            (TextSpan span, string text) = TextParser.ReplaceEmptySpan(theory, fromData);

            await VerifyNoDiagnosticAsync(
                source : text,
                additionalSources : null,
                options : options,
                cancellationToken).ConfigureAwait(false);
        }
Exemple #5
0
        public async Task VerifyDiagnosticAndFixAsync(
            string source,
            string expected,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            TestSourceTextAnalysis analysis = TestSourceText.GetSpans(source);

            IEnumerable <Diagnostic> diagnostics = analysis.Spans.Select(f => CreateDiagnostic(f.Span, f.LineSpan));

            await VerifyDiagnosticAsync(analysis.Source, diagnostics, additionalSources : null, options : options, cancellationToken : cancellationToken).ConfigureAwait(false);

            await VerifyFixAsync(analysis.Source, expected, options, cancellationToken).ConfigureAwait(false);
        }
 public async Task VerifyNoRefactoringAsync(
     string source,
     TextSpan span,
     string equivalenceKey               = null,
     CodeVerificationOptions options     = null,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     await VerifyNoRefactoringAsync(
         source,
         ImmutableArray.Create(span),
         equivalenceKey,
         options,
         cancellationToken).ConfigureAwait(false);
 }
        public async Task VerifyDiagnosticAsync(
            string source,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            TestSourceTextAnalysis analysis = TestSourceText.GetSpans(source);

            await VerifyDiagnosticAsync(
                analysis.Source,
                analysis.Spans.Select(f => CreateDiagnostic(f.Span, f.LineSpan)),
                additionalSources : null,
                options : options,
                cancellationToken).ConfigureAwait(false);
        }
Exemple #8
0
        public async Task VerifyNoRefactoringAsync(
            string source,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            TextParserResult result = TextParser.GetSpans(source, LinePositionSpanInfoComparer.IndexDescending);

            await VerifyNoRefactoringAsync(
                source : result.Text,
                spans : result.Spans.Select(f => f.Span),
                equivalenceKey : equivalenceKey,
                options : options,
                cancellationToken : cancellationToken).ConfigureAwait(false);
        }
        public async Task VerifyNoRefactoringAsync(
            string source,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            TextSpanParserResult result = SpanParser.GetSpans(source, reverse: true);

            await VerifyNoRefactoringAsync(
                source : result.Text,
                spans : result.Spans.Select(f => f.Span),
                equivalenceKey : equivalenceKey,
                options : options,
                cancellationToken : cancellationToken).ConfigureAwait(false);
        }
Exemple #10
0
        public async Task VerifyFixAsync(
            string theory,
            string fromData,
            string toData,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            (string source, string expected, TextSpan span) = TestSourceText.ReplaceSpan(theory, fromData, toData);

            await VerifyFixAsync(
                source : source,
                expected : expected,
                options : options,
                cancellationToken : cancellationToken).ConfigureAwait(false);
        }
        public async Task VerifyNoRefactoringAsync(
            string source,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            TestSourceTextAnalysis analysis = TestSourceText.GetSpans(source, reverse: true);

            await VerifyNoRefactoringAsync(
                source : analysis.Source,
                spans : analysis.Spans.Select(f => f.Span),
                equivalenceKey : equivalenceKey,
                options : options,
                cancellationToken : cancellationToken).ConfigureAwait(false);
        }
Exemple #12
0
        public async Task VerifyNoFixAsync(
            string source,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            Document document = CreateDocument(source);

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

            ImmutableArray <string> fixableDiagnosticIds = FixProvider.FixableDiagnosticIds;

            foreach (Diagnostic diagnostic in compilation.GetDiagnostics(cancellationToken: cancellationToken))
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (!fixableDiagnosticIds.Contains(diagnostic.Id))
                {
                    continue;
                }

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

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

                    Assert.True(false, "No code fix expected.");
                },
                    CancellationToken.None);

                await FixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);
            }
        }
Exemple #13
0
        public async Task VerifyNoDiagnosticAsync(
            string source,
            string[] additionalSources          = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (!Analyzer.Supports(Descriptor))
            {
                Assert.True(false, $"Diagnostic \"{Descriptor.Id}\" is not supported by analyzer \"{Analyzer.GetType().Name}\".");
            }

            using (Workspace workspace = new AdhocWorkspace())
            {
                Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options);

                Document document = WorkspaceFactory.AddDocument(project, source, additionalSources ?? Array.Empty <string>());

                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> analyzerDiagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false);

                foreach (Diagnostic diagnostic in analyzerDiagnostics)
                {
                    if (string.Equals(diagnostic.Id, Descriptor.Id, StringComparison.Ordinal))
                    {
                        Assert.True(false, $"No diagnostic expected{analyzerDiagnostics.Where(f => string.Equals(f.Id, Descriptor.Id, StringComparison.Ordinal)).ToDebugString()}");
                    }
                }
            }
        }
Exemple #14
0
        public async Task VerifyFixAsync(
            string theory,
            string fromData,
            string toData,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            (TextSpan span, string source, string expected) = SpanParser.ReplaceSpan(theory, fromData, toData);

            await VerifyFixAsync(
                source : source,
                expected : expected,
                equivalenceKey : equivalenceKey,
                options : options,
                cancellationToken : cancellationToken).ConfigureAwait(false);
        }
        public static void VerifyCompilerDiagnostics(
            ImmutableArray <Diagnostic> diagnostics,
            CodeVerificationOptions options)
        {
            DiagnosticSeverity maxAllowedSeverity = options.MaxAllowedCompilerDiagnosticSeverity;

            ImmutableArray <string> allowedDiagnosticIds = options.AllowedCompilerDiagnosticIds;

            if (IsAny())
            {
                IEnumerable <Diagnostic> notAllowed = diagnostics
                                                      .Where(f => f.Severity > maxAllowedSeverity && !allowedDiagnosticIds.Any(id => id == f.Id));

                Assert.True(false, $"No compiler diagnostics with severity higher than '{maxAllowedSeverity}' expected{notAllowed.ToDebugString()}");
            }

            bool IsAny()
            {
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    if (diagnostic.Severity <= maxAllowedSeverity)
                    {
                        continue;
                    }

                    bool isAllowed = false;
                    foreach (string diagnosticId in allowedDiagnosticIds)
                    {
                        if (diagnostic.Id == diagnosticId)
                        {
                            isAllowed = true;
                            break;
                        }
                    }

                    if (!isAllowed)
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
        public async Task VerifyDiagnosticAsync(
            string theory,
            string fromData,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            (string source, TextSpan span) = TestSourceText.ReplaceSpan(theory, fromData);

            TestSourceTextAnalysis analysis = TestSourceText.GetSpans(source);

            if (analysis.Spans.Any())
            {
                await VerifyDiagnosticAsync(analysis.Source, analysis.Spans.Select(f => f.Span), options, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                await VerifyDiagnosticAsync(source, span, options, cancellationToken).ConfigureAwait(false);
            }
        }
        public async Task VerifyRefactoringAsync(
            string source,
            string expected,
            string[] additionalSources          = null,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            TextParserResult result = TextParser.GetSpans(source, reverse: true);

            await VerifyRefactoringAsync(
                source : result.Text,
                expected : expected,
                spans : result.Spans.Select(f => f.Span),
                additionalSources : additionalSources,
                equivalenceKey : equivalenceKey,
                options : options,
                cancellationToken : cancellationToken).ConfigureAwait(false);
        }
Exemple #18
0
        public async Task VerifyDiagnosticAsync(
            string theory,
            string fromData,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            (TextSpan span, string text) = SpanParser.ReplaceSpan(theory, fromData);

            SpanParserResult result = SpanParser.GetSpans(text);

            if (result.Spans.Any())
            {
                await VerifyDiagnosticAsync(result.Text, result.Spans.Select(f => f.Span), options, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                await VerifyDiagnosticAsync(text, span, options, cancellationToken).ConfigureAwait(false);
            }
        }
        public async Task VerifyRefactoringAsync(
            string source,
            string expected,
            IEnumerable <TextSpan> spans,
            string equivalenceKey               = null,
            string[] additionalSources          = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            foreach (TextSpan span in spans)
            {
                cancellationToken.ThrowIfCancellationRequested();

                await VerifyRefactoringAsync(
                    source : source,
                    expected : expected,
                    span,
                    equivalenceKey : equivalenceKey,
                    additionalSources : additionalSources,
                    options : options,
                    cancellationToken : cancellationToken).ConfigureAwait(false);
            }
        }
 public virtual Project AddProject(Solution solution, CodeVerificationOptions options = null)
 {
     return(solution
            .AddProject(DefaultProjectName, DefaultProjectName, Language)
            .WithMetadataReferences(DefaultProjectReferences));
 }
Exemple #21
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);
            }
        }
        public async Task VerifyRefactoringAsync(
            string source,
            string expected,
            TextSpan span,
            string equivalenceKey               = null,
            string[] additionalSources          = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            Document document = CreateDocument(source, additionalSources ?? Array.Empty <string>());

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

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

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

            VerifyCompilerDiagnostics(compilerDiagnostics, options);
            CodeAction action = null;

            var context = new CodeRefactoringContext(
                document,
                span,
                a =>
            {
                if (equivalenceKey == null ||
                    string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal))
                {
                    if (action == null)
                    {
                        action = a;
                    }
                }
            },
                CancellationToken.None);

            await RefactoringProvider.ComputeRefactoringsAsync(context).ConfigureAwait(false);

            Assert.True(action != null, "No code refactoring has been registered.");

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

            semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

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

            VerifyCompilerDiagnostics(newCompilerDiagnostics, options);

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

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

            Assert.Equal(expected, actual);
        }
Exemple #23
0
        public static void VerifyNoNewCompilerDiagnostics(
            ImmutableArray <Diagnostic> diagnostics,
            ImmutableArray <Diagnostic> newDiagnostics,
            CodeVerificationOptions options)
        {
            ImmutableArray <string> allowedDiagnosticIds = options.AllowedCompilerDiagnosticIds;

            if (allowedDiagnosticIds.IsDefault)
            {
                allowedDiagnosticIds = ImmutableArray <string> .Empty;
            }

            if (IsAnyNewCompilerDiagnostic())
            {
                IEnumerable <Diagnostic> diff = newDiagnostics
                                                .Where(diagnostic => !allowedDiagnosticIds.Any(id => id == diagnostic.Id))
                                                .Except(diagnostics, DiagnosticDeepEqualityComparer.Instance);

                Assert.True(false, $"Code fix introduced new compiler diagnostics.{diff.ToDebugString()}");
            }

            bool IsAnyNewCompilerDiagnostic()
            {
                foreach (Diagnostic newDiagnostic in newDiagnostics)
                {
                    if (!IsAllowed(newDiagnostic) &&
                        !EqualsAny(newDiagnostic))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            bool IsAllowed(Diagnostic diagnostic)
            {
                foreach (string diagnosticId in allowedDiagnosticIds)
                {
                    if (diagnostic.Id == diagnosticId)
                    {
                        return(true);
                    }
                }

                return(false);
            }

            bool EqualsAny(Diagnostic newDiagnostic)
            {
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    if (DiagnosticDeepEqualityComparer.Instance.Equals(diagnostic, newDiagnostic))
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
Exemple #24
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);
            }
        }
Exemple #25
0
        public async Task VerifyDiagnosticAsync(
            string source,
            IEnumerable <Diagnostic> expectedDiagnostics,
            string[] additionalSources          = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            using (Workspace workspace = new AdhocWorkspace())
            {
                Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options);

                Document document = WorkspaceFactory.AddDocument(project, source, additionalSources ?? Array.Empty <string>());

                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);

                if (diagnostics.Length > 0 &&
                    Analyzer.SupportedDiagnostics.Length > 1)
                {
                    VerifyDiagnostics(FilterDiagnostics(diagnostics), expectedDiagnostics, cancellationToken);
                }
                else
                {
                    VerifyDiagnostics(diagnostics, expectedDiagnostics, cancellationToken);
                }
            }

            IEnumerable <Diagnostic> FilterDiagnostics(ImmutableArray <Diagnostic> diagnostics)
            {
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    bool success = false;
                    foreach (Diagnostic expectedDiagnostic in expectedDiagnostics)
                    {
                        if (DiagnosticComparer.Id.Equals(diagnostic, expectedDiagnostic))
                        {
                            success = true;
                            break;
                        }
                    }

                    if (success)
                    {
                        yield return(diagnostic);
                    }
                }
            }
        }