2017-05-14 68 views
0

我想寫由羅斯林代碼重構,所以我寫了這樣的代碼有沒有辦法根據Roslyn中的InvocationExpressionSyntax獲取MethodDeclarationSyntax?

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

我選擇A()爲InvocationExpressionSyntax,所以我想知道我能否獲得MethodDeclarationSyntax或所選擇的方法的更好的屬性。

意味着

public static void A() { } 

[Obsolete()] 

這可能嗎?

我想找到重構目的的方法的所有屬性。

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

編輯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}"; 
    } 

代碼重構項目:

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 ????? 
    } 
} 
+1

這是什麼情況?我相信你基本上想獲得'SemanticModel'並調用'model.GetSymbolInfo(invocation)'。這將解析符號,然後你可以在符號上調用'GetAttributes()'。但你確實需要語義模型...... –

+0

@JonSkeet,我編輯了我的帖子,示例來自代碼重構VS模板我得到'var typeDecl = node.Parent作爲InvocationExpressionSyntax;'但是你說我需要SemanticModel,所以我該如何?你能解釋更多基於上述來源? –

+0

那麼給一個'Document',你可以調用'Document.GetSemanticModelAsync' ... –

回答

0

我懷疑你只是想要得到的語義模型,問它的符號,並獲得屬性:

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

我不不知道獲得語義模型有多昂貴 - 可能會有更多高性能的替代品,但我預計這至少可以起作用。

+0

謝謝,你的解決方案完美適用於上面的示例,但我在單獨的程序集中定義的屬性和在另一個程序集中編程的方法,我想獲取GetAttributes ()在當前項目中使用該方法似乎不起作用。如你所說,它是空的。你有解決方案嗎 ?它是否適用於外部源代碼?我再次編輯我的帖子 –

+0

@ user7489391:這不是Stack Overflow的工作原理 - 你不會不斷改變你的要求。這不是一個交互式調試會話。我希望'GetAttributes()'可以很好地處理來自其他程序集的方法和屬性,只要編譯器可以解決它們。 –

相關問題