2017-05-19 45 views
15

我試圖替換Roslyn語法樹中的節點,它只是工作,但有一個煩惱,感覺它不應該是一個問題。爲什麼SyntaxNode.ReplaceNode更改SyntaxTree選項?

語法樹是從一個腳本生成的,我希望結果也是一個基於腳本的語法樹 - 但由於某種原因,替換樹中的節點會創建一個新的語法樹,其中包含更改的選項:Kind變成Regular而不是Script。這可以用SyntaxTree.WithRootAndOptions修復,但是如果我需要調用它,感覺就像我做錯了什麼。

樣例程序:

using Microsoft.CodeAnalysis; 
using Microsoft.CodeAnalysis.CSharp; 
using Microsoft.CodeAnalysis.CSharp.Scripting; 
using Microsoft.CodeAnalysis.CSharp.Syntax; 
using Microsoft.CodeAnalysis.Scripting; 
using System; 
using System.Linq; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Script script = CSharpScript.Create("Console.WriteLine(\"Before\")", 
      ScriptOptions.Default.AddImports("System")); 

     var compilation = script.GetCompilation(); 
     var tree = compilation.SyntaxTrees.Single(); 

     var after = SyntaxFactory.LiteralExpression(
      SyntaxKind.StringLiteralExpression, 
      SyntaxFactory.Literal("After")); 

     var root = tree.GetRoot(); 
     var before = root.DescendantNodes().OfType<LiteralExpressionSyntax>().Single(); 
     var newRoot = root.ReplaceNode(before, after); 
     var fixedTree = newRoot.SyntaxTree.WithRootAndOptions(newRoot, tree.Options); 

     Console.WriteLine(newRoot);       // Console.WriteLine("After") 
     Console.WriteLine(tree.Options.Kind);    // Script 
     Console.WriteLine(newRoot.SyntaxTree.Options.Kind); // Regular 
     Console.WriteLine(fixedTree.Options.Kind);   // Script 
    } 
} 

(輸出是評論)

這是解決辦法實際上是正確的,或者是有一些不同的方式,我應該更換在樹的節點?

+0

語言版本也發生變化。您必須明確指定是否需要C#5語法樹。我也使用'.WithRootAndOptions()',從來沒有問題。 – Tamas

+0

我的直覺是說這是一個錯誤... –

+0

@JasonMalinowski:我很高興你是那個說 - 我當然不想:)(但是,對我來說也是這樣。 ) –

回答

0

當您替換樹中的節點時,將創建一個新的節點子樹。實質上,這個新的子樹不包含在SyntaxTree中。但是,如果您觀察到節點上的SyntaxTree屬性,則會創建一個新屬性。在這樣做的時候,原來的SyntaxTree早已不復存在,所以不可能保留解析選項。即使可能,保留選項也沒有意義,因爲您不再擁有解析器生成的樹。

Roslyn創建此SyntaxTree的原因是,所有子樹在技術上都包含在SyntaxTree實例中,因此Roslyn可以將診斷與它關聯。如果您使用SemanticModel的探索性API試圖綁定&獲取目前不是編譯組成部分的樹的片段的語義信息,這很有用。診斷報告錯誤及其位置,表示它所在的樹實例。

+1

「即使有可能,保留選項也沒有意義,因爲您不再擁有解析器生成的樹。」儘管如此,這種感覺更像是一種理論而非實際的理由。當然,說「我希望這棵樹像另一棵樹一樣,這個節點發生了變化」並不是一種不尋常的情況。「當我有更多時間時,我需要仔細閱讀其餘的答案,但從根本上來說,這至少在API使用方面感到*尷尬。它可能必須是這樣,但它是不幸的IMO: –

相關問題