2016-11-24 6 views
1

私はroslynでコード解析ルールを作成しようとしています。ObjectCreationExpressionSyntaxの引数がtry catchブロックにラップされているかどうかを確認してください。

基本的には、Microsoft.Practices.Prism.Commands.DelegateCommand()が作成された各引数がtry catchにラップされているかどうかをチェックする必要があります。

主なアイデアは、最初のStatementSyntaxTryStatementSyntaxかどうDelegateCommandクラスのすべてのObjectCreationExpressionSyntaxオブジェクトを収集し、各コンストラクタの引数をチェックしています。

StatementSyntaxをすべてArgumentSyntaxから手に入れることができますか?それとも別のアプローチがあるかもしれませんか?

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 私はあなたが右に見ることができるように

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

で書いたものをここで

(スクリーンショットはLINQ debugging featureからOzCodeからである)持っているもの、あなたの例で見てみましょう引数の中に3種類の構文ノードがあるので、それらをすべて扱う一般的な方法はありません。

あなたはそれを処理する2つの方法があります。 SyntaxNodeを取得

  1. Writeメソッドとその種類に応じて、最初の文はトライの\ catch文
  2. 書き込みSyntaxWalkerあるかどうかを確認し、そこに関連する方法、およびを訪れ、最初の文が試みているかどうかを確認\あなたはこの(または自分でまたはSyntaxWalkerの適切なVisitメソッドをオーバーライドすることによって)のようなものを書く必要があるParenthesizedLambdaExpressionSyntax最初のケースを処理するために、例えばcatch文

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

これは単なる例です。実際のコードでは、すべてのケースを処理する必要があります。あなたが最初の方法のシンボルを取得する必要がありますIdentifierNameSyntaxについては

semanticModel.GetSymbolInfo(identifier).Symbol 

次にあなたがDeclaringSyntaxReferencesから構文ノードを取得し、スパンを使用する必要がある、またはあなたがシンボルまたは任意の他の方法(のlocationを使用することができますConstructFromかもしれない)。

関連する問題