2013-04-09 31 views
12

Şu anda, ToString() özel olarak adlandırılmış olsun veya olmasın, belirli bir enumun bir dizeye dönüştürüldüğü her yerde bir çözüm bulmaya çalışıyorum. (Bu gizleme geliştirmek için enum açıklamaları kullanarak bir dönüşümle değiştirilir.)Her yeri bulmak bir enum dizgeye dönüştürülür

Örnek: kod bulmak istiyoruz string str = "Value: " + SomeEnum.someValue;

bir sarmalayıcı sınıf örtülü içeren enum kendisi yerine denedik gibi enum türüne dönüşümler ve sarmalayıcı sınıfındaki ToString() öğesini geçersiz kılar, ancak ToString() geçersiz kılmanın kullanımlarını aramayı denediğimde, bana ToString() öğesinin herhangi bir yerde (ve yalnızca) nerede çağrıldığı çözümdeki yerlerin listesini verir. açıkça denir). Arama, Visual Studio'da ReSharper ile yapıldı.

Bu enos-to-string dönüşümlerini bulmanın başka bir yolu var mı? Tüm çözümü el ile yapmak çok eğlenceli gibi gelmiyor.

+7

Roslyn ekibi, ben bu yüzden bu etiketlediniz ben bunu görürsünüz biliyorum. :-) Mevcut Roslyn bitleri, bu tür bir dönüşüm için AST'yi aramaya izin verecek mi? –

+6

Sadece zaten ne yaptığını bir uzantısı, sizin sarıcı sınıfında ise ayrıca string' 'bir' implicit' dönüşüm oluşturmak ve '[Eski]' nitelik, derleyici uyarı/hata her yerde sizi bilgilendirecektir uygulamaların kullanım ile işaretleyin : http://stackoverflow.com/questions/10585594/how-to-get-find-usages-working-with-implicit-operator-methods Bu bir cevap değil, bir çimdik içinde size yardımcı olabilir. –

cevap

16

Roslyn'deki numara, SemanticModel.GetTypeInfo() numaralı telefonu kullanmak ve bu tür örtük dönüşümleri bulmak için ConvertedType numaralı telefonu incelemektir.

Tam bir örnek:

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

Orada güzel LINQ kullanımı Kevin. :-) –

+0

Genellikle lambda sözdizimini tercih ederim, ancak bu durumda hata ayıklama için izin cümlelerini gerçekten istedim. –