0

至于定义 Roslyn Analyzer 规则的学习经验,假设我定义了如下接口

//These are a marker interfaces.
public interface ISomethingRoot1 {}
public interface ISomethingRoot2 {}

public interface ISomething: ISomethingRoot1
{
    int SomeOperation();    
}

public interface ISomething2: ISomethingRoot2
{
    int SomeOperation2();
}

我如何检查从标记接口继承的所有接口(甚至可能实现这些接口的类和从实现类继承的类,但现在是次要的)的函数ISomethingRoot1签名ISomethingRoot2?我看到至少有一个问题与此有关Find all class declarations than inherit from another with Roslyn,但我没有掌握它的窍门。看起来我应该注册到SymbolKind.NamedType操作,但是找到从andAnalyzeSymbol继承的函数签名的部分会是什么样子?ISomethingRoot1ISomethingRoot2

这是我目前正在做的一些代码,以使问题更清楚:

[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public class PublicInterfaceAnalyzer: DiagnosticAnalyzer
{               
    private static ImmutableArray<DiagnosticDescriptor> SupportedRules { get; } = 
        new ImmutableArray<DiagnosticsDescriptor>(new DiagnosticDescriptor(id: "CheckId1",
            title: "Check1",
            messageFormat: "Placeholder text",
            category: "Usage",
            defaultSeverity: DiagnosticSeverity.Warning,
            isEnabledByDefault: true));

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

    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => SupportedRules;


    private void AnalyzeSymbol(SymbolAnalysisContext context)
    {                     
        //How to check that the functions have, say, a certain kind of
        //of a return value or parameters or naming? I think I know how
        //to do that, but I'm not sure how to get a hold of the correct
        //interfaces and have a collection or their (public) methods to check.

        //This could be one way to go, but then in Initialize
        //should be "SymbolKind.Method", would that be the route to take?
        //The following omits the code to get the interfaces and do some
        //of the checks as this is code in progress and the main problem
        //is getting hold of the function signatures of interfaces that  
        //inherit from the marker interfaces.
        var symbol = (IMethodSymbol)context.Symbol;                                   
        context.ReportDiagnostic(Diagnostic.Create(SupportedRules[0], symbol.Locations[0], symbol.Name));          
    }                                        
}
4

1 回答 1

2

您可以通过以下方式获得对标记界面的引用:

var marker1 = context.SemanticModel.Compilation.GetTypeByMetadataName("NS.ISomethingRoot1");

然后,如果您在SymbolActionfor 中NamedTypes,您可以检查当前处理的符号是否实现了此功能marker1

var symbol = context.Symbol as INamedTypeSymbol;
var implements = symbol.AllInterfaces.Any(@interface => @interface.Equals(marker1));

然后你可以做任何你想做的检查类型的成员。您可以通过调用获得成员symbol.GetMembers()

于 2015-11-23T07:33:18.297 回答