2017-09-20 29 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 :

에 내놓고.

private void testM3(string caller) 

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

에 그리고이 부분 :

내가 방법을 전환하기 위해 노력하고있어
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; 

} 

는 다음과 같이 선언 : VS 구문 영상 효과에 내놓고 나는이 건설 한

은 실패한 시도입니다. 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

당신은 두 개의 실수를 가지고 :

  • System.Runtime.CompilerServices.CallerMemberName

    IdentifierNamequalifiedName가CallerMemberNameSystem.Runtime.CompilerServices을 포함 qualifiedName가입니다. System.Runtime.CompilerServicesSystem.RuntimeCompilerServices qualifiedName가 로하고 IdentifierName이 포함되어 있습니다.그리고 마지막으로 System.Runtime은 두 개의 식별자 이름을 포함합니다. 아래 코드에 표시된대로

    그래서 당신은 AttributeSyntax의 생성을 수정해야합니다

    AttributeSyntax ats = SyntaxFactory.Attribute(
             SyntaxFactory.QualifiedName(
              SyntaxFactory.QualifiedName(
               SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Runtime")), 
               SyntaxFactory.IdentifierName("CompilerServices")), 
             SyntaxFactory.IdentifierName("CallerMemberName"))); 
    
  • EqualsValueClause

    AssignmentExpression 포함되지해야하지만해야 직접 LiteralExpression의 어떤 종류가 포함되어 있습니다. 귀하의 경우는 StringLiteralExpression의 : 그런데

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

, 당신은 노드의 복사본을 생성하는 등의 ParameterSyntax.WithDefault로, 노드의 몇 가지 유용한 방법을 사용할 수 있습니다 당신이 원하는 때 (SyntaxTree은 로슬린에 불변) 기존 노드에 작은 변경 사항을 적용한 다음 repearment합니다.

0

당신은 당신이 원하는 코드를 생성하는 데 필요한 코드를 얻을 수있는 다음 방법에 대한 Roslyn Quoter 한 번 봐 걸릴 경우 다음을

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

} 

당신은 사용하여 매개 변수의 기본값이 구성되어 있음을 알 수를 방법은합니다 (로슬린의 quoter은 일반적으로 SyntaxFactory을 생략) :

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

그래서 당신은 당신의 매개 변수에 위의 코드를 호출하여 기존의 기본을 교체해야 기본 (대신 UNC로 EqualsValueClause을 추가하려면 ommented 코드) :

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