C# 在Roslyn中是否有基于InvocationExpressionSyntax的MethodDeclarationSyntax?

C# 在Roslyn中是否有基于InvocationExpressionSyntax的MethodDeclarationSyntax?,c#,roslyn,C#,Roslyn,我想写roslyn的代码重构,所以我写了一个类似 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 Wo

我想写roslyn的代码重构,所以我写了一个类似

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!");
    }
}
我选择了一个()作为InvocationExpressionSyntax,所以我想知道我是否可以获取所选方法的MethodDeclarationSyntax或更好的属性

意味着

可能吗

我想找到一个方法的所有属性,以便进行重构

编辑

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);
}
编辑2

类库1:

班级图书馆2

代码重构项目:


我怀疑您只是想获取语义模型,向它索要符号,然后获取属性:

// 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

我不知道获取语义模型的成本有多高——可能有更高性能的替代方案,但我希望这至少能起作用。

您的上下文是什么?我相信您基本上希望获得
SemanticModel
并调用
model.GetSymbolInfo(调用)
。这将解析符号,然后可以对符号调用
GetAttributes()
。但是你确实需要语义模型…@JonSkeet,我编辑了我的帖子,样本来自代码重构VS模板,我得到了'var typeDecl=node.Parent as InvocationExpressionSyntax;'但你说我需要语义模型,那我该怎么做?您能否根据上述源代码进行更多解释?如果有
文档
,您可以调用
文档。GetSemanticModelAsync
…谢谢,您的解决方案对上述示例非常有效,但我在单独的程序集中定义了属性,并在另一个程序集中编程了方法,我想获得GetAttributes()从目前的项目来看,这种方法似乎不起作用。正如你所说,它是空的。你有解决办法吗?它适用于外部源代码吗?我编辑了我的帖子again@user7489391:这不是堆栈溢出的工作方式-您不必不断更改您的请求。这不是一个交互式调试会话。我希望
GetAttributes()
能够很好地处理来自其他程序集的方法和属性,只要编译器能够解析它们。
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);
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
    public class CustomAttribute : Attribute
    {}
public static class Class1
{
    [CustomAttribute] // Comes from ClassLibrary1
    public static string SayHelloTo(string name)
    {
        return $"Hello {name}";
    }
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 ?????
    }
 }
// 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