如何使用SemanticModel检查变量是否已经过测试?

我正在研究一个Roslyn扩展,以警告未受保护的.ValueNullable<T>值的访问。

这提供了以下行为:

警告:在访问'Value'属性之前,必须检查Nullable'x'的空值

这个扩展已经有些作品了,但测试访问是否“安全”的代码有点像黑客。 我现在走纯粹的语法树,寻找if声明。

这种方法非常难看,并产生一堆无效的警告。

以下是访问x.Value应该安全的一些示例:

int y;
int? x = foo();

y = x != null ? x.Value : 42;

if (x > 4)
  y = x.Value;

if (x != null && someExpr) // With && only one branch needs to be a test
  y = x.Value;

if (x == 3 || x == 4) // With || both branches must be a test
  y = x.Value;

if (x == null) return; // Exit method body before access .Value
y = x.Value;

有没有一种方法可以使用SemanticModel来正确编写这个测试?

我正在考虑的一件事是在语法树上进行抽象解释。 但是,这看起来很多工作,我希望不需要一个完整的抽象解释器。

我不太确定在Roslyn中如何实现死代码分析,但似乎与此有关。


我还没有和Roslyn一起玩过。 但是作为ReSharper的用户,它也具有这个确切的功能,我可以做以下的陈述:

我的观察结果是,ReSharper仅查看相应符号的最近一次使用(类型Nullable <>)。 这是一个迭代证明。 如果变量已经被使用(显然)成功,那么连续使用是安全的。 然后,直到以前的使用检查,证明这又是一个安全的访问。 因此:检查以前的访问是否有其他先前的访问或针对null的回收比较以查看它是否安全。

if( x != null)
     x.access

例:

var z = x.Value; // unsafe because it is first and un-tested
var y = x.Value; // safe because it is not first and therefore dependent on first access

解决这个问题需要流量分析,Roslyn还没有做过。

链接地址: http://www.djcxy.com/p/20193.html

上一篇: How to use SemanticModel to check if variable has been tested?

下一篇: How does this extra thread make it faster than unthreaded?