Skip to content

Commit

Permalink
Remove usage of WaitAndGetResult (#76474)
Browse files Browse the repository at this point in the history
  • Loading branch information
CyrusNajmabadi authored Dec 17, 2024
2 parents f9ccce0 + ccaf149 commit 6f8ea71
Show file tree
Hide file tree
Showing 39 changed files with 517 additions and 471 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.InteractiveWindow;
using Microsoft.VisualStudio.InteractiveWindow.Commands;
Expand Down Expand Up @@ -70,7 +69,6 @@ internal CSharpInteractiveEvaluator(
IInteractiveWindowCommandsFactory commandsFactory,
ImmutableArray<IInteractiveWindowCommand> commands,
ITextDocumentFactoryService textDocumentFactoryService,
EditorOptionsService editorOptionsService,
InteractiveEvaluatorLanguageInfoProvider languageInfo,
string initialWorkingDirectory)
{
Expand All @@ -87,10 +85,8 @@ internal CSharpInteractiveEvaluator(

_session = new InteractiveSession(
_workspace,
threadingContext,
listener,
textDocumentFactoryService,
editorOptionsService,
languageInfo,
initialWorkingDirectory);

Expand Down
81 changes: 40 additions & 41 deletions src/EditorFeatures/Core/Formatting/FormatCommandHandler.Paste.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Formatting.Rules;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Commanding;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Formatting;

Expand All @@ -29,59 +28,59 @@ public void ExecuteCommand(PasteCommandArgs args, Action nextHandler, CommandExe

var cancellationToken = context.OperationContext.UserCancellationToken;
if (cancellationToken.IsCancellationRequested)
{
return;
}

try
{
ExecuteCommandWorker(args, caretPosition, cancellationToken);
_threadingContext.JoinableTaskFactory.Run(() => ExecuteCommandWorkerAsync());
}
catch (OperationCanceledException)
{
// According to Editor command handler API guidelines, it's best if we return early if cancellation
// is requested instead of throwing. Otherwise, we could end up in an invalid state due to already
// calling nextHandler().
}
}

private void ExecuteCommandWorker(PasteCommandArgs args, SnapshotPoint? caretPosition, CancellationToken cancellationToken)
{
if (!caretPosition.HasValue)
return;
return;

var subjectBuffer = args.SubjectBuffer;
if (!subjectBuffer.TryGetWorkspace(out var workspace) ||
!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
async Task ExecuteCommandWorkerAsync()
{
return;
if (!caretPosition.HasValue)
return;

var subjectBuffer = args.SubjectBuffer;
if (!subjectBuffer.TryGetWorkspace(out var workspace) ||
!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return;
}

var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
return;

if (!_globalOptions.GetOption(FormattingOptionsStorage.FormatOnPaste, document.Project.Language))
return;

var solution = document.Project.Solution;
var services = solution.Services;
var formattingRuleService = services.GetService<IHostDependentFormattingRuleFactoryService>();
if (formattingRuleService != null && formattingRuleService.ShouldNotFormatOrCommitOnPaste(document.Id))
return;

var formattingService = document.GetLanguageService<IFormattingInteractionService>();
if (formattingService == null || !formattingService.SupportsFormatOnPaste)
return;

var trackingSpan = caretPosition.Value.Snapshot.CreateTrackingSpan(caretPosition.Value.Position, 0, SpanTrackingMode.EdgeInclusive);
var span = trackingSpan.GetSpan(subjectBuffer.CurrentSnapshot).Span.ToTextSpan();

// Note: C# always completes synchronously, TypeScript is async
var changes = await formattingService.GetFormattingChangesOnPasteAsync(document, subjectBuffer, span, cancellationToken).ConfigureAwait(true);
if (changes.IsEmpty)
return;

subjectBuffer.ApplyChanges(changes);
}

var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
return;

if (!_globalOptions.GetOption(FormattingOptionsStorage.FormatOnPaste, document.Project.Language))
return;

var solution = document.Project.Solution;
var services = solution.Services;
var formattingRuleService = services.GetService<IHostDependentFormattingRuleFactoryService>();
if (formattingRuleService != null && formattingRuleService.ShouldNotFormatOrCommitOnPaste(document.Id))
return;

var formattingService = document.GetLanguageService<IFormattingInteractionService>();
if (formattingService == null || !formattingService.SupportsFormatOnPaste)
return;

var trackingSpan = caretPosition.Value.Snapshot.CreateTrackingSpan(caretPosition.Value.Position, 0, SpanTrackingMode.EdgeInclusive);
var span = trackingSpan.GetSpan(subjectBuffer.CurrentSnapshot).Span.ToTextSpan();

// Note: C# always completes synchronously, TypeScript is async
var changes = formattingService.GetFormattingChangesOnPasteAsync(document, subjectBuffer, span, cancellationToken).WaitAndGetResult(cancellationToken);
if (changes.IsEmpty)
return;

subjectBuffer.ApplyChanges(changes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ internal void DisconnectAndRollbackEdits(bool documentIsClosed)
}
}

internal void ApplyConflictResolutionEdits(IInlineRenameReplacementInfo conflictResolution, LinkedFileMergeSessionResult mergeResult, IEnumerable<Document> documents, CancellationToken cancellationToken)
internal async Task ApplyConflictResolutionEditsAsync(IInlineRenameReplacementInfo conflictResolution, LinkedFileMergeSessionResult mergeResult, IEnumerable<Document> documents, CancellationToken cancellationToken)
{
_session._threadingContext.ThrowIfNotOnUIThread();

Expand All @@ -330,7 +330,8 @@ internal void ApplyConflictResolutionEdits(IInlineRenameReplacementInfo conflict
var newDocument = mergeResult.MergedSolution.GetDocument(documents.First().Id);
var originalDocument = _baseDocuments.Single(d => d.Id == newDocument.Id);

var changes = GetTextChangesFromTextDifferencingServiceAsync(originalDocument, newDocument, cancellationToken).WaitAndGetResult(cancellationToken);
var changes = await GetTextChangesFromTextDifferencingServiceAsync(
originalDocument, newDocument, cancellationToken).ConfigureAwait(true);

// TODO: why does the following line stop responding when uncommented?
// newDocument.GetTextChangesAsync(this.baseDocuments.Single(d => d.Id == newDocument.Id), cancellationToken).WaitAndGetResult(cancellationToken).Reverse();
Expand Down Expand Up @@ -436,18 +437,19 @@ internal void ApplyConflictResolutionEdits(IInlineRenameReplacementInfo conflict

foreach (var document in documents)
{
var relevantReplacements = conflictResolution.GetReplacements(document.Id).Where(r => GetRenameSpanKind(r.Kind) != RenameSpanKind.None);
var relevantReplacements = conflictResolution
.GetReplacements(document.Id)
.Where(r => GetRenameSpanKind(r.Kind) != RenameSpanKind.None)
.ToImmutableArray();
if (!relevantReplacements.Any())
{
continue;
}

var mergedReplacements = linkedDocumentsMightConflict
? GetMergedReplacementInfos(
? await GetMergedReplacementInfosAsync(
relevantReplacements,
conflictResolution.NewSolution.GetDocument(document.Id),
mergeResult.MergedSolution.GetDocument(document.Id),
cancellationToken)
cancellationToken).ConfigureAwait(true)
: relevantReplacements;

// Show merge conflicts comments as unresolvable conflicts, and do not
Expand Down Expand Up @@ -578,8 +580,8 @@ private static async Task<IEnumerable<TextChange>> GetTextChangesFromTextDiffere
}
}

private IEnumerable<InlineRenameReplacement> GetMergedReplacementInfos(
IEnumerable<InlineRenameReplacement> relevantReplacements,
private async Task<ImmutableArray<InlineRenameReplacement>> GetMergedReplacementInfosAsync(
ImmutableArray<InlineRenameReplacement> relevantReplacements,
Document preMergeDocument,
Document postMergeDocument,
CancellationToken cancellationToken)
Expand All @@ -606,23 +608,27 @@ private IEnumerable<InlineRenameReplacement> GetMergedReplacementInfos(
preMergeDocumentTextString = preMergeDocument.GetTextSynchronously(cancellationToken).ToString();
}

var result = new FixedSizeArrayBuilder<InlineRenameReplacement>(relevantReplacements.Length);
foreach (var replacement in relevantReplacements)
{
var buffer = snapshotSpanToClone.HasValue ? _textBufferCloneService.CloneWithUnknownContentType(snapshotSpanToClone.Value) : _textBufferFactoryService.CreateTextBuffer(preMergeDocumentTextString, contentType);
var trackingSpan = buffer.CurrentSnapshot.CreateTrackingSpan(replacement.NewSpan.ToSpan(), SpanTrackingMode.EdgeExclusive, TrackingFidelityMode.Forward);

using (var edit = _subjectBuffer.CreateEdit(EditOptions.None, null, s_calculateMergedSpansEditTag))
{
foreach (var change in textDiffService.GetTextChangesAsync(preMergeDocument, postMergeDocument, cancellationToken).WaitAndGetResult(cancellationToken))
{
var textChanges = await textDiffService.GetTextChangesAsync(
preMergeDocument, postMergeDocument, cancellationToken).ConfigureAwait(true);
foreach (var change in textChanges)
buffer.Replace(change.Span.ToSpan(), change.NewText);
}

edit.ApplyAndLogExceptions();
}

yield return new InlineRenameReplacement(replacement.Kind, replacement.OriginalSpan, trackingSpan.GetSpan(buffer.CurrentSnapshot).Span.ToTextSpan());
result.Add(new InlineRenameReplacement(
replacement.Kind, replacement.OriginalSpan, trackingSpan.GetSpan(buffer.CurrentSnapshot).Span.ToTextSpan()));
}

return result.MoveToImmutable();
}

private static RenameSpanKind GetRenameSpanKind(InlineRenameReplacementKind kind)
Expand Down
15 changes: 8 additions & 7 deletions src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -574,9 +574,9 @@ private void QueueApplyReplacements()

// Switch to a background thread for expensive work
await TaskScheduler.Default;
var computedMergeResult = await ComputeMergeResultAsync(replacementInfo, cancellationToken);
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: true, cancellationToken);
ApplyReplacements(computedMergeResult.replacementInfo, computedMergeResult.mergeResult, cancellationToken);
var computedMergeResult = await ComputeMergeResultAsync(replacementInfo, cancellationToken).ConfigureAwait(false);
await ApplyReplacementsAsync(
computedMergeResult.replacementInfo, computedMergeResult.mergeResult, cancellationToken).ConfigureAwait(true);
});
replacementOperation.Task.CompletesAsyncOperation(asyncToken);
}
Expand All @@ -588,10 +588,10 @@ private void QueueApplyReplacements()
return (replacementInfo, mergeResult);
}

private void ApplyReplacements(IInlineRenameReplacementInfo replacementInfo, LinkedFileMergeSessionResult mergeResult, CancellationToken cancellationToken)
private async Task ApplyReplacementsAsync(
IInlineRenameReplacementInfo replacementInfo, LinkedFileMergeSessionResult mergeResult, CancellationToken cancellationToken)
{
_threadingContext.ThrowIfNotOnUIThread();
cancellationToken.ThrowIfCancellationRequested();
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

RaiseReplacementsComputed(replacementInfo);

Expand All @@ -602,7 +602,8 @@ private void ApplyReplacements(IInlineRenameReplacementInfo replacementInfo, Lin
if (documents.Any())
{
var textBufferManager = _openTextBuffers[textBuffer];
textBufferManager.ApplyConflictResolutionEdits(replacementInfo, mergeResult, documents, cancellationToken);
await textBufferManager.ApplyConflictResolutionEditsAsync(
replacementInfo, mergeResult, documents, cancellationToken).ConfigureAwait(true);
}
}

Expand Down
Loading

0 comments on commit 6f8ea71

Please sign in to comment.