【发布时间】:2018-05-27 14:48:46
【问题描述】:
我正在使用 .NET 编译器 API 在 Roslyn 中编写一些代码分析器/代码修复器。我希望代码修复来转换以下代码:
string.Format("{0} {1}", A, B)
到
StringExtensions.SafeJoin(" ", A, B)
到目前为止,我有这个代码:
private async Task<Document> UseJoinAsync(Document document, InvocationExpressionSyntax invocationExpr, CancellationToken cancellationToken)
{
var argumentList = invocationExpr.ArgumentList;
var firstArgument = argumentList.Arguments[1];
var secondArgument = argumentList.Arguments[2];
var statement =
InvocationExpression(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName("StringExtensions"), // requires using Trilogy.Miscellaneous
IdentifierName("SafeJoin")))
.WithArgumentList(
ArgumentList(
SeparatedList<ArgumentSyntax>(
new SyntaxNodeOrToken[]
{
Argument(
LiteralExpression(
SyntaxKind.StringLiteralExpression,
Literal(" "))),
Token(SyntaxKind.CommaToken),
firstArgument,
Token(SyntaxKind.CommaToken),
secondArgument
}))).WithLeadingTrivia(invocationExpr.GetLeadingTrivia()).WithTrailingTrivia(invocationExpr.GetTrailingTrivia())
.WithAdditionalAnnotations(Formatter.Annotation);
var root = await document.GetSyntaxRootAsync(cancellationToken);
var newRoot = root.ReplaceNode(invocationExpr, statement);
var newDocument = document.WithSyntaxRoot(newRoot);
return newDocument;
}
但是,我有两个悬而未决的问题:
1) 如何将所需的using Trilogy.Miscellaneous 添加到文件顶部。
和
2) 如何检测我的项目是否引用了所需的程序集。在这种情况下,如果我的程序集 Trilogy.Common 未被引用,我将不提供代码修复,或者我会建议 string.Join(" ", A, B) 而不是我自己的 SafeJoin 实现。
更新
我已经通过如下更新我的代码解决了#1...
var newRoot = root.ReplaceNode(invocationExpr, statement);
// Iterate through our usings to see if we've got what we need...
if (root?.Usings.Any(u => u.Name.ToString() == "Trilogy.Miscellaneous") == false)
{
// Create and add the using statement...
var usingStatement = UsingDirective(QualifiedName(IdentifierName("Trilogy"), IdentifierName("Miscellaneous")));
newRoot = newRoot.AddUsings(usingStatement);
}
var newDocument = document.WithSyntaxRoot(newRoot);
return newDocument;
仍然希望对第 2 项有所帮助。
【问题讨论】:
-
我只是好奇,但 SafeJoin 的名称有点暗示 string.Join 不安全?真的吗?如果是这样,它有什么问题?
-
我知道
String.Format()有问题,如果 args 的数量与格式字符串中{#}的数量不匹配,但如果它实际上有两个 args,我看不到问题... -
String.Format() 或 Join 如果参数为 null 或空,或者只是空格本身,则可以为您留下额外或尾随空格。我们不希望那样。 var a = "你好"; var b =“出”;字符串 c = null; // 返回 "Hello out"
标签: c# roslyn roslyn-code-analysis