我正在尝试使用Roslyn SDK和StackExchange.Precompilation
(谢谢!)在C#6中实现面向方面的编程。我现在的具体问题是,从IdentifierNameSyntax
实例开始,我想找到"成员类型" (标识符所引用的(方法,属性,字段,变量等)。 (如何)可以这样做?
背景
我正在研究的第一个概念验证是一些旧的设计合同。我有一个NonNullAttribute
,可以应用于参数,属性或方法返回值。除了属性之外,还有一个实现StackExchange.Precompilation.ICompileModule
接口的类,在编译时将对标记的参数或返回值插入空检查。
这与PostSharp的NonNullAttribute
相同,但转换是在Roslyn的一个语法树上完成的,而不是在已编译的程序集上。它也类似于Code Contracts,但是采用声明属性方法,并且再次在语法树上运行而不是IL。
例如,此源代码:
[return: NonNull]
public string Capitalize([NonNull] string text) {
return text.ToUpper();
}
将在预编译期间转换为此内容:
[return: NonNull]
public string Capitalize([NonNull] string text) {
if (Object.Equals(text, null))
throw new ArgumentNullException(nameof(text));
var result = text.ToUpper();
if (Object.Equals(result, null))
throw new PostconditionFailedException("Result cannot be null.");
return result;
}
(PostconditionFailedException
是我为了补充ArgumentException
的返回值而做出的自定义异常。如果框架中已有类似内容,请告知我们。)
对于具有此属性的属性,会有类似的转换,但前提条件和后置条件分别在set
和get
访问器中实现。
我需要找到"成员类型的具体原因"这里的标识符用于实现后置条件的优化。请注意,在上面的后编译示例中,将返回的值存储在局部变量中,进行检查,然后返回本地。此存储对于转换评估方法或复杂表达式的return
语句是必需的,但如果返回的表达式只是字段或局部变量引用,则创建本地临时存储是浪费的。
因此,在扫描return
语句时,我首先检查语句的格式是ReturnKeyword
- IdentifierSyntaxToken
- SemicolonToken
。如果是这样,那么我需要检查该标识符引用的内容,因此如果引用对象是字段或var,我会避免使用局部变量分配。
更新 有关更多上下文,请查看参考GitHub上的项目。
答案 0 :(得分:2)
您需要使用SemanticModel.GetSymbolInfo
来确定标识符绑定的符号。
答案 1 :(得分:0)
使用SemanticModel.GetTypeInfo.Type
获取TypeInfo并使用它来探索Type