提交 8ce5c4b1 编写于 作者: C CyrusNajmabadi

Only pass FixAllContexts to methods that actuall y need it. For internal...

Only pass FixAllContexts to methods that actuall y need it.  For internal methods that don't need all that functionality, pass a FixAllState instead.
上级 e793919a
......@@ -51,7 +51,8 @@ public async Task<Solution> GetFixAllChangedSolutionAsync(FixAllContext fixAllCo
return null;
}
return await GetFixAllOperationsAsync(codeAction, fixAllContext, showPreviewChangesDialog).ConfigureAwait(false);
return await GetFixAllOperationsAsync(
codeAction, showPreviewChangesDialog, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false);
}
private async Task<CodeAction> GetFixAllCodeActionAsync(FixAllContext fixAllContext)
......@@ -83,13 +84,14 @@ private async Task<CodeAction> GetFixAllCodeActionAsync(FixAllContext fixAllCont
}
}
private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(CodeAction codeAction, FixAllContext fixAllContext, bool showPreviewChangesDialog)
private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(
CodeAction codeAction, bool showPreviewChangesDialog,
FixAllState fixAllState, CancellationToken cancellationToken)
{
// We have computed the fix all occurrences code fix.
// Now fetch the new solution with applied fix and bring up the Preview changes dialog.
var cancellationToken = fixAllContext.CancellationToken;
var workspace = fixAllContext.Project.Solution.Workspace;
var workspace = fixAllState.Project.Solution.Workspace;
cancellationToken.ThrowIfCancellationRequested();
var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false);
......@@ -104,11 +106,11 @@ private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(Co
if (showPreviewChangesDialog)
{
newSolution = PreviewChanges(
fixAllContext.Project.Solution,
fixAllState.Project.Solution,
newSolution,
FeaturesResources.FixAllOccurrences,
codeAction.Title,
fixAllContext.Project.Language,
fixAllState.Project.Language,
workspace,
cancellationToken);
if (newSolution == null)
......
......@@ -37,18 +37,20 @@ public async override Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
var documentsAndDiagnosticsToFixMap =
await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false);
return !isGlobalSuppression ?
await batchFixer.GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false) :
GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Document, documentsAndDiagnosticsToFixMap);
return !isGlobalSuppression
? await batchFixer.GetFixAsync(
documentsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false)
: GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Document, documentsAndDiagnosticsToFixMap);
}
else
{
var projectsAndDiagnosticsToFixMap =
await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false);
return !isGlobalSuppression ?
await batchFixer.GetFixAsync(projectsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false) :
GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Project, projectsAndDiagnosticsToFixMap);
return !isGlobalSuppression
? await batchFixer.GetFixAsync(
projectsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false)
: GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Project, projectsAndDiagnosticsToFixMap);
}
}
}
......
......@@ -25,15 +25,16 @@ private static class PragmaBatchFixHelpers
Document document,
ImmutableArray<IPragmaBasedCodeAction> pragmaActions,
ImmutableArray<Diagnostic> pragmaDiagnostics,
FixAllContext fixAllContext)
FixAllState fixAllState,
CancellationToken cancellationToken)
{
// This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005.
#pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction
return CodeAction.Create(
((CodeAction)pragmaActions[0]).Title,
createChangedDocument: ct =>
BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllContext.CancellationToken),
equivalenceKey: fixAllContext.CodeActionEquivalenceKey);
BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, cancellationToken),
equivalenceKey: fixAllState.CodeActionEquivalenceKey);
#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction
}
......
......@@ -26,7 +26,9 @@ public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppr
_suppressionFixProvider = suppressionFixProvider;
}
public override async Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
public override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{
var pragmaActionsBuilder = ImmutableArray.CreateBuilder<IPragmaBasedCodeAction>();
var pragmaDiagnosticsBuilder = ImmutableArray.CreateBuilder<Diagnostic>();
......@@ -34,11 +36,12 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr
foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && !d.IsSuppressed))
{
var span = diagnostic.Location.SourceSpan;
var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync(document, span, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false);
var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync(
document, span, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);
var pragmaSuppression = pragmaSuppressions.SingleOrDefault();
if (pragmaSuppression != null)
{
if (fixAllContext.IsFixMultiple)
if (fixAllState.IsFixMultiple)
{
pragmaSuppression = pragmaSuppression.CloneForFixMultipleContext();
}
......@@ -51,8 +54,10 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr
// Get the pragma batch fix.
if (pragmaActionsBuilder.Count > 0)
{
var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(_suppressionFixProvider, document,
pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllContext);
var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(
_suppressionFixProvider, document,
pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(),
fixAllState, cancellationToken);
addFix(pragmaBatchFix);
}
......
......@@ -32,7 +32,9 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
_suppressionFixProvider = suppressionFixProvider;
}
public override async Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
public override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{
// Batch all the pragma remove suppression fixes by executing them sequentially for the document.
var pragmaActionsBuilder = ImmutableArray.CreateBuilder<IPragmaBasedCodeAction>();
......@@ -40,14 +42,15 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr
foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && d.IsSuppressed))
{
var span = diagnostic.Location.SourceSpan;
var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(document, span, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false);
var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(
document, span, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);
var removeSuppressionFix = removeSuppressionFixes.SingleOrDefault();
if (removeSuppressionFix != null)
{
var codeAction = removeSuppressionFix.Action as RemoveSuppressionCodeAction;
if (codeAction != null)
{
if (fixAllContext.IsFixMultiple)
if (fixAllState.IsFixMultiple)
{
codeAction = codeAction.CloneForFixMultipleContext();
}
......@@ -69,22 +72,27 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr
// Get the pragma batch fix.
if (pragmaActionsBuilder.Count > 0)
{
var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(_suppressionFixProvider, document,
pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllContext);
var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(
_suppressionFixProvider, document,
pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(),
fixAllState, cancellationToken);
addFix(pragmaBatchFix);
}
}
public async override Task AddProjectFixesAsync(Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
public async override Task AddProjectFixesAsync(
Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{
foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed))
{
var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(project, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false);
var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(
project, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);
var removeSuppressionCodeAction = removeSuppressionFixes.SingleOrDefault()?.Action as RemoveSuppressionCodeAction;
if (removeSuppressionCodeAction != null)
{
if (fixAllContext.IsFixMultiple)
if (fixAllState.IsFixMultiple)
{
removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext();
}
......@@ -94,14 +102,14 @@ public async override Task AddProjectFixesAsync(Project project, ImmutableArray<
}
}
public override async Task<CodeAction> TryGetMergedFixAsync(IEnumerable<CodeAction> batchOfFixes, FixAllContext fixAllContext)
public override async Task<CodeAction> TryGetMergedFixAsync(
IEnumerable<CodeAction> batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken)
{
// Batch all the attribute removal fixes into a single fix.
// Pragma removal fixes have already been batch for each document AddDocumentFixes method.
// This ensures no merge conflicts in merging all fixes by our base implementation.
var cancellationToken = fixAllContext.CancellationToken;
var oldSolution = fixAllContext.Project.Solution;
var oldSolution = fixAllState.Project.Solution;
var currentSolution = oldSolution;
var attributeRemoveFixes = new List<AttributeRemoveAction>();
......@@ -139,13 +147,13 @@ public override async Task<CodeAction> TryGetMergedFixAsync(IEnumerable<CodeActi
var batchAttributeRemoveFix = Create(
attributeRemoveFixes.First().Title,
createChangedSolution: ct => Task.FromResult(currentSolution),
equivalenceKey: fixAllContext.CodeActionEquivalenceKey);
equivalenceKey: fixAllState.CodeActionEquivalenceKey);
#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction
newBatchOfFixes.Insert(0, batchAttributeRemoveFix);
}
return await base.TryGetMergedFixAsync(newBatchOfFixes, fixAllContext).ConfigureAwait(false);
return await base.TryGetMergedFixAsync(newBatchOfFixes, fixAllState, cancellationToken).ConfigureAwait(false);
}
private static async Task<ImmutableArray<SyntaxNode>> GetAttributeNodesToFixAsync(ImmutableArray<AttributeRemoveAction> attributeRemoveFixes, CancellationToken cancellationToken)
......
......@@ -31,12 +31,12 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
if (fixAllContext.Document != null)
{
var documentsAndDiagnosticsToFixMap = await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false);
return await GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false);
return await GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false);
}
else
{
var projectsAndDiagnosticsToFixMap = await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false);
return await GetFixAsync(projectsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false);
return await GetFixAsync(projectsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false);
}
}
......@@ -44,7 +44,7 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
internal override async Task<CodeAction> GetFixAsync(
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> documentsAndDiagnosticsToFixMap,
FixAllContext fixAllContext)
FixAllState fixAllState, CancellationToken cancellationToken)
{
if (documentsAndDiagnosticsToFixMap != null && documentsAndDiagnosticsToFixMap.Any())
{
......@@ -52,22 +52,22 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
var fixesBag = new ConcurrentBag<CodeAction>();
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, fixAllContext.CancellationToken))
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, cancellationToken))
{
fixAllContext.CancellationToken.ThrowIfCancellationRequested();
cancellationToken.ThrowIfCancellationRequested();
var documents = documentsAndDiagnosticsToFixMap.Keys;
var tasks = documents.Select(d => AddDocumentFixesAsync(d, documentsAndDiagnosticsToFixMap[d], fixesBag.Add, fixAllContext))
var tasks = documents.Select(d => AddDocumentFixesAsync(d, documentsAndDiagnosticsToFixMap[d], fixesBag.Add, fixAllState, cancellationToken))
.ToArray();
await Task.WhenAll(tasks).ConfigureAwait(false);
}
if (fixesBag.Any())
{
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, fixAllContext.CancellationToken))
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, cancellationToken))
{
FixAllLogger.LogFixesToMergeStats(fixesBag);
return await TryGetMergedFixAsync(fixesBag, fixAllContext).ConfigureAwait(false);
return await TryGetMergedFixAsync(fixesBag, fixAllState, cancellationToken).ConfigureAwait(false);
}
}
}
......@@ -75,10 +75,11 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
return null;
}
public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
public async virtual Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{
Debug.Assert(!diagnostics.IsDefault);
var cancellationToken = fixAllContext.CancellationToken;
cancellationToken.ThrowIfCancellationRequested();
var fixerTasks = new Task[diagnostics.Length];
......@@ -105,13 +106,13 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra
// TODO: Wrap call to ComputeFixesAsync() below in IExtensionManager.PerformFunctionAsync() so that
// a buggy extension that throws can't bring down the host?
var task = fixAllContext.CodeFixProvider.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask;
var task = fixAllState.CodeFixProvider.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask;
await task.ConfigureAwait(false);
foreach (var fix in fixes)
{
cancellationToken.ThrowIfCancellationRequested();
if (fix != null && fix.EquivalenceKey == fixAllContext.CodeActionEquivalenceKey)
if (fix != null && fix.EquivalenceKey == fixAllState.CodeActionEquivalenceKey)
{
addFix(fix);
}
......@@ -124,7 +125,7 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra
internal override async Task<CodeAction> GetFixAsync(
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> projectsAndDiagnosticsToFixMap,
FixAllContext fixAllContext)
FixAllState fixAllState, CancellationToken cancellationToken)
{
if (projectsAndDiagnosticsToFixMap != null && projectsAndDiagnosticsToFixMap.Any())
{
......@@ -132,20 +133,20 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra
var fixesBag = new ConcurrentBag<CodeAction>();
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, fixAllContext.CancellationToken))
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, cancellationToken))
{
var projects = projectsAndDiagnosticsToFixMap.Keys;
var tasks = projects.Select(p => AddProjectFixesAsync(p, projectsAndDiagnosticsToFixMap[p], fixesBag.Add, fixAllContext))
var tasks = projects.Select(p => AddProjectFixesAsync(p, projectsAndDiagnosticsToFixMap[p], fixesBag.Add, fixAllState, cancellationToken))
.ToArray();
await Task.WhenAll(tasks).ConfigureAwait(false);
}
if (fixesBag.Any())
{
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, fixAllContext.CancellationToken))
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, cancellationToken))
{
FixAllLogger.LogFixesToMergeStats(fixesBag);
return await TryGetMergedFixAsync(fixesBag, fixAllContext).ConfigureAwait(false);
return await TryGetMergedFixAsync(fixesBag, fixAllState, cancellationToken).ConfigureAwait(false);
}
}
}
......@@ -153,10 +154,11 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra
return null;
}
public virtual async Task AddProjectFixesAsync(Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
public virtual async Task AddProjectFixesAsync(
Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{
Debug.Assert(!diagnostics.IsDefault);
var cancellationToken = fixAllContext.CancellationToken;
cancellationToken.ThrowIfCancellationRequested();
var fixes = new List<CodeAction>();
......@@ -175,39 +177,39 @@ public virtual async Task AddProjectFixesAsync(Project project, ImmutableArray<D
// TODO: Wrap call to ComputeFixesAsync() below in IExtensionManager.PerformFunctionAsync() so that
// a buggy extension that throws can't bring down the host?
var task = fixAllContext.CodeFixProvider.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask;
var task = fixAllState.CodeFixProvider.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask;
await task.ConfigureAwait(false);
foreach (var fix in fixes)
{
cancellationToken.ThrowIfCancellationRequested();
if (fix != null && fix.EquivalenceKey == fixAllContext.CodeActionEquivalenceKey)
if (fix != null && fix.EquivalenceKey == fixAllState.CodeActionEquivalenceKey)
{
addFix(fix);
}
}
}
public virtual async Task<CodeAction> TryGetMergedFixAsync(IEnumerable<CodeAction> batchOfFixes, FixAllContext fixAllContext)
public virtual async Task<CodeAction> TryGetMergedFixAsync(
IEnumerable<CodeAction> batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken)
{
Contract.ThrowIfNull(batchOfFixes);
Contract.ThrowIfFalse(batchOfFixes.Any());
var solution = fixAllContext.Solution;
var cancellationToken = fixAllContext.CancellationToken;
var solution = fixAllState.Solution;
var newSolution = await TryMergeFixesAsync(solution, batchOfFixes, cancellationToken).ConfigureAwait(false);
if (newSolution != null && newSolution != solution)
{
var title = GetFixAllTitle(fixAllContext);
var title = GetFixAllTitle(fixAllState);
return new CodeAction.SolutionChangeAction(title, _ => Task.FromResult(newSolution));
}
return null;
}
public virtual string GetFixAllTitle(FixAllContext fixAllContext)
public virtual string GetFixAllTitle(FixAllState fixAllState)
{
var diagnosticIds = fixAllContext.DiagnosticIds;
var diagnosticIds = fixAllState.DiagnosticIds;
string diagnosticId;
if (diagnosticIds.Count() == 1)
{
......@@ -218,17 +220,17 @@ public virtual string GetFixAllTitle(FixAllContext fixAllContext)
diagnosticId = string.Join(",", diagnosticIds.ToArray());
}
switch (fixAllContext.Scope)
switch (fixAllState.Scope)
{
case FixAllScope.Custom:
return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnostic, diagnosticId);
case FixAllScope.Document:
var document = fixAllContext.Document;
var document = fixAllState.Document;
return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnosticInScope, diagnosticId, document.Name);
case FixAllScope.Project:
var project = fixAllContext.Project;
var project = fixAllState.Project;
return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnosticInScope, diagnosticId, project.Name);
case FixAllScope.Solution:
......
......@@ -23,10 +23,13 @@ internal class BatchSimplificationFixAllProvider : BatchFixAllProvider
protected BatchSimplificationFixAllProvider() { }
public override async Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
public override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{
var changedDocument = await AddSimplifierAnnotationsAsync(document, diagnostics, fixAllContext).ConfigureAwait(false);
var title = GetFixAllTitle(fixAllContext);
var changedDocument = await AddSimplifierAnnotationsAsync(
document, diagnostics, fixAllState, cancellationToken).ConfigureAwait(false);
var title = GetFixAllTitle(fixAllState);
var codeAction = new MyCodeAction(title, (c) => Task.FromResult(changedDocument));
addFix(codeAction);
}
......@@ -52,19 +55,20 @@ protected virtual Task<Document> AddSimplifyAnnotationsAsync(Document document,
}
/// <summary>
/// By default, this property returns false and <see cref="AddSimplifierAnnotationsAsync(Document, ImmutableArray{Diagnostic}, FixAllContext)"/> will just add <see cref="Simplifier.Annotation"/> to each node to simplify
/// By default, this property returns false and <see cref="AddSimplifierAnnotationsAsync(Document, ImmutableArray{Diagnostic}, FixAllState, CancellationToken)"/> will just add <see cref="Simplifier.Annotation"/> to each node to simplify
/// returned by <see cref="GetNodeToSimplify(SyntaxNode, SemanticModel, Diagnostic, Workspace, out string, CancellationToken)"/>.
///
/// Override this property to return true if the fix all provider needs to add simplify annotations/fixup any of the parent nodes of the nodes to simplify.
/// This could be the case if simplifying certain nodes can enable cascaded simplifications, such as parentheses removal on parenting node.
/// <see cref="AddSimplifierAnnotationsAsync(Document, ImmutableArray{Diagnostic}, FixAllContext)"/> will end up invoking <see cref="AddSimplifyAnnotationsAsync(Document, SyntaxNode, CancellationToken)"/> for each node to simplify.
/// <see cref="AddSimplifierAnnotationsAsync(Document, ImmutableArray{Diagnostic}, FixAllState, CancellationToken)"/> will end up invoking <see cref="AddSimplifyAnnotationsAsync(Document, SyntaxNode, CancellationToken)"/> for each node to simplify.
/// Ensure that you override <see cref="AddSimplifyAnnotationsAsync(Document, SyntaxNode, CancellationToken)"/> method when this property returns true.
/// </summary>
protected virtual bool NeedsParentFixup { get { return false; } }
private async Task<Document> AddSimplifierAnnotationsAsync(Document document, ImmutableArray<Diagnostic> diagnostics, FixAllContext fixAllContext)
private async Task<Document> AddSimplifierAnnotationsAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
FixAllState fixAllState, CancellationToken cancellationToken)
{
var cancellationToken = fixAllContext.CancellationToken;
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
......@@ -73,8 +77,8 @@ private async Task<Document> AddSimplifierAnnotationsAsync(Document document, Im
foreach (var diagnostic in diagnostics)
{
string codeActionEquivalenceKey;
var node = GetNodeToSimplify(root, model, diagnostic, fixAllContext.Solution.Workspace, out codeActionEquivalenceKey, cancellationToken);
if (node != null && fixAllContext.CodeActionEquivalenceKey == codeActionEquivalenceKey)
var node = GetNodeToSimplify(root, model, diagnostic, fixAllState.Solution.Workspace, out codeActionEquivalenceKey, cancellationToken);
if (node != null && fixAllState.CodeActionEquivalenceKey == codeActionEquivalenceKey)
{
nodesToSimplify.Add(node);
}
......
......@@ -160,7 +160,8 @@ private static Document GetReportedDocument(Diagnostic diagnostic, ImmutableDict
return null;
}
internal virtual async Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>>> GetProjectDiagnosticsToFixAsync(FixAllContext fixAllContext)
internal virtual async Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>>> GetProjectDiagnosticsToFixAsync(
FixAllContext fixAllContext)
{
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, fixAllContext.CancellationToken))
{
......
......@@ -16,47 +16,47 @@ namespace Microsoft.CodeAnalysis.CodeFixes
/// </summary>
public sealed partial class FixAllContext
{
private readonly FixAllState _state;
internal FixAllState State { get; }
internal FixAllProvider FixAllProvider => _state.FixAllProvider;
internal FixAllProvider FixAllProvider => State.FixAllProvider;
/// <summary>
/// Solution to fix all occurrences.
/// </summary>
public Solution Solution => _state.Solution;
public Solution Solution => State.Solution;
/// <summary>
/// Project within which fix all occurrences was triggered.
/// </summary>
public Project Project => _state.Project;
public Project Project => State.Project;
/// <summary>
/// Document within which fix all occurrences was triggered.
/// Can be null if the context was created using <see cref="FixAllContext.FixAllContext(Project, CodeFixProvider, FixAllScope, string, IEnumerable{string}, DiagnosticProvider, CancellationToken)"/>.
/// </summary>
public Document Document => _state.Document;
public Document Document => State.Document;
/// <summary>
/// Underlying <see cref="CodeFixes.CodeFixProvider"/> which triggered this fix all.
/// </summary>
public CodeFixProvider CodeFixProvider => _state.CodeFixProvider;
public CodeFixProvider CodeFixProvider => State.CodeFixProvider;
/// <summary>
/// <see cref="FixAllScope"/> to fix all occurrences.
/// </summary>
public FixAllScope Scope => _state.Scope;
public FixAllScope Scope => State.Scope;
/// <summary>
/// Diagnostic Ids to fix.
/// Note that <see cref="GetDocumentDiagnosticsAsync(Document)"/>, <see cref="GetProjectDiagnosticsAsync(Project)"/> and <see cref="GetAllDiagnosticsAsync(Project)"/> methods
/// return only diagnostics whose IDs are contained in this set of Ids.
/// </summary>
public ImmutableHashSet<string> DiagnosticIds => _state.DiagnosticIds;
public ImmutableHashSet<string> DiagnosticIds => State.DiagnosticIds;
/// <summary>
/// The <see cref="CodeAction.EquivalenceKey"/> value expected of a <see cref="CodeAction"/> participating in this fix all.
/// </summary>
public string CodeActionEquivalenceKey => _state.CodeActionEquivalenceKey;
public string CodeActionEquivalenceKey => State.CodeActionEquivalenceKey;
/// <summary>
/// CancellationToken for fix all session.
......@@ -125,12 +125,10 @@ public sealed partial class FixAllContext
FixAllState state,
CancellationToken cancellationToken)
{
_state = state;
State = state;
this.CancellationToken = cancellationToken;
}
internal bool IsFixMultiple => _state.DiagnosticProvider.IsFixMultiple;
/// <summary>
/// Gets all the diagnostics in the given document filtered by <see cref="DiagnosticIds"/>.
/// </summary>
......@@ -146,7 +144,7 @@ public async Task<ImmutableArray<Diagnostic>> GetDocumentDiagnosticsAsync(Docume
return ImmutableArray<Diagnostic>.Empty;
}
var getDiagnosticsTask = _state.DiagnosticProvider.GetDocumentDiagnosticsAsync(document, this.CancellationToken);
var getDiagnosticsTask = State.DiagnosticProvider.GetDocumentDiagnosticsAsync(document, this.CancellationToken);
return await GetFilteredDiagnosticsAsync(getDiagnosticsTask, this.DiagnosticIds).ConfigureAwait(false);
}
......@@ -206,8 +204,8 @@ private async Task<ImmutableArray<Diagnostic>> GetProjectDiagnosticsAsync(Projec
}
var getDiagnosticsTask = includeAllDocumentDiagnostics ?
_state.DiagnosticProvider.GetAllDiagnosticsAsync(project, CancellationToken) :
_state.DiagnosticProvider.GetProjectDiagnosticsAsync(project, CancellationToken);
State.DiagnosticProvider.GetAllDiagnosticsAsync(project, CancellationToken) :
State.DiagnosticProvider.GetProjectDiagnosticsAsync(project, CancellationToken);
return await GetFilteredDiagnosticsAsync(getDiagnosticsTask, this.DiagnosticIds).ConfigureAwait(false);
}
......@@ -222,17 +220,17 @@ public FixAllContext WithCancellationToken(CancellationToken cancellationToken)
return this;
}
return new FixAllContext(_state, cancellationToken);
return new FixAllContext(State, cancellationToken);
}
internal Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixAsync()
{
return _state.DiagnosticProvider.GetDocumentDiagnosticsToFixAsync(this);
return State.DiagnosticProvider.GetDocumentDiagnosticsToFixAsync(this);
}
internal Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>>> GetProjectDiagnosticsToFixAsync()
{
return _state.DiagnosticProvider.GetProjectDiagnosticsToFixAsync(this);
return State.DiagnosticProvider.GetProjectDiagnosticsToFixAsync(this);
}
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
......@@ -42,14 +43,14 @@ public virtual IEnumerable<string> GetSupportedFixAllDiagnosticIds(CodeFixProvid
internal virtual Task<CodeAction> GetFixAsync(
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> documentsAndDiagnosticsToFixMap,
FixAllContext fixAllContext)
FixAllState fixAllState, CancellationToken cancellationToken)
{
return Task.FromResult<CodeAction>(null);
}
internal virtual Task<CodeAction> GetFixAsync(
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> projectsAndDiagnosticsToFixMap,
FixAllContext fixAllContext)
FixAllState fixAllState, CancellationToken cancellationToken)
{
return Task.FromResult<CodeAction>(null);
}
......
......@@ -95,6 +95,8 @@ internal partial class FixAllState
this.DiagnosticProvider = fixAllDiagnosticProvider;
}
internal bool IsFixMultiple => this.DiagnosticProvider.IsFixMultiple;
public FixAllState WithScopeAndEquivalenceKey(FixAllScope scope, string codeActionEquivalenceKey)
{
if (this.Scope == scope && this.CodeActionEquivalenceKey == codeActionEquivalenceKey)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册