简体   繁体   English

如何使用 Roslyn 将 SyntaxTree 或 UnitCompilationRoot 包装在区域或注释中?

[英]How can I wrap a SyntaxTree or UnitCompilationRoot in a region or comment using Roslyn?

I'm using CSharpSyntaxTree.ParseText to create a syntax tree from an arbitrary block of code;我正在使用CSharpSyntaxTree.ParseText从任意代码块创建语法树; I'd like to be able to wrap or encapsulate either that SyntaxTree or its UnitCompilationRoot in a region.我希望能够将该SyntaxTree或其UnitCompilationRoot包装或封装在一个区域中。 I'm aware of the Quoter website that allows you to see how any arbitrary code could be written using the Roslyn API, but the way it breaks down the code into its raw components doesn't help with the use-case of adding a region to a SyntaxTree or UnitCompilationRoot .我知道 Quoter 网站允许您查看如何使用 Roslyn API 编写任意代码,但是它将代码分解为其原始组件的方式无助于添加区域的用例到SyntaxTreeUnitCompilationRoot

Example using arbitrary code使用任意代码的示例

// Create syntax tree from template
var str = @"public class Foo { }"
var syntaxTree = CSharpSyntaxTree.ParseText(str);

// Add Region
// ????

Regions are represented by Roslyn as special kind of SyntaxTrivia .区域由 Roslyn 表示为特殊类型的SyntaxTrivia So for the purpose of wrapping block of code into region you may get target SyntaxNode and replace it's leading and trailing trivia with regions trivia.因此,为了将代码块包装到区域中,您可以获取目标SyntaxNode并将其前导和尾随琐事替换为区域琐事。 The following code demonstrates how this can be done:以下代码演示了如何做到这一点:

public static T AddRegion<T>(this T node, string regionName) where T : SyntaxNode
{
    return node
        // inserts #region RegionName before node
        .WithLeadingTrivia(node.GetLeadingTrivia().Insert(0, GetRegionLeadingTrivia(regionName)))
        // inserts #endregion after node
        .WithTrailingTrivia(node.GetTrailingTrivia().Add(GetRegionTrailingTrivia()));
}

public static SyntaxTrivia GetRegionLeadingTrivia(string regionName)
{
    return SyntaxFactory.Trivia(
        SyntaxFactory
            .RegionDirectiveTrivia(true)
            .WithEndOfDirectiveToken(
                SyntaxFactory.Token(
                    SyntaxFactory.TriviaList(SyntaxFactory.PreprocessingMessage(regionName)),
                    SyntaxKind.EndOfDirectiveToken,
                    SyntaxFactory.TriviaList())));
}

public static SyntaxTrivia GetRegionTrailingTrivia()
{
    return SyntaxFactory.Trivia(SyntaxFactory.EndRegionDirectiveTrivia(true));
}

To perform more complex operations you may use CSharpSyntaxRewriter class .要执行更复杂的操作,您可以使用CSharpSyntaxRewriter class Some examples of using that class may be found at here .可以在此处找到使用 class 的一些示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM