Is there anyway to get MethodDeclarationSyntax based on InvocationExpressionSyntax in Roslyn?

I want to write code refactor by roslyn so I wrote a code like

class Program
{
    [Obsolete()]
    public static void A() { }

    static void Main(string[] args)
    {
        A(); // I moved the mouse here and captured as InvocationExpressionSyntax 
        Console.WriteLine("Hello World!");
    }
}

I selected A() as InvocationExpressionSyntax so I want to know Can I get MethodDeclarationSyntax or better Attributes of the selected method.

means

public static void A() { }

or

[Obsolete()]

Is it possible ?

I want to find all attributes of a method for refactoring purpose.

EDIT

public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
{
    // TODO: Replace the following code with your own analysis, generating a CodeAction for each refactoring to offer

    var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

    // Find the node at the selection.
    var node = root.FindNode(context.Span);

    // Only offer a refactoring if the selected node is a type declaration node.
    var typeDecl = node.Parent as InvocationExpressionSyntax;
    if (typeDecl == null)
    {
        return;
    }

    // For any type declaration node, create a code action to reverse the identifier text.
    var action = CodeAction.Create("Reverse type name", c => ReverseTypeNameAsync(context.Document, typeDecl, c));

    // Register this code action.
    context.RegisterRefactoring(action);
}

EDIT 2

ClassLibrary1 :

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
    public class CustomAttribute : Attribute
    {}

ClassLibrary2

public static class Class1
{
    [CustomAttribute] // Comes from ClassLibrary1
    public static string SayHelloTo(string name)
    {
        return $"Hello {name}";
    }

Code Refactor Project :

class Program
{
    [Obsolete()]
    public static void A() { }

    static void Main(string[] args)
    {
        A(); // I moved the mouse here and captured as InvocationExpressionSyntax 
        var t = ClassLibrary2.Class1.SayHelloTo("Test");  // ????? Symbol is NULL ?????
    }
 }
Jon Skeet
people
quotationmark

I suspect you just want to get the semantic model, ask it for the symbol, and get the attributes:

// After you've made sure that you've got an InvocationExpressionSyntax
var model = await context.Document
    .GetSemanticModelAsync(context.CancellationToken)
    .ConfigureAwait(false);
var symbol = model.GetSymbolInfo(invocation);
var attributes = symbol.Symbol?.GetAttributes();
// Examine attributes; it will be null if the symbol wasn't resolved

I don't know how expensive it is to get the semantic model - there may be more performant alternatives, but I'd expect this to at least work.

people

See more on this question at Stackoverflow