■課題
Roslyn(Microsoft.CodeAnalysis)を使ってC#ソースコードを解析し、enumとそれに含まれる列挙子を抽出するプログラムを書いています。
各列挙子の値について、簡単かつRoslynが算出した値を取得する手段を探しています。
■試したこと
以下のI/Fはダメでした:
- SemanticModel.GetConstantValue()は、nullが返る。
- SemanticModel.GetDeclaredSymbol();で戻ってくるIFieldSymbolのConstantValueには、nullが入っている。
■回避策
以下は対応アイディアとして検討していますが、さらに楽な手段がないか探しています。
(1)
「列挙子シンボル = 値,」の形式で記述しているケースでは、EnumDeclarationSyntax.EqualsValueによって「 = 値」の部分を取得できます。なので本文字列をパースして自前で算出すれば値は得られます。
これを避けているのは、Roslynは元々コンパイラで、アセンブリを生成する過程では同様にパース・値算出を行っているはずです。
車輪の再発明をしたくない(結果を食い違いさせたくない)ですし、I/Fが提供されているなら自作は避けたいです。
(2)
CSharpCompilation.Emit()によってメモリ上でビルドして、得たアセンブリをリフレクションで解析する。
これを避けているのは、単に手間がかかるからです。Roslynの算出結果を利用しているという点では要求を満たします。
■環境
VS2017(ver.15.9.26)
C#プロジェクト(.NET Framework 4.7.2)
nugetでMicrosoft.CodeAnalysis(ver.3.7.0)を取得
■実装中のコード
C#
1var srcCode = File.ReadAllText(path); 2var syntaxTree = CSharpSyntaxTree.ParseText(srcCode); 3var compilation = CSharpCompilation.Create("test", new[] { syntaxTree }, null); 4var semanticModel = compilation.GetSemanticModel(syntaxTree); 5var nodes = syntaxTree.GetRoot().DescendantNodes(); 6foreach(var syntax in nodes.OfType<EnumDeclarationSyntax>()) 7{ 8 foreach(var memberSyntaxTree in syntax.Members) 9 { 10 var symbol = semanticModel.GetDeclaredSymbol(memberSyntaxTree); 11 12 // ダメなコードの例。 13 var value = semanticModel.GetConstantValue(memberSyntaxTree); 14 15 Console.WriteLine($"{symbol} = {value}"); 16 } 17}
あなたの回答
tips
プレビュー