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);
}