2016-11-09 38 views
1

我試圖從我的CS文件中使用Roslyn和Im解壓縮部分代碼,它遭受以下問題。#if在roslyn中解析指令代碼

我的C#代碼文件:

class ConditionalCompilationCode 
    { 
#if Condition2 
      int test2=0; 
#endif 
#if Condition1 
      int test1=0; 
#endif 

     public static void Main1(string[] args) 
     { 
      int test = 0; 
#if Condition1 
      test = 1; 
#else 
      test =2; 
#endif 

#if Condition2 
      test =3; 
#else 
      test = 4; 
#endif 

     } 
#if Condition2 
      private void testmethod1() 
     { 
      test2 = 1; 
     } 
#endif 
#if !Condition2 
     private void testmethod2() 
     { 
      test1 = 1; 
     } 
#endif 
#if Condition1 
     private void testmethod3() 
     { 
      test1 = 1; 
     } 
#endif 
#if !Condition1 
      private void testmethod4() 
     { 
      test2 = 1; 
     } 
#endif 
    } 
} 

我羅斯林代碼:

string fileContent = File.ReadAllText(fileName); 

SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(fileContent); 

var syntaxRootNode = syntaxTree.GetRoot(); 
      if (syntaxRootNode.GetFirstToken().Kind() == SyntaxKind.None) 
       return; 
      foreach (NamespaceDeclarationSyntax namespaceSyntax in syntaxRootNode.DescendantNodes().OfType<NamespaceDeclarationSyntax>().ToArray()) 
      { 

       IEnumerable<SyntaxNode> nodeList = namespaceSyntax.ChildNodes(); 
       string className = null; 
       foreach (SyntaxNode syntaxNode in nodeList) 
       { 
        SyntaxKind kind = syntaxNode.Kind(); 
        switch (kind) 
        { 
         case SyntaxKind.ClassDeclaration: 
          UpdateClassSignature(syntaxNode as TypeDeclarationSyntax);        
          break; 
         case SyntaxKind.EnumDeclaration: 

          break; 
         case SyntaxKind.InterfaceDeclaration: 

          break; 
         case SyntaxKind.StructDeclaration: 

          break; 

        } 

       } 

      } 

    private void UpdateClassSignature(TypeDeclarationSyntax classDeclarationSyntax) 
     { 

      foreach (MemberDeclarationSyntax member in classDeclarationSyntax.Members) 
      { 
       SyntaxKind kind = member.Kind(); 
       switch (kind) 
       { 
        case SyntaxKind.FieldDeclaration: 
         break; 
        case SyntaxKind.PropertyDeclaration: 
         break; 
        case SyntaxKind.MethodDeclaration: 
        case SyntaxKind.ConstructorDeclaration: 
        case SyntaxKind.DestructorDeclaration: 
         break; 
        case SyntaxKind.IndexerDeclaration: 
         ExtractIndexer(member as IndexerDeclarationSyntax, classSign); 
         break; 
        case SyntaxKind.DelegateDeclaration: 
         //TODO: Add Delegate Support. 
         break; 
        case SyntaxKind.OperatorDeclaration: 
        case SyntaxKind.ConversionOperatorDeclaration: 
         //Skip. 
         //TODO: Need to add operator suport. 
         break; 
        case SyntaxKind.EventFieldDeclaration: 
         //TODO: Add support to event. 
         break; 
        case SyntaxKind.EventDeclaration: 
         //TODO: Add support to event. 
         break; 
        case SyntaxKind.EnumDeclaration: 
         break; 
        case SyntaxKind.ClassDeclaration: 
         break; 
        case SyntaxKind.StructDeclaration: 
         break; 
        default: 
         break; 
       } 
      } 
     } 

在處理上述CS文件使用羅斯林,在classDeclarationSyntax.Members包含以下三個值:

  1. MethodDeclarationSyntax MethodDeclaration

    public static void Main1(string[] args) 
    { 
        int test = 0; 
        #if Condition1 
        test = 1; 
        #else 
        test =2; 
        #endif 
    
        #if Condition2 
        test =3; 
        #else 
        test = 4; 
        #endif 
    
    } 
    
  2. MethodDeclarationSyntax MethodDeclaration

    private void testmethod2() 
    { 
        test1 = 1; 
    } 
    
  3. MethodDeclarationSyntax MethodDeclaration

    private void testmethod4() 
    { 
        test2 = 1; 
    } 
    

我的項目有 「條件1」 指令孤單。只有當條件有「條件1」時,你能幫助我獲得代碼嗎?

在此先感謝。

+0

你想用這個做什麼?你想過濾一個條件分支左右嗎? – Ties

+0

@Ties我只想解析我的CS文件並在分析的語法樹中處理活動代碼。 –

回答

4

您需要通過調用WithPreprocessorSymbols()的,將要定義的符號傳遞給解析器。

+0

感謝您的幫助,它的工作。請參考以下代碼: 列表 preProcessorSymbols =新列表(); preProcessorSymbols.Add(「Condition1」); CSharpParseOptions options = CSharpParseOptions.Default; // new CSharpParseOptions(LanguageVersion.CSharp6,DocumentationMode.Parse,SourceCodeKind.Regular,preProcessorSymbols); options = options.WithPreprocessorSymbols(preProcessorSymbols);語法樹語法樹= CSharpSyntaxTree.ParseText(fileContent,options);' –