Re[11]: Новости C#12
От: · Великобритания  
Дата: 17.11.23 10:33
Оценка:
Здравствуйте, 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 и в мысленно накладывать патчи, описанные в других файлах. Может, конечно, это я только такой отсталый, но, имхо, позволять машине так издеваться над человеками — негуманно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[12]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.11.23 10:45
Оценка:
Здравствуйте, ·, Вы писали:


·>Лично я не смогу читать оригинальный Program.cs и в мысленно накладывать патчи, описанные в других файлах. Может, конечно, это я только такой отсталый, но, имхо, позволять машине так издеваться над человеками — негуманно.


Ты тот же Linq читаешь с кучей расширений. И ничего. Главное результат. Ну и можешь помечать комментарием (атрибутами) код который должен подменяться. Это и генератору хорошо и тебе при чтении
и солнце б утром не вставало, когда бы не было меня
Отредактировано 17.11.2023 11:03 Serginio1 . Предыдущая версия .
Re[13]: Новости C#12
От: · Великобритания  
Дата: 17.11.23 11:42
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>·>Лично я не смогу читать оригинальный Program.cs и в мысленно накладывать патчи, описанные в других файлах. Может, конечно, это я только такой отсталый, но, имхо, позволять машине так издеваться над человеками — негуманно.

S> Ты тот же Linq читаешь с кучей расширений. И ничего. Главное результат. Ну и можешь помечать комментарием (атрибутами) код который должен подменяться. Это и генератору хорошо и тебе при чтении
Ты вообще за контекстом не следишь? Какое это имеет отношение к InterceptsLocation?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[14]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.11.23 11:55
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Serginio1, Вы писали:


S>>·>Лично я не смогу читать оригинальный Program.cs и в мысленно накладывать патчи, описанные в других файлах. Может, конечно, это я только такой отсталый, но, имхо, позволять машине так издеваться над человеками — негуманно.

S>> Ты тот же Linq читаешь с кучей расширений. И ничего. Главное результат. Ну и можешь помечать комментарием (атрибутами) код который должен подменяться. Это и генератору хорошо и тебе при чтении
·>Ты вообще за контекстом не следишь? Какое это имеет отношение к InterceptsLocation?
Прямое. Ты можешь пометить заменяемый код как комментарий. Это помощь и SG для создания расширения и атрибутов InterceptsLocation и тебе для чтения
и солнце б утром не вставало, когда бы не было меня
Re[4]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.11.23 11:58
Оценка:
Здравствуйте, Silver_S, Вы писали:

S>>interceptors понравились для SG.

S>> Теперь и существующий код можно подменять!
S>>https://github.com/dotnet/roslyn/blob/main/docs/features/interceptors.md

S_S>Немного странноватая фича. Выглядит как инструкция — в теле метода в такой-то строке подменить вызов метода. Для каждого вида изменений в коде по отдельной такой фиче что-ли делать будут. Не проще ли было разрешить в SG подменять все тело метода (все определение).


Как я и говорил удобно для моков
https://habr.com/ru/companies/pvs-studio/articles/768802/

Перехват осуществляется посредством указания атрибута InterceptsLocation, в который надо передать имя файла и позиции строки и символа, на которых вызывается метод.

Хоть польза для AOT здесь также имеется, фокус приходится на кодогенерацию. Например, можно было бы помечтать о библиотеках, упрощающих работу с аспектно-ориентированным программированием. Однако ещё более заманчиво звучат фреймворки для юнит-тестов – наконец-то можно будет перестать делать по интерфейсу на каждый класс, просто чтобы замокать его в тестах. По крайней мере, это активно дискутируется в сообществе, что приятно.

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

и солнце б утром не вставало, когда бы не было меня
Re[15]: Новости C#12
От: · Великобритания  
Дата: 17.11.23 12:07
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>> Ты тот же Linq читаешь с кучей расширений. И ничего. Главное результат. Ну и можешь помечать комментарием (атрибутами) код который должен подменяться. Это и генератору хорошо и тебе при чтении

S>·>Ты вообще за контекстом не следишь? Какое это имеет отношение к InterceptsLocation?
S> Прямое. Ты можешь пометить заменяемый код как комментарий. Это помощь и SG для создания расширения и атрибутов InterceptsLocation и тебе для чтения
Но ведь можешь-то и не пометить! Отмечать в исходнике части кода которые надо как-то особо обработать, через partial/спец-аннотации — хороший подход. А вот InterceptsLocation — жуть полная.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[16]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.11.23 12:11
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Serginio1, Вы писали:


S>>>> Ты тот же Linq читаешь с кучей расширений. И ничего. Главное результат. Ну и можешь помечать комментарием (атрибутами) код который должен подменяться. Это и генератору хорошо и тебе при чтении

S>>·>Ты вообще за контекстом не следишь? Какое это имеет отношение к InterceptsLocation?
S>> Прямое. Ты можешь пометить заменяемый код как комментарий. Это помощь и SG для создания расширения и атрибутов InterceptsLocation и тебе для чтения
·>Но ведь можешь-то и не пометить! Отмечать в исходнике части кода которые надо как-то особо обработать, через partial/спец-аннотации — хороший подход. А вот InterceptsLocation — жуть полная.

По мне так нормально. Многие так поступают для обработки кода. Перевода итд.
Как раньше написал хорошо для использования моков
https://habr.com/ru/companies/pvs-studio/articles/768802/

Перехват осуществляется посредством указания атрибута InterceptsLocation, в который надо передать имя файла и позиции строки и символа, на которых вызывается метод.

Хоть польза для AOT здесь также имеется, фокус приходится на кодогенерацию. Например, можно было бы помечтать о библиотеках, упрощающих работу с аспектно-ориентированным программированием. Однако ещё более заманчиво звучат фреймворки для юнит-тестов – наконец-то можно будет перестать делать по интерфейсу на каждый класс, просто чтобы замокать его в тестах. По крайней мере, это активно дискутируется в сообществе, что приятно.

и солнце б утром не вставало, когда бы не было меня
Re[5]: Новости C#12
От: · Великобритания  
Дата: 17.11.23 12:16
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>наконец-то можно будет перестать делать по интерфейсу на каждый класс, просто чтобы замокать его в тестах.

Вот собственно реальная проблема — так ведь её и нужно фиксить. Достаточно просто позволить мокать классы.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.11.23 13:13
Оценка:
Здравствуйте, ·, Вы писали:

S>>наконец-то можно будет перестать делать по интерфейсу на каждый класс, просто чтобы замокать его в тестах.

·>Вот собственно реальная проблема — так ведь её и нужно фиксить. Достаточно просто позволить мокать классы.
InterceptsLocation самое простое решение. Для моков вообще не трогает код.
Куда проще?
и солнце б утром не вставало, когда бы не было меня
Re[7]: Новости C#12
От: · Великобритания  
Дата: 17.11.23 14:03
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>>наконец-то можно будет перестать делать по интерфейсу на каждый класс, просто чтобы замокать его в тестах.

S>·>Вот собственно реальная проблема — так ведь её и нужно фиксить. Достаточно просто позволить мокать классы.
S> InterceptsLocation самое простое решение. Для моков вообще не трогает код.
S>Куда проще?
Ага, простое, но неправильное. Т.к. ты сможешь мокать только классы написанные на c# и только лежащие в твоём проекте в виде исходников.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[8]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.11.23 15:09
Оценка:
Здравствуйте, ·, Вы писали:

S>>>>наконец-то можно будет перестать делать по интерфейсу на каждый класс, просто чтобы замокать его в тестах.

S>>·>Вот собственно реальная проблема — так ведь её и нужно фиксить. Достаточно просто позволить мокать классы.
S>> InterceptsLocation самое простое решение. Для моков вообще не трогает код.
S>>Куда проще?
·>Ага, простое, но неправильное. Т.к. ты сможешь мокать только классы написанные на c# и только лежащие в твоём проекте в виде исходников.

Я могу мокать вызовы любых классов!
У меня есть проект я хочу проверить работу некоего класса, но вызовы определенных классов, я хочу поменить на свои.
При этом сам объект этого класса может быть null. Не суть. Главное подменить вызов!
Эти классы могут быть написаны на чем угодно. Подменяются вызовы в моем коде!
и солнце б утром не вставало, когда бы не было меня
Отредактировано 17.11.2023 15:11 Serginio1 . Предыдущая версия .
Re[9]: Новости C#12
От: · Великобритания  
Дата: 17.11.23 19:43
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>·>Ага, простое, но неправильное. Т.к. ты сможешь мокать только классы написанные на c# и только лежащие в твоём проекте в виде исходников.

S>Эти классы могут быть написаны на чем угодно. Подменяются вызовы в моем коде!
Именно, что _только_ в твоём (притом если ты _только_ на шарпе пишешь). Подменять надо не место вызова, а то что вызывается. Т.к место вызова может быть где угодно, и в библиотечном коде в том числе.
Простой пример. В своём коде ты пишешь:
void myMethod(MockableThing thing)
{
  Logger.LogInformation("thing is {thing}", thing);
}

где-то в недрах какой-то библиотеки логгирования позовётся ToString. Как InterceptsLocation поможет тебе замокать этот вызов?
Этой же проблеме будет подвержена и работа с аспектно-ориентированным программированием.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 17.11.2023 19:45 · . Предыдущая версия .
Re[10]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 18.11.23 08:50
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Serginio1, Вы писали:


S>>·>Ага, простое, но неправильное. Т.к. ты сможешь мокать только классы написанные на c# и только лежащие в твоём проекте в виде исходников.

S>>Эти классы могут быть написаны на чем угодно. Подменяются вызовы в моем коде!
·>Именно, что _только_ в твоём (притом если ты _только_ на шарпе пишешь). Подменять надо не место вызова, а то что вызывается. Т.к место вызова может быть где угодно, и в библиотечном коде в том числе.
·>Простой пример. В своём коде ты пишешь:
·>
·>void myMethod(MockableThing thing)
·>{
·>  Logger.LogInformation("thing is {thing}", thing);
·>}
·>

·>где-то в недрах какой-то библиотеки логгирования позовётся ToString. Как InterceptsLocation поможет тебе замокать этот вызов?
·>Этой же проблеме будет подвержена и работа с аспектно-ориентированным программированием.

Вот я Logger.LogInformation("thing is {thing}", thing); я и замокаю.
Суть моков проверить свой код, а не сторонних библиотек. То есть я должен подсунуть свой ответ и проверить различные вариации для проверки своего кода.
Ты разве моками не занимался?
и солнце б утром не вставало, когда бы не было меня
Re[11]: Новости C#12
От: · Великобритания  
Дата: 18.11.23 11:09
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Вот я Logger.LogInformation("thing is {thing}", thing); я и замокаю.

В смысле будешь выпиливать все логгинг стейтменты при прогоне тестов? Для упавшего теста ты просто не сможешь разобраться почему он упал, если это произошло на билд-сервере вчера ночью. Особенно актуально для какого-нибудь хитрого многопоточного кода.

S>Суть моков проверить свой код, а не сторонних библиотек. То есть я должен подсунуть свой ответ и проверить различные вариации для проверки своего кода.

Но если ты в своём коде используешь хоть какой-нибудь библиотечный код, то всё.

S>Ты разве моками не занимался?

Занимался конечно. Надо создавать моковый инстанс thing, и тогда он может гулять по всему коду где угодно. А мокать call-sites — бесполезно, работает только на игрушечных примерах.
В java такой проблемы с моками никогда не было. Стандартно там можно создавать моки для любого класса, который не final (или sealed в терминологии c#). Впрочем, есть ещё PowerMock — она манипуляцией байткода позволяет мокать вообще всё, но это считается bad practice.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[12]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 18.11.23 15:58
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Serginio1, Вы писали:


S>>Вот я Logger.LogInformation("thing is {thing}", thing); я и замокаю.

·>В смысле будешь выпиливать все логгинг стейтменты при прогоне тестов? Для упавшего теста ты просто не сможешь разобраться почему он упал, если это произошло на билд-сервере вчера ночью. Особенно актуально для какого-нибудь хитрого многопоточного кода.

S>>Суть моков проверить свой код, а не сторонних библиотек. То есть я должен подсунуть свой ответ и проверить различные вариации для проверки своего кода.

·>Но если ты в своём коде используешь хоть какой-нибудь библиотечный код, то всё.

S>>Ты разве моками не занимался?

·>Занимался конечно. Надо создавать моковый инстанс thing, и тогда он может гулять по всему коду где угодно. А мокать call-sites — бесполезно, работает только на игрушечных примерах.
·>В java такой проблемы с моками никогда не было. Стандартно там можно создавать моки для любого класса, который не final (или sealed в терминологии c#). Впрочем, есть ещё PowerMock — она манипуляцией байткода позволяет мокать вообще всё, но это считается bad practice.


Во во создавать кучу интерфейсов и их реализацию. Про это и речь
Еще раз меня не интересуют сторонний код. Меня интересует только свой.
У меня может не быть возможности использовать сторонний код либо по времени исполнения, либо конкретно нельзя подключиться, либо долгая инициализация, а мне надо проверить только конкретный кусок кода итд.
Вот InterceptsLocation как раз для этого прекрасно подходят!

В статье же прямо написано

Хоть польза для AOT здесь также имеется, фокус приходится на кодогенерацию. Например, можно было бы помечтать о библиотеках, упрощающих работу с аспектно-ориентированным программированием. Однако ещё более заманчиво звучат фреймворки для юнит-тестов – наконец-то можно будет перестать делать по интерфейсу на каждый класс, просто чтобы замокать его в тестах. По крайней мере, это активно дискутируется в сообществе, что приятно.

и солнце б утром не вставало, когда бы не было меня
Re[11]: Новости C#12
От: IT Россия linq2db.com
Дата: 18.11.23 18:47
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Так-то и SG тоже выглядят немножко странно — зачем нам порождать какие-то файлы, с каким-то текстом, когда мы работаем с AST? Не проще ли было бы сразу породить в памяти нужное AST и отдать компилятору?


Разве что в виде квази-цитирования. Вручную его задолбаешься создавать.
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: Новости C#12
От: IT Россия linq2db.com
Дата: 18.11.23 18:50
Оценка:
Здравствуйте, ·, Вы писали:

·>Сабжевое же указание номеров строк в другом файле — это хрень полная, т.к. нечеловекочитаемо, непонятна целевая аудитория. Выглядит как workaround проблем дизайна их тулчейна.


Сгенерируй рядом комментарий с подробностями специально для человеков. В чём проблема?
Если нам не помогут, то мы тоже никого не пощадим.
Re[13]: Новости C#12
От: · Великобритания  
Дата: 19.11.23 10:30
Оценка:
Здравствуйте, IT, Вы писали:

IT>·>Сабжевое же указание номеров строк в другом файле — это хрень полная, т.к. нечеловекочитаемо, непонятна целевая аудитория. Выглядит как workaround проблем дизайна их тулчейна.

IT>Сгенерируй рядом комментарий с подробностями специально для человеков. В чём проблема?
Рядом где? Генерировать можно только генерируемый код. Исходный Program.cs менять нельзя, тут выше писали.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[13]: Новости C#12
От: · Великобритания  
Дата: 19.11.23 10:36
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>>Ты разве моками не занимался?

S>·>Занимался конечно. Надо создавать моковый инстанс thing, и тогда он может гулять по всему коду где угодно. А мокать call-sites — бесполезно, работает только на игрушечных примерах.
S>·>В java такой проблемы с моками никогда не было. Стандартно там можно создавать моки для любого класса, который не final (или sealed в терминологии c#). Впрочем, есть ещё PowerMock — она манипуляцией байткода позволяет мокать вообще всё, но это считается bad practice.
S>Во во создавать кучу интерфейсов и их реализацию. Про это и речь
Не понял ты о чём. В java никогда не надо было создавать кучу интерфейсов и их реализацию.

S> Еще раз меня не интересуют сторонний код. Меня интересует только свой.

Твой код может обращаться к стороннему, к каким-нибудь утилитным функциям.

S>У меня может не быть возможности использовать сторонний код либо по времени исполнения, либо конкретно нельзя подключиться, либо долгая инициализация, а мне надо проверить только конкретный кусок кода итд.

S> Вот InterceptsLocation как раз для этого прекрасно подходят!
Только в весьма ограниченных случаях.

S>В статье же прямо написано

На заборе тоже написано.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[14]: Новости C#12
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 19.11.23 10:51
Оценка:
Здравствуйте, ·, Вы писали:

Причем тут ява?
S>> Еще раз меня не интересуют сторонний код. Меня интересует только свой.
·>Твой код может обращаться к стороннему, к каким-нибудь утилитным функциям.
Вот эти вызовы мне и надо подменить через InterceptsLocation и вернуть нужные мне данные изменить состояние моих объектов!
S>>У меня может не быть возможности использовать сторонний код либо по времени исполнения, либо конкретно нельзя подключиться, либо долгая инициализация, а мне надо проверить только конкретный кусок кода итд.
S>> Вот InterceptsLocation как раз для этого прекрасно подходят!
·>Только в весьма ограниченных случаях.
Везде!
S>>В статье же прямо написано
·>На заборе тоже написано.
Аргуиент!
и солнце б утром не вставало, когда бы не было меня
Отредактировано 19.11.2023 10:54 Serginio1 . Предыдущая версия . Еще …
Отредактировано 19.11.2023 10:52 Serginio1 . Предыдущая версия .
Отредактировано 19.11.2023 10:51 Serginio1 . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.