| File: ExtractMethod\VisualBasicMethodExtractor.vb | Web Access |
| Project: src\roslyn\src\Features\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.Features.vbproj (Microsoft.CodeAnalysis.VisualBasic.Features) |
' 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.Threading Imports Microsoft.CodeAnalysis.ExtractMethod Imports Microsoft.CodeAnalysis.Formatting.Rules Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Partial Friend NotInheritable Class VisualBasicExtractMethodService Partial Friend Class VisualBasicMethodExtractor Inherits MethodExtractor Public Sub New(result As SelectionResult, options As ExtractMethodGenerationOptions) MyBase.New(result, options, localFunction:=False) End Sub Protected Overrides Function CreateCodeGenerator(selectionResult As SelectionResult, analyzerResult As AnalyzerResult) As CodeGenerator Return VisualBasicCodeGenerator.Create(selectionResult, analyzerResult, Me.Options) End Function Protected Overrides Function Analyze(cancellationToken As CancellationToken) As AnalyzerResult Dim analyzer = New VisualBasicAnalyzer(Me.OriginalSelectionResult, cancellationToken) Return analyzer.Analyze() End Function Protected Overrides Function GetInsertionPointNode( analyzerResult As AnalyzerResult, cancellationToken As CancellationToken) As SyntaxNode Dim document = Me.OriginalSelectionResult.SemanticDocument Dim spanStart = OriginalSelectionResult.FinalSpan.Start Contract.ThrowIfFalse(spanStart >= 0) Dim root = document.Root Dim basePosition = root.FindToken(spanStart) Dim enclosingTopLevelNode As SyntaxNode = basePosition.GetAncestor(Of PropertyBlockSyntax)() enclosingTopLevelNode = If(enclosingTopLevelNode, basePosition.GetAncestor(Of EventBlockSyntax)) enclosingTopLevelNode = If(enclosingTopLevelNode, basePosition.GetAncestor(Of MethodBlockBaseSyntax)) enclosingTopLevelNode = If(enclosingTopLevelNode, basePosition.GetAncestor(Of FieldDeclarationSyntax)) enclosingTopLevelNode = If(enclosingTopLevelNode, basePosition.GetAncestor(Of PropertyStatementSyntax)) Contract.ThrowIfNull(enclosingTopLevelNode) Return enclosingTopLevelNode End Function Protected Overrides Async Function PreserveTriviaAsync(root As SyntaxNode, cancellationToken As CancellationToken) As Task(Of TriviaResult) Dim semanticDocument = Me.OriginalSelectionResult.SemanticDocument Dim preservationService = semanticDocument.Document.Project.Services.GetService(Of ISyntaxTriviaService)() Dim result = preservationService.SaveTriviaAroundSelection(root, Me.OriginalSelectionResult.FinalSpan) Return New VisualBasicTriviaResult( Await semanticDocument.WithSyntaxRootAsync(result.Root, cancellationToken).ConfigureAwait(False), result) End Function Protected Overrides Function GetCustomFormattingRule(document As Document) As AbstractFormattingRule Return FormattingRule.Instance End Function Protected Overrides Function ParseTypeName(name As String) As SyntaxNode Return SyntaxFactory.ParseTypeName(name) End Function Private NotInheritable Class FormattingRule Inherits CompatAbstractFormattingRule Public Shared ReadOnly Instance As New FormattingRule() Private Sub New() End Sub Public Overrides Function GetAdjustNewLinesOperationSlow(ByRef previousToken As SyntaxToken, ByRef currentToken As SyntaxToken, ByRef nextOperation As NextGetAdjustNewLinesOperation) As AdjustNewLinesOperation If Not previousToken.IsLastTokenOfStatement() Then Return nextOperation.Invoke(previousToken, currentToken) End If ' between [generated code] and [existing code] If Not CommonFormattingHelpers.HasAnyWhitespaceElasticTrivia(previousToken, currentToken) Then Return nextOperation.Invoke(previousToken, currentToken) End If ' make sure attribute and previous statement has at least 1 blank lines between them If IsLessThanInAttribute(currentToken) Then Return FormattingOperations.CreateAdjustNewLinesOperation(2, AdjustNewLinesOption.ForceLines) End If ' make sure previous statement and next type has at least 1 blank lines between them If TypeOf currentToken.Parent Is TypeStatementSyntax AndAlso currentToken.Parent.GetFirstToken(includeZeroWidth:=True) = currentToken Then Return FormattingOperations.CreateAdjustNewLinesOperation(2, AdjustNewLinesOption.ForceLines) End If Return nextOperation.Invoke(previousToken, currentToken) End Function Private Shared Function IsLessThanInAttribute(token As SyntaxToken) As Boolean ' < in attribute If token.Kind = SyntaxKind.LessThanToken AndAlso token.Parent.Kind = SyntaxKind.AttributeList AndAlso DirectCast(token.Parent, AttributeListSyntax).LessThanToken.Equals(token) Then Return True End If Return False End Function End Class Protected Overrides Function InsertNewLineBeforeLocalFunctionIfNecessaryAsync( document As Document, invocationNameToken As SyntaxToken, methodDefinition As SyntaxNode, cancellationToken As CancellationToken) As Task(Of (document As Document, invocationNameToken As SyntaxToken)) ' VB doesn't need to do any correction, so we just return the values untouched Return Task.FromResult((document, invocationNameToken)) End Function End Class End Class End Namespace