How to use SemanticModel to check if variable has been tested?

I'm working on a Roslyn extension to warn against unprotected .Value accesses of Nullable<T> values.

This provides the following behaviour:

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

This extension already sort of works, but the code to test if an access is "safe" is sort of a hack. I now simply walk the syntax tree, looking for if statements.

This approach is quite ugly and produces a bunch of invalid warnings.

Here are some examples of cases where access x.Value should be safe:

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;

Is there a way to use the SemanticModel to properly write this test?

One of things I'm thinking about is to do Abstract interpretation over the syntax tree. But that seems like a lot of work, and I'm hoping a full blown abstract interpreter is not needed.

I'm not quite sure how dead code analysis is implemented in Roslyn, but it seems somewhat related to this.


I haven't played with Roslyn at all, yet. But being a user of ReSharper which has this exact feature as well, I can do the following statement:

My observation is that ReSharper only looks to the last recent usage of the respective symbol (type Nullable<>). This is an iterative proof. If the variable has been used (obviously) successfully, it is safe for continuus usage. Then it is up to the previous usage check to proove that this again is a safe access. Thus: check the previous access for either another previous access or a salvaging comparison against null to see if it is safe.

if( x != null)
     x.access

Example:

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/20194.html

上一篇: 输入私人类型的签名

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