【问题标题】:IParameterSymbol.GetAttributes() does not return actual symbolsIParameterSymbol.GetAttributes() 不返回实际符号
【发布时间】:2019-06-06 07:44:51
【问题描述】:

我正在编写 roslyn 分析器,它应该检查方法的参数是否在当前方法声明或接口之一中使用 [NotNull] 属性声明,并对其方法体进行一些检查。我用RegisterCodeBlockAction注册了CodeBlockAction,但是当我试图从接口/基类中的参数声明中获取属性时,它有时会返回空数组。

我发现,如果接口/基类位于其他程序集中,并且实际上分析器工作正常,当 Intelisense 运行它时会发生这种情况,但构建输出中没有警告\错误。我认为这是因为引用程序集的语义分析没有完全完成(但这有点奇怪)。

我写了一些日志

6/6/2019 13:59:47 Analize method symbol "ClassLibrary1.Program.Foo(string)" with 1 interfaces
6/6/2019 13:59:47 declaration ClassLibrary2.IFoo.Foo(string): [0 attributes] string s
6/6/2019 13:59:47 declaration ClassLibrary1.Program.Foo(string): [0 attributes] string s
6/6/2019 13:59:59 Analize method symbol "ClassLibrary1.Program.Foo(string)" with 1 interfaces
6/6/2019 13:59:59 declaration ClassLibrary2.IFoo.Foo(string): [1 attributes] string s
6/6/2019 13:59:59 declaration ClassLibrary1.Program.Foo(string): [0 attributes] string s

所以你可以看到,在 13:59:47(msbuild 运行)没有属性,但在 13:59:59(我在 Visual Studio 中打开文档)有一个属性。

我是如何获取 iterfaces 和参数的:

var allMethodDeclarations = //some code using methodSymbol.ContainingType.Interfaces

for (var i = 0; i < methodSymbol.Parameters.Length; ++i)
{
    var currentParameter = methodSymbol.Parameters[i];

    //parameters can be renamed, the only way is to use the order
    var hasNotNull = allMethodDeclarations
        .Select(d => d.Parameters[i])
        .SelectMany(p => p.GetAttributes())
        .Any(a => a.AttributeClass.Name == nameof(NotNullAttribute));

    if (hasNotNull)
    {
       //do something
    }
}

重现错误的示例代码:

在汇编 1 中

    public interface IFoo
    {
        void Foo([NotNull] string s);
    }

在程序集 2 中,引用程序集 1

    public class Program : IFoo
    {
        public void Foo(string s)
        {

        }
    }

【问题讨论】:

  • 我还发现 IFoo 的语法树也没有被解析:IMethodSymbol.DeclaringSyntaxReferences 返回 IFoo.Foo 的空数组
  • RegisterSemanticModelAction 产生相同的结果
  • 同RegisterCompilationAction,IMethodSymbol中没有信息,DeclaringSyntaxReferences也没有任何有用的信息。因此,即使在 RegisterCompilationAction 上也无法获取有关引用符号的信息?

标签: c# roslyn roslyn-code-analysis


【解决方案1】:

好的,我明白了。这是因为来自 Jetbrains.Annotations 的 NotNullAttribute 上的条件编译属性,所以编译器显示来自实际引用符号的数据(它跳过 [NotNull] 因为未定义 JETBRAINS_ANNOTATIONS),并且 Visual Studio 提供来自代码的真实属性列表,并且条件编译不考虑这种方式。 它看起来不一致,但我必须在我的项目中定义 JETBRAINS_ANNOTATIONS 才能使分析器工作。

【讨论】:

    猜你喜欢
    • 2015-02-07
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 2015-09-10
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多