/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructCommandHandler.vb
184 строки
10 KB
Cyrus Najmabadi
Organize VB imports
27 июн 2025, 21:53
27 июн 2025, 21:53
e9c47fd
Код
Авторство
О чём код?
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports System.ComponentModel.Composition Imports System.Diagnostics.CodeAnalysis Imports System.Threading Imports Microsoft.CodeAnalysis.AddImport Imports Microsoft.CodeAnalysis.CodeCleanup Imports Microsoft.CodeAnalysis.CodeCleanup.Providers Imports Microsoft.CodeAnalysis.Editor.Implementation.EndConstructGeneration Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.Commanding Imports Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion Imports Microsoft.VisualStudio.Text Imports Microsoft.VisualStudio.Text.Editor Imports Microsoft.VisualStudio.Text.Editor.Commanding.Commands Imports Microsoft.VisualStudio.Text.Operations Imports Microsoft.VisualStudio.Utilities Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration <Export(GetType(ICommandHandler))> <ContentType(ContentTypeNames.VisualBasicContentType)> <Name(PredefinedCommandHandlerNames.EndConstruct)> <Order(After:=PredefinedCompletionNames.CompletionCommandHandler)> <Order(After:=PredefinedCommandHandlerNames.AutomaticLineEnder)> Friend Class EndConstructCommandHandler Implements IChainedCommandHandler(Of ReturnKeyCommandArgs) Implements IChainedCommandHandler(Of TypeCharCommandArgs) Implements IChainedCommandHandler(Of AutomaticLineEnderCommandArgs) Private ReadOnly _threadingContext As IThreadingContext Private ReadOnly _editorOperationsFactoryService As IEditorOperationsFactoryService Private ReadOnly _undoHistoryRegistry As ITextUndoHistoryRegistry Private ReadOnly _editorOptionsService As EditorOptionsService <ImportingConstructor()> <SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification:="Used in test code: https://github.com/dotnet/roslyn/issues/42814")> Public Sub New( threadingContext As IThreadingContext, editorOperationsFactoryService As IEditorOperationsFactoryService, undoHistoryRegistry As ITextUndoHistoryRegistry, editorOptionsService As EditorOptionsService) _threadingContext = threadingContext _editorOperationsFactoryService = editorOperationsFactoryService _undoHistoryRegistry = undoHistoryRegistry _editorOptionsService = editorOptionsService End Sub Public ReadOnly Property DisplayName As String = VBEditorResources.End_Construct Implements INamed.DisplayName Public Function GetCommandState_ReturnKeyCommandHandler(args As ReturnKeyCommandArgs, nextHandler As Func(Of CommandState)) As CommandState Implements IChainedCommandHandler(Of ReturnKeyCommandArgs).GetCommandState Return nextHandler() End Function Public Sub ExecuteCommand_ReturnKeyCommandHandler(args As ReturnKeyCommandArgs, nextHandler As Action, context As CommandExecutionContext) Implements IChainedCommandHandler(Of ReturnKeyCommandArgs).ExecuteCommand _threadingContext.JoinableTaskFactory.Run(Function() ExecuteEndConstructOnReturnAsync( args.TextView, args.SubjectBuffer, nextHandler, context.OperationContext.UserCancellationToken)) End Sub Public Function GetCommandState_TypeCharCommandHandler(args As TypeCharCommandArgs, nextHandler As Func(Of CommandState)) As CommandState Implements IChainedCommandHandler(Of TypeCharCommandArgs).GetCommandState Return nextHandler() End Function Public Sub ExecuteCommand_TypeCharCommandHandler(args As TypeCharCommandArgs, nextHandler As Action, context As CommandExecutionContext) Implements IChainedCommandHandler(Of TypeCharCommandArgs).ExecuteCommand _threadingContext.JoinableTaskFactory.Run( Async Function() nextHandler() If Not _editorOptionsService.GlobalOptions.GetOption(EndConstructGenerationOptionsStorage.EndConstruct, LanguageNames.VisualBasic) Then Return End If Dim textSnapshot = args.SubjectBuffer.CurrentSnapshot Dim document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges() If document Is Nothing Then Return End If ' End construct is not cancellable. Dim endConstructService = document.GetLanguageService(Of IEndConstructGenerationService)() Await endConstructService.TryDoAsync( args.TextView, args.SubjectBuffer, args.TypedChar, context.OperationContext.UserCancellationToken).ConfigureAwait(True) End Function) End Sub Public Function GetCommandState_AutomaticLineEnderCommandHandler(args As AutomaticLineEnderCommandArgs, nextHandler As Func(Of CommandState)) As CommandState Implements IChainedCommandHandler(Of AutomaticLineEnderCommandArgs).GetCommandState Return CommandState.Available End Function Public Sub ExecuteCommand_AutomaticLineEnderCommandHandler(args As AutomaticLineEnderCommandArgs, nextHandler As Action, context As CommandExecutionContext) Implements IChainedCommandHandler(Of AutomaticLineEnderCommandArgs).ExecuteCommand _threadingContext.JoinableTaskFactory.Run(Function() ExecuteEndConstructOnReturnAsync( args.TextView, args.SubjectBuffer, Sub() Dim operations = Me._editorOperationsFactoryService.GetEditorOperations(args.TextView) If operations Is Nothing Then nextHandler() Else operations.InsertNewLine() End If End Sub, context.OperationContext.UserCancellationToken)) End Sub Private Async Function ExecuteEndConstructOnReturnAsync( textView As ITextView, subjectBuffer As ITextBuffer, nextHandler As Action, cancellationToken As CancellationToken) As Task If Not _editorOptionsService.GlobalOptions.GetOption(EndConstructGenerationOptionsStorage.EndConstruct, LanguageNames.VisualBasic) OrElse Not subjectBuffer.CanApplyChangeDocumentToWorkspace() Then nextHandler() Return End If Dim textSnapshot = subjectBuffer.CurrentSnapshot Dim document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges() If document Is Nothing Then Return End If Await CleanupBeforeEndConstructAsync( textView, subjectBuffer, document, cancellationToken).ConfigureAwait(True) Dim endConstructService = document.GetLanguageService(Of IEndConstructGenerationService)() Dim result = Await endConstructService.TryDoAsync( textView, subjectBuffer, vbLf(0), cancellationToken).ConfigureAwait(True) If Not result Then nextHandler() Return End If End Function Private Async Function CleanupBeforeEndConstructAsync( view As ITextView, buffer As ITextBuffer, document As Document, cancellationToken As CancellationToken) As Task Dim position = view.GetCaretPoint(buffer) If Not position.HasValue Then Return End If Dim root = document.GetSyntaxRootSynchronously(cancellationToken) Dim statement = root.FindToken(position.Value).GetAncestor(Of StatementSyntax)() If statement Is Nothing OrElse TypeOf statement Is EmptyStatementSyntax OrElse Not statement.ContainsDiagnostics Then Return End If Dim codeCleanups = CodeCleaner.GetDefaultProviders(document). WhereAsArray(Function(p) Return p.Name = PredefinedCodeCleanupProviderNames.NormalizeModifiersOrOperators End Function) Dim options = buffer.GetCodeCleanupOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat:=False, allowImportsInHiddenRegions:=document.AllowImportsInHiddenRegions()) Dim cleanDocument = Await CodeCleaner.CleanupAsync( document, GetSpanToCleanup(statement), options, codeCleanups, cancellationToken).ConfigureAwait(True) Dim changes = cleanDocument.GetTextChangesSynchronously(document, cancellationToken) Using transaction = New CaretPreservingEditTransaction(VBEditorResources.End_Construct, view, _undoHistoryRegistry, _editorOperationsFactoryService) transaction.MergePolicy = AutomaticCodeChangeMergePolicy.Instance buffer.ApplyChanges(changes) transaction.Complete() End Using End Function Private Shared Function GetSpanToCleanup(statement As StatementSyntax) As TextSpan Dim firstToken = statement.GetFirstToken() Dim lastToken = statement.GetLastToken() Dim previousToken = firstToken.GetPreviousToken() Dim nextToken = lastToken.GetNextToken() Return TextSpan.FromBounds(If(previousToken.Kind <> SyntaxKind.None, previousToken, firstToken).SpanStart, If(nextToken.Kind <> SyntaxKind.None, nextToken, lastToken).Span.End) End Function End Class End Namespace