2017-02-09 19 views
0

私は、.NET Compiler Platform(Roslyn)を使用してコードを修正してコードアナライザを作成しています。 FieldDeclarationSyntaxは、前のStackoverflowの質問のコードサンプルに基づいて、1行に複数のフィールド宣言を持つことができることを知っているので、すべての(密封されていない)パブリックフィールドを別の自動プロパティに変換する必要があります。フィールド宣言をroslynの別の自動プロパティに変換するにはどうすればよいですか?

複数のフィールド宣言のこの事実は、ここで議論されている:私はこれにコードの定着を持ちたい

public int AnyNumericField = 0; 
    public string AnyStringField = ""; 
    // multiple field declaration sample 
    public int field1, field2, field3 = 0; 
    public StringBuilder sb1 = new StringBuilder(); 

::私は分析するHow to get a Roslyn FieldSymbol from a FieldDeclarationSyntax node?

のサンプルコードは、このです

public int AnyNumericField { get; set; } = 0; 
    public string AnyStringField { get; set; } = ""; 
    // multiple field declaration sample 
    public int field1 { get; set; } = 0; 
    public int field2 { get; set; } = 0; 
    public int field3 { get; set; } = 0; 
    public StringBuilder sb1 { get; set; } = new StringBuilder(); 

私の現在のアナライザーコードはこれです:

private void AnalyzePublicField(SymbolAnalysisContext context) 
    { 
     var aPublicField = (IFieldSymbol)context.Symbol; 
     if ((aPublicField.DeclaredAccessibility == Accessibility.Public) && (!aPublicField.IsSealed)) 
     { 
      var diagnostic = Diagnostic.Create(RuleCA1501, aPublicField.Locations[0], aPublicField.Name); 

      context.ReportDiagnostic(diagnostic); 
     } 
    } 

私の質問は、このためにコードフィーダを書くにはどうすればいいですか?フィールドシンボルの代わりにFieldDeclarationSyntaxを渡すようにアナライザを変更する必要がありますか? 複数のフィールド宣言の行を個別の自動プロパティに変換/変換する方法の具体的なサンプルが見つかりません。

UPDATE 1: これまでのところ、このコードを使用して、自動プロパティを構築するための私の理解:

   PropertyDeclarationSyntax @propSymbol = SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(fieldSymbol.MetadataName), memberName).AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); 

       @propSymbol = @propSymbol.AddAccessorListAccessors(
        SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) 
         .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken) 
         )); 
       @propSymbol = @propSymbol.AddAccessorListAccessors(
        SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) 
        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken) 
        )); 

PropertyDeclarationSyntaxためのコードは、この記事に触発されていますcodefixでhttps://dogschasingsquirrels.com/2014/08/04/code-generation-with-roslyn-fields-and-properties/

答えて

0

、あなたは次のコードを使用してVariableDeclarationSyntaxにアクセスできます。

var diagnostic = context.Diagnostics.First(); 
var diagnosticSpan = diagnostic.Location.SourceSpan; 
var syntaxNode = root.FindNode(diagnosticSpan); 
var variableDeclarator = syntaxNode.FirstAncestorOrSelf<VariableDeclaratorSyntax>(); 
var variableDeclaration = variableDeclarator?.Parent as VariableDeclarationSyntax; 

この宣言には多くの宣言子が含まれていますが、それらのすべてが同じ可視性と修飾子を共有しているため、すべてを修正する必要があります。これは対応するプロパティを生成することを意味し、上記のvariableDeclarationを生成されたプロパティに置き換える必要があります。 https://github.com/SonarSource-VisualStudio/sonaranalyzer-dotnet/blob/master/src/SonarAnalyzer.CSharp/Rules/MultipleVariableDeclarationCodeFixProvider.cs

はところで、私は

public int field1, field2, field3 = 0; 

がに変換されるべきだと思う:あなたは同じ宣言内で複数の変数は、自分の宣言に分割されているかのサンプルはこちらを見てしたい場合があります

public int field1 { get; set; } 
public int field2 { get; set; } 
public int field3 { get; set; } = 0; 

なく

public int field1 { get; set; } = 0; 
public int field2 { get; set; } = 0; 
public int field3 { get; set; } = 0; 

また、この変換によってコードが壊れることがあります。たとえば、フィールドをrefまたはoutとして渡すと、そのフィールドはプロパティに変更できません。

+0

コード修正プログラムプロバイダをどのように登録しますか? AFAIK、コードの修正は 'Task 'または 'Task 'を返すべきです。私はあなたが指しているコードでそれを見ていない。 –

+0

答えにリンクされたソースコード、特にベースクラスを見てください。標準のRoslynメカニズムを使用する必要があります。したがって、 'CodeFixProvider'で' Task RegisterCodeFixesAsync'をオーバーライドし、その変更を 'context.RegisterCodeFix'で登録する必要があります。 – Tamas

+0

OK、カスタムコードフィックスを最初にチェックしましょう。 –

関連する問題