示例#1
0
        private async static Task VerifyFixAllAsync(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string[] oldSources, string[] newSources, bool allowNewCompilerDiagnostics, LanguageVersion languageVersionCSharp, string equivalenceKey = null)
        {
            var project             = CreateProject(oldSources, language, languageVersionCSharp);
            var compilerDiagnostics = (await Task.WhenAll(project.Documents.Select(d => GetCompilerDiagnosticsAsync(d))).ConfigureAwait(true)).SelectMany(d => d);
            var fixAllProvider      = codeFixProvider.GetFixAllProvider();

            if (equivalenceKey == null)
            {
                equivalenceKey = codeFixProvider.GetType().Name;
            }
            FixAllContext fixAllContext;

            if (analyzer != null)
            {
                var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzer, project.Documents.ToArray()).ConfigureAwait(true);

                Func <Document, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getDocumentDiagnosticsAsync = (doc, ids, ct) =>
                                                                                                                                               Task.FromResult(analyzerDiagnostics.Where(d => d.Location.SourceTree.FilePath == doc.Name));
                Func <Project, bool, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getProjectDiagnosticsAsync = (proj, b, ids, ct) =>
                                                                                                                                                   Task.FromResult((IEnumerable <Diagnostic>)analyzerDiagnostics); //todo: verify, probably wrong
                var fixAllDiagnosticProvider = new FixAllDiagnosticProvider(codeFixProvider.FixableDiagnosticIds.ToImmutableHashSet(), getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync);
                fixAllContext = new FixAllContext(project.Documents.First(), codeFixProvider, FixAllScope.Solution,
                                                  equivalenceKey,
                                                  codeFixProvider.FixableDiagnosticIds,
                                                  fixAllDiagnosticProvider,
                                                  CancellationToken.None);
            }
            else
            {
                Func <Document, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getDocumentDiagnosticsAsync = async(doc, ids, ct) =>
                {
                    var compilerDiags = await GetCompilerDiagnosticsAsync(doc).ConfigureAwait(true);

                    return(compilerDiags.Where(d => codeFixProvider.FixableDiagnosticIds.Contains(d.Id)));
                };
                Func <Project, bool, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getProjectDiagnosticsAsync = async(proj, b, ids, ct) =>
                {
                    var theDocs = proj.Documents;
                    var diags   = await Task.WhenAll(theDocs.Select(d => getDocumentDiagnosticsAsync(d, ids, ct))).ConfigureAwait(true);

                    return(diags.SelectMany(d => d));
                };
                var fixAllDiagnosticProvider = new FixAllDiagnosticProvider(codeFixProvider.FixableDiagnosticIds.ToImmutableHashSet(), getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync);
                fixAllContext = new FixAllContext(project.Documents.First(), codeFixProvider, FixAllScope.Solution,
                                                  equivalenceKey,
                                                  codeFixProvider.FixableDiagnosticIds,
                                                  fixAllDiagnosticProvider,
                                                  CancellationToken.None);
            }
            var action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(true);

            if (action == null)
            {
                throw new Exception("No action supplied for the code fix.");
            }
            project = await ApplyFixAsync(project, action).ConfigureAwait(true);

            //check if applying the code fix introduced any new compiler diagnostics
            var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, (await Task.WhenAll(project.Documents.Select(d => GetCompilerDiagnosticsAsync(d))).ConfigureAwait(true)).SelectMany(d => d));

            if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any())
            {
                Assert.True(false, $"Fix introduced new compiler diagnostics:\r\n{string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString()))}\r\n");
            }
            var docs = project.Documents.ToArray();

            for (int i = 0; i < docs.Length; i++)
            {
                var document = docs[i];
                var actual   = await GetStringFromDocumentAsync(document).ConfigureAwait(true);

                newSources[i].Should().Be(actual);
            }
        }