private async static Task VerifyFixAllAsync(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string[] oldSources, string[] newSources, bool allowNewCompilerDiagnostics, LanguageVersion languageVersionCSharp, Microsoft.CodeAnalysis.VisualBasic.LanguageVersion languageVersionVB, string equivalenceKey = null) { var project = CreateProject(oldSources, language, languageVersionCSharp, languageVersionVB); 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); } }
private async static Task VerifyFixAllAsync(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string[] oldSources, string[] newSources, bool allowNewCompilerDiagnostics, LanguageVersion languageVersionCSharp, Microsoft.CodeAnalysis.VisualBasic.LanguageVersion languageVersionVB, string equivalenceKey = null) { var project = CreateProject(oldSources, language, languageVersionCSharp, languageVersionVB); 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); } }
private async static Task VerifyFixAllAsync(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, bool allowNewCompilerDiagnostics, LanguageVersion languageVersionCSharp, Microsoft.CodeAnalysis.VisualBasic.LanguageVersion languageVersionVB, string equivalenceKey = null) { var document = CreateDocument(oldSource, language, languageVersionCSharp, languageVersionVB); var compilerDiagnostics = await GetCompilerDiagnosticsAsync(document).ConfigureAwait(true); var getDocumentDiagnosticsAsync = analyzer != null ? (Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>>)(async (doc, ids, ct) => await GetSortedDiagnosticsFromDocumentsAsync(analyzer, new[] { doc }).ConfigureAwait(true)) : (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?.Invoke(d, ids, ct))).ConfigureAwait(true); return diags.SelectMany(d => d); }; var fixAllProvider = codeFixProvider.GetFixAllProvider(); var fixAllDiagnosticProvider = new FixAllDiagnosticProvider(codeFixProvider.FixableDiagnosticIds.ToImmutableHashSet(), getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync); if (equivalenceKey == null) equivalenceKey = codeFixProvider.GetType().Name; var fixAllContext = new FixAllContext(document, codeFixProvider, FixAllScope.Document, 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."); document = await ApplyFixAsync(document, action).ConfigureAwait(true); //check if applying the code fix introduced any new compiler diagnostics var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, await GetCompilerDiagnosticsAsync(document).ConfigureAwait(true)); if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) { // Format and get the compiler diagnostics again so that the locations make sense in the output document = document.WithSyntaxRoot(Formatter.Format(await document.GetSyntaxRootAsync().ConfigureAwait(true), Formatter.Annotation, document.Project.Solution.Workspace)); newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, await GetCompilerDiagnosticsAsync(document).ConfigureAwait(true)); Assert.True(false, $"Fix introduced new compiler diagnostics:\r\n{string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString()))}\r\n\r\nNew document:\r\n{(await document.GetSyntaxRootAsync().ConfigureAwait(true)).ToFullString()}\r\n"); } var actual = await GetStringFromDocumentAsync(document).ConfigureAwait(true); Assert.Equal(newSource, actual); }