从ArgumentListSyntax中删除OpenParen SyntaxToken的简单方法

本文关键字:简单 方法 SyntaxToken OpenParen ArgumentListSyntax 删除 | 更新日期: 2024-08-09 22:36:48

假设我有这个InvocationExpression GetDelegate<Func<double,double,double>>("Add")(),我该如何删除ArgumentListSyntax中的打开/关闭parens
我正试图找出Node.ReplaceNodes<gt;()方法,但即使使用该方法,我也不知道如何将节点替换为零。

我检查了这段示例代码,他把整个节点撕成了组件,只是为了修改它。没有更简单的方法吗?我找不到任何类型的Node.RemoveNode()方法。

我也尝试过做这样的事情,但没有成功:

argNodeMinusParen = argNodeMinusParen.WithArgumentList(argNodeMinusParen .ArgumentList.ReplaceToken(Syntax.Token(SyntaxKind.OpenParenToken), Syntax.Token(SyntaxKind.WhitespaceTrivia)));

澄清:我正在尝试修改此InvocationExpression,因此:

GetDelegate<Func<double,double,double>>("Add")()

GetDelegate<Func<double,double,double>>("Add")

我试图解决的问题:

从这个代码开始。

    private void Init()
    {
        StoredMethods.Add("Add", /*new InvocationExpression for identical signature method as controller.Add*/);
        StoredMethods.Add("Mul", /*new InvocationExpression for identical signature method as controller.SubMember.Mul*/);
    }
    private void RandomMethod()
    {
        var result = controller.SubMember.Mul(2, 3);
        var result2 = controller.Add(5, 5);
        var result3 = controller.Add(controller.SubMember.Mul(4, 5), 6);
        var result4 = controller.Subtract(5, controller.Add(1, 1));
    }
    public Dictionary<string, InvocationExpressionSyntax> StoredMethods
    {
        get;
        set;
    }

我想把它变成这个。请注意,这只是半伪代码,我实际上在做一些更复杂的静态泛型类型的东西,为了清晰起见,这是简化的。

对于在整个项目中找到的每个调用,如果在StoredMethods中找到方法名称,请将该调用替换为StoredMethod调用。结果应该是:

    private void RandomMethod()
    {
        var result = StoredMethods.GetDelegate("Mul")(2, 3);
        var result2 = StoredMethods.GetDelegate("Add")(5, 5);
        var result3 = StoredMethods.GetDelegate("Add")(StoredMethods.GetDelegate("Mul")(4, 5), 6);
        var result4 = controller.Subtract(5, StoredMethods.GetDelegate("Add")(1, 1));
    }//Notice that Subtract was NOT substituted, because it wasn't in StoredMethods, where Add was replaced in the inner arg

我更大的问题是试图弄清楚如何处理嵌套/组合的类和成员。我认为递归可以处理多个MemeberAccess表达式,但我很难把这个问题分解开来。此外,我正在使用SyntaxRewriter访问每个节点,所以我不知道如何将compilationUnit带入

从ArgumentListSyntax中删除OpenParen SyntaxToken的简单方法

你不能从"删除parens"的角度来看待它,Roslyn与字符无关,它与语法树有关。如果你把你的表达式看作一棵树的一部分,你会发现它有两个相关的属性:

  • 代表GetDelegate<Func<double,double,double>>("Add")Expression
  • 表示()ArgumentList

所以,你想要的是Expression(这里是innerInvocation变量):

var code = "GetDelegate<Func<double,double,double>>('"Add'")()";
var outerInvocation = (InvocationExpressionSyntax)Syntax.ParseExpression(code);
var innerInvocation = (InvocationExpressionSyntax)outerInvocation.Expression;

如果调用是某个较大代码片段的一部分,并且您希望删除其中的parens,则需要使用Replace():

var compilationUnit = …;
// or some other code to locate the invocation
var outerInvocation = compilationUnit.DescendantNodes()
                                     .OfType<InvocationExpressionSyntax>()
                                     .First();
var innerInvocation = (InvocationExpressionSyntax)outerInvocation.Expression;
var newCompilationUnit = compilationUnit.ReplaceNode(
    outerInvocation, innerInvocation);