2013-04-09 21 views
12

Tôi hiện đang cố gắng tìm ở khắp mọi nơi trong một giải pháp mà một enum cụ thể được chuyển thành một chuỗi, có hay không ToString() được gọi một cách rõ ràng. (Những đang được thay thế bằng một chuyển đổi sử dụng mô tả enum để cải thiện obfuscation.)Tìm ở khắp mọi nơi một enum được chuyển thành chuỗi

Ví dụ: Tôi muốn tìm mã như string str = "Value: " + SomeEnum.someValue;

tôi đã cố gắng thay thế các enum chính nó với một lớp wrapper chứa ngầm chuyển đổi sang kiểu enum và ghi đè ToString() trong lớp trình bao bọc, nhưng khi tôi thử tìm kiếm sử dụng ToString() ghi đè nó sẽ cho tôi một danh sách các địa điểm trong giải pháp ToString() được gọi trên bất kỳ thứ gì (và chỉ ở đâu nó được gọi một cách rõ ràng). Việc tìm kiếm đã được thực hiện với ReSharper trong Visual Studio.

Có cách nào khác để tìm các chuyển đổi enum-to-string này không? Việc trải qua toàn bộ giải pháp theo cách thủ công không có vẻ thú vị.

+7

đội Roslyn, tôi đã gắn thẻ này vì vậy tôi biết bạn sẽ nhìn thấy nó. :-) Các bit phát hành hiện tại của Roslyn có cho phép tìm kiếm AST cho loại chuyển đổi này không? –

+6

Chỉ cần mở rộng những gì bạn đã làm, nếu trong lớp wrapper của bạn, bạn cũng tạo một chuyển đổi 'implicit' thành' string' và đánh dấu nó bằng thuộc tính '[Obsolete]', cảnh báo trình biên dịch/lỗi sẽ thông báo cho bạn ở mọi nơi : http://stackoverflow.com/questions/10585594/how-to-get-find-usages-working-with-implicit-operator-methods Nó không phải là một câu trả lời, nhưng có thể giúp bạn trong một pinch. –

Trả lời

16

Bí quyết trong Roslyn là sử dụng SemanticModel.GetTypeInfo() và sau đó kiểm tra ConvertedType để tìm các loại chuyển đổi tiềm ẩn này.

Một ví dụ hoàn chỉnh:

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

Sử dụng tốt LINQ ở đó Kevin. :-) –

+0

Tôi thường ưu tiên cú pháp lambda, nhưng trong trường hợp này, tôi thực sự muốn các mệnh đề cho phép gỡ lỗi. –

Các vấn đề liên quan