3

我正在尝试开发一个源生成器来使用该接口在部分类上自动实现一个接口。

我相信这必须是Microsoft 新的 Source Generators的常见用例,甚至在Roslyn Source Generator Cookbook中列为用例,但没有示例实现。

我已经搜索过,但很难在 Roslyn Analyzers 中找到针对此场景的问题。

在说明书中,他们使用 SyntaxReceiver 类来过滤Execute调用应该处理哪些语法节点:

        class SluggableSyntaxReceiver : ISyntaxReceiver
        {
            public List<ClassDeclarationSyntax> ClassesToAugment { get; } = new List<ClassDeclarationSyntax>();

            public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
            {
                // Business logic to decide what we're interested in goes here
                if(syntaxNode is ClassDeclarationSyntax cds && cds.HasInterface("IChangeTracked"))
                    ClassesToAugment.Add(cds)
            }

        }

查看说明书以了解生成器的实现细节。

我要确定的是如何HasInterface在 ClassDeclarationSyntax 节点上实现我的扩展。

        public static bool HasInterface(this ClassDeclarationSyntax source, string interfaceName)
        {
            IEnumerable<TypeSyntax> baseTypes = source.BaseList.Types.Select(baseType=>baseType.Type);
            // Ideally some call to do something like...
            return baseTypes.Any(baseType=>baseType.Name==interfaceName);
        }

我如何能:

  1. 从 ClassDeclarationSyntax 中获取 BaseList 属性,
  2. 确定类是否是部分的
  3. 访问接口
  4. 确定是否有任何接口属于特定类型。
4

1 回答 1

2

我必须相信有比我做的更好的方法来做到这一点,但是对于它的价值,这里有一个工作实现,它确定一个特定的ClassDeclarationSyntax显式实现一个接口:

        /// <summary>Indicates whether or not the class has a specific interface.</summary>
        /// <returns>Whether or not the SyntaxList contains the attribute.</returns>
        public static bool HasInterface(this ClassDeclarationSyntax source, string interfaceName)
        {
            IEnumerable<BaseTypeSyntax> baseTypes = source.BaseList.Types.Select(baseType => baseType);

            // To Do - cleaner interface finding.
            return baseTypes.Any(baseType => baseType.ToString() ==interfaceName);
        }
于 2021-06-17T15:12:16.117 回答