Skip to content

Commit 586b8fa

Browse files
Switch all of 'end construct' over to jtf. (#76504)
2 parents c49efbd + cd7efc7 commit 586b8fa

34 files changed

+841
-842
lines changed

src/EditorFeatures/CSharp/EndConstruct/CSharpEndConstructGenerationService.cs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,21 @@
66
using System.Composition;
77
using System.Diagnostics.CodeAnalysis;
88
using System.Threading;
9+
using System.Threading.Tasks;
910
using Microsoft.CodeAnalysis.Editor.Implementation.EndConstructGeneration;
1011
using Microsoft.CodeAnalysis.Host.Mef;
1112
using Microsoft.VisualStudio.Text;
1213
using Microsoft.VisualStudio.Text.Editor;
14+
using Roslyn.Utilities;
1315

1416
namespace Microsoft.CodeAnalysis.Editor.CSharp.EndConstructGeneration;
1517

1618
[ExportLanguageService(typeof(IEndConstructGenerationService), LanguageNames.CSharp), Shared]
1719
[ExcludeFromCodeCoverage]
18-
internal class CSharpEndConstructGenerationService : IEndConstructGenerationService
20+
[method: ImportingConstructor]
21+
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
22+
internal sealed class CSharpEndConstructGenerationService() : IEndConstructGenerationService
1923
{
20-
[ImportingConstructor]
21-
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
22-
public CSharpEndConstructGenerationService()
23-
{
24-
}
25-
26-
public bool TryDo(
27-
ITextView textView,
28-
ITextBuffer subjectBuffer,
29-
char typedChar,
30-
CancellationToken cancellationToken)
31-
{
32-
return false;
33-
}
24+
public Task<bool> TryDoAsync(ITextView textView, ITextBuffer subjectBuffer, char typedChar, CancellationToken cancellationToken)
25+
=> SpecializedTasks.False;
3426
}

src/EditorFeatures/Core/EndConstructGeneration/IEndConstructGenerationService.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
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.Threading;
6+
using System.Threading.Tasks;
87
using Microsoft.CodeAnalysis.Host;
98
using Microsoft.VisualStudio.Text;
109
using Microsoft.VisualStudio.Text.Editor;
@@ -13,5 +12,5 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.EndConstructGeneration;
1312

1413
internal interface IEndConstructGenerationService : ILanguageService
1514
{
16-
bool TryDo(ITextView textView, ITextBuffer subjectBuffer, char typedChar, CancellationToken cancellationToken);
15+
Task<bool> TryDoAsync(ITextView textView, ITextBuffer subjectBuffer, char typedChar, CancellationToken cancellationToken);
1716
}

src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructCommandHandler.vb

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,25 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
6666
End Function
6767

6868
Public Sub ExecuteCommand_TypeCharCommandHandler(args As TypeCharCommandArgs, nextHandler As Action, context As CommandExecutionContext) Implements IChainedCommandHandler(Of TypeCharCommandArgs).ExecuteCommand
69-
nextHandler()
69+
_threadingContext.JoinableTaskFactory.Run(
70+
Async Function()
71+
nextHandler()
7072

71-
If Not _editorOptionsService.GlobalOptions.GetOption(EndConstructGenerationOptionsStorage.EndConstruct, LanguageNames.VisualBasic) Then
72-
Return
73-
End If
73+
If Not _editorOptionsService.GlobalOptions.GetOption(EndConstructGenerationOptionsStorage.EndConstruct, LanguageNames.VisualBasic) Then
74+
Return
75+
End If
7476

75-
Dim textSnapshot = args.SubjectBuffer.CurrentSnapshot
76-
Dim document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges()
77-
If document Is Nothing Then
78-
Return
79-
End If
77+
Dim textSnapshot = args.SubjectBuffer.CurrentSnapshot
78+
Dim document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges()
79+
If document Is Nothing Then
80+
Return
81+
End If
8082

81-
' End construct is not cancellable.
82-
Dim endConstructService = document.GetLanguageService(Of IEndConstructGenerationService)()
83-
endConstructService.TryDo(args.TextView, args.SubjectBuffer, args.TypedChar, context.OperationContext.UserCancellationToken)
83+
' End construct is not cancellable.
84+
Dim endConstructService = document.GetLanguageService(Of IEndConstructGenerationService)()
85+
Await endConstructService.TryDoAsync(
86+
args.TextView, args.SubjectBuffer, args.TypedChar, context.OperationContext.UserCancellationToken).ConfigureAwait(True)
87+
End Function)
8488
End Sub
8589

8690
Public Function GetCommandState_AutomaticLineEnderCommandHandler(args As AutomaticLineEnderCommandArgs, nextHandler As Func(Of CommandState)) As CommandState Implements IChainedCommandHandler(Of AutomaticLineEnderCommandArgs).GetCommandState
@@ -123,7 +127,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
123127
textView, subjectBuffer, document, cancellationToken).ConfigureAwait(True)
124128

125129
Dim endConstructService = document.GetLanguageService(Of IEndConstructGenerationService)()
126-
Dim result = endConstructService.TryDo(textView, subjectBuffer, vbLf(0), cancellationToken)
130+
Dim result = Await endConstructService.TryDoAsync(
131+
textView, subjectBuffer, vbLf(0), cancellationToken).ConfigureAwait(True)
127132

128133
If Not result Then
129134
nextHandler()

src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructState.vb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
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 System.Threading
6+
57
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
6-
Friend Class EndConstructState
8+
Friend NotInheritable Class EndConstructState
79
Private ReadOnly _caretPosition As Integer
8-
Private ReadOnly _semanticModel As Lazy(Of SemanticModel)
10+
Private ReadOnly _semanticModel As AsyncLazy(Of SemanticModel)
911
Private ReadOnly _tree As SyntaxTree
1012
Private ReadOnly _tokenToLeft As SyntaxToken
1113
Private ReadOnly _newLineCharacter As String
1214

13-
Public Sub New(caretPosition As Integer, semanticModel As Lazy(Of SemanticModel), syntaxTree As SyntaxTree, tokenToLeft As SyntaxToken, newLineCharacter As String)
15+
Public Sub New(caretPosition As Integer, semanticModel As AsyncLazy(Of SemanticModel), syntaxTree As SyntaxTree, tokenToLeft As SyntaxToken, newLineCharacter As String)
1416
ThrowIfNull(syntaxTree)
1517

1618
_caretPosition = caretPosition
@@ -26,11 +28,9 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
2628
End Get
2729
End Property
2830

29-
Public ReadOnly Property SemanticModel As SemanticModel
30-
Get
31-
Return _semanticModel.Value
32-
End Get
33-
End Property
31+
Public Function GetSemanticModelAsync(cancellationToken As CancellationToken) As Task(Of SemanticModel)
32+
Return _semanticModel.GetValueAsync(cancellationToken)
33+
End Function
3434

3535
Public ReadOnly Property SyntaxTree As SyntaxTree
3636
Get

src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructStatementVisitor.vb

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,51 @@ Imports Microsoft.VisualStudio.Text.Editor
1212
Imports Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods
1313

1414
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
15-
Partial Friend Class EndConstructStatementVisitor
15+
Partial Friend NotInheritable Class EndConstructStatementVisitor
1616
Inherits VisualBasicSyntaxVisitor(Of AbstractEndConstructResult)
1717

1818
Private ReadOnly _textView As ITextView
1919
Private ReadOnly _subjectBuffer As ITextBuffer
20-
Private ReadOnly _cancellationToken As CancellationToken
2120
Private ReadOnly _state As EndConstructState
21+
Private ReadOnly _cancellationToken As CancellationToken
22+
23+
''' <summary>
24+
''' Note: this is only passed in when <see cref="NeedsSemanticModel"/> return true. Any functions that require
25+
''' a semantic model must declare their need up front so we do not pay the cost for semantics for all the cases
26+
''' that do not need it.
27+
''' </summary>
28+
Private ReadOnly _semanticModel As SemanticModel
2229

23-
Public Sub New(textView As ITextView,
24-
subjectBuffer As ITextBuffer,
25-
state As EndConstructState,
26-
cancellationToken As CancellationToken)
30+
Public Sub New(
31+
textView As ITextView,
32+
subjectBuffer As ITextBuffer,
33+
state As EndConstructState,
34+
semanticModel As SemanticModel,
35+
cancellationToken As CancellationToken)
2736

2837
_textView = textView
2938
_subjectBuffer = subjectBuffer
3039
_state = state
40+
_semanticModel = semanticModel
3141
_cancellationToken = cancellationToken
3242
End Sub
3343

44+
Public Shared Function NeedsSemanticModel(node As SyntaxNode) As Boolean
45+
' All of these call HandleMethodBlockSyntax, which needs semantics
46+
If TypeOf node Is MethodStatementSyntax OrElse
47+
TypeOf node Is SubNewStatementSyntax OrElse
48+
TypeOf node Is OperatorStatementSyntax Then
49+
Return True
50+
End If
51+
52+
' Calls GenerateAddOrRemoveHandler and GenerateRaiseEventHandler, both which needs semantics
53+
If TypeOf node Is EventStatementSyntax Then
54+
Return True
55+
End If
56+
57+
Return False
58+
End Function
59+
3460
Public Overrides Function VisitDoStatement(node As DoStatementSyntax) As AbstractEndConstructResult
3561
Dim needsEnd = node.GetAncestorsOrThis(Of DoLoopBlockSyntax)().Any(Function(block) block.LoopStatement.IsMissing)
3662

@@ -100,11 +126,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
100126
End If
101127
End Function
102128

103-
Private Function TryGenerateResultForConstructorSpitWithInitializeComponent(methodBlock As MethodBlockBaseSyntax) As AbstractEndConstructResult
129+
Private Function TryGenerateResultForConstructorSpitWithInitializeComponent(
130+
methodBlock As MethodBlockBaseSyntax) As AbstractEndConstructResult
104131
If methodBlock.BlockStatement.Kind = SyntaxKind.SubNewStatement Then
105-
Dim boundConstructor = _state.SemanticModel.GetDeclaredSymbol(DirectCast(methodBlock.BlockStatement, SubNewStatementSyntax))
132+
Dim boundConstructor = _semanticModel.GetDeclaredSymbol(DirectCast(methodBlock.BlockStatement, SubNewStatementSyntax))
106133
If boundConstructor IsNot Nothing Then
107-
If boundConstructor.ContainingType.IsDesignerGeneratedTypeWithInitializeComponent(_state.SemanticModel.Compilation) Then
134+
If boundConstructor.ContainingType.IsDesignerGeneratedTypeWithInitializeComponent(_semanticModel.Compilation) Then
108135
Dim aligningWhitespace = _subjectBuffer.CurrentSnapshot.GetAligningWhitespace(methodBlock.BlockStatement.SpanStart)
109136
Dim innerAligningWhitespace = aligningWhitespace & " "
110137

@@ -161,10 +188,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
161188
Dim aligningWhitespace = _subjectBuffer.CurrentSnapshot.GetAligningWhitespace(node.SpanStart)
162189
Dim stringBuilder As New StringBuilder
163190
stringBuilder.Append(_textView.Options.GetNewLineCharacter())
164-
StringBuilder.Append(aligningWhitespace & " Case ")
191+
stringBuilder.Append(aligningWhitespace & " Case ")
165192
Dim finalCaretPoint = stringBuilder.Length
166193
stringBuilder.AppendLine()
167-
StringBuilder.Append(aligningWhitespace & "End Select")
194+
stringBuilder.Append(aligningWhitespace & "End Select")
168195

169196
Return New ReplaceSpanResult(New SnapshotSpan(_subjectBuffer.CurrentSnapshot, _state.CaretPosition, 0),
170197
stringBuilder.ToString(), newCaretPosition:=finalCaretPoint)

src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructStatementVisitor_CustomEvents.vb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,21 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
3737
End Function
3838

3939
Private Function GenerateAddOrRemoveHandler(eventStatement As EventStatementSyntax, kind As SyntaxKind) As String()
40-
Dim type = _state.SemanticModel.GetTypeInfo(DirectCast(eventStatement.AsClause, SimpleAsClauseSyntax).Type, Me._cancellationToken)
40+
Dim type = _semanticModel.GetTypeInfo(DirectCast(eventStatement.AsClause, SimpleAsClauseSyntax).Type, Me._cancellationToken)
4141
Dim position As Integer = eventStatement.SpanStart
4242
Dim aligningWhitespace = _subjectBuffer.CurrentSnapshot.GetAligningWhitespace(position) & " "
43-
Return {aligningWhitespace & SyntaxFacts.GetText(kind) & "(value As " & type.Type.ToMinimalDisplayString(_state.SemanticModel, position, SymbolDisplayFormats.NameFormat) & ")",
43+
Return {aligningWhitespace & SyntaxFacts.GetText(kind) & "(value As " & type.Type.ToMinimalDisplayString(_semanticModel, position, SymbolDisplayFormats.NameFormat) & ")",
4444
"",
4545
aligningWhitespace & "End " & SyntaxFacts.GetText(kind)}
4646
End Function
4747

4848
Private Function GenerateRaiseEventHandler(eventStatement As EventStatementSyntax) As String()
49-
Dim type = TryCast(_state.SemanticModel.GetTypeInfo(DirectCast(eventStatement.AsClause, SimpleAsClauseSyntax).Type, Me._cancellationToken).Type, INamedTypeSymbol)
49+
Dim type = TryCast(_semanticModel.GetTypeInfo(DirectCast(eventStatement.AsClause, SimpleAsClauseSyntax).Type, Me._cancellationToken).Type, INamedTypeSymbol)
5050
Dim signature = ""
5151

5252
If type IsNot Nothing AndAlso type.DelegateInvokeMethod IsNot Nothing Then
5353
Dim parameterStrings = type.DelegateInvokeMethod.Parameters.Select(
54-
Function(p) p.ToMinimalDisplayString(_state.SemanticModel, eventStatement.SpanStart))
54+
Function(p) p.ToMinimalDisplayString(_semanticModel, eventStatement.SpanStart))
5555
signature = String.Join(", ", parameterStrings)
5656
End If
5757

src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructStatementVisitor_IfStatement.vb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
77

88
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
99
Partial Friend Class EndConstructStatementVisitor
10-
1110
Public Overrides Function VisitIfStatement(node As IfStatementSyntax) As AbstractEndConstructResult
1211
Dim needsEnd = node.GetAncestorsOrThis(Of MultiLineIfBlockSyntax)().Any(Function(block) block.EndIfStatement.IsMissing)
1312

src/EditorFeatures/VisualBasic/EndConstructGeneration/VisualBasicEndConstructGenerationService.vb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,13 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
161161
Dim bufferOptions = _editorOptionsFactoryService.GetOptions(subjectBuffer)
162162

163163
Return New EndConstructState(
164-
caretPosition.Value, New Lazy(Of SemanticModel)(Function() document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken)), tree, tokenToLeft, bufferOptions.GetNewLineCharacter())
164+
caretPosition.Value, AsyncLazy.Create(Function(c) document.GetSemanticModelAsync(c)), tree, tokenToLeft, bufferOptions.GetNewLineCharacter())
165165
End Function
166166

167-
Friend Overridable Function TryDoEndConstructForEnterKey(textView As ITextView,
168-
subjectBuffer As ITextBuffer,
169-
cancellationToken As CancellationToken) As Boolean
167+
Friend Overridable Async Function TryDoEndConstructForEnterKeyAsync(
168+
textView As ITextView,
169+
subjectBuffer As ITextBuffer,
170+
cancellationToken As CancellationToken) As Task(Of Boolean)
170171
Using Logger.LogBlock(FunctionId.EndConstruct_DoStatement, cancellationToken)
171172
Using transaction = New CaretPreservingEditTransaction(VBEditorResources.End_Construct, textView, _undoHistoryRegistry, _editorOperationsFactoryService)
172173
transaction.MergePolicy = AutomaticCodeChangeMergePolicy.Instance
@@ -285,7 +286,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
285286
Return False
286287
End If
287288

288-
Dim visitor = New EndConstructStatementVisitor(textView, subjectBuffer, state, cancellationToken)
289+
Dim semanticModel = If(EndConstructStatementVisitor.NeedsSemanticModel(statement),
290+
Await state.GetSemanticModelAsync(cancellationToken).ConfigureAwait(True),
291+
Nothing)
292+
Dim visitor = New EndConstructStatementVisitor(textView, subjectBuffer, state, semanticModel, cancellationToken)
289293
Dim result = visitor.Visit(statement)
290294

291295
If result Is Nothing Then
@@ -480,10 +484,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration
480484
End Using
481485
End Function
482486

483-
Public Function TryDo(textView As ITextView, subjectBuffer As ITextBuffer, typedChar As Char, cancellationToken As CancellationToken) As Boolean Implements IEndConstructGenerationService.TryDo
487+
Public Async Function TryDoAsync(textView As ITextView, subjectBuffer As ITextBuffer, typedChar As Char, cancellationToken As CancellationToken) As Task(Of Boolean) Implements IEndConstructGenerationService.TryDoAsync
484488
Select Case typedChar
485489
Case vbLf(0)
486-
Return Me.TryDoEndConstructForEnterKey(textView, subjectBuffer, cancellationToken)
490+
Return Await Me.TryDoEndConstructForEnterKeyAsync(textView, subjectBuffer, cancellationToken).ConfigureAwait(True)
487491
Case ">"c
488492
Return Me.TryDoXmlElementEndConstruct(textView, subjectBuffer, cancellationToken)
489493
Case "-"c

src/EditorFeatures/VisualBasic/Utilities/CommandHandlers/AbstractImplementAbstractClassOrInterfaceCommandHandler.vb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Utilities.CommandHandlers
6767

6868
' It's possible that there may be an end construct to generate at this position.
6969
' We'll go ahead and generate it before determining whether we need to move the caret
70-
TryGenerateEndConstruct(args, _cancellationToken)
70+
Await TryGenerateEndConstructAsync(args, _cancellationToken).ConfigureAwait(True)
7171

7272
Dim snapshot = args.SubjectBuffer.CurrentSnapshot
7373
Dim caretPosition = args.TextView.GetCaretPoint(args.SubjectBuffer).Value
@@ -92,7 +92,9 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Utilities.CommandHandlers
9292
Return True
9393
End Function
9494

95-
Private Shared Function TryGenerateEndConstruct(args As ReturnKeyCommandArgs, cancellationToken As CancellationToken) As Boolean
95+
Private Shared Async Function TryGenerateEndConstructAsync(
96+
args As ReturnKeyCommandArgs,
97+
cancellationToken As CancellationToken) As Task(Of Boolean)
9698
Dim textSnapshot = args.SubjectBuffer.CurrentSnapshot
9799

98100
Dim document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges()
@@ -112,7 +114,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Utilities.CommandHandlers
112114

113115
Dim endConstructGenerationService = document.GetLanguageService(Of IEndConstructGenerationService)()
114116

115-
Return endConstructGenerationService.TryDo(args.TextView, args.SubjectBuffer, vbLf(0), cancellationToken)
117+
Return Await endConstructGenerationService.TryDoAsync(
118+
args.TextView, args.SubjectBuffer, vbLf(0), cancellationToken).ConfigureAwait(True)
116119
End Function
117120

118121
Private Overloads Async Function TryExecuteAsync(

0 commit comments

Comments
 (0)