2015-10-25 50 views
3

我寫了我的類MonitorSyntaxRewriter,它繼承自CSharpSyntaxRewriter。有了這個類,我改變了我的SyntaxTree。但是,我怎樣才能在某處「注入」這個修改的synaxtree?我的意思是,我在Visual Studio中有一些隨機項目,而在Build上,我希望所有的語法樹都通過這個MonitorSyntaxRewriter。有什麼選擇嗎?Roslyn SyntaxTree更改注入

還是有其他一些可能的解決方法嗎? (創造新的解決方案......)。我只是不希望在項目中更改我的* .cs文件。

回答

3

據我所知,在編譯併發送到磁盤之前,您無法插入構建過程並重新編寫語法樹。

這意味着實現你想要的並不容易。但是,您的項目並非不可能,您可以想象創建自己的Visual Studio擴展,該擴展爲Visual Studio添加了一個菜單選項,並啓動了您自己的構建併發出流程。

爲了重寫語法樹並將它們應用於解決方案,您需要將它們應用於其父文檔。編寫Visual Studio擴展時,您需要訪問VisualStudioWorkspace。這包含當前打開的解決方案中的解決方案,項目和文檔。我已經寫了一些background info的工作區,你可能會感興趣的

可以MEF一個MEF出口類中通過導入Visual Studio的工作區:

[Import(typeof(Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace))] 

一旦你有機會獲得VisualStudioWorkspace,您可以逐個重寫每個文檔。下面的示例代碼應該讓你開始:

Workspace ws = null; //Normally you'd get access to the VisualStudioWorkspace here. 
var currentSolution = ws.CurrentSolution; 

foreach (var projectId in currentSolution.ProjectIds) 
{ 
    var project = currentSolution.GetProject(projectId); 
    foreach (var documentId in project.DocumentIds) 
    { 
     Document doc = project.GetDocument(documentId); 
     var root = await doc.GetSyntaxRootAsync(); 

     //Rewrite your root here 
     var rewrittenRoot = RewriteSyntaxRoot(root); 

     //Save the changes to the current document 
     doc = doc.WithSyntaxRoot(root); 
     //Persist your changes to the current project 
     project = doc.Project; 
    } 
    //Persist the project changes to the current solution 
    currentSolution = project.Solution; 
} 

//Now you have your rewritten solution. You can emit the projects to disk one by one if you'd like. 

這不會修改用戶的密碼,但將允許您發出您的自定義項目到磁盤或一個MemoryStream,你可以加載到AppDomain或直接運行取決於你想要做什麼。

+0

正式從VisualStudioWorkspace發出並不真正支持 - 有一些屬性我們可能無法正常流動。此外,這當然意味着任何構建都將與正在安裝的Visual Studio綁定並實際執行構建,這對於您應該運行的連續構建服務器來說似乎不好。 –

+0

最終,這是一個我們現在正在努力思考的情景,需要支持所有的支持......這很難。 –