Неожиданные разрывы строк с Roslyn C # CodeFixProvider и Trivia - PullRequest
0 голосов
/ 22 апреля 2019

В настоящее время я пытаюсь написать C # CodeFixProvider, который должен заменить вызовы методов setXXX () доступом к установщику свойств, если существует соответствующее свойство.В основном

setSimpleProperty(42);

заменено на

SimpleProperty = 42;

Кажется, что ядро ​​работает нормально, но я борюсь с пустяками.В следующем примере

/*a*/setSimpleProperty(/*b*/ 42 /*c*/)/*d*/;
  1. a приводит пустяки к вызову
  2. b завершает пустяки к открытой скобке списка аргументов
  3. c завершаетпустяки к самому аргументу
  4. 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);
}

Так что не так?Откуда я получаю разрывы строки?

1 Ответ

0 голосов
/ 23 апреля 2019

Почему вы используете AppendLeadingTrivia вместо WithLeadingTrivia, то же самое для трейлинга.Я полагаю, что вы "добавляете" в ElasticTrivia, и это зависит от того, что делает Normalizer.Вы контролируете все мелочи в вашем примере.

...