/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService_IntroduceQueryLocal.vb
102 строки
5 KB
Cyrus Najmabadi
Simplify VB side
03 дек 2024, 09:00
03 дек 2024, 09:00
fb6bac7
Код
Авторство
О чём код?
' 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 Imports Microsoft.CodeAnalysis.CodeActions Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.IntroduceVariable Partial Friend Class VisualBasicIntroduceVariableService Protected Overrides Function IntroduceQueryLocal( document As SemanticDocument, expression As ExpressionSyntax, allOccurrences As Boolean, cancellationToken As CancellationToken) As Document Dim oldOutermostQuery = expression.GetAncestorsOrThis(Of QueryExpressionSyntax)().LastOrDefault() Dim newLocalNameToken = GenerateUniqueLocalName( document, expression, isConstant:=False, containerOpt:=oldOutermostQuery, cancellationToken:=cancellationToken) Dim newLocalName = SyntaxFactory.IdentifierName(newLocalNameToken) Dim letClause = SyntaxFactory.LetClause( SyntaxFactory.ExpressionRangeVariable( SyntaxFactory.VariableNameEquals( SyntaxFactory.ModifiedIdentifier(newLocalNameToken.WithAdditionalAnnotations(RenameAnnotation.Create()))), expression)).WithAdditionalAnnotations(Formatter.Annotation) Dim matches = FindMatches(document, expression, document, {oldOutermostQuery}, allOccurrences, cancellationToken) Dim innermostClauses = New HashSet(Of QueryClauseSyntax)( matches.Select(Function(expr) expr.GetAncestor(Of QueryClauseSyntax)())) If innermostClauses.Count = 1 Then ' If there was only one match, or all the matches came from the same ' statement, then we want to place the declaration right above that ' statement. Note: we special case this because the statement we are going ' to go above might not be in a block and we may have to generate it Return IntroduceQueryLocalForSingleOccurrence( document, expression, newLocalName, letClause, allOccurrences, cancellationToken) End If Dim oldInnerMostCommonQuery = matches.FindInnermostCommonNode(Of QueryExpressionSyntax)() Dim newInnerMostQuery = Rewrite(document, expression, newLocalName, document, oldInnerMostCommonQuery, allOccurrences, cancellationToken) Dim allAffectedClauses = New HashSet(Of QueryClauseSyntax)( matches.SelectMany(Function(expr) expr.GetAncestorsOrThis(Of QueryClauseSyntax)())) Dim oldClauses = oldInnerMostCommonQuery.Clauses Dim newClauses = newInnerMostQuery.Clauses Dim firstClauseAffectedInQuery = oldClauses.First(AddressOf allAffectedClauses.Contains) Dim firstClauseAffectedIndex = oldClauses.IndexOf(firstClauseAffectedInQuery) Dim finalClauses = newClauses.Take(firstClauseAffectedIndex). Concat(letClause). Concat(newClauses.Skip(firstClauseAffectedIndex)).ToList() Dim finalQuery = newInnerMostQuery.WithClauses(SyntaxFactory.List(finalClauses)) Dim newRoot = document.Root.ReplaceNode(oldInnerMostCommonQuery, finalQuery) Return document.Document.WithSyntaxRoot(newRoot) End Function Private Function IntroduceQueryLocalForSingleOccurrence( document As SemanticDocument, expression As ExpressionSyntax, newLocalName As NameSyntax, letClause As LetClauseSyntax, allOccurrences As Boolean, cancellationToken As CancellationToken) As Document Dim oldClause = expression.GetAncestor(Of QueryClauseSyntax)() Dim newClause = Rewrite(document, expression, newLocalName, document, oldClause, allOccurrences, cancellationToken) Dim oldQuery = DirectCast(oldClause.Parent, QueryExpressionSyntax) Dim newQuery = GetNewQuery(oldQuery, oldClause, newClause, letClause) Dim newRoot = document.Root.ReplaceNode(oldQuery, newQuery) Return document.Document.WithSyntaxRoot(newRoot) End Function Private Shared Function GetNewQuery( oldQuery As QueryExpressionSyntax, oldClause As QueryClauseSyntax, newClause As QueryClauseSyntax, letClause As LetClauseSyntax) As QueryExpressionSyntax Dim oldClauses = oldQuery.Clauses Dim oldClauseIndex = oldClauses.IndexOf(oldClause) Dim newClauses = oldClauses.Take(oldClauseIndex). Concat(letClause). Concat(newClause). Concat(oldClauses.Skip(oldClauseIndex + 1)).ToList() Return oldQuery.WithClauses(SyntaxFactory.List(newClauses)) End Function End Class End Namespace