查找所有类声明而不是从Roslyn继承另一个类声明

Sco*_*kay 6 c# roslyn

我有一个CSharpCompilation包含SyntaxTrees 数组的实例,我试图找到从类继承的所有类声明

例如

// Not in syntax tree but referenced in project
public class Base{}

// In syntax tree, how to find all such classes?
public class MyClass : Base {}
Run Code Online (Sandbox Code Playgroud)

我尝试过一些东西但是对所有选项都有些困惑,似乎无法找到正确的方法来做到这一点.

我试图获取符号但这对继承的类型不起作用

SyntaxTree[] trees = context.CSharpCompilation.SyntaxTrees;
IEnumerable<ISymbol> symbols = context.CSharpCompilation.GetSymbolsWithName(x => x == typeof(Base).Name, SymbolFilter.Type);
Run Code Online (Sandbox Code Playgroud)

对Roslyn来说是一个新手,并且非常感谢任何有关如何实现这一目标的建议或指示.

Dav*_*chl 7

首先,你需要获得Base的符号.如果这是您事先知道的特定类型,则可以使用Compilation.GetTypeByMetadataName.该链接还将向您显示该方法的100多个示例.

从那里,它取决于你想要做什么.如果您是从分析器内部执行此操作(我怀疑您的代码中的"context.CSharpCompilation"),并且您尝试识别并检查这些派生类型的某些属性,则可以使用RegisterSymbolAction作为SymbolKind. NamedType,然后检查每个类型的BaseType(可能递归,取决于您要完成的任务),看看您是否找到上面的GetTypeByMetadataName发现的类型.

如果您在分析器的上下文之外进行解决方案范围的分析,那么在Roslyn代码库中有一个帮助器,但它是内部的.这里有一个现有请求作出ITypeSymbolExtensions公开,所以我提到这个线程在该请求,并建议扩大到包括INamedTypeSymbolExtensions.

  • 链接已失效。如果能包含相关示例就更好了。 (3认同)

Sco*_*kay 4

所以我想出了以下方法,它将递归检查所有类的继承类型

public class BaseClassRewriter : CSharpSyntaxRewriter
{
    private readonly SemanticModel _model;

    public BaseClassRewriter(SemanticModel model)
    {
        _model = model;
    }

    public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
    {
        var symbol = _model.GetDeclaredSymbol(node);
        if (InheritsFrom<BaseClass>(symbol))
        {
            // hit!
        }
    }

    private bool InheritsFrom<T>(INamedTypeSymbol symbol)
    {
        while (true)
        {
            if (symbol.ToString() == typeof(T).FullName)
            {
                return true;
            }
            if (symbol.BaseType != null)
            {
                symbol = symbol.BaseType;
                continue;
            }
            break;
        }
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)