我正在尝试用roslyn编写代码分析规则。
基本上,我必须检查创建Microsoft.Practices.Prism.Commands.DelegateCommand()
的每个参数是否都包含在try catch
中。
主要思想是收集ObjectCreationExpressionSyntax
类的所有DelegateCommand
个对象,如果第一个StatementSyntax
是TryStatementSyntax
,则检查每个构造函数的参数。
您可以帮助我从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;
}
}
}
Bellow你可以找到我实际编译的搜索内容:
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 :(得分:2)
你从一个好的方式开始,但要完全处理它,它需要更多的工作。
让我们看一下我们的内容
(屏幕截图来自LINQ debugging feature的OzCode)
我写的是
var argsExpr = objCreation.Select(o => o.ArgumentList.Arguments.First())
正如您在窗口右侧所看到的,我们在参数中有三种类型的语法节点,因此我们没有一般方法来处理它们。
您有两种方法可以处理它。
例如,为了处理ParenthesizedLambdaExpressionSyntax
的第一个案例,您需要编写类似这样的内容(或者自己或通过覆盖Visit
的相应SyntaxWalker
方法)
public static bool IsTryStatement(ParenthesizedLambdaExpressionSyntax node)
{
return ((BlockSyntax) node.Body).Statements.First() is TryStatementSyntax;
}
这只是一个例子。在您的真实代码中,您需要处理所有情况。
对于IdentifierNameSyntax
,您需要先获取方法符号:
semanticModel.GetSymbolInfo(identifier).Symbol
然后你需要从DeclaringSyntaxReferences
获取语法节点并使用span,或者你可以使用符号的location
或任何其他方式(ConstructFrom
)。