我目前正在尝试编写一个C#CodeFixProvider,如果存在相应的属性,它应该用属性setter访问替换对setXXX()方法的调用。基本上
setSimpleProperty(42);
被替换为
SimpleProperty = 42;
核心似乎工作正常,但我正在努力与琐事。在以下示例中
/*a*/setSimpleProperty(/*b*/ 42 /*c*/)/*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);
}
那有什么不对?我从哪里获得换行符?
为什么使用AppendLeadingTrivia而不是WithLeadingTrivia,对于Trailing也是如此。我是你“追加”到ElasticTrivia然后它取决于Normalizer的作用。你正在控制你的例子中的所有琐事。