2012-06-29 7 views
13

tôi có thể có được một danh sách từ các giải pháp của tất cả các cuộc gọi đến một phương pháp particuliar sử dụng đoạn mã sau:Bắt đối số phương pháp với Roslyn

var createCommandList = new List<MethodSymbol>(); 
INamedTypeSymbol interfaceSymbol = 
    (from p 
    in solution.Projects 
    select p.GetCompilation().GetTypeByMetadataName(
     "BuySeasons.BsiServices.DataResource.IBsiDataConnection") 
    ).FirstOrDefault(); 
foreach (ISymbol symbol in interfaceSymbol.GetMembers("CreateCommand")) 
{ 
    if (symbol.Kind == CommonSymbolKind.Method 
     && symbol is MethodSymbol) 
    { 
     createCommandList.Add(symbol as MethodSymbol); 
    } 
} 
foreach (MethodSymbol methodSymbol in createCommandList) 
{ 
    foreach (ReferencedSymbol referenceSymbol 
     in methodSymbol.FindReferences(solution)) 
    { 
     foreach (ReferenceLocation referenceLocation 
      in from l 
       in referenceSymbol.Locations 
       orderby l.Document.FilePath 
       select l) 
     { 
      if (referenceLocation.Location.GetLineSpan(false) 
        .StartLinePosition.Line == 
       referenceLocation.Location.GetLineSpan(false) 
        .EndLinePosition.Line) 
      { 
       Debug.WriteLine("{0} {1} at {2} {3}/{4} - {5}", 
        methodSymbol.Name, 
        "(" + String.Join(",", 
         (from p 
         in methodSymbol.Parameters 
         select p.Type.Name + " " + p.Name).ToArray() 
         ) + ")", 
       Path.GetFileName(referenceLocation.Location.GetLineSpan(false) 
        .Path), 
       referenceLocation.Location.GetLineSpan(false) 
        .StartLinePosition.Line, 
       referenceLocation.Location.GetLineSpan(false) 
        .StartLinePosition.Character, 
       referenceLocation.Location.GetLineSpan(false) 
        .EndLinePosition.Character)); 
      } 
      else 
      { 
       throw new ApplicationException("Call spans multiple lines"); 
      } 
     } 
    } 
} 

Nhưng điều này mang lại cho tôi một danh sách các ReferencedSymbol. Mặc dù điều này mang lại cho tôi các tập tin và số dòng mà phương pháp được gọi là từ tôi cũng muốn nhận được các đối số cụ thể mà phương pháp được gọi là với. Làm thế nào tôi có thể chuyển đổi những gì tôi có hoặc có được thông tin tương tự với Roslyn? (thông báo trước tiên tôi nạp giải pháp với phương thức Solution.Load và sau đó lặp lại để tìm ra phương thức được xác định/khai báo ở đâu (createCommandList)).

Trả lời

0

Bạn có thể tìm kiếm cây cú pháp của tham chiếu tại vị trí nguồn cụ thể mà nó xuất hiện để tìm nút bạn đang tìm kiếm. Bạn sẽ cần phải sử dụng một cuộc gọi như DescendentNodes từ nút gốc của cây và có thể bạn sẽ cần phải yêu cầu loại nút ngôn ngữ cụ thể mà bạn đang tìm kiếm. Khi bạn có nút trong cây giới thiệu, bạn có thể sử dụng mô hình ngữ nghĩa của cây đó để cho bạn biết thông tin khác về các đối số.

2

Bạn đã sử dụng Roslyn tại đây. Khi bạn có một số referenceSymbol, bạn có thể lấy Cú pháp khai báo phương thức và sau đó nhìn xuống cây để lấy danh sách tham số.

tôi đã chèn một biến arguments sử dụng referenceSymbol của bạn:

// Snip start 
foreach (MethodSymbol methodSymbol in createCommandList) 
{ 
    foreach (ReferencedSymbol referenceSymbol 
     in methodSymbol.FindReferences(solution)) 
    { 
     var arguments = referenceSymbol.Definition.DeclaringSyntaxNodes.First() 
      .DescendantNodes().OfType<ParameterSyntax>().ToList(); 

     foreach (ReferenceLocation referenceLocation in 
      from l 
      in referenceSymbol.Locations 
      orderby l.Document.FilePath 
      select l) 
     { 
// Snip end 

Khi bạn thực hiện một đầu ra Debug, sau đó bạn có thể sử dụng danh sách các đối số để có được các tên.

Giải pháp của tôi yêu cầu nhận được First() của số DeclaringSyntaxNodes, mà tôi không thích nhiều lắm nhưng không thể tìm thấy cách khác để lấy các nút con cháu của cây cú pháp.

0

Tôi đã phát hiện ra một cách khác để lấy danh sách Tham số từ một phương thức có thể hoạt động cho những người khác.

Nói rằng tôi có phương pháp sau đây có hai tham số:

public string DebugPage(string enabled, string show){ 
    //do stuff 
} 

Sau đó, bạn sẽ có được các nút của bạn tuy nhiên bạn muốn. Ví dụ này mang lại cho tôi một danh sách các phương pháp công cộng:

IEnumerable<MethodDeclarationSyntax> methods = from m in root.DescendantNodes().OfType<MethodDeclarationSyntax>() where m.Modifiers.ToString().Contains("public") select m; 

Sau đó, tôi có thể lặp qua rằng danh sách các phương pháp để có được tại khách sạn ParameterList của phương pháp được tiếp xúc để làm cho hoạt động này thực sự dễ dàng. Tính đến hết vòng này danh sách parameters sẽ giữ tên của từng tham số trong phương pháp này (trong ví dụ của phương pháp Debug trên nó sẽ giữ các giá trị enabledshow như mong đợi):

var parameters = new List<string>(); 

foreach (var method in methods) 
{ 
    foreach (var n in method.ParameterList.Parameters) 
    { 
    var parameterName = n.Identifier.Text; 
    parameters.Add(parameterName); 
    } 
}