roslyn analyzer for finding classes that inherit from generic types

Viewed 204

I'm writing a Rosyln analyzer using VS 2019. I want it to find all classes that inherit from MyNameSpace.MyLib.MyClass< T> or MyNameSpace.MyLib.MyClass< T,U> and mark them with a warning.

I'm looking for classes that inherit from MyNameSpace.MyLib.MyClass< T> but I cant seem to figure out how to realize that the instance type (ex. MyNameSpace.MyLib.MyClass< MyOtherClass>) is a MyNameSpace.MyLib.MyClass< T>

The problem is occurring in the line below:

if(InheritsFrom(namedTypeSymbol, myclassOfT) || 
   InheritsFrom(namedTypeSymbol, myclassOfTU))

How can I fix this so that it recognizes MyNameSpace.MyLib.MyClass< MyOtherClass>) as a MyNameSpace.MyLib.MyClass< T>?

Here's the code I'm using, and below it is the test I'm trying to it test with.

        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
        }

        private static void AnalyzeSymbol(SymbolAnalysisContext context)
        {

            var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;

            INamedTypeSymbol myclassOfT = context.Compilation.GetTypeByMetadataName("MyNamespace.MyLib.MyClass`1");
            INamedTypeSymbol myclassOfTU = context.Compilation.GetTypeByMetadataName("MyNamespace.MyLib.MyClass`2");

            if(InheritsFrom(namedTypeSymbol, myclassOfT) || InheritsFrom(namedTypeSymbol, myclassOfTU))
            {
                ... raises diagnostic 
            }
        }

       // got InheritsFrom from:
       // https://www.meziantou.net/working-with-types-in-a-roslyn-analyzer.htm#checking-a-type-inhe

       private static bool InheritsFrom(INamedTypeSymbol symbol, ITypeSymbol type)
       {
            var baseType = symbol.BaseType;
            while (baseType != null)
            {
                 if (type.Equals(baseType))
                     return true;

                 baseType = baseType.BaseType;
             }
             return false;
         }
     }

And here's the test:

    public class AnalyzerTest : DiagnosticVerifier
    {
        [TestMethod]
        public void ShouldRaiseWarning()
        {
            var test = @"
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Diagnostics;

    namespace ConsoleApplication1
    {
        public class TypeName : MyNameSpace.MyLib.MyClass<FakeType>
        {   
            public void OneMethod()
            {
            }
        }
        public class FakeType
        {
        }
    }

    namespace MyNameSpace.MyLib
    {
        public class MyClass<T>
        {
        }
        public class MyClass<T,U>
        {
        }  
}
";
            VerifyCSharpDiagnostic(test);

        }
0 Answers
Related