在 InvocatioExpression 中插入新方法调用
Insert new method call in InvocatioExpression
我正在编写 visual studio 代码修复程序,它将在这种语句中插入 AsEnumerable
调用:
model.clients.Take(10).Select(c => new Client(c));
我能够检测到此类语句,但在 Select
方法之前插入 AsEnumerable
时遇到问题。这是我试过的:
var expressionSyntax = SyntaxFactory.ParseExpression(".AsEnumerable()");
var memberAccessExpressionSyntax = invocationExpr.Expression as MemberAccessExpressionSyntax;
var root = await document.GetSyntaxRootAsync(cancellationToken);
var newRoot = root.InsertNodesAfter(memberAccessExpressionSyntax.Expression, new[] {expressionSyntax});
return document.WithSyntaxRoot(newRoot);
但我得到
"System.InvalidOperationException: The item specified is not the
element of a list."
查看堆栈跟踪:https://gist.github.com/anonymous/02c41f232829163b25ae
调用 InsertNodesAfter
方法的正确方法是什么?
InsertNodesAfter
仅适用于列表中的节点。方法调用不是列表,而是调用表达式树。
您需要将 XXX.Select(...)
调用中的表达式替换为 XXX.AsEnumerable()
(重用相同的 XXX
节点)。
要了解这些表达式树的工作原理,请使用 Roslyn 语法可视化工具。
我是这样解决的:
var memberAccessExpressionSyntax = invocationExpr.Expression as MemberAccessExpressionSyntax;
var root = await document.GetSyntaxRootAsync(cancellationToken);
var accessExpression = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, memberAccessExpressionSyntax.Expression, SyntaxFactory.IdentifierName("AsEnumerable"));
var invocationExpression = SyntaxFactory.InvocationExpression(accessExpression);
var enumerableMemberAccessExpression = memberAccessExpressionSyntax.WithExpression(invocationExpression);
root = root.ReplaceNode(invocationExpr, invocationExpr.WithExpression(enumerableMemberAccessExpression));
我正在编写 visual studio 代码修复程序,它将在这种语句中插入 AsEnumerable
调用:
model.clients.Take(10).Select(c => new Client(c));
我能够检测到此类语句,但在 Select
方法之前插入 AsEnumerable
时遇到问题。这是我试过的:
var expressionSyntax = SyntaxFactory.ParseExpression(".AsEnumerable()");
var memberAccessExpressionSyntax = invocationExpr.Expression as MemberAccessExpressionSyntax;
var root = await document.GetSyntaxRootAsync(cancellationToken);
var newRoot = root.InsertNodesAfter(memberAccessExpressionSyntax.Expression, new[] {expressionSyntax});
return document.WithSyntaxRoot(newRoot);
但我得到
"System.InvalidOperationException: The item specified is not the element of a list."
查看堆栈跟踪:https://gist.github.com/anonymous/02c41f232829163b25ae
调用 InsertNodesAfter
方法的正确方法是什么?
InsertNodesAfter
仅适用于列表中的节点。方法调用不是列表,而是调用表达式树。
您需要将 XXX.Select(...)
调用中的表达式替换为 XXX.AsEnumerable()
(重用相同的 XXX
节点)。
要了解这些表达式树的工作原理,请使用 Roslyn 语法可视化工具。
我是这样解决的:
var memberAccessExpressionSyntax = invocationExpr.Expression as MemberAccessExpressionSyntax;
var root = await document.GetSyntaxRootAsync(cancellationToken);
var accessExpression = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, memberAccessExpressionSyntax.Expression, SyntaxFactory.IdentifierName("AsEnumerable"));
var invocationExpression = SyntaxFactory.InvocationExpression(accessExpression);
var enumerableMemberAccessExpression = memberAccessExpressionSyntax.WithExpression(invocationExpression);
root = root.ReplaceNode(invocationExpr, invocationExpr.WithExpression(enumerableMemberAccessExpression));