Skip to content

Commit cdb3c71

Browse files
Merge branch 'main' into renameTrackingExtensino2
2 parents 0162e46 + f827454 commit cdb3c71

File tree

21 files changed

+257
-336
lines changed

21 files changed

+257
-336
lines changed

src/EditorFeatures/Core.Wpf/Interactive/ResetInteractive.cs

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,36 +41,35 @@ internal ResetInteractive(EditorOptionsService editorOptionsService, Func<string
4141
_createImport = createImport;
4242
}
4343

44-
internal Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
44+
internal async Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
4545
{
4646
if (GetProjectProperties(out var references, out var referenceSearchPaths, out var sourceSearchPaths, out var projectNamespaces, out var projectDirectory, out var platform))
4747
{
48-
// Now, we're going to do a bunch of async operations. So create a wait
49-
// indicator so the user knows something is happening, and also so they cancel.
50-
var uiThreadOperationExecutor = GetUIThreadOperationExecutor();
51-
var context = uiThreadOperationExecutor.BeginExecute(title, EditorFeaturesWpfResources.Building_Project, allowCancellation: true, showProgress: false);
52-
53-
var resetInteractiveTask = ResetInteractiveAsync(
54-
interactiveWindow,
55-
references,
56-
referenceSearchPaths,
57-
sourceSearchPaths,
58-
projectNamespaces,
59-
projectDirectory,
60-
platform,
61-
context);
62-
63-
// Once we're done resetting, dismiss the wait indicator and focus the REPL window.
64-
return resetInteractiveTask.SafeContinueWith(
65-
_ =>
66-
{
67-
context.Dispose();
68-
ExecutionCompleted?.Invoke(this, new EventArgs());
69-
},
70-
TaskScheduler.FromCurrentSynchronizationContext());
48+
try
49+
{
50+
// Now, we're going to do a bunch of async operations. So create a wait
51+
// indicator so the user knows something is happening, and also so they cancel.
52+
var uiThreadOperationExecutor = GetUIThreadOperationExecutor();
53+
using var context = uiThreadOperationExecutor.BeginExecute(title, EditorFeaturesWpfResources.Building_Project, allowCancellation: true, showProgress: false);
54+
55+
// We want to come back onto the calling context to dismiss the wait indicator and to notify about
56+
// execution completion.
57+
await ResetInteractiveAsync(
58+
interactiveWindow,
59+
references,
60+
referenceSearchPaths,
61+
sourceSearchPaths,
62+
projectNamespaces,
63+
projectDirectory,
64+
platform,
65+
context).ConfigureAwait(true);
66+
}
67+
finally
68+
{
69+
// Once we're done resetting focus the REPL window.
70+
ExecutionCompleted?.Invoke(this, new EventArgs());
71+
}
7172
}
72-
73-
return Task.CompletedTask;
7473
}
7574

7675
private async Task ResetInteractiveAsync(

src/EditorFeatures/Core.Wpf/SignatureHelp/Controller.Session.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ internal partial class Controller
1515
internal partial class Session : Session<Controller, Model, ISignatureHelpPresenterSession>
1616
{
1717
public Session(Controller controller, ISignatureHelpPresenterSession presenterSession)
18-
: base(controller, new ModelComputation<Model>(controller.ThreadingContext, controller, TaskScheduler.Default), presenterSession)
18+
: base(controller, new ModelComputation<Model>(controller.ThreadingContext, controller), presenterSession)
1919
{
2020
this.PresenterSession.ItemSelected += OnPresenterSessionItemSelected;
2121
}

src/EditorFeatures/Core.Wpf/SignatureHelp/Controller.Session_ComputeModel.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
using Microsoft.CodeAnalysis.ErrorReporting;
1414
using Microsoft.CodeAnalysis.Internal.Log;
1515
using Microsoft.CodeAnalysis.LanguageService;
16-
using Microsoft.CodeAnalysis.Options;
1716
using Microsoft.CodeAnalysis.Shared.Extensions;
1817
using Microsoft.CodeAnalysis.SignatureHelp;
1918
using Microsoft.VisualStudio.Text;
19+
using Microsoft.VisualStudio.Threading;
2020
using Roslyn.Utilities;
2121

2222
namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.SignatureHelp
@@ -37,9 +37,8 @@ public void ComputeModel(
3737
// If we've already computed a model, then just use that. Otherwise, actually
3838
// compute a new model and send that along.
3939
Computation.ChainTaskAndNotifyControllerWhenFinished(
40-
(model, cancellationToken) => ComputeModelInBackgroundAsync(
41-
model, providers, caretPosition, disconnectedBufferGraph,
42-
triggerInfo, cancellationToken));
40+
(currentModel, cancellationToken) => ComputeModelInBackgroundAsync(
41+
currentModel, providers, caretPosition, disconnectedBufferGraph, triggerInfo, cancellationToken));
4342
}
4443

4544
private async Task<Model> ComputeModelInBackgroundAsync(

src/EditorFeatures/Core.Wpf/SignatureHelp/Controller.Session_SetModelSelectedItem.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
#nullable disable
6-
75
using System;
6+
using System.Threading.Tasks;
87
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
98
using Microsoft.CodeAnalysis.SignatureHelp;
9+
using Microsoft.VisualStudio.Threading;
1010
using Roslyn.Utilities;
1111

1212
namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.SignatureHelp
@@ -20,20 +20,17 @@ private void SetModelExplicitlySelectedItem(Func<Model, SignatureHelpItem> selec
2020
this.Computation.ThreadingContext.ThrowIfNotOnUIThread();
2121

2222
Computation.ChainTaskAndNotifyControllerWhenFinished(
23-
model => SetModelExplicitlySelectedItemInBackground(model, selector),
23+
(model, cancellationToken) => Task.FromResult(SetModelExplicitlySelectedItemInBackground(model, selector)),
2424
updateController: false);
2525
}
2626

27-
private Model SetModelExplicitlySelectedItemInBackground(
28-
Model model,
27+
private Model? SetModelExplicitlySelectedItemInBackground(
28+
Model? model,
2929
Func<Model, SignatureHelpItem> selector)
3030
{
3131
this.Computation.ThreadingContext.ThrowIfNotOnBackgroundThread();
32-
3332
if (model == null)
34-
{
3533
return null;
36-
}
3734

3835
var selectedItem = selector(model);
3936
Contract.ThrowIfFalse(model.Items.Contains(selectedItem));

src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,85 +8,77 @@
88
using System.Collections.Immutable;
99
using System.Composition;
1010
using System.Threading;
11-
using Microsoft.CodeAnalysis.CodeActions;
11+
using System.Threading.Tasks;
1212
using Microsoft.CodeAnalysis.CodeFixes;
1313
using Microsoft.CodeAnalysis.Extensions;
1414
using Microsoft.CodeAnalysis.Host.Mef;
15-
using Microsoft.CodeAnalysis.Shared.TestHooks;
16-
using Roslyn.Utilities;
1715

18-
namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions
16+
namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions;
17+
18+
/// <summary>
19+
/// Service to compute and apply <see cref="FixMultipleCodeAction"/> code fixes.
20+
/// </summary>
21+
[ExportWorkspaceService(typeof(IFixMultipleOccurrencesService), ServiceLayer.Host), Shared]
22+
[method: ImportingConstructor]
23+
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
24+
internal sealed class FixMultipleOccurrencesService() : IFixMultipleOccurrencesService
1925
{
20-
/// <summary>
21-
/// Service to compute and apply <see cref="FixMultipleCodeAction"/> code fixes.
22-
/// </summary>
23-
[ExportWorkspaceService(typeof(IFixMultipleOccurrencesService), ServiceLayer.Host), Shared]
24-
internal sealed class FixMultipleOccurrencesService : IFixMultipleOccurrencesService
26+
public Task<Solution> GetFixAsync(
27+
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix,
28+
Workspace workspace,
29+
CodeFixProvider fixProvider,
30+
FixAllProvider fixAllProvider,
31+
string equivalenceKey,
32+
string waitDialogTitle,
33+
string waitDialogMessage,
34+
IProgress<CodeAnalysisProgress> progress,
35+
CancellationToken cancellationToken)
2536
{
26-
[ImportingConstructor]
27-
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
28-
public FixMultipleOccurrencesService(IAsynchronousOperationListenerProvider listenerProvider)
29-
{
30-
listenerProvider.GetListener(FeatureAttribute.LightBulb);
31-
}
37+
var fixMultipleState = FixAllState.Create(
38+
fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
3239

33-
public Solution GetFix(
34-
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix,
35-
Workspace workspace,
36-
CodeFixProvider fixProvider,
37-
FixAllProvider fixAllProvider,
38-
string equivalenceKey,
39-
string waitDialogTitle,
40-
string waitDialogMessage,
41-
IProgress<CodeAnalysisProgress> progress,
42-
CancellationToken cancellationToken)
43-
{
44-
var fixMultipleState = FixAllState.Create(
45-
fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
40+
return GetFixedSolutionAsync(
41+
fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, progress, cancellationToken);
42+
}
4643

47-
return GetFixedSolution(
48-
fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, progress, cancellationToken);
49-
}
44+
public Task<Solution> GetFixAsync(
45+
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix,
46+
Workspace workspace,
47+
CodeFixProvider fixProvider,
48+
FixAllProvider fixAllProvider,
49+
string equivalenceKey,
50+
string waitDialogTitle,
51+
string waitDialogMessage,
52+
IProgress<CodeAnalysisProgress> progress,
53+
CancellationToken cancellationToken)
54+
{
55+
var fixMultipleState = FixAllState.Create(
56+
fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
5057

51-
public Solution GetFix(
52-
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix,
53-
Workspace workspace,
54-
CodeFixProvider fixProvider,
55-
FixAllProvider fixAllProvider,
56-
string equivalenceKey,
57-
string waitDialogTitle,
58-
string waitDialogMessage,
59-
IProgress<CodeAnalysisProgress> progress,
60-
CancellationToken cancellationToken)
61-
{
62-
var fixMultipleState = FixAllState.Create(
63-
fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
58+
return GetFixedSolutionAsync(
59+
fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, progress, cancellationToken);
60+
}
6461

65-
return GetFixedSolution(
66-
fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, progress, cancellationToken);
67-
}
62+
private static async Task<Solution> GetFixedSolutionAsync(
63+
FixAllState fixAllState,
64+
Workspace workspace,
65+
string title,
66+
string waitDialogMessage,
67+
IProgress<CodeAnalysisProgress> progress,
68+
CancellationToken cancellationToken)
69+
{
70+
var fixMultipleCodeAction = new FixMultipleCodeAction(
71+
fixAllState, title, waitDialogMessage);
6872

69-
private static Solution GetFixedSolution(
70-
FixAllState fixAllState,
71-
Workspace workspace,
72-
string title,
73-
string waitDialogMessage,
74-
IProgress<CodeAnalysisProgress> progress,
75-
CancellationToken cancellationToken)
73+
Solution newSolution = null;
74+
var extensionManager = workspace.Services.GetService<IExtensionManager>();
75+
await extensionManager.PerformActionAsync(fixAllState.FixAllProvider, async () =>
7676
{
77-
var fixMultipleCodeAction = new FixMultipleCodeAction(
78-
fixAllState, title, waitDialogMessage);
79-
80-
Solution newSolution = null;
81-
var extensionManager = workspace.Services.GetService<IExtensionManager>();
82-
extensionManager.PerformAction(fixAllState.FixAllProvider, () =>
83-
{
84-
// We don't need to post process changes here as the inner code action created for Fix multiple code fix already executes.
85-
newSolution = fixMultipleCodeAction.GetChangedSolutionInternalAsync(
86-
fixAllState.Solution, progress, postProcessChanges: false, cancellationToken).WaitAndGetResult(cancellationToken);
87-
});
77+
// We don't need to post process changes here as the inner code action created for Fix multiple code fix already executes.
78+
newSolution = await fixMultipleCodeAction.GetChangedSolutionInternalAsync(
79+
fixAllState.Solution, progress, postProcessChanges: false, cancellationToken).ConfigureAwait(false);
80+
}).ConfigureAwait(false);
8881

89-
return newSolution;
90-
}
82+
return newSolution;
9183
}
9284
}

src/EditorFeatures/Core/ChangeSignature/AbstractChangeSignatureCommandHandler.cs

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,26 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System.Diagnostics.CodeAnalysis;
6+
using System.Threading.Tasks;
67
using Microsoft.CodeAnalysis.Editor.Host;
78
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
89
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
910
using Microsoft.CodeAnalysis.Editor.Undo;
1011
using Microsoft.CodeAnalysis.Notification;
11-
using Microsoft.CodeAnalysis.Options;
1212
using Microsoft.CodeAnalysis.Shared.Extensions;
1313
using Microsoft.VisualStudio.Commanding;
1414
using Microsoft.VisualStudio.Text;
1515
using Microsoft.VisualStudio.Text.Editor;
1616
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
1717
using Microsoft.VisualStudio.Utilities;
18-
using Roslyn.Utilities;
1918

2019
namespace Microsoft.CodeAnalysis.ChangeSignature;
2120

22-
internal abstract class AbstractChangeSignatureCommandHandler : ICommandHandler<ReorderParametersCommandArgs>,
23-
ICommandHandler<RemoveParametersCommandArgs>
21+
internal abstract class AbstractChangeSignatureCommandHandler(IThreadingContext threadingContext)
22+
: ICommandHandler<ReorderParametersCommandArgs>,
23+
ICommandHandler<RemoveParametersCommandArgs>
2424
{
25-
private readonly IThreadingContext _threadingContext;
26-
27-
protected AbstractChangeSignatureCommandHandler(IThreadingContext threadingContext)
28-
{
29-
_threadingContext = threadingContext;
30-
}
25+
private readonly IThreadingContext _threadingContext = threadingContext;
3126

3227
public string DisplayName => EditorFeaturesResources.Change_Signature;
3328

@@ -55,49 +50,48 @@ private bool ExecuteCommand(ITextView textView, ITextBuffer subjectBuffer, Comma
5550
{
5651
using (context.OperationContext.AddScope(allowCancellation: true, FeaturesResources.Change_signature))
5752
{
58-
if (!IsAvailable(subjectBuffer, out var workspace))
59-
{
60-
return false;
61-
}
53+
return _threadingContext.JoinableTaskFactory.Run(() => ExecuteCommandAsync(textView, subjectBuffer, context));
54+
}
55+
}
6256

63-
var caretPoint = textView.GetCaretPoint(subjectBuffer);
64-
if (!caretPoint.HasValue)
65-
{
66-
return false;
67-
}
57+
private static async Task<bool> ExecuteCommandAsync(ITextView textView, ITextBuffer subjectBuffer, CommandExecutionContext context)
58+
{
59+
if (!IsAvailable(subjectBuffer, out var workspace))
60+
return false;
6861

69-
var document = subjectBuffer.CurrentSnapshot.GetFullyLoadedOpenDocumentInCurrentContextWithChanges(
70-
context.OperationContext, _threadingContext);
71-
if (document == null)
72-
{
73-
return false;
74-
}
62+
var caretPoint = textView.GetCaretPoint(subjectBuffer);
63+
if (!caretPoint.HasValue)
64+
return false;
7565

76-
var changeSignatureService = document.GetRequiredLanguageService<AbstractChangeSignatureService>();
66+
var document = await subjectBuffer.CurrentSnapshot.GetFullyLoadedOpenDocumentInCurrentContextWithChangesAsync(context.OperationContext).ConfigureAwait(true);
67+
if (document == null)
68+
return false;
7769

78-
var cancellationToken = context.OperationContext.UserCancellationToken;
70+
var changeSignatureService = document.GetRequiredLanguageService<AbstractChangeSignatureService>();
7971

80-
// TODO: Make asynchronous and avoid expensive semantic operations on UI thread:
81-
// https://github.com/dotnet/roslyn/issues/62135
72+
var cancellationToken = context.OperationContext.UserCancellationToken;
8273

83-
// Async operation to determine the change signature
84-
var changeSignatureContext = changeSignatureService.GetChangeSignatureContextAsync(
85-
document,
86-
caretPoint.Value.Position,
87-
restrictToDeclarations: false,
88-
cancellationToken).WaitAndGetResult(context.OperationContext.UserCancellationToken);
74+
// TODO: Make asynchronous and avoid expensive semantic operations on UI thread:
75+
// https://github.com/dotnet/roslyn/issues/62135
8976

90-
// UI thread bound operation to show the change signature dialog.
91-
var changeSignatureOptions = AbstractChangeSignatureService.GetChangeSignatureOptions(changeSignatureContext);
77+
// Async operation to determine the change signature
78+
var changeSignatureContext = await changeSignatureService.GetChangeSignatureContextAsync(
79+
document,
80+
caretPoint.Value.Position,
81+
restrictToDeclarations: false,
82+
cancellationToken).ConfigureAwait(true);
9283

93-
// Async operation to compute the new solution created from the specified options.
94-
var result = changeSignatureService.ChangeSignatureWithContextAsync(changeSignatureContext, changeSignatureOptions, cancellationToken).WaitAndGetResult(cancellationToken);
84+
// UI thread bound operation to show the change signature dialog.
85+
var changeSignatureOptions = AbstractChangeSignatureService.GetChangeSignatureOptions(changeSignatureContext);
9586

96-
// UI thread bound operation to show preview changes dialog / show error message, then apply the solution changes (if applicable).
97-
HandleResult(result, document.Project.Solution, workspace, context);
87+
// Async operation to compute the new solution created from the specified options.
88+
var result = await changeSignatureService.ChangeSignatureWithContextAsync(
89+
changeSignatureContext, changeSignatureOptions, cancellationToken).ConfigureAwait(true);
9890

99-
return true;
100-
}
91+
// UI thread bound operation to show preview changes dialog / show error message, then apply the solution changes (if applicable).
92+
HandleResult(result, document.Project.Solution, workspace, context);
93+
94+
return true;
10195
}
10296

10397
private static void HandleResult(ChangeSignatureResult result, Solution oldSolution, Workspace workspace, CommandExecutionContext context)

0 commit comments

Comments
 (0)