gpt4 book ai didi

c# - 使用 roslyn 生成语义代码

转载 作者:太空狗 更新时间:2023-10-29 18:24:53 34 4
gpt4 key购买 nike

我们尝试找出如何使用 Roslyn 生成代码。我不是在谈论像 CSharpSyntaxTree.ParseText 这样的东西,它会接受一些字符串并将它们转换成 AST。相反,我想以某种方式构建我的模型(伪代码):

  1. 创建文件作为编译单元
  2. 将类MyClass 添加到文件
  3. 将方法 DoSomething 添加到 MyClass
  4. 以类似于 System.Linq.Expressions 的方式设置 DoSomething 的主体

我们最近发现了 Microsoft.CodeAnalysis.CSharp.SyntaxFactory,它似乎很有前途。但是,显然我们必须自己添加琐事。

在使用SyntaxFactory.CompilationUnit() 构建树并来回添加一些成员后,ToFullString() 的输出只是一堆文本,即既不可读,也不可编译(例如,缺少大括号)。从模型生成文本时我们是否遗漏了什么?

编辑:

使用工作区时,您可以设置影响空白行为的选项:

public string Generate (CompilationNode rootNode)
{
var cw = new CustomWorkspace();
cw.Options.WithChangedOption (CSharpFormattingOptions.IndentBraces, true);
var formattedCode = Formatter.Format (CreateFile(rootNode), cw);
return formattedCode.ToFullString();
}

这已经产生了更好的结果。有人可以确认这是一个好的解决方案还是一个 hack?

还有一个问题。我们想要生成一个自动属性,目前使用的是 SF.AccessorDeclaration,但在转换为完整字符串时缺少分号。

最佳答案

您基本上必须添加 block 定义,然后 Roslyn 会为您处理琐事,只要您使用 Formatter(如您所写)

这是一个简单类的示例,无需我指定任何琐事即可正确生成

var consoleWriteLine = Syntax.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
Syntax.IdentifierName("Console"),
name: Syntax.IdentifierName("WriteLine"));

var arguments = Syntax.ArgumentList (
Syntax.SeparatedList (
new[]
{
Syntax.Argument (
Syntax.LiteralExpression (
SyntaxKind.StringLiteralExpression,
Syntax.Literal (@"""Goodbye everyone!""", "Goodbye everyone!")))
}));

var consoleWriteLineStatement = Syntax.ExpressionStatement (Syntax.InvocationExpression (consoleWriteLine, arguments));

var voidType = Syntax.ParseTypeName ("void");
var method = Syntax.MethodDeclaration (voidType, "Method").WithBody (Syntax.Block(consoleWriteLineStatement));

var intType = Syntax.ParseTypeName ("int");
var getterBody = Syntax.ReturnStatement (Syntax.DefaultExpression (intType));
var getter = Syntax.AccessorDeclaration (SyntaxKind.GetAccessorDeclaration, Syntax.Block (getterBody));
var property = Syntax.PropertyDeclaration (intType, "Property").WithAccessorList (Syntax.AccessorList (Syntax.SingletonList (getter)));

var @class = Syntax.ClassDeclaration ("MyClass").WithMembers (Syntax.List (new MemberDeclarationSyntax[] { method, property }));

var cw = new CustomWorkspace();
cw.Options.WithChangedOption (CSharpFormattingOptions.IndentBraces, true);
var formattedCode = Formatter.Format (@class, cw);

Console.WriteLine (formattedCode.ToFullString());

注意:Syntax = Microsoft.CodeAnalysis.CSharp.SyntaxFactory

这会生成以下类定义:

class MyClass
{
void Method()
{
Console.WriteLine("Goodbye everyone!");
}

int Property
{
get
{
return default(int);
}
}
}

看起来不错。

关于c# - 使用 roslyn 生成语义代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27842159/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com