Finding all class declarations than inherit from another with Roslyn

前端 未结 3 1191
终归单人心
终归单人心 2020-12-10 15:45

I have a CSharpCompilation instance containing an array of SyntaxTrees and I am trying to find all the class declarations that inherit from a class

相关标签:
3条回答
  • 2020-12-10 16:28

    First you'll need to get the symbol for Base. If this is a particular type you know about in advance, you can use Compilation.GetTypeByMetadataName for this. That link will also show you over 100 examples of that method in use.

    From there, it depends on what you're trying to do. If you're doing this from inside an analyzer (which I suspect from the "context.CSharpCompilation" in your code), and you're trying to identify and then check some property of these derived types, you could use RegisterSymbolAction for SymbolKind.NamedType, and then check each type's BaseType (possibly recursively, depending on what you're trying to accomplish) to see if you find the type discovered by GetTypeByMetadataName above.

    If you're doing solution-wide analysis outside the context of an analyzer, then there's a helper for this in the Roslyn codebase, but it's internal. There's an existing request to make ITypeSymbolExtensions public, so I've mentioned this thread in that request and suggested expanding it to include INamedTypeSymbolExtensions.

    0 讨论(0)
  • 2020-12-10 16:32

    So I came up with the following which will recursively check all classes for the inherited type

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-10 16:40
    var classDecSynList = classDecSynList.Where(x=>
           (((IdentifierNameSyntax(x.BaseList.Types.FirstOrDefault()))
                  .Identifier.ValueText=="Base"));
    

    Assuming you have all the class declaration Syntax list;

    0 讨论(0)
提交回复
热议问题