簡體   English   中英

替換Roslyn語法樹中的多個節點

[英]Replacing multiple nodes in Roslyn syntax tree

我正在嘗試使用roslyn替換語法樹中的幾個節點。 但它的不變性質似乎妨礙了我。

    public static string Rewrite(string content)
    {
        var tree = CSharpSyntaxTree.ParseText(content);
        var root = tree.GetRoot();

        var methods =root
            .DescendantNodes(node=>true)
            .OfType<MethodDeclarationSyntax>()
            .ToList();

        foreach(var method in methods)
        {
            var returnActions = method
                .DescendantNodes(node => true)
                .OfType<BinaryExpressionSyntax>()
                //Ok this is cheating
                .Where(node => node.OperatorToken.ValueText == "==")
                .Where(node => node.Right.ToString() == "\"#exit#\"" || node.Right.ToString() == "\"#break#\"")
                .Select(node => node.Parent as IfStatementSyntax)
                .ToList();

            var lookup = new Dictionary<StatementSyntax,StatementSyntax>();

            if (returnActions.Count > 0)
            {
                foreach(var ifStatement in returnActions)
                {
                    var mainCall = ifStatement.GetPrevious() as ExpressionStatementSyntax;                        
                    var newIfStatement = ifStatement.WithCondition(mainCall.Expression.WithoutTrivia());

                    lookup[mainCall] = null;
                    lookup[ifStatement] = newIfStatement;
                }

                //this only replace some of the nodes
                root = root.ReplaceNodes(lookup.Keys, (s, d) => lookup[s]);
            }
        }

        return root.ToFullString();
    }

問題是,當我調用root.ReplaceNodes只有部分節點被替換。

我想替換會更改樹,以便其他節點不再與原始樹匹配,因此無法替換。

但是解決這個問題的最佳方法是什么?

一遍又一遍地循環過程直到不再發生變化感覺跛腳:)

這些更改可以嵌套發生,我認為這就是導致問題的原因。 我可以以某種方式對變更集進行排序以解決這個問題,還是有一種慣用的方式來處理這里的事情?

我想替換會更改樹,以便其他節點不再與原始樹匹配,因此無法替換。

你是對的。 替換節點會創建全新的語法樹。 來自先前語法樹的節點無法與這些新語法樹進行比較。

將多個更改應用於語法樹有四種方法:

  1. 使用DocumentEditor - 請參閱: https//stackoverflow.com/a/30563669/300908
  2. 使用Annotations (第236和240行)
  3. 使用.TrackNodes()
  4. 創建一個CSharpSyntaxRewriter ,以自下而上的方式替換節點。 我在博客上寫過這篇文章

在這些選項中,我相信DocumentEditor具有最容易使用的聲譽。 它很可能是未來應用多項更改的慣用方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM