Roslyn:检查方法参数是否不能为空

时间:2014-07-30 09:13:03

标签: c# .net roslyn

使用Roslyn,我的目的是检查在取消引用参数之前是否检查方法参数是否为null。当然,这种检查可以采用一种子方法。

我的方法是获取参数的第一个解引用并搜索它与方法start之间的语法树进行空检查。如何进行某种控制流分析,以确定参数的第一次解引用是否可以参数为空?

1 个答案:

答案 0 :(得分:1)

这是一个过于宽泛的问题,稍微解释一下你的最终目标是什么。您是否尝试在它们发生之前检测到空指针异常,100%? (几乎不可能)

我几个月前写过静态分析,我没有使用roslyn,但这没关系。

检查这个以便让你可能已经开始 - 它会在有未使用的变量时报告警告:

internal class UnUsedVariableWarningDefinition : ICodeIssue
{
    public IEnumerable<IssueReport> Analyze()
    {
        var usageMap = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);
        var variableMap = new Dictionary<string, IdentifierNode>(StringComparer.InvariantCultureIgnoreCase);

        foreach (var node in NodeAnalyzerHelper.FindNodesDfs(Root))
        {
            var assignmentNode = node as AssignmentNode;
            if (assignmentNode != null)
            {
                var variableNode = assignmentNode.Identifier;

                int usages;
                if (!usageMap.TryGetValue(variableNode.Identifier, out usages))
                {
                    usageMap[variableNode.Identifier] = 0;
                    variableMap[variableNode.Identifier] = variableNode;
                }
            }
            else
            {
                // not really an assignmentNode,
                // let's see if we have detected the usage of IdentifierNode somewhere.
                var variableNode = node as IdentifierNode;
                if (variableNode != null)
                {
                    if (usageMap.ContainsKey(variableNode.Identifier))
                        usageMap[variableNode.Identifier]++;
                }
            }
        }

        foreach (var node in usageMap.Where(x => x.Value == 0).Select(x => variableMap[x.Key]))
        {
            yield return node.ConstructWarning("No usages of this variable found. Are you sure this is needed?");
        }
    }
}

请注意,FindNodesDfs()基本上是一个语法树walker,它以语法节点深度优先的方式进行处理。它的作用就是扫描AssigfnmentNodes并将它们放到Dictionary中,一旦识别出IdentifierNode,它会检查字典是否曾经遇到过赋值。我想,这有点类似于你想做的事情。