2015-08-24 8 views
1

我正在使用並試圖找出代碼分析服務。在我的學習過程中,我想創建一個分析器,當將using語句放置在代碼文件的頂部時,而不是在名稱空間聲明中時,會導致出現警告。我還希望IDE爲我提供一個快捷方式,以便輕鬆修復錯誤代碼。CodeFixProvider派生類:如何正確地格式化在新塊中移動的代碼?

例如,每當代碼分析工具見此:

using System; 
using System.Collections.Generic; 

namespace MyNamespace 
{ 
    class TypeName 
    { 
    } 
} 

...我想讓它顯示一個警告,並建議把它變成這樣:

namespace MyNamespace 
{ 
    using System; 
    using System.Collections.Generic; 

    class TypeName 
    { 
    } 
} 

我設法得到我的分析儀類(從DiagnosticAnalyzer派生)像我想要的那樣工作。 我現在的主要問題是CodeFixProvider派生類

從技術上講,現在它起作用了;語句下移到名稱空間聲明。但格式不太好。下面是我在嘗試修復上面的第一個代碼塊時實際得到的結果:

* 
namespace ConsoleApplication1 
{ 

    using System; 
    using System.Collections.Generic; 
    class TypeName 
    { 
    } 
} 

星號字符表示剩餘的回車符。還要注意在第一個命名空間括號後面有一個換行符,而在使用語句和類聲明之間沒有。我希望該線條向下移動並坐在課堂之上。

這裏是(內部的利益部分)我CodeFixProvider派生類代碼:

public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) 
{ 
    foreach (var diagnostic in context.Diagnostics) 
    { 
     context.RegisterCodeFix(
      CodeAction.Create(
       title: Title, 
       createChangedDocument: c => ProvideDocumentAsync(context.Document, c), 
       equivalenceKey: Title), 
      diagnostic); 
    } 
} 

private async Task<Document> ProvideDocumentAsync(Document document, CancellationToken cancellationToken) 
{ 
    var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) as CompilationUnitSyntax; 

    if (root == null) return null; 

    var newRootUsings = new SyntaxList<UsingDirectiveSyntax>(); 
    var newRoot = root.WithUsings(newRootUsings); 

    foreach (var namespaceDecl in newRoot.Members.OfType<NamespaceDeclarationSyntax>()) 
    { 
     NamespaceDeclarationSyntax newNsDecl = namespaceDecl; 

     foreach (var statement in root.Usings) 
     { 
      var newStatement = statement.WithLeadingTrivia(statement.GetLeadingTrivia().Union(new[] { Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Whitespace(" ") })); 

      newNsDecl = newNsDecl.AddUsings(newStatement); 
     } 

     newRoot = newRoot.ReplaceNode(namespaceDecl, newNsDecl); 
    } 

    return document.WithSyntaxRoot(newRoot); 
} 

正如你可以看到我也沒搞清楚,如何添加額外的壓痕(帶GetLeadingTrivia法)。我想我可以爲額外的線路做同樣的事情,但不知何故,我覺得可能還有一種我還沒有意識到的更好的方式,用這些新的代碼分析/重構工具變得很綠。

那麼,關於如何使格式化或任何其他方面的任何指導更好?

UPDATE:

它只是發生在我今天的「權利」的格式爲羅斯林代碼修復提供商內申請應該是默認的代碼編輯器應用的一個(在我的情況下,Visual Studio 2015),擁有自己的一套規則。

我的理解是,編譯器引擎中的Formatter類可以允許「暗示」代碼編輯器,以便某些節點/文本區域需要格式化。試圖對代碼進行格式化的代碼修復可能會做得太多。

如果有人認爲我錯了,那麼非常歡迎您的加入。我仍然在與羅斯林一起訓練車輪並願意學習。

回答

2

添加.WithAdditionalAnnotations(Formatter.Annotation)告訴Roslyn自動格式化您的更改。

+0

在哪個元素上? – Crono

+0

@Crono:任何包含所有要格式化的節點的祖先。 – SLaks

+0

所以這將是根本因素,因爲我想擺脫剩餘的頭號線。但這將如何影響不變的節點?例如,如果我在'TypeName'類中聲明瞭一個方法,它會被重新格式化嗎? – Crono

相關問題