| File: CodeCleanup\VisualBasicCodeCleanerService.vb | Web Access |
| Project: src\roslyn\src\Workspaces\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.Workspaces.vbproj (Microsoft.CodeAnalysis.VisualBasic.Workspaces) |
' 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.Collections.Immutable Imports Microsoft.CodeAnalysis.CodeCleanup Imports Microsoft.CodeAnalysis.CodeCleanup.Providers Imports Microsoft.CodeAnalysis.LanguageService Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.LanguageService Namespace Microsoft.CodeAnalysis.VisualBasic.CodeCleanup Partial Friend Class VisualBasicCodeCleanerService Inherits AbstractCodeCleanerService Private Shared ReadOnly s_defaultProviders As ImmutableArray(Of ICodeCleanupProvider) = ImmutableArray.Create(Of ICodeCleanupProvider)( New AddMissingTokensCodeCleanupProvider(), New FixIncorrectTokensCodeCleanupProvider(), New ReduceTokensCodeCleanupProvider(), New NormalizeModifiersOrOperatorsCodeCleanupProvider(), New RemoveUnnecessaryLineContinuationCodeCleanupProvider(), New CaseCorrectionCodeCleanupProvider(), New SimplificationCodeCleanupProvider(), New FormatCodeCleanupProvider()) Public Overrides Function GetDefaultProviders() As ImmutableArray(Of ICodeCleanupProvider) Return s_defaultProviders End Function Protected Overrides Function GetSpansToAvoid(root As SyntaxNode) As ImmutableArray(Of TextSpan) ' We don't want to touch nodes in the document that have syntax errors on them and which ' contain multi-line string literals. It's quite possible that there is some string ' literal on a previous line that was intended to be terminated on that line, but which ' wasn't. The string may then have terminated on this line (because of the start of ' another literal) causing the literal contents to then be considered code. We don't ' want to cleanup 'code' that the user intends to be the content of a string literal. Dim result = ArrayBuilder(Of TextSpan).GetInstance() ProcessNode(root, result) Return result.ToImmutableAndFree() End Function Private Shared Sub ProcessNode(node As SyntaxNode, result As ArrayBuilder(Of TextSpan)) If SkipProcessing(node, result) Then Return End If For Each child In node.ChildNodesAndTokens() If child.IsNode Then ProcessNode(child.AsNode(), result) Else ProcessToken(child.AsToken(), result) End If Next End Sub Private Shared Sub ProcessToken(token As SyntaxToken, result As ArrayBuilder(Of TextSpan)) If SkipProcessing(token, result) Then Return End If Dim parentMultiLineNode = GetMultiLineContainer(token.Parent) If parentMultiLineNode IsNot Nothing Then If ContainsMultiLineStringLiteral(parentMultiLineNode) Then result.Add(parentMultiLineNode.FullSpan) End If End If End Sub Private Shared Function SkipProcessing(nodeOrToken As SyntaxNodeOrToken, result As ArrayBuilder(Of TextSpan)) As Boolean ' Don't bother looking at nodes or token that don't have any syntax errors in them. If Not nodeOrToken.ContainsDiagnostics Then Return True End If If result.Count > 0 AndAlso result.Last.Contains(nodeOrToken.Span) Then ' Don't bother looking at nodes or token that are contained within a span we've already ' marked as something to avoid. We would only ever produce mark the same (or smaller) ' span again. Return True End If Return False End Function Private Shared Function ContainsMultiLineStringLiteral(node As SyntaxNode) As Boolean Return node.DescendantTokens().Any( Function(t) If t.Kind() = SyntaxKind.StringLiteralToken OrElse t.Kind() = SyntaxKind.InterpolatedStringTextToken Then Return Not VisualBasicSyntaxFacts.Instance.IsOnSingleLine(t.Parent, fullSpan:=False) End If Return False End Function) End Function Private Shared Function GetMultiLineContainer(node As SyntaxNode) As SyntaxNode If node Is Nothing Then Return Nothing End If If Not VisualBasicSyntaxFacts.Instance.IsOnSingleLine(node, fullSpan:=False) Then Return node End If Return GetMultiLineContainer(node.Parent) End Function End Class End Namespace