本文整理汇总了C#中Microsoft.CodeAnalysis.CodeFixes.CodeFixProvider.RegisterCodeFixesAsync方法的典型用法代码示例。如果您正苦于以下问题:C# CodeFixProvider.RegisterCodeFixesAsync方法的具体用法?C# CodeFixProvider.RegisterCodeFixesAsync怎么用?C# CodeFixProvider.RegisterCodeFixesAsync使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.CodeAnalysis.CodeFixes.CodeFixProvider
的用法示例。
在下文中一共展示了CodeFixProvider.RegisterCodeFixesAsync方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: GetFixesAsync
private static async Task<IEnumerable<CodeAction>> GetFixesAsync(Solution solution, CodeFixProvider codeFixProvider, Diagnostic diagnostic)
{
List<CodeAction> codeActions = new List<CodeAction>();
await codeFixProvider.RegisterCodeFixesAsync(new CodeFixContext(solution.GetDocument(diagnostic.Location.SourceTree), diagnostic, (a, d) => codeActions.Add(a), CancellationToken.None));
return codeActions;
}
示例2: VerifyFix
private void VerifyFix(Document document, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string newSource, int? codeFixIndex, bool useCompilerAnalyzerDriver, bool allowNewCompilerDiagnostics)
{
Diagnostic[] analyzerDiagnostics = GetSortedDiagnostics(analyzer, document, useCompilerAnalyzerDriver: useCompilerAnalyzerDriver);
System.Collections.Immutable.ImmutableArray<Diagnostic> compilerDiagnostics = document.GetSemanticModelAsync().Result.GetDiagnostics();
// TODO(mavasani): Delete the below if statement once FxCop Analyzers have been ported to new IDiagnosticAnalyzer API.
if (!useCompilerAnalyzerDriver)
{
Assert.True(analyzerDiagnostics.IsEmpty());
return;
}
int attempts = analyzerDiagnostics.Length;
for (int i = 0; i < attempts; ++i)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
codeFixProvider.RegisterCodeFixesAsync(context).Wait();
if (!actions.Any())
{
break;
}
if (codeFixIndex != null)
{
document = document.Apply(actions.ElementAt((int)codeFixIndex));
break;
}
document = document.Apply(actions.ElementAt(0));
analyzerDiagnostics = GetSortedDiagnostics(analyzer, document, useCompilerAnalyzerDriver: useCompilerAnalyzerDriver);
IEnumerable<Diagnostic> newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, document.GetSemanticModelAsync().Result.GetDiagnostics());
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(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace));
newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, document.GetSemanticModelAsync().Result.GetDiagnostics());
Assert.True(false,
string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
newCompilerDiagnostics.Select(d => d.ToString()).Join("\r\n"),
document.GetSyntaxRootAsync().Result.ToFullString()));
}
if (analyzerDiagnostics.IsEmpty())
{
break;
}
}
Document newDocument = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result;
SyntaxNode root = newDocument.GetSyntaxRootAsync().Result;
root = Formatter.Format(root, Formatter.Annotation, newDocument.Project.Solution.Workspace);
string actual = root.GetText().ToString();
Assert.Equal(newSource, actual);
}
示例3: VerifyFix
/// <summary>
/// General verifier for codefixes.
/// Creates a Document from the source string, then gets diagnostics on it and applies the relevant codefixes.
/// Then gets the string after the codefix is applied and compares it with the expected result.
/// Note: If any codefix causes new diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true.
/// </summary>
/// <param name="language">The language the source code is in</param>
/// <param name="analyzer">The analyzer to be applied to the source code</param>
/// <param name="codeFixProvider">The codefix to be applied to the code wherever the relevant Diagnostic is found</param>
/// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param>
/// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param>
/// <param name="codeFixIndex">Index determining which codefix to apply if there are multiple</param>
/// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param>
private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics)
{
var document = CreateDocument(oldSource, language);
var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
var compilerDiagnostics = GetCompilerDiagnostics(document);
var attempts = analyzerDiagnostics.Length;
for (int i = 0; i < attempts; ++i)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
codeFixProvider.RegisterCodeFixesAsync(context).Wait();
if (!actions.Any())
{
break;
}
if (codeFixIndex != null)
{
document = ApplyFix(document, actions.ElementAt((int)codeFixIndex));
break;
}
document = ApplyFix(document, actions.ElementAt(0));
analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
//check if applying the code fix introduced any new compiler diagnostics
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(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace));
newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
var xxx = document.GetSyntaxRootAsync().Result.ToString();
Assert.IsTrue(false,
string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())),
document.GetSyntaxRootAsync().Result.ToFullString()));
}
//check if there are analyzer diagnostics left after the code fix
if (!analyzerDiagnostics.Any())
{
break;
}
}
//after applying all of the code fixes, compare the resulting string to the inputted one
var actual = GetStringFromDocument(document);
Assert.AreEqual(newSource, actual);
}
示例4: VerifyFix
private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics)
{
var document = CreateDocument(oldSource, language);
var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
var compilerDiagnostics = GetCompilerDiagnostics(document);
for (int i = 0; i < analyzerDiagnostics.Length; i++)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
codeFixProvider.RegisterCodeFixesAsync(context).Wait();
if (!actions.Any())
{
break;
}
if (codeFixIndex != null)
{
document = ApplyFix(document, actions[codeFixIndex.Value]);
break;
}
document = ApplyFix(document, actions[0]);
analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any())
{
document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace));
newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
Assert.Fail($"Fix introduced new compiler diagnostics:{NewLine}{string.Join(NewLine, newCompilerDiagnostics.Select(d => d.ToString()))}{NewLine}{NewLine}New document:{NewLine}{document.GetSyntaxRootAsync().Result.ToFullString()}{NewLine}");
}
if (!analyzerDiagnostics.Any())
{
break;
}
}
Assert.AreEqual(newSource, GetStringFromDocument(document));
}
示例5: GetCodeActionsForDiagnostic
private static IEnumerable<CodeAction> GetCodeActionsForDiagnostic(CodeFixProvider codeFixProvider, Document document,
Diagnostic diagnostic)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, diagnostic, (a, d) => actions.Add(a), CancellationToken.None);
codeFixProvider.RegisterCodeFixesAsync(context).Wait();
return actions;
}
示例6: GetCodeFixesAsync
private async Task<ImmutableArray<CodeFix>> GetCodeFixesAsync(
Document document, TextSpan span, CodeFixProvider fixer,
ImmutableArray<Diagnostic> diagnostics, CancellationToken cancellationToken)
{
var fixes = ArrayBuilder<CodeFix>.GetInstance();
var context = new CodeFixContext(document, span, diagnostics,
// TODO: Can we share code between similar lambdas that we pass to this API in BatchFixAllProvider.cs, CodeFixService.cs and CodeRefactoringService.cs?
(action, applicableDiagnostics) =>
{
// Serialize access for thread safety - we don't know what thread the fix provider will call this delegate from.
lock (fixes)
{
fixes.Add(new CodeFix(document.Project, action, applicableDiagnostics));
}
},
verifyArguments: false,
cancellationToken: cancellationToken);
var task = fixer.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask;
await task.ConfigureAwait(false);
return fixes.ToImmutableAndFree();
}
示例7: VerifyFixAsync
/// <summary>
/// General verifier for code fixes.
/// Creates a <see cref="Document"/> from the source string, then gets <see cref="Diagnostic"/>s on it and
/// applies the relevant code fixes. Then gets the string after the code fix is applied and compares it with the
/// expected result.
/// <note type="note">
/// <para>If any code fix causes new diagnostics to show up, the test fails unless
/// <paramref name="allowNewCompilerDiagnostics"/> is set to <see langword="true"/>.</para>
/// </note>
/// </summary>
/// <param name="language">The language the source classes are in. Values may be taken from the
/// <see cref="LanguageNames"/> class.</param>
/// <param name="analyzers">The analyzer to be applied to the source code.</param>
/// <param name="codeFixProvider">The code fix to be applied to the code wherever the relevant
/// <see cref="Diagnostic"/> is found.</param>
/// <param name="oldSource">A class in the form of a string before the code fix was applied to it.</param>
/// <param name="newSource">A class in the form of a string after the code fix was applied to it.</param>
/// <param name="codeFixIndex">Index determining which code fix to apply if there are multiple.</param>
/// <param name="allowNewCompilerDiagnostics">A value indicating whether or not the test will fail if the code
/// fix introduces other warnings after being applied.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
private async Task VerifyFixAsync(string language, ImmutableArray<DiagnosticAnalyzer> analyzers, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics, CancellationToken cancellationToken)
{
var document = this.CreateDocument(oldSource, language);
var compilerDiagnostics = await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false);
var previousDiagnostics = ImmutableArray.Create<Diagnostic>();
bool done;
do
{
var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzers, new[] { document }, cancellationToken).ConfigureAwait(false);
if (analyzerDiagnostics.Length == 0)
{
break;
}
if (!AreDiagnosticsDifferent(analyzerDiagnostics, previousDiagnostics))
{
break;
}
previousDiagnostics = analyzerDiagnostics;
done = true;
for (var i = 0; i < analyzerDiagnostics.Length; i++)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostics[i], (a, d) => actions.Add(a), cancellationToken);
await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);
if (actions.Count > 0)
{
var fixedDocument = await ApplyFixAsync(document, actions.ElementAt(codeFixIndex.GetValueOrDefault(0)), cancellationToken).ConfigureAwait(false);
if (fixedDocument != document)
{
done = false;
var newText = await fixedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);
// workaround for issue #936 - force re-parsing to get the same sort of syntax tree as the original document.
document = document.WithText(newText);
break;
}
}
}
}
while (!done);
var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false));
// check if applying the code fix introduced any new compiler diagnostics
if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any())
{
// Format and get the compiler diagnostics again so that the locations make sense in the output
document = await Formatter.FormatAsync(document, Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);
newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false));
string message =
string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())),
(await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false)).ToFullString());
Assert.True(false, message);
}
// after applying all of the code fixes, compare the resulting string to the inputted one
var actual = await GetStringFromDocumentAsync(document, cancellationToken).ConfigureAwait(false);
Assert.Equal(newSource, actual);
}
示例8: GetFixAllAnalyzerAsync
private static async Task<Document> GetFixAllAnalyzerAsync(FixAllScope scope, ImmutableArray<DiagnosticAnalyzer> analyzers, CodeFixProvider codeFixProvider, int? codeFixIndex, Document document, int maxNumberOfIterations, CancellationToken cancellationToken)
{
var previousDiagnostics = ImmutableArray.Create<Diagnostic>();
var fixAllProvider = codeFixProvider.GetFixAllProvider();
if (fixAllProvider == null)
{
return null;
}
bool done;
do
{
var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzers, new[] { document }, cancellationToken).ConfigureAwait(false);
if (analyzerDiagnostics.Length == 0)
{
break;
}
if (!AreDiagnosticsDifferent(analyzerDiagnostics, previousDiagnostics))
{
break;
}
if (--maxNumberOfIterations < 0)
{
Assert.True(false, "The upper limit for the number of fix all iterations was exceeded");
}
string equivalenceKey = null;
foreach (var diagnostic in analyzerDiagnostics)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, diagnostic, (a, d) => actions.Add(a), cancellationToken);
await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);
if (actions.Count > (codeFixIndex ?? 0))
{
equivalenceKey = actions[codeFixIndex ?? 0].EquivalenceKey;
break;
}
}
previousDiagnostics = analyzerDiagnostics;
done = true;
FixAllContext.DiagnosticProvider fixAllDiagnosticProvider = TestDiagnosticProvider.Create(analyzerDiagnostics);
FixAllContext fixAllContext = new FixAllContext(document, codeFixProvider, scope, equivalenceKey, codeFixProvider.FixableDiagnosticIds, fixAllDiagnosticProvider, cancellationToken);
CodeAction action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false);
if (action == null)
{
return document;
}
var fixedDocument = await ApplyFixAsync(document, action, cancellationToken).ConfigureAwait(false);
if (fixedDocument != document)
{
done = false;
var newText = await fixedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);
// workaround for issue #936 - force re-parsing to get the same sort of syntax tree as the original document.
document = document.WithText(newText);
}
}
while (!done);
return document;
}
示例9: GetFixAllAnalyzerAsync
private static async Task<Document> GetFixAllAnalyzerAsync(FixAllScope scope, ImmutableArray<DiagnosticAnalyzer> analyzers, CodeFixProvider codeFixProvider, int? codeFixIndex, Document document, int numberOfIterations, CancellationToken cancellationToken)
{
int expectedNumberOfIterations = numberOfIterations;
if (numberOfIterations < 0)
{
numberOfIterations = -numberOfIterations;
}
var previousDiagnostics = ImmutableArray.Create<Diagnostic>();
var fixAllProvider = codeFixProvider.GetFixAllProvider();
if (fixAllProvider == null)
{
return null;
}
bool done;
do
{
var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzers, new[] { document }, cancellationToken).ConfigureAwait(false);
if (analyzerDiagnostics.Length == 0)
{
break;
}
if (!AreDiagnosticsDifferent(analyzerDiagnostics, previousDiagnostics))
{
break;
}
if (--numberOfIterations < 0)
{
Assert.True(false, "The upper limit for the number of fix all iterations was exceeded");
}
string equivalenceKey = null;
foreach (var diagnostic in analyzerDiagnostics)
{
if (!codeFixProvider.FixableDiagnosticIds.Contains(diagnostic.Id))
{
// do not pass unsupported diagnostics to a code fix provider
continue;
}
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, diagnostic, (a, d) => actions.Add(a), cancellationToken);
await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);
if (actions.Count > (codeFixIndex ?? 0))
{
equivalenceKey = actions[codeFixIndex ?? 0].EquivalenceKey;
break;
}
}
previousDiagnostics = analyzerDiagnostics;
done = true;
FixAllContext.DiagnosticProvider fixAllDiagnosticProvider = TestDiagnosticProvider.Create(analyzerDiagnostics);
IEnumerable<string> analyzerDiagnosticIds = analyzers.SelectMany(x => x.SupportedDiagnostics).Select(x => x.Id);
IEnumerable<string> compilerDiagnosticIds = codeFixProvider.FixableDiagnosticIds.Where(x => x.StartsWith("CS", StringComparison.Ordinal));
IEnumerable<string> disabledDiagnosticIds = document.Project.CompilationOptions.SpecificDiagnosticOptions.Where(x => x.Value == ReportDiagnostic.Suppress).Select(x => x.Key);
IEnumerable<string> relevantIds = analyzerDiagnosticIds.Concat(compilerDiagnosticIds).Except(disabledDiagnosticIds).Distinct();
FixAllContext fixAllContext = new FixAllContext(document, codeFixProvider, scope, equivalenceKey, relevantIds, fixAllDiagnosticProvider, cancellationToken);
CodeAction action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false);
if (action == null)
{
return document;
}
var fixedDocument = await ApplyFixAsync(document, action, cancellationToken).ConfigureAwait(false);
if (fixedDocument != document)
{
done = false;
var newText = await fixedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);
// workaround for issue #936 - force re-parsing to get the same sort of syntax tree as the original document.
document = document.WithText(newText);
}
}
while (!done);
if (expectedNumberOfIterations >= 0)
{
Assert.Equal($"{expectedNumberOfIterations} iterations", $"{expectedNumberOfIterations - numberOfIterations} iterations");
}
return document;
}
示例10: GetFixResult
/// <summary>
/// Apply codefixes and returns reslt.
/// Creates a Document from the source string, then gets diagnostics on it and applies the relevant codefixes.
/// Note: If any codefix causes new diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true.
/// </summary>
/// <param name="language">The language the source code is in</param>
/// <param name="analyzer">The analyzer to be applied to the source code</param>
/// <param name="codeFixProvider">The codefix to be applied to the code wherever the relevant Diagnostic is found</param>
/// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param>
/// <param name="equivalenceKey">CodeAction.EquivalenceKey determining which codefix to apply if there are multiple</param>
/// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param>
internal static string GetFixResult(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string equivalenceKey, bool allowNewCompilerDiagnostics)
{
var document = CodeAnalysisHelper.CreateDocument(oldSource, language);
var analyzerDiagnostics = CodeAnalysisHelper.GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
var compilerDiagnostics = CodeAnalysisHelper.GetCompilerDiagnostics(document);
var attempts = analyzerDiagnostics.Length;
for (int i = 0; i < attempts; ++i)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
codeFixProvider.RegisterCodeFixesAsync(context).Wait();
if (!actions.Any())
{
break;
}
if (equivalenceKey != null)
{
document = CodeAnalysisHelper.ApplyFix(document, actions.Single(n => n.EquivalenceKey == equivalenceKey));
break;
}
document = CodeAnalysisHelper.ApplyFix(document, actions.ElementAt(0));
analyzerDiagnostics = CodeAnalysisHelper.GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
var newCompilerDiagnostics = CodeAnalysisHelper.GetNewDiagnostics(compilerDiagnostics, CodeAnalysisHelper.GetCompilerDiagnostics(document));
//check if applying the code fix introduced any new compiler diagnostics
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(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace));
newCompilerDiagnostics = CodeAnalysisHelper.GetNewDiagnostics(compilerDiagnostics, CodeAnalysisHelper.GetCompilerDiagnostics(document));
Assert.IsTrue(false,
string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())),
document.GetSyntaxRootAsync().Result.ToFullString()));
}
//check if there are analyzer diagnostics left after the code fix
if (!analyzerDiagnostics.Any())
{
break;
}
}
var newSource = CodeAnalysisHelper.GetStringFromDocument(document);
return newSource;
}
示例11: VerifyCSharpFixFromProjectsAsync
private async Task VerifyCSharpFixFromProjectsAsync(DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldProjectFilePath, string newProjectFilePath, int? codeFixIndex)
{
var oldDocuments = await GetDocumentsAsync(oldProjectFilePath);
var newDocuments = await GetDocumentsAsync(newProjectFilePath);
Solution newSolution = null;
var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, oldDocuments);
var attempts = analyzerDiagnostics.Length;
for (int i = 0; i < attempts; ++i)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(oldDocuments[0], analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
codeFixProvider.RegisterCodeFixesAsync(context).Wait();
if (!actions.Any())
{
break;
}
if (codeFixIndex != null)
{
newSolution = ApplyFix(actions.ElementAt((int)codeFixIndex));
break;
}
newSolution = ApplyFix(actions.ElementAt(0));
analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, oldDocuments);
//check if there are analyzer diagnostics left after the code fix
if (!analyzerDiagnostics.Any())
{
break;
}
}
var errors = new List<Exception>();
foreach (var oldDocument in oldDocuments.Where(d => d.Name != "AssemblyInfo.cs"))
{
var fixedDocument = newSolution.Projects.Single(p => p.Name == oldDocument.Project.Name).Documents.Single(d => d.Name == oldDocument.Name);
var expectedDocument = newDocuments.Single(d => d.Name == oldDocument.Name);
//after applying all of the code fixes, compare the resulting string to the inputted one
var actual = GetStringFromDocument(fixedDocument);
var expected = GetStringFromDocument(expectedDocument);
try
{
Assert.AreEqual(expected, actual);
}
catch (Exception ex)
{
errors.Add(ex);
}
}
if (errors.Count > 0)
{
Assert.Fail(string.Join("\n\n", errors.Select(e => e.Message)));
}
}
示例12: VerifyFixAsync
/// <summary>
/// General verifier for code fixes.
/// Creates a <see cref="Document"/> from the source string, then gets <see cref="Diagnostic"/>s on it and
/// applies the relevant code fixes. Then gets the string after the code fix is applied and compares it with the
/// expected result.
/// <note type="note">
/// <para>If any code fix causes new diagnostics to show up, the test fails unless
/// <paramref name="allowNewCompilerDiagnostics"/> is set to <see langword="true"/>.</para>
/// </note>
/// </summary>
/// <param name="language">The language the source classes are in. Values may be taken from the
/// <see cref="LanguageNames"/> class.</param>
/// <param name="analyzer">The analyzer to be applied to the source code.</param>
/// <param name="codeFixProvider">The code fix to be applied to the code wherever the relevant
/// <see cref="Diagnostic"/> is found.</param>
/// <param name="oldSource">A class in the form of a string before the code fix was applied to it.</param>
/// <param name="newSource">A class in the form of a string after the code fix was applied to it.</param>
/// <param name="codeFixIndex">Index determining which code fix to apply if there are multiple.</param>
/// <param name="allowNewCompilerDiagnostics">A value indicating whether or not the test will fail if the code
/// fix introduces other warnings after being applied.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
private async Task VerifyFixAsync(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics, CancellationToken cancellationToken)
{
var document = CreateDocument(oldSource, language);
var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzer, new[] { document }, cancellationToken).ConfigureAwait(false);
var compilerDiagnostics = await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false);
var attempts = analyzerDiagnostics.Length;
for (int i = 0; i < attempts; ++i)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), cancellationToken);
await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);
if (!actions.Any())
{
break;
}
if (codeFixIndex != null)
{
document = await ApplyFixAsync(document, actions.ElementAt((int)codeFixIndex), cancellationToken).ConfigureAwait(false);
break;
}
document = await ApplyFixAsync(document, actions.ElementAt(0), cancellationToken).ConfigureAwait(false);
analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzer, new[] { document }, cancellationToken).ConfigureAwait(false);
// check if there are analyzer diagnostics left after the code fix
if (!analyzerDiagnostics.Any())
{
break;
}
}
var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false));
// check if applying the code fix introduced any new compiler diagnostics
if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any())
{
// Format and get the compiler diagnostics again so that the locations make sense in the output
document = await Formatter.FormatAsync(document, Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);
newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false));
Assert.True(false,
string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())),
(await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false)).ToFullString()));
}
// after applying all of the code fixes, compare the resulting string to the inputted one
var actual = await GetStringFromDocumentAsync(document, cancellationToken).ConfigureAwait(false);
Assert.Equal(newSource, actual);
}
示例13: GetDiagnosticAndFixes
internal IEnumerable<Tuple<Diagnostic, CodeFixCollection>> GetDiagnosticAndFixes(
IEnumerable<Diagnostic> diagnostics,
DiagnosticAnalyzer provider,
CodeFixProvider fixer,
TestDiagnosticAnalyzerDriver testDriver,
Document document,
TextSpan span,
string annotation,
string fixAllActionId)
{
foreach (var diagnostic in diagnostics)
{
if (annotation == null)
{
var fixes = new List<CodeFix>();
var context = new CodeFixContext(document, diagnostic, (a, d) => fixes.Add(new CodeFix(document.Project, a, d)), CancellationToken.None);
fixer.RegisterCodeFixesAsync(context).Wait();
if (fixes.Any())
{
var codeFix = new CodeFixCollection(fixer, diagnostic.Location.SourceSpan, fixes);
yield return Tuple.Create(diagnostic, codeFix);
}
}
else
{
var fixAllProvider = fixer.GetFixAllProvider();
Assert.NotNull(fixAllProvider);
FixAllScope scope = GetFixAllScope(annotation);
Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getDocumentDiagnosticsAsync =
(d, diagIds, c) =>
{
var root = d.GetSyntaxRootAsync().Result;
var diags = testDriver.GetDocumentDiagnostics(provider, d, root.FullSpan);
diags = diags.Where(diag => diagIds.Contains(diag.Id));
return Task.FromResult(diags);
};
Func<Project, bool, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getProjectDiagnosticsAsync =
(p, includeAllDocumentDiagnostics, diagIds, c) =>
{
var diags = includeAllDocumentDiagnostics ?
testDriver.GetAllDiagnostics(provider, p) :
testDriver.GetProjectDiagnostics(provider, p);
diags = diags.Where(diag => diagIds.Contains(diag.Id));
return Task.FromResult(diags);
};
var diagnosticIds = ImmutableHashSet.Create(diagnostic.Id);
var fixAllDiagnosticProvider = new FixAllCodeActionContext.FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync);
var fixAllContext = diagnostic.Location.IsInSource ?
new FixAllContext(document, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider, CancellationToken.None) :
new FixAllContext(document.Project, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider, CancellationToken.None);
var fixAllFix = fixAllProvider.GetFixAsync(fixAllContext).WaitAndGetResult(CancellationToken.None);
if (fixAllFix != null)
{
var diagnosticSpan = diagnostic.Location.IsInSource ? diagnostic.Location.SourceSpan : default(TextSpan);
var codeFix = new CodeFixCollection(fixAllProvider, diagnosticSpan, ImmutableArray.Create(new CodeFix(document.Project, fixAllFix, diagnostic)));
yield return Tuple.Create(diagnostic, codeFix);
}
}
}
}
示例14: FixEachAnalyzerDiagnosticAsync
private static async Task<Project> FixEachAnalyzerDiagnosticAsync(ImmutableArray<DiagnosticAnalyzer> analyzers, CodeFixProvider codeFixProvider, int? codeFixIndex, Project project, int numberOfIterations, CancellationToken cancellationToken)
{
int expectedNumberOfIterations = numberOfIterations;
if (numberOfIterations < 0)
{
numberOfIterations = -numberOfIterations;
}
var previousDiagnostics = ImmutableArray.Create<Diagnostic>();
bool done;
do
{
var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzers, project.Documents.ToArray(), cancellationToken).ConfigureAwait(false);
if (analyzerDiagnostics.Length == 0)
{
break;
}
if (!AreDiagnosticsDifferent(analyzerDiagnostics, previousDiagnostics))
{
break;
}
if (--numberOfIterations < 0)
{
Assert.True(false, "The upper limit for the number of code fix iterations was exceeded");
}
previousDiagnostics = analyzerDiagnostics;
done = true;
foreach (var diagnostic in analyzerDiagnostics)
{
if (!codeFixProvider.FixableDiagnosticIds.Contains(diagnostic.Id))
{
// do not pass unsupported diagnostics to a code fix provider
continue;
}
var actions = new List<CodeAction>();
var context = new CodeFixContext(project.GetDocument(diagnostic.Location.SourceTree), diagnostic, (a, d) => actions.Add(a), cancellationToken);
await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);
if (actions.Count > 0)
{
var fixedProject = await ApplyFixAsync(project, actions.ElementAt(codeFixIndex.GetValueOrDefault(0)), cancellationToken).ConfigureAwait(false);
if (fixedProject != project)
{
done = false;
project = await RecreateProjectDocumentsAsync(fixedProject, cancellationToken).ConfigureAwait(false);
break;
}
}
}
}
while (!done);
if (expectedNumberOfIterations >= 0)
{
Assert.Equal($"{expectedNumberOfIterations} iterations", $"{expectedNumberOfIterations - numberOfIterations} iterations");
}
return project;
}
示例15: VerifyNumberOfCodeActionsAsync
/// <summary>
/// General verifier for a diagnostics that verifies how many code actions a code fix registered.
/// Creates a Document from the source string, then gets diagnostics on it and verify if it has x number of code actions registred.
/// It will fail the test if it has a different number of code actions registred to it.
/// </summary>
/// <param name="language">The language the source code is in</param>
/// <param name="analyzer">The analyzer to be applied to the source code</param>
/// <param name="codeFixProvider">The codefix to be applied to the code wherever the relevant Diagnostic is found</param>
/// <param name="source">A class in the form of a string before the CodeFix was applied to it</param>
/// <param name="languageVersionCSharp">C# language version used for compiling the test project, required unless you inform the VB language version.</param>
/// <param name="languageVersionVB">VB language version used for compiling the test project, required unless you inform the C# language version.</param>
/// <param name="numberOfCodeActions">The expected number of code actions provided by the code fix.</param>
private async static Task VerifyNumberOfCodeActionsAsync(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string source, int numberOfCodeActions, LanguageVersion languageVersionCSharp, Microsoft.CodeAnalysis.VisualBasic.LanguageVersion languageVersionVB)
{
var document = CreateDocument(source, language, languageVersionCSharp, languageVersionVB);
var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzer, new[] { document }).ConfigureAwait(true);
foreach (var analyzerDiagnostic in analyzerDiagnostics)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostic, (a, d) => actions.Add(a), CancellationToken.None);
await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(true);
var numberOfCodeActionsFound = actions.Count();
Assert.True(numberOfCodeActions == numberOfCodeActionsFound, $"Should have {numberOfCodeActions} code actions registered for diagnostic '{analyzerDiagnostic.Id}' but got {numberOfCodeActionsFound}.");
}
}