1

How do I get the modifiers from a particular method in a class? I'm able to get the IMethodSymbol but can't find any properties referring to modifiers. I need to know whether the accessibility of the method is greater than private.

The class itself is declared in the solution and my starting point in the analyzer is a SyntaxNodeAnalysisContext.Node of type MemberAccessExpressionSyntax (SyntaxKind.SimpleMemberAccessExpression).

I was thinking I could use SyntaxGenerator but from the SyntaxNodeAnalysisContext I don't know how to traverse to a Document or solution/workspace.

silkfire
  • 24,585
  • 15
  • 82
  • 105

1 Answers1

0

The "original" C# (access) modifier is available in the "original" MethodDeclarationSyntax from the SyntaxTree, but no longer in the IMethodSymbol retrieved via the SemanticModel where that information can be read from the ISymbol.DeclaredAccessibility property which is an enum of type Accessibility.

DiagnosticAnalyzer code:

public override void Initialize(AnalysisContext context)
{
    context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
    context.EnableConcurrentExecution();

    context.RegisterSyntaxNodeAction(OnMethodDeclaration, SyntaxKind.MethodDeclaration);
    context.RegisterSyntaxNodeAction(OnSimpleMemberAccess, SyntaxKind.SimpleMemberAccessExpression);
}

private static void OnMethodDeclaration(SyntaxNodeAnalysisContext context)
{
    var methodDeclaration = (MethodDeclarationSyntax)context.Node; // public override async Task ExecuteAsync() => await Task.Yield();

    Debug.Assert(methodDeclaration.Modifiers.Count == 3); // public override async
    Debug.Assert(methodDeclaration.Modifiers[0].IsKind(SyntaxKind.PublicKeyword)); // public
    Debug.Assert(methodDeclaration.Modifiers[1].IsKind(SyntaxKind.OverrideKeyword)); // override
    Debug.Assert(methodDeclaration.Modifiers[2].IsKind(SyntaxKind.AsyncKeyword)); // async
}

private static void OnSimpleMemberAccess(SyntaxNodeAnalysisContext context)
{
    Debug.Assert(context.Node is MemberAccessExpressionSyntax); // new Class().ExecuteAsync
    SymbolInfo info = context.SemanticModel.GetSymbolInfo(context.Node);

    Debug.Assert(info.Symbol is IMethodSymbol); // Class.ExecuteAsync()
    var method = (IMethodSymbol)info.Symbol;

    Debug.Assert(method.DeclaredAccessibility == Accessibility.Public); // Public
}

Example code:

await new Class().ExecuteAsync();

public class Class : Base
{
    public override async Task ExecuteAsync() => await Task.Yield();
}
FlashOver
  • 1,855
  • 1
  • 13
  • 24