2016-11-24 32 views
1

我正在嘗試使用roslyn編寫代碼分析規則。檢查ObjectCreationExpressionSyntax的參數是否包含在try catch塊中

基本上,我必須檢查一個Microsoft.Practices.Prism.Commands.DelegateCommand()創建的每個參數是否包裝在try catch或不包含。

主要的想法是收集DelegateCommand類的所有ObjectCreationExpressionSyntax對象和檢查每個構造函數的參數,如果第一StatementSyntaxTryStatementSyntax與否。

你能幫我把StatementSyntaxArgumentSyntax?或者你可能有另一種方法?

public IEnumerable<IdentifierInfo> Collect(SyntaxNode rootNode, SemanticModel semanticModel) 
{ 
    ObjectCreationExpressionSyntax[] objCreation = rootNode 
                .DescendantNodes() 
                .OfType<ObjectCreationExpressionSyntax>() 
                .Where(c=>(c.Type as IdentifierNameSyntax)?.Identifier.Value.ToString() == "DelegateCommand") 
                .ToArray(); 

    foreach (var obj in objCreation) 
    { 
     var args = obj.ArgumentList.Arguments; 

     foreach (ArgumentSyntax arg in args) 
     { 
      var expession = arg.Expression; 
      var symbol = semanticModel.GetSymbolInfo(expession).Symbol as IMethodSymbol; 
     } 
    } 
} 

婁你可以找到我其實編譯尋遍:

public class Program 
{ 
    public delegate void MyDelegate(); 
    public static void DelegateMethod() { try { } catch { } } 
    public static void Main(string[] args) 
    { 
     DelegateCommand del1 = new DelegateCommand(() => {try{}catch{}}); 
     DelegateCommand del2 = new DelegateCommand(new Action(() => { })); 
     DelegateCommand del3 = new DelegateCommand(DelegateMethod); 
     var barInit = (Action)(DelegateMethod); 
     DelegateCommand del4 = new DelegateCommand(barInit); 
     ICommand test; 
     test = new Microsoft.Practices.Prism.Commands.DelegateCommand(() => { }); 
    } 
} 
+0

這是PRISM 5或以上?那麼你可能也想處理'DelegateCommand.FromAsync()'變體,不是嗎? – Ties

回答

2

你的一個好辦法啓動,但完全處理它,它需要更多的工作。

讓我們看看在你的例子我們有什麼

LINQ result (截圖是從LINQ debugging featureOzCode

這裏是我寫的是

var argsExpr = objCreation.Select(o => o.ArgumentList.Arguments.First()) 

正如你可以看到右邊在窗口的一邊,我們在參數中有三種類型的語法節點,所以我們沒有一個通用的方法來處理它們。

你有兩種處理方法。

  1. 寫入方法得到SyntaxNode,並根據其類型,檢查第一條語句是一個try \ catch語句
  2. 寫SyntaxWalker並參觀相關的方法,並在那裏,檢查第一條語句是一個try \ catch語句

例如處理是ParenthesizedLambdaExpressionSyntax你需要寫這樣的事情(或由自己或通過重寫SyntaxWalker適當Visit法)

第一案0
public static bool IsTryStatement(ParenthesizedLambdaExpressionSyntax node) 
{ 
    return ((BlockSyntax) node.Body).Statements.First() is TryStatementSyntax; 
} 

這只是一個例子。在你真實的代碼中,你需要處理所有的情況。

對於您需要首先獲得方法符號IdentifierNameSyntax

semanticModel.GetSymbolInfo(identifier).Symbol 

然後,你需要從DeclaringSyntaxReferences得到的語法點和使用範圍,也可以使用符號或任何其他方式的location(也許)。