Всем привет!
Хочу поделиться своим опытом работы с генераторами.
Несколько лет назад игрался с аналогичной библиотекой для генерации кода
CodeGenerator.Roslyn
Ради эксперимента потратил пару дней чтобы попробовать сделать не только генерацию а возможность модификации исходного кода.
Вот что получилось в итоге.
Пример:
[TryCatchOrdered(ExecutionOrder = 1)]
[DuplicateWithSuffixByNameOrdered("t", ExecutionOrder = 2)]
[RemoveOrdered(ExecutionOrder = 3)]
public partial class Foo
{
[DuplicateWithSuffixByNameOrdered("t", ExecutionOrder = 1)]
public object `Prop1;
[DuplicateWithSuffixByNameOrdered("k", ExecutionOrder = 1)]
public int? Prop2;
public void Test()
{
var aa = 1;
var dd = 3;
var bb = 0;
var cc = aa / bb;
}
}
После трансформации код заменяется на:
[TryCatchOrdered(ExecutionOrder = 1)]
[DuplicateWithSuffixByNameOrdered("t", ExecutionOrder = 2)]
[RemoveOrdered(ExecutionOrder = 3)]
public partial class Foot
{
[DuplicateWithSuffixByNameOrdered("t", ExecutionOrder = 1)]
public object Prop1;
[DuplicateWithSuffixByNameOrdered("t", ExecutionOrder = 1)]
public object Prop1t;
[DuplicateWithSuffixByNameOrdered("k", ExecutionOrder = 1)]
public int? Prop2;
[DuplicateWithSuffixByNameOrdered("k", ExecutionOrder = 1)]
public int? Prop2k;
public void Test()
{
try
{
var aa = 1;
var dd = 3;
var bb = 0;
var cc = aa / bb;
}
catch (Exception ex)
{
}
}
}
Что происходит в результате трансформации:
1) Вначале применяются все атрибуты для нижнего уровня свойства методы и т.д.
В данном случае атрибут DuplicateWithSuffixByNameOrdered служит для дублирования объявления свойства или класса с другим именем — к имени добавляется суффикс
2) Потом применяются все атрибуты для классов:
Атрибут TryCatchOrdered — модифицирует все методы класса оборачивая содержимое в try {} catch {} (чисто для примера)
Атрибут DuplicateWithSuffixByNameOrdered — для дублирования класса с другим именем
Атрибут RemoveOrdered — для удаления исходного класса с именем Foo (если его убрать то будет 2 класса Foo и Foot)
В принципе метод рабочий, чтобы заставить работать пришлось сильно пободаться с иммутабельностью в Roslyn

Если развивать дальше то можно сделать поддержку AOP, макросов и других вещей.
Единственный непонятный момент что делать с отладкой сгенерированного кода.
P.S. На исходном форуме мое сообщение особого интереса не вызвало и проект я забросил.
Кому интересно можно поиграться с проектом в репе:
https://github.com/GoldyD/CodeGeneration.Roslyn