Здравствуйте, Sinclair, Вы писали:
S>·>Ок. На самом деле на входе не Program.cs, а его AST. Ну тогда байткод, конечно сложнее будет анализировать (ибо он даже к яп не привязан). Впрочем подменить вызов метода на какой-то другой — довольно просто и в байткоде. S>Это-то как раз да, но для начала нужно этот новый метод откуда-то взять. И вот получить его из AST на порядок проще, чем синтезировать из байт-кода. Я вот в своём проекте начинал как раз со сшивки байт-кода, но быстро упёрся в неразрешимые проблемы. А с AST всё получилось как надо.
Просто меня немного удивляет сама идея — мы пишем на ЯП вроде как высокого уровня — но получается хрень, что приходится потом подправлять. Ну ведь ЯП же высокого уровня — значит можно писать же нормально сразу?
А манипуляции с байткодом вроде как более менее понятны — именно какие-то низкоуровневые штуки, инструментация, типа обернуть что-нибудь как-нибудь с целью логгирования или типа того, AOP какой-нибудь.
Править же код на c# — это кажется дикостью. c# пишут человеки для человеков в первую очередь. Если на нём нельзя написать нормально что тебе хочется — есть другие ЯП.
S>·>Тут будет вопрос как можно будет анализировать и преобразовывать аргументы вызова метода. Отличить простую лямду от непростой и что потом с ней делать. Но это всё нерелевантно. Тут вопрос не в том как можно анализировать и генерировать код, а накой результат всего этого описывать в виде патча файл/строка/позиция, и т.п., притом только с возможностью делать подмену вызова метода, вместо того, чтобы просто получить произвольный результирующий код и его компилировать как обычно. S>Да, выглядит это пока феерически криво. Я думаю, что парни пытаются нащупать способ дать ровно столько гибкости, сколько необходимо. Произвольные манипуляции AST чреваты тем, что новое AST не удастся скомпилировать в байт-код — и даже диагностику причин толком провести будет невозможно. Им же нужно сделать так, чтобы ошибки в коде "расширений компилятора" диагностировались, и ломали только расширения — а не сам компилятор.
По-моему это норма — такие манипуляции — это как крайнее средство. Байткод, кстати, верифицируется. Если нагенерится фигня — оно тупо не загрузится.
S>Ну вот пока сделали вот такую залипуху — на конкретной фазе компиляции подтягиваем набор "патчей" и применяем их. S>Так-то и SG тоже выглядят немножко странно — зачем нам порождать какие-то файлы, с каким-то текстом, когда мы работаем с AST? Не проще ли было бы сразу породить в памяти нужное AST и отдать компилятору?
Именно. Фактически с этого вопроса я и влез в этот топик.
Сам SG, т.е. программно сгеренить исходник — это ещё ок, т.к. потом этот исходник можно показать человеку, чтобы он видел что происходит, бряку всунуть, дебагером пройтись, плюс вся навигация в IDE, стектрейсы и т.п.
Сабжевое же указание номеров строк в другом файле — это хрень полная, т.к. нечеловекочитаемо, непонятна целевая аудитория. Выглядит как workaround проблем дизайна их тулчейна.
S>·>Ну раз есть AST, то "распарсить Program.cs а AST", "заменить в AST вызов source.Where(n=>n%2==0) на вызов EnumerableHelper.Where2314234235569567(source)", "сохранить в Program_modified.cs вместе с реализацией Where2314234235569567 как приватного метода", "скомпилировать". S>Ну, это примерно то же самое, вид сбоку. Только придётся делать плюс-минус каждый раз, как происходит компиляция.
Да ровно так же — что генераторы, что замены надо делать каждый раз при изменении Program.cs и/или самого генератора|заменятора.
S>А SG и Interceptors срабатывают однократно.
Ага-ага. Кеширование промежуточных резлультатов умел ещё make, которому скоро пол века стукнет.
S>Ну, и в вашем предложении получается удвоение объёма кода на ровном месте — ведь придётся хранить полный клон всего Program.cs, который отличается только одной строчкой. S>А в нынешнем подходе хранится "набор патчей" в виде списка атрибутов InterceptsLocation.
так как это .cs — это должно быть для человеков. И в этом случае экономия на байтах не оправдана.
Лично я не смогу читать оригинальный Program.cs и в мысленно накладывать патчи, описанные в других файлах. Может, конечно, это я только такой отсталый, но, имхо, позволять машине так издеваться над человеками — негуманно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай