【问题标题】:#if directive code parsing in roslynroslyn 中的 #if 指令代码解析
【发布时间】:2016-11-09 08:42:25
【问题描述】:

我尝试使用 Roslyn 从我的 CS 文件中提取部分代码,但遇到了以下问题。

我的 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
    }
}

我的 roslyn 代码:

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;
                }
            }
        }

在使用 roslyn 处理上述 CS 文件时,在类DeclarationSyntax.Members 中包含以下三个值:

  1. MethodDeclarationSyntax 方法声明

    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 方法声明

    private void testmethod2()
    {
        test1 = 1;
    }
    
  3. MethodDeclarationSyntax 方法声明

    private void testmethod4()
    {
        test2 = 1;
    }
    

我的项目只有“Condition1”指令。仅当条件只有“Condition1”时,您能帮我获取代码吗?

提前致谢。

【问题讨论】:

  • 你想用这个实现什么?你要过滤掉一个条件分支吗?
  • @Ties 我只想解析我的 CS 文件并处理解析后的语法树中的活动代码。

标签: c# roslyn roslyn-code-analysis


【解决方案1】:

您需要传递一个调用WithPreprocessorSymbols()CSharpParseOptions 以将您要定义的符号传递给解析器。

【讨论】:

  • 感谢您的帮助。请参考以下代码: List preProcessorSymbols = new List(); preProcessorSymbols.Add("Condition1"); CSharpParseOptions options = CSharpParseOptions.Default;// new CSharpParseOptions(LanguageVersion.CSharp6, DocumentationMode.Parse, SourceCodeKind.Regular, preProcessorSymbols); options = options.WithPreprocessorSymbols(preProcessorSymbols); SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(fileContent, options);'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-21
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
相关资源
最近更新 更多