Как генерировать код C # из ICompilationUnit (ICSharpCode) - PullRequest
0 голосов
/ 24 марта 2011

Я пытаюсь обновить существующий код 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

Что я хотел бы сделать, это сгенерировать код C # из visitor.Cu. Есть ли способ генерировать код C # из ICompilationUnit?

1 Ответ

2 голосов
/ 24 марта 2011

Вы добавляете метод как IMethod - IMethod просто представляет метод как объект DOM вместе с некоторой информацией о его сигнатуре (без какого-либо кода) - поэтому я не вижу, как вы сможете генерировать C # код из него ...

(если вы не имеете в виду создание кода только для сигнатуры метода? В этом случае вам следует обратиться к классу ICSharpCode.SharpDevelop.Dom.Refactoring.CodeGenerator для преобразования DOM-> AST, в частности, к методу ConvertMember(IMethod m, ClassFinder targetContext)).

Ваш CompilationUnit , однако, является абстрактным синтаксическим деревом файла кода и может быть легко преобразован обратно в код C # / VB.NET с использованием классов CSharpOutputVisitor и VBNetOutputVisitor.

Вы можете добавить MethodDeclaration, представляющий код вашего метода, в TypeDefinition, представляющий некоторый класс в исходном файле, а затем использовать вышеупомянутых выходных посетителей для генерации кода с вставленным новым методом.

Для вашего удобства я прилагаю метод расширения PrettyPrint, который полезен при работе по преобразованию INodes в код:

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