提交 86f7a704 编写于 作者: C CyrusNajmabadi

Restructure code.

上级 3ae31b36
......@@ -634,6 +634,7 @@
<Compile Include="Shared\Tagging\EventSources\TaggerEventSources.EditorFormatMapChangedEventSource.cs" />
<Compile Include="Shared\Tagging\EventSources\TaggerEventSources.ViewSpanChangedEventSource.cs" />
<Compile Include="Shared\Utilities\SynchronizationContextTaskScheduler.cs" />
<Compile Include="Implementation\Suggestions\SuggestedActionWithPreview.cs" />
<Compile Include="Tagging\AbstractAsynchronousTaggerProvider.Tagger.cs" />
<Compile Include="Tagging\AbstractAsynchronousTaggerProvider.TagSource.cs" />
<Compile Include="Tagging\AbstractAsynchronousTaggerProvider.TagSource_ReferenceCounting.cs" />
......
......@@ -4,27 +4,23 @@
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions
{
/// <summary>
/// Represents light bulb menu item for code fixes.
/// </summary>
internal sealed class CodeFixSuggestedAction : SuggestedAction, ISuggestedActionWithFlavors, ITelemetryDiagnosticID<string>
internal sealed class CodeFixSuggestedAction : SuggestedActionWithPreview, ISuggestedActionWithFlavors, ITelemetryDiagnosticID<string>
{
private readonly CodeFix _fix;
public SuggestedActionSet FixAllSuggestedActionSet { get; }
private readonly SuggestedActionSet _fixAllSuggestedActionSet;
private ImmutableArray<SuggestedActionSet> _actionSets;
......@@ -41,126 +37,10 @@ internal sealed class CodeFixSuggestedAction : SuggestedAction, ISuggestedAction
: base(workspace, subjectBuffer, editHandler, waitIndicator, action, provider, operationListener)
{
_fix = fix;
FixAllSuggestedActionSet = fixAllSuggestedActionSet;
_fixAllSuggestedActionSet = fixAllSuggestedActionSet;
}
public override bool HasActionSets
{
get
{
// HasActionSets is called synchronously on the UI thread. In order to avoid blocking the UI thread,
// we need to provide a 'quick' answer here as opposed to the 'right' answer. Providing the 'right'
// answer is expensive (because we will need to call CodeAction.GetPreviewOperationsAsync() (to
// compute whether or not we should display the flavored action for 'Preview Changes') which in turn
// will involve computing the changed solution for the ApplyChangesOperation for the fix / refactoring
// So we always return 'true' here (so that platform will call GetActionSetsAsync() below). Platform
// guarantees that nothing bad will happen if we return 'true' here and later return 'null' / empty
// collection from within GetPreviewAsync().
return true;
}
}
public async override Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
// Light bulb will always invoke this property on the UI thread.
AssertIsForeground();
if (_actionSets.IsDefault)
{
var extensionManager = this.Workspace.Services.GetService<IExtensionManager>();
_actionSets = await extensionManager.PerformFunctionAsync(Provider, async () =>
{
var builder = ArrayBuilder<SuggestedActionSet>.GetInstance();
// We use ConfigureAwait(true) to stay on the UI thread.
var previewChangesSuggestedActionSet = await GetPreviewChangesSuggestedActionSetAsync(cancellationToken).ConfigureAwait(true);
if (previewChangesSuggestedActionSet != null)
{
builder.Add(previewChangesSuggestedActionSet);
}
cancellationToken.ThrowIfCancellationRequested();
var fixAllSuggestedActionSet = this.FixAllSuggestedActionSet;
if (fixAllSuggestedActionSet != null)
{
builder.Add(fixAllSuggestedActionSet);
}
return builder.ToImmutableAndFree();
// We use ConfigureAwait(true) to stay on the UI thread.
}, defaultValue: ImmutableArray<SuggestedActionSet>.Empty).ConfigureAwait(true);
}
Contract.ThrowIfTrue(_actionSets.IsDefault);
return _actionSets;
}
private async Task<SuggestedActionSet> GetPreviewChangesSuggestedActionSetAsync(CancellationToken cancellationToken)
{
var previewResult = await GetPreviewResultAsync(cancellationToken).ConfigureAwait(true);
if (previewResult == null)
{
return null;
}
var changeSummary = previewResult.ChangeSummary;
if (changeSummary == null)
{
return null;
}
var previewAction = new PreviewChangesCodeAction(Workspace, CodeAction, changeSummary);
var previewSuggestedAction = new PreviewChangesSuggestedAction(
Workspace, SubjectBuffer, EditHandler, WaitIndicator, previewAction, Provider, OperationListener);
return new SuggestedActionSet(ImmutableArray.Create(previewSuggestedAction));
}
/// <summary>
/// If the provided fix all context is non-null and the context's code action Id matches the given code action's Id then,
/// returns the set of fix all occurrences actions associated with the code action.
/// </summary>
internal static SuggestedActionSet GetFixAllSuggestedActionSet(
CodeAction action,
int actionCount,
FixAllState fixAllState,
IEnumerable<FixAllScope> supportedScopes,
Diagnostic firstDiagnostic,
Workspace workspace,
ITextBuffer subjectBuffer,
ICodeActionEditHandlerService editHandler,
IWaitIndicator waitIndicator,
IAsynchronousOperationListener operationListener)
{
if (fixAllState == null)
{
return null;
}
if (actionCount > 1 && action.EquivalenceKey == null)
{
return null;
}
var fixAllSuggestedActions = ArrayBuilder<FixAllSuggestedAction>.GetInstance();
foreach (var scope in supportedScopes)
{
var fixAllStateForScope = fixAllState.WithScopeAndEquivalenceKey(scope, action.EquivalenceKey);
var fixAllAction = new FixAllCodeAction(fixAllStateForScope, showPreviewChangesDialog: true);
var fixAllSuggestedAction = new FixAllSuggestedAction(
workspace, subjectBuffer, editHandler, waitIndicator, fixAllAction,
fixAllStateForScope.FixAllProvider, firstDiagnostic, operationListener);
fixAllSuggestedActions.Add(fixAllSuggestedAction);
}
return new SuggestedActionSet(
fixAllSuggestedActions.ToImmutableAndFree(),
title: EditorFeaturesResources.Fix_all_occurrences_in);
}
protected override SuggestedActionSet GetAdditionalActionSet() => _fixAllSuggestedActionSet;
public string GetDiagnosticID()
{
......
......@@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions
/// <summary>
/// Represents light bulb menu item for code refactorings.
/// </summary>
internal sealed class CodeRefactoringSuggestedAction : SuggestedAction
internal sealed class CodeRefactoringSuggestedAction : SuggestedActionWithPreview
{
public CodeRefactoringSuggestedAction(
Workspace workspace,
......@@ -25,4 +25,4 @@ internal sealed class CodeRefactoringSuggestedAction : SuggestedAction
{
}
}
}
}
\ No newline at end of file
......@@ -386,5 +386,25 @@ public override int GetHashCode()
}
#endregion
protected async Task<SuggestedActionSet> GetPreviewChangesSuggestedActionSetAsync(CancellationToken cancellationToken)
{
var previewResult = await GetPreviewResultAsync(cancellationToken).ConfigureAwait(true);
if (previewResult == null)
{
return null;
}
var changeSummary = previewResult.ChangeSummary;
if (changeSummary == null)
{
return null;
}
var previewAction = new PreviewChangesCodeAction(Workspace, CodeAction, changeSummary);
var previewSuggestedAction = new PreviewChangesSuggestedAction(
Workspace, SubjectBuffer, EditHandler, WaitIndicator, previewAction, Provider, OperationListener);
return new SuggestedActionSet(ImmutableArray.Create(previewSuggestedAction));
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions
{
internal class SuggestedActionWithChildActions : SuggestedAction
{
public SuggestedActionWithChildActions(
Workspace workspace,
ITextBuffer subjectBuffer,
ICodeActionEditHandlerService editHandler,
IWaitIndicator waitIndicator,
CodeAction codeAction,
object provider,
IAsynchronousOperationListener operationListener,
SuggestedActionSet childActions)
: base(workspace, subjectBuffer, editHandler, waitIndicator,
codeAction, provider, operationListener,
SpecializedCollections.SingletonEnumerable(childActions))
{
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions
{
internal class SuggestedActionWithPreview : SuggestedAction
{
private ImmutableArray<SuggestedActionSet> _actionSets;
public SuggestedActionWithPreview(
Workspace workspace, ITextBuffer subjectBuffer, ICodeActionEditHandlerService editHandler,
IWaitIndicator waitIndicator, CodeAction codeAction, object provider,
IAsynchronousOperationListener operationListener)
: base(workspace, subjectBuffer, editHandler, waitIndicator, codeAction,
provider, operationListener, actionSets: null)
{
}
// HasActionSets is called synchronously on the UI thread. In order to avoid blocking the UI thread,
// we need to provide a 'quick' answer here as opposed to the 'right' answer. Providing the 'right'
// answer is expensive (because we will need to call CodeAction.GetPreviewOperationsAsync() (to
// compute whether or not we should display the flavored action for 'Preview Changes') which in turn
// will involve computing the changed solution for the ApplyChangesOperation for the fix / refactoring
// So we always return 'true' here (so that platform will call GetActionSetsAsync() below). Platform
// guarantees that nothing bad will happen if we return 'true' here and later return 'null' / empty
// collection from within GetPreviewAsync().
public override bool HasActionSets => true;
public async sealed override Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
// Light bulb will always invoke this property on the UI thread.
AssertIsForeground();
if (_actionSets.IsDefault)
{
var extensionManager = this.Workspace.Services.GetService<IExtensionManager>();
_actionSets = await extensionManager.PerformFunctionAsync(Provider, async () =>
{
var builder = ArrayBuilder<SuggestedActionSet>.GetInstance();
// We use ConfigureAwait(true) to stay on the UI thread.
var previewChangesSuggestedActionSet = await GetPreviewChangesSuggestedActionSetAsync(cancellationToken).ConfigureAwait(true);
if (previewChangesSuggestedActionSet != null)
{
builder.Add(previewChangesSuggestedActionSet);
}
var additionalSet = this.GetAdditionalActionSet();
if (additionalSet != null)
{
builder.Add(additionalSet);
}
return builder.ToImmutableAndFree();
// We use ConfigureAwait(true) to stay on the UI thread.
}, defaultValue: ImmutableArray<SuggestedActionSet>.Empty).ConfigureAwait(true);
}
Contract.ThrowIfTrue(_actionSets.IsDefault);
return _actionSets;
}
protected virtual SuggestedActionSet GetAdditionalActionSet() => null;
}
}
\ No newline at end of file
......@@ -349,7 +349,7 @@ private IEnumerable<SuggestedActionSet> OrganizeFixes(Workspace workspace, IEnum
var fixCount = fixes.Length;
Func<CodeAction, SuggestedActionSet> getFixAllSuggestedActionSet =
codeAction => CodeFixSuggestedAction.GetFixAllSuggestedActionSet(
codeAction => GetFixAllSuggestedActionSet(
codeAction, fixCount, fixCollection.FixAllState,
fixCollection.SupportedScopes, fixCollection.FirstDiagnostic,
workspace, _subjectBuffer, _owner._editHandler,
......@@ -434,6 +434,48 @@ private IEnumerable<SuggestedActionSet> OrganizeFixes(Workspace workspace, IEnum
map[groupKey].Add(suggestedAction);
}
/// <summary>
/// If the provided fix all context is non-null and the context's code action Id matches the given code action's Id then,
/// returns the set of fix all occurrences actions associated with the code action.
/// </summary>
internal static SuggestedActionSet GetFixAllSuggestedActionSet(
CodeAction action,
int actionCount,
FixAllState fixAllState,
IEnumerable<FixAllScope> supportedScopes,
Diagnostic firstDiagnostic,
Workspace workspace,
ITextBuffer subjectBuffer,
ICodeActionEditHandlerService editHandler,
IWaitIndicator waitIndicator,
IAsynchronousOperationListener operationListener)
{
if (fixAllState == null)
{
return null;
}
if (actionCount > 1 && action.EquivalenceKey == null)
{
return null;
}
var fixAllSuggestedActions = ArrayBuilder<FixAllSuggestedAction>.GetInstance();
foreach (var scope in supportedScopes)
{
var fixAllStateForScope = fixAllState.WithScopeAndEquivalenceKey(scope, action.EquivalenceKey);
var fixAllAction = new FixAllCodeAction(fixAllStateForScope, showPreviewChangesDialog: true);
var fixAllSuggestedAction = new FixAllSuggestedAction(
workspace, subjectBuffer, editHandler, waitIndicator, fixAllAction,
fixAllStateForScope.FixAllProvider, firstDiagnostic, operationListener);
fixAllSuggestedActions.Add(fixAllSuggestedAction);
}
return new SuggestedActionSet(
fixAllSuggestedActions.ToImmutableAndFree(),
title: EditorFeaturesResources.Fix_all_occurrences_in);
}
/// <summary>
/// Return prioritized set of fix groups such that fix group for suppression always show up at the bottom of the list.
/// </summary>
......
......@@ -891,7 +891,8 @@ End Namespace",
"Imports System.Collections.Generic
Namespace N1
Class Test
Private a As [|System.Collections.Generic.List(Of System.String()(,)(,,,)) |]
Private a As [|System.Collections.Generic.List(Of System.String()(,)(,,,))
|]
End Class
End Namespace",
"Imports System.Collections.Generic
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册