如何从 ICompilationUnit 生成 C# 代码 (ICSharpCode)

发布于 2024-10-26 16:31:02 字数 616 浏览 2 评论 0原文

我正在尝试更新现有的 C# 代码。使用 ICSharpCode.NRefactory.IParser 解析代码。我的系统广泛使用 ICompilationUnit 来探索现有代码。

现在,我想向现有文件添加一个方法并将其作为 C# 代码保存回磁盘。到目前为止,我已经:

CompilationUnit compilationUnit = GetCompilationUnit();
var visitor = new NRefactoryASTConvertVisitor(new ParseProjectContent());
compilationUnit.AcceptVisitor(visitor, null);
IMethod method = //GetMethod from otherplace
visitor.Cu.Classes[0].Methods.Add(method);
// How the updated visitor.Cu be transformed to C# code

我想做的是从 visitor.Cu 生成 C# 代码。有没有办法从 ICompilationUnit 生成 C# 代码?

I'm trying to update an existing C# code. The code is parsed using ICSharpCode.NRefactory.IParser. My system is using widely ICompilationUnit to explore existing code.

Now, I want to add a method to an existing file and save it back to disk as C# code. So far I have:

CompilationUnit compilationUnit = GetCompilationUnit();
var visitor = new NRefactoryASTConvertVisitor(new ParseProjectContent());
compilationUnit.AcceptVisitor(visitor, null);
IMethod method = //GetMethod from otherplace
visitor.Cu.Classes[0].Methods.Add(method);
// How the updated visitor.Cu be transformed to C# code

What I'd like to do is to generate C# code from visitor.Cu. Is there a way to generate C# code from ICompilationUnit?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尘世孤行 2024-11-02 16:31:02

您将该方法添加为 IMethod - IMethod 只是将方法表示为 DOM 实体以及有关其签名的一些信息(没有任何代码) - 所以我不知道您如何能够从中生成 C# 代码...

(除非您的意思是仅为方法的签名生成代码?在这种情况下,您应该查看 ICSharpCode.SharpDevelop.Dom.Refactoring.CodeGenerator 类以进行 DOM->AST 转换,特别是 ConvertMember(IMethod m,ClassFinder targetContext) 方法)。

然而,您的 CompilationUnit 是代码文件的抽象语法树,并且可以使用 CSharpOutputVisitor 和 VBNetOutputVisitor 类轻松转换回 C#/VB.NET 代码。

您可以将表示方法代码的 MethodDeclaration 添加到表示原始文件中某个类的 TypeDefinition,然后使用上述输出访问者生成插入了新方法的代码。

为了方便起见,我附加了一个 PrettyPrint 扩展方法,该方法在将 INode 转换为代码时非常有用:

    public static string PrettyPrint(this INode code, LanguageProperties language)
    {
        if (code == null) return string.Empty;
        IOutputAstVisitor csOutVisitor = CreateCodePrinter(language);
        code.AcceptVisitor(csOutVisitor, null);
        return csOutVisitor.Text;
    }

    private static IOutputAstVisitor CreateCodePrinter(LanguageProperties language)
    {
        if (language == LanguageProperties.CSharp) return new CSharpOutputVisitor();
        if (language == LanguageProperties.VBNet) return new VBNetOutputVisitor();
        throw new NotSupportedException();
    }

    public static string ToCSharpCode(this INode code)
    {
        return code.PrettyPrint(LanguageProperties.CSharp);
    }

You're adding the method as an IMethod - an IMethod just represents a method as a DOM entity along with some information about its signature (without any code) - so I don't see how you would be able to generate C# code from it...

(unless you mean generating code just for the method's signature? in which case you should look into the class ICSharpCode.SharpDevelop.Dom.Refactoring.CodeGenerator for the DOM->AST conversion, specifically the ConvertMember(IMethod m, ClassFinder targetContext) method).

Your CompilationUnit, however, is the Abstract Syntax Tree of the code file, and can easily be converted back to C#/VB.NET code using the CSharpOutputVisitor and VBNetOutputVisitor classes.

You could add a MethodDeclaration that represents your method's code to a TypeDefinition which represents some class in the original file, and then use the aforementioned output visitors to generate the code with your new method inserted.

For your convinience I'm attaching a PrettyPrint extension method that is useful when working on converting INodes to code:

    public static string PrettyPrint(this INode code, LanguageProperties language)
    {
        if (code == null) return string.Empty;
        IOutputAstVisitor csOutVisitor = CreateCodePrinter(language);
        code.AcceptVisitor(csOutVisitor, null);
        return csOutVisitor.Text;
    }

    private static IOutputAstVisitor CreateCodePrinter(LanguageProperties language)
    {
        if (language == LanguageProperties.CSharp) return new CSharpOutputVisitor();
        if (language == LanguageProperties.VBNet) return new VBNetOutputVisitor();
        throw new NotSupportedException();
    }

    public static string ToCSharpCode(this INode code)
    {
        return code.PrettyPrint(LanguageProperties.CSharp);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文