Skip to content

Commit 549eca4

Browse files
Merge branch 'main' into sigHelpCompletion
2 parents 9c434a3 + 4234893 commit 549eca4

File tree

4 files changed

+64
-34
lines changed

4 files changed

+64
-34
lines changed

src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructCommandHandler.vb

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,33 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
3232
Implements IChainedCommandHandler(Of TypeCharCommandArgs)
3333
Implements IChainedCommandHandler(Of AutomaticLineEnderCommandArgs)
3434

35+
Private ReadOnly _threadingContext As IThreadingContext
3536
Private ReadOnly _editorOperationsFactoryService As IEditorOperationsFactoryService
3637
Private ReadOnly _undoHistoryRegistry As ITextUndoHistoryRegistry
3738
Private ReadOnly _editorOptionsService As EditorOptionsService
3839

3940
<ImportingConstructor()>
4041
<SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification:="Used in test code: https://github.com/dotnet/roslyn/issues/42814")>
41-
Public Sub New(editorOperationsFactoryService As IEditorOperationsFactoryService,
42-
undoHistoryRegistry As ITextUndoHistoryRegistry,
43-
editorOptionsService As EditorOptionsService)
44-
42+
Public Sub New(
43+
threadingContext As IThreadingContext,
44+
editorOperationsFactoryService As IEditorOperationsFactoryService,
45+
undoHistoryRegistry As ITextUndoHistoryRegistry,
46+
editorOptionsService As EditorOptionsService)
47+
_threadingContext = threadingContext
4548
_editorOperationsFactoryService = editorOperationsFactoryService
4649
_undoHistoryRegistry = undoHistoryRegistry
4750
_editorOptionsService = editorOptionsService
4851
End Sub
4952

50-
Public ReadOnly Property DisplayName As String Implements INamed.DisplayName
51-
Get
52-
Return VBEditorResources.End_Construct
53-
End Get
54-
End Property
53+
Public ReadOnly Property DisplayName As String = VBEditorResources.End_Construct Implements INamed.DisplayName
5554

5655
Public Function GetCommandState_ReturnKeyCommandHandler(args As ReturnKeyCommandArgs, nextHandler As Func(Of CommandState)) As CommandState Implements IChainedCommandHandler(Of ReturnKeyCommandArgs).GetCommandState
5756
Return nextHandler()
5857
End Function
5958

6059
Public Sub ExecuteCommand_ReturnKeyCommandHandler(args As ReturnKeyCommandArgs, nextHandler As Action, context As CommandExecutionContext) Implements IChainedCommandHandler(Of ReturnKeyCommandArgs).ExecuteCommand
61-
ExecuteEndConstructOnReturn(args.TextView, args.SubjectBuffer, nextHandler)
60+
_threadingContext.JoinableTaskFactory.Run(Function() ExecuteEndConstructOnReturnAsync(
61+
args.TextView, args.SubjectBuffer, nextHandler, context.OperationContext.UserCancellationToken))
6262
End Sub
6363

6464
Public Function GetCommandState_TypeCharCommandHandler(args As TypeCharCommandArgs, nextHandler As Func(Of CommandState)) As CommandState Implements IChainedCommandHandler(Of TypeCharCommandArgs).GetCommandState
@@ -80,25 +80,33 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
8080

8181
' End construct is not cancellable.
8282
Dim endConstructService = document.GetLanguageService(Of IEndConstructGenerationService)()
83-
endConstructService.TryDo(args.TextView, args.SubjectBuffer, args.TypedChar, CancellationToken.None)
83+
endConstructService.TryDo(args.TextView, args.SubjectBuffer, args.TypedChar, context.OperationContext.UserCancellationToken)
8484
End Sub
8585

8686
Public Function GetCommandState_AutomaticLineEnderCommandHandler(args As AutomaticLineEnderCommandArgs, nextHandler As Func(Of CommandState)) As CommandState Implements IChainedCommandHandler(Of AutomaticLineEnderCommandArgs).GetCommandState
8787
Return CommandState.Available
8888
End Function
8989

9090
Public Sub ExecuteCommand_AutomaticLineEnderCommandHandler(args As AutomaticLineEnderCommandArgs, nextHandler As Action, context As CommandExecutionContext) Implements IChainedCommandHandler(Of AutomaticLineEnderCommandArgs).ExecuteCommand
91-
ExecuteEndConstructOnReturn(args.TextView, args.SubjectBuffer, Sub()
92-
Dim operations = Me._editorOperationsFactoryService.GetEditorOperations(args.TextView)
93-
If operations Is Nothing Then
94-
nextHandler()
95-
Else
96-
operations.InsertNewLine()
97-
End If
98-
End Sub)
91+
_threadingContext.JoinableTaskFactory.Run(Function() ExecuteEndConstructOnReturnAsync(
92+
args.TextView,
93+
args.SubjectBuffer,
94+
Sub()
95+
Dim operations = Me._editorOperationsFactoryService.GetEditorOperations(args.TextView)
96+
If operations Is Nothing Then
97+
nextHandler()
98+
Else
99+
operations.InsertNewLine()
100+
End If
101+
End Sub,
102+
context.OperationContext.UserCancellationToken))
99103
End Sub
100104

101-
Private Sub ExecuteEndConstructOnReturn(textView As ITextView, subjectBuffer As ITextBuffer, nextHandler As Action)
105+
Private Async Function ExecuteEndConstructOnReturnAsync(
106+
textView As ITextView,
107+
subjectBuffer As ITextBuffer,
108+
nextHandler As Action,
109+
cancellationToken As CancellationToken) As Task
102110
If Not _editorOptionsService.GlobalOptions.GetOption(EndConstructGenerationOptionsStorage.EndConstruct, LanguageNames.VisualBasic) OrElse
103111
Not subjectBuffer.CanApplyChangeDocumentToWorkspace() Then
104112
nextHandler()
@@ -111,18 +119,23 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
111119
Return
112120
End If
113121

114-
CleanupBeforeEndConstruct(textView, subjectBuffer, document, CancellationToken.None)
122+
Await CleanupBeforeEndConstructAsync(
123+
textView, subjectBuffer, document, cancellationToken).ConfigureAwait(True)
115124

116125
Dim endConstructService = document.GetLanguageService(Of IEndConstructGenerationService)()
117-
Dim result = endConstructService.TryDo(textView, subjectBuffer, vbLf(0), CancellationToken.None)
126+
Dim result = endConstructService.TryDo(textView, subjectBuffer, vbLf(0), cancellationToken)
118127

119128
If Not result Then
120129
nextHandler()
121130
Return
122131
End If
123-
End Sub
132+
End Function
124133

125-
Private Sub CleanupBeforeEndConstruct(view As ITextView, buffer As ITextBuffer, document As Document, cancellationToken As CancellationToken)
134+
Private Async Function CleanupBeforeEndConstructAsync(
135+
view As ITextView,
136+
buffer As ITextBuffer,
137+
document As Document,
138+
cancellationToken As CancellationToken) As Task
126139
Dim position = view.GetCaretPoint(buffer)
127140
If Not position.HasValue Then
128141
Return
@@ -141,15 +154,16 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
141154
End Function)
142155

143156
Dim options = buffer.GetCodeCleanupOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat:=False, allowImportsInHiddenRegions:=document.AllowImportsInHiddenRegions())
144-
Dim cleanDocument = CodeCleaner.CleanupAsync(document, GetSpanToCleanup(statement), options, codeCleanups, cancellationToken:=cancellationToken).WaitAndGetResult(cancellationToken)
157+
Dim cleanDocument = Await CodeCleaner.CleanupAsync(
158+
document, GetSpanToCleanup(statement), options, codeCleanups, cancellationToken).ConfigureAwait(True)
145159
Dim changes = cleanDocument.GetTextChangesSynchronously(document, cancellationToken)
146160

147161
Using transaction = New CaretPreservingEditTransaction(VBEditorResources.End_Construct, view, _undoHistoryRegistry, _editorOperationsFactoryService)
148162
transaction.MergePolicy = AutomaticCodeChangeMergePolicy.Instance
149163
buffer.ApplyChanges(changes)
150164
transaction.Complete()
151165
End Using
152-
End Sub
166+
End Function
153167

154168
Private Shared Function GetSpanToCleanup(statement As StatementSyntax) As TextSpan
155169
Dim firstToken = statement.GetFirstToken()

src/EditorFeatures/VisualBasicTest/AutomaticCompletion/AutomaticLineEnderTests.vb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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+
Imports Microsoft.CodeAnalysis.Editor.[Shared].Utilities
56
Imports Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion
67
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions
78
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Utilities
@@ -271,6 +272,7 @@ End Module
271272

272273
Protected Overrides Function CreateNextHandler(workspace As EditorTestWorkspace) As Action
273274
Dim endConstructor = New EndConstructCommandHandler(
275+
workspace.GetService(Of IThreadingContext),
274276
workspace.GetService(Of IEditorOperationsFactoryService),
275277
workspace.GetService(Of ITextUndoHistoryRegistry),
276278
workspace.GetService(Of EditorOptionsService))

src/EditorFeatures/VisualBasicTest/EndConstructGeneration/EndConstructTestingHelpers.vb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
Imports System.Threading
66
Imports Microsoft.CodeAnalysis
7+
Imports Microsoft.CodeAnalysis.Editor.[Shared].Utilities
78
Imports Microsoft.CodeAnalysis.Editor.UnitTests
89
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Utilities
910
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
@@ -223,6 +224,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.EndConstructGenera
223224

224225
Dim factory = workspace.GetService(Of IEditorOperationsFactoryService)()
225226
Dim endConstructor = New EndConstructCommandHandler(
227+
workspace.GetService(Of IThreadingContext),
226228
factory,
227229
workspace.GetService(Of ITextUndoHistoryRegistry),
228230
workspace.GetService(Of EditorOptionsService))

src/Workspaces/Core/Portable/Workspace/Solution/Document.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -416,16 +416,28 @@ public Document WithFilePath(string? filePath)
416416
=> this.Project.Solution.WithDocumentFilePath(this.Id, filePath).GetRequiredDocument(Id);
417417

418418
/// <summary>
419-
/// Get the text changes between this document and a prior version of the same document.
420-
/// The changes, when applied to the text of the old document, will produce the text of the current document.
419+
/// Get the text changes between this document and a prior version of the same document. The changes, when applied
420+
/// to the text of the old document, will produce the text of the current document.
421421
/// </summary>
422-
public Task<IEnumerable<TextChange>> GetTextChangesAsync(Document oldDocument, CancellationToken cancellationToken = default)
422+
public async Task<IEnumerable<TextChange>> GetTextChangesAsync(Document oldDocument, CancellationToken cancellationToken = default)
423423
{
424-
return Task.FromResult<IEnumerable<TextChange>>(GetTextChangesSynchronously(oldDocument, cancellationToken));
424+
return await GetTextChangesAsync(useAsync: true, oldDocument, cancellationToken).ConfigureAwait(false);
425425
}
426426

427+
/// <summary>
428+
/// Similar to <see cref="GetTextChangesAsync(Document, CancellationToken)"/>, but should be used when in a forced
429+
/// synchronous context.
430+
/// </summary>
427431
internal ImmutableArray<TextChange> GetTextChangesSynchronously(
428432
Document oldDocument, CancellationToken cancellationToken)
433+
{
434+
// Should always complete synchronously since we passed in 'useAsync: false'
435+
var result = GetTextChangesAsync(useAsync: false, oldDocument, cancellationToken);
436+
return result.VerifyCompleted();
437+
}
438+
439+
private async Task<ImmutableArray<TextChange>> GetTextChangesAsync(
440+
bool useAsync, Document oldDocument, CancellationToken cancellationToken)
429441
{
430442
try
431443
{
@@ -462,16 +474,16 @@ internal ImmutableArray<TextChange> GetTextChangesSynchronously(
462474
// get changes by diffing the trees
463475
if (this.SupportsSyntaxTree)
464476
{
465-
var tree = this.GetSyntaxTreeSynchronously(cancellationToken);
466-
var oldTree = oldDocument.GetSyntaxTreeSynchronously(cancellationToken);
477+
var tree = useAsync ? await GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false) : this.GetSyntaxTreeSynchronously(cancellationToken);
478+
var oldTree = useAsync ? await oldDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false) : oldDocument.GetSyntaxTreeSynchronously(cancellationToken);
467479

468480
RoslynDebug.Assert(tree is object);
469481
RoslynDebug.Assert(oldTree is object);
470482
return tree.GetChanges(oldTree).ToImmutableArray();
471483
}
472484

473-
text = this.GetTextSynchronously(cancellationToken);
474-
oldText = oldDocument.GetTextSynchronously(cancellationToken);
485+
text = useAsync ? await this.GetTextAsync(cancellationToken).ConfigureAwait(false) : this.GetTextSynchronously(cancellationToken);
486+
oldText = useAsync ? await oldDocument.GetTextAsync(cancellationToken).ConfigureAwait(false) : oldDocument.GetTextSynchronously(cancellationToken);
475487

476488
return text.GetTextChanges(oldText).ToImmutableArray();
477489
}

0 commit comments

Comments
 (0)