2013-04-09 2 views
12

現在、ToString()が明示的に呼び出されているかどうかに関わらず、特定の列挙型が文字列に変換されるソリューションのどこでも検索しようとしています。 (これらは、難読化を改善するために、列挙の説明を使用して変換で置換されている。)列挙型が文字列に変換されているところを見つける

例:私は暗黙含むラッパークラスで列挙自体を交換しようとしたようなstring str = "Value: " + SomeEnum.someValue;

としてコードを見つけたいです変換をEnum型に変換し、ラッパークラスのToString()をオーバーライドしますが、ToString()オーバーライドの使用を検索すると、ToString()が何かに対して呼び出される場所のリストが表示されます明示的に呼び出されます)。検索はVisual StudioのReSharperで行いました。

これらの列挙型から文字列への変換を見つける別の方法はありますか?手動でソリューション全体を調べるのは面白いとは言えません。

+7

ロザリンチームは、私は、私はあなたがそれを見ることができます知ってこれをタグ付けしました。 :-) Roslynの現在リリースされているビットは、このような変換のためにASTを検索できますか? –

+6

あなたがすでに行っていることの拡張だけで、ラッパークラスで 'string'への'暗黙の '変換を作成し、それを' [Obsolete] '属性でマークすると、コンパイラの警告/エラーは、 :http://stackoverflow.com/questions/10585594/how-to-get-find-usages-working-with-implicit-operator-methodsそれは答えではありませんが、ピンチであなたを助けるかもしれません。 –

答えて

16

Roslynの秘訣は、SemanticModel.GetTypeInfo()を使用して、ConvertedTypeをチェックして、これらの暗黙的な変換を見つけることです。

完全な例:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Roslyn.Compilers; 
using Roslyn.Compilers.CSharp; 
using Roslyn.Services; 
using Roslyn.Services.CSharp; 
using Roslyn.Compilers.Common; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var code = @"enum E { V } class { static void Main() { string s = ""Value: "" + E.V; } }"; 
     var doc = Solution.Create(SolutionId.CreateNewId()) 
      .AddCSharpProject("foo", "foo") 
      .AddMetadataReference(MetadataFileReference.CreateAssemblyReference("mscorlib")) 
      .AddDocument("doc.cs", code); 
     var stringType = doc.Project.GetCompilation().GetSpecialType(SpecialType.System_String); 
     var e = doc.Project.GetCompilation().GlobalNamespace.GetTypeMembers("E").Single(); 
     var v = e.GetMembers("V").Single(); 
     var refs = v.FindReferences(doc.Project.Solution); 
     var toStrings = from referencedLocation in refs 
         from r in referencedLocation.Locations 
         let node = GetNode(doc, r.Location) 
         let convertedType = doc.GetSemanticModel().GetTypeInfo(GetNode(doc, r.Location)).ConvertedType 
         where convertedType.Equals(stringType) 
         select r.Location; 
     foreach (var loc in toStrings) 
     { 
      Console.WriteLine(loc); 
     } 
    } 

    static CommonSyntaxNode GetNode(IDocument doc, CommonLocation loc) 
    { 
     return loc.SourceTree.GetRoot().FindToken(loc.SourceSpan.Start).Parent.Parent.Parent; 
    } 
} 
+1

そこにLINQをうまく利用しています。 :-) –

+0

私はラムダの構文を好んでいますが、この場合は本当にデバッグのためにlet節が必要でした。 –

関連する問題