2013-05-03 71 views
2

我有兩個輸出DLL的解決方案(實際上更多,但讓我們保持簡單)。項目「特​​別」參考項目「共同」。羅斯林編譯與兩個程序集?

我嘗試編寫一個代碼生成器,用於解析「Special」中的某些文件,並將生成的存根代碼放置到「Common」項目中。爲了處理這個循環引用,我需要處理不能編譯的代碼。所以我正在使用Roslyn。

生成器需要根據繼承信息取代某些類型,所以我需要構造一個編譯單元以獲得對語義模型的訪問權限。另外,我需要根據類型的來源來替換一些東西(不管它們是在「特殊」還是「常用」中定義的,或者更精確:基於全局程序集屬性)。

生成器必須能夠作爲MSBuild任務運行。

我嘗試了兩種方法來設置我的環境,我堅持兩個:

  1. 我想只是加載發生器內我的解決方案。由於「無法投射透明代理以鍵入'Roslyn.Utilities.SerializableDataStorage'」,因此失敗。然後,我嘗試從頭開始創建解決方案,添加IProjects和IDocuments,並且我已經嘗試了this answer中建議的LoadProjectFromCommandLineArguments,但是對我來說沒有任何效果,並且從MSBuild運行時也會遇到相同的異常(它通過控制檯啓動時運行良好)。

    任何人都知道如何處理SerializableDataStorage異常?

  2. 我試着創建一個編譯並添加我所有的cs源代碼。但是現在我無法找到一種方法來知道我的符號是來自大會「特別」還是「共同」。

    我可以使用一個彙編編譯成兩個不同的程序集嗎?或者我可以傳遞一個編譯作爲另一個編譯的參考? (有沒有MetadataReference我可以喂到Compilation.AddReference指向另一個編譯?)

PS:我的東西還沒有嘗試過是添加某種元數據(如註釋節點在開始)加入到語法樹中,或者使用SyntaxTree.FilePath屬性和一些映射,在我的生成器中使用這些信息來判斷定義的類型是來自「Special」還是「Common」。我寧願不會做這樣的事情,因爲它會很快變得混亂(實際上,我有大約20個dll)。

+0

關於第一個問題:您是如何獲得機器上的二進制文件的,以及該文件正在運行的進程的「bitness」是什麼?你可以嘗試安裝Roslyn CTP而不是通過NuGet嗎?此外,如果它是一個64位進程,你可以嘗試在32位進程中運行它嗎? – 2013-05-03 21:48:18

+0

我在64位,Windows 8上運行,並且通過nuget獲得了roslyn。我不知道如何告訴Visual Studio以任何特定模式(32或64)運行MSBuild ..我試着將項目設置爲「更喜歡32位」,但得到了同樣的異常。 – Imi 2013-05-06 10:32:26

+0

如果您通過Visual Studio使用msbuild,它將始終使用32位版本。從命令行中,您可以明確地從%Windir%\ Microsoft.Net \ Framework64 \ v4.0.30319目錄中啓動64位版本。另外 - 嘗試安裝CTP MSI(將Roslyn程序集添加到GAC),然後查看是否解決了該問題。 – 2013-05-06 15:04:53

回答

3

因此,編譯和構建的程序集之間存在1:1的對應關係,因此如果在分析過程中需要表示兩個程序集,則需要兩個編譯。要在它們之間添加引用,只需執行compilation.AddReference(new CompilationReference(sourceCompilation))並且符號應該導入您期望的內容。不要忘記編譯是不可改變的,所以如果你曾經fork過源代碼編譯,你可能不得不分叉引用編譯。

在任何給定的符號上,都有一個屬性ContainingAssembly,它可以讓您回到符號來自的組件。確保您在編譯時正確設置了輸出名稱,並且可以讓您弄清楚。