2017-09-20 10 views
0

Roslynを使用してC#で以前のコードアナライザを変更していますが、もう少しの変更が必要です。 Finding all not inheriting C# classes with Roslyn and changing to inheriting from base object (java-like)Roslynの属性とデフォルト値を追加して関数宣言パラメータを変更する#

私が解析されてきた、すべてのメソッド宣言を見つけるためにツリーを横断し、そのパラメータ:私はこの質問で作業するためにいくつかのベースを作成しましたhttps://github.com/dotnet/roslyn/wiki/Getting-Started-C%23-Syntax-Analysis

に基づか。私はこれを構築しましVSシンタックスビジュアライザに基づか:私はメソッドを変換しようとしている

foreach (var c in root1.DescendantNodesAndSelf()) 
{ 
    var methodDeclaration = c as MethodDeclarationSyntax; 

    if (methodDeclaration == null) 
     continue; 

    if (methodDeclaration.ParameterList != null) //Have parameters 
    { 
     foreach (var p in methodDeclaration.ParameterList.Parameters) 
     { 
      var parameter = p as ParameterSyntax; 
      String name, type; 
      name = parameter.GetLastToken().Value.ToString(); 
      type = parameter.GetFirstToken().Value.ToString(); 

      if (parameter == null) 
       continue; 

      if (name == "caller" && type == "string") 
      { 
       AttributeSyntax ats = SyntaxFactory.Attribute(SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System.Runtime.CompilerServices"),SyntaxFactory.IdentifierName("CallerMemberName"))); 
       SeparatedSyntaxList<AttributeSyntax> ssl = new SeparatedSyntaxList<AttributeSyntax>(); 
       ssl = ssl.Add(ats); 
       AttributeListSyntax als = SyntaxFactory.AttributeList(ssl); 
       var par1 = parameter.AddAttributeLists(als); 
       //ExpressionSyntax es = SyntaxFactory.AssignmentExpression(SyntaxKind.EqualsValueClause,null,SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression)) 
       //SyntaxFactory.EqualsValueClause(es); 
       par1 = par1.AddModifiers(); 
       root2 = root2.ReplaceNode(parameter, par1); 
      } 
     } 
    } 
    else //Don't have parameters 
     continue; 

} 

すると、このように宣言:

private void testM3([System.Runtime.CompilerServices.CallerMemberName] string caller = "") 

そして、この部分に

private void testM3(string caller) 

は、私の失敗の試みですequalsノードの作成

私が理解から、この部分:

AttributeSyntax ats = SyntaxFactory.Attribute(SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System.Runtime.CompilerServices"),SyntaxFactory.IdentifierName("CallerMemberName"))); 
SeparatedSyntaxList<AttributeSyntax> ssl = new SeparatedSyntaxList<AttributeSyntax>(); 
ssl = ssl.Add(ats); 
AttributeListSyntax als = SyntaxFactory.AttributeList(ssl); 
var par1 = parameter.AddAttributeLists(als); 

は私に既に属性が含まvar par1における新しいパラメータノードを与えるので、私は、デフォルト値の設定を追加する必要があります。私はこの属性について間違っている場合は私を修正してください、私はこれを表現ノードを正しく構築する方法を知りたいです。

答えて

1

は、次の2つのミスがあります

  • System.Runtime.CompilerServices.CallerMemberName

    IdentifierNameとして修飾名CallerMemberNameとしてSystem.Runtime.CompilerServicesが含まれている修飾名です。 System.Runtime.CompilerServices IdentifierNameとしてSystem.Runtimeとして修飾名CompilerServicesが含まれています。最後にSystem.Runtimeには、2つの識別子名が含まれています。

    だからあなたは以下のコードに示されているようAttributeSyntaxの作成を修正する必要があります。

    AttributeSyntax ats = SyntaxFactory.Attribute(
             SyntaxFactory.QualifiedName(
              SyntaxFactory.QualifiedName(
               SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Runtime")), 
               SyntaxFactory.IdentifierName("CompilerServices")), 
             SyntaxFactory.IdentifierName("CallerMemberName"))); 
    
  • EqualsValueClauseAssignmentExpressionを含めることはできませんが、直接LiteralExpressionのいくつかの種類が含まれていなければなりません。お使いの場合には、それはStringLiteralExpressionです:

    var par1 = parameter 
            .AddAttributeLists(als) 
            .WithDefault(SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("")))); 
    

ところでお好きな時に、あなたは(SyntaxTreeはロザリン不変である)ノードのコピーを作成するために、たとえばParameterSyntax.WithDefaultとして、ノードのいくつかの有用な方法を使用することができます既存のノードに小さな変更をアプライしてからそれをrepaceします。

0

次のメソッドのRoslyn Quoterを見てみる場合は、目的のコードを生成するために必要なコードを入手することができます。

public void GetSomething([CallerMemberName] string test=""){ 

} 

あなたはパラメータのデフォルト値は以下を用いて構成されていることがわかりますこの方法は、(ロザリンクォータは通常SyntaxFactoryを省略):

.WithDefault(SyntaxFactory.EqualsValueClause(
        SyntaxFactory.LiteralExpression(
          SyntaxKind.StringLiteralExpression, 
          SyntaxFactory.Literal("") 
          ) 
        ) 
      ); 

だから、あなたは自分のパラメータに上記のコードを呼び出すことにより、既存のデフォルトを交換する必要がデフォルト(代わりのUNCとしてあなたEqualsValueClauseを追加するためにommentedコード):

par1 = par1.WithDefault(SyntaxFactory.EqualsValueClause(
        SyntaxFactory.LiteralExpression(
          SyntaxKind.StringLiteralExpression, 
          SyntaxFactory.Literal("") 
          ) 
        ) 
      ); 
関連する問題