我有以下代码来检测方法调用。我想在源代码中添加一个简单的语句(例如,Console.WriteLine("Test"(; (在该调用语句之前和之后,并将其保存回源文件。任何代码片段或示例显示如何做到这一点?
var methodDeclarations = classitem.DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (var memmeth in methodDeclarations)
{
var varInvocations = memmeth.DescendantNodes().OfType<InvocationExpressionSyntax>();
foreach (InvocationExpressionSyntax invoc in varInvocations)
{
// insert new statement before and after the invocation
您正在尝试将语句与表达式混合使用。
如果我写
this.Test();
在我的代码中,它是 ExpressionStatement(表达式语句中的 IncallExpression(中的 SimpleExpressionStatement。
语句基本上是表示一行代码的元素,在我们的示例中是这个。test((;,可能类似于返回;扔;等。
因此,如果要在表达式之前或之后插入语句,则必须在包含语句之前或之后插入该语句。
但是,这可能会产生问题,因为在同一语句中可以有多个表达式,例如
if(Test() && Test2()){
}
因此,为了在方法调用之前或之后插入新语句,您可以简单地找到最近的语句并将其插入该语句之前或之后,例如:
var statements = new List<StatementSyntax>();
var methodDeclarations = root.DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (var memmeth in methodDeclarations)
{
var varInvocations = memmeth.DescendantNodes().OfType<InvocationExpressionSyntax>();
foreach (InvocationExpressionSyntax invoc in varInvocations)
{
// Find the relevant node
var statement = invoc.Ancestors().OfType<StatementSyntax>().FirstOrDefault();
statements.Add(statement);
}
}
// Track the nodes so you can change it in the tree even after modifying it
root = root.TrackNodes(statements.Distinct());
foreach(var statement in statements)
{
var currentStatement = root.GetCurrentNode(statement);
root = root.InsertNodesAfter(currentStatement,
new[] { SyntaxFactory.ExpressionStatement(
SyntaxFactory.InvocationExpression(
SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.IdentifierName("Console"),
SyntaxFactory.IdentifierName("WriteLine"))
))});
currentStatement = root.GetCurrentNode(statement);
root = root.InsertNodesBefore(currentStatement,
new[] { SyntaxFactory.ExpressionStatement(
SyntaxFactory.InvocationExpression(
SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.IdentifierName("Console"),
SyntaxFactory.IdentifierName("WriteLine"))
))});
}