#c# #roslyn #codefixprovider
#c# #roslyn #codefixprovider
Вопрос:
В настоящее время я пытаюсь написать C # CodeFixProvider, который должен заменять вызовы методов setXXX() доступом к установщику свойств, если соответствующее свойство существует. В основном
setSimpleProperty(42);
заменяется на
SimpleProperty = 42;
Ядро, кажется, работает нормально, но я борюсь с мелочами. В следующем примере
/*a*/setSimpleProperty(/*b*/ 42 /*c*/)/*d*/;
- a приводит мелочи к вызову
- b завершает trivia открытой фигурной скобкой списка аргументов
- c завершает trivia до самого аргумента
- d завершает мелочи до вызова
Я попытался правильно обработать их, чтобы получить ожидаемый результат
/*a*/SimpleProperty = /*b*/42/*c*//*d*/;
Однако я получаю неожиданные разрывы строк и не могу понять, что не так:
/*a*/
SimpleProperty =
/*b*/ 42 /*c*//*d*/;
Мой базовый код выглядит следующим образом:
private static Task<Document> ReplaceMethodCallWithPropertySetAsync(Document document, InvocationExpressionSyntax invocation, ISymbol property, CancellationToken cancellationToken)
{
ExpressionSyntax propertyAccess = null;
if (invocation.Expression is IdentifierNameSyntax)
{
propertyAccess = SyntaxFactory.IdentifierName(property.Name);
}
else if (invocation.Expression is MemberAccessExpressionSyntax memberAccess)
{
propertyAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, memberAccess.Expression, SyntaxFactory.IdentifierName(property.Name));
}
var val = invocation.ArgumentList.Arguments.First().Expression.AppendLeadingTrivia(invocation.ArgumentList.OpenParenToken.TrailingTrivia);
var newNode = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, propertyAccess, val);
newNode = newNode.AppendLeadingTrivia(invocation.GetLeadingTrivia()).AppendTrailingTrivia(invocation.GetTrailingTrivia());
return document.ReplaceNodeAsync(invocation, newNode, cancellationToken);
}
AppendLeadingTrivia / AppendTralingTrivia — это просто вспомогательные методы расширения:
public static T AppendTrailingTrivia<T>(this T node, IEnumerable<SyntaxTrivia> trivias) where T : SyntaxNode
{
if (trivias == null)
return node;
if (node.HasTrailingTrivia)
return node.WithTrailingTrivia(node.GetTrailingTrivia().Concat(trivias));
else
return node.WithTrailingTrivia(trivias);
}
Так что же не так? Откуда я получаю разрывы строк?