Comments 15
Интересно, а есть генераторы, которые бы позволили генерировать .NET типы с методами "для удобства работы разработчика и т.п. IntelliSense", но без костыля в виде Source, т.е. шарпового кода? Строготипизированные, так сказать, генераторы сразу готовых типов (классов, структур, интерфейсов и т.д.) вместо текста-кода, который потом компилируется во всё то же самое?
«Сразу готовых» имеются в виду DLL? Тогда пришлось бы делать компиляцию прямо во время генерации, кажется это будет не слишком быстро.
А в чём, по-вашему, проблема с использованием исходного кода как источника для компиляции сгенерированного кода?
Ну смотрите.
Исходная задача: иметь динамически изменяющуюся (от работы разработчика с кодом проекта) инфраструктуру из генерируемых типов и членов этих типов, а также помощь разработчику в виде подсветки IntelliSense. Это если я правильно понимаю полноту всей задачи, которую призван решить инструмент Source Generators.
Здесь следует обратить внимание на то, что нигде в задаче прямо не сказано, что требуется генерировать именно исходный код в виде текста. Да и какой в этом может быть смысл, если подумать? Нажать F12 и посмотреть реализацию какого-нибудь автосгенерированного метода или всего типа? Но для этого подойдёт и обычный встроенный в IDE-шку декомпилятор.
Из чего следует, что генерация сперва корректного кода, и только затем его последующая интерпретация инструментариями Source Generators во временные недосборки и их частичное подключение к среде разработки - процесс весьма неоптимальный. Мы с лёгкостью могли бы генерировать сразу типы, члены типов и инструкции для тел методов этих типов.
Если приводить аналогию, то это как если бы для обращения к какому-то классу-сервису, который ожидает от нас определенную DTO с данными, сперва генерировали бы текстовый JSON этой модели, а затем десериализовывали бы её в требуемую DTO-шку.
Поэтому и возникает резонный вопрос, а зачем нам эти танцы с генерацией текста, когда логичнее (и правильнее, и оптимальнее) было бы генерировать сразу нужные структуры для решения поставленной задачи.
Да, но текст на C# генерировать значительно проще чем IL =) В смысле для головы программиста.
Мне кажется, не должно быть сложно придумать способ, работающий без Reflection.Emit.
IDE-шка ведь имеет представление о нашем коде без какой-либо компиляции, прямо в процессе написания кода. Значит, у неё в памяти уже есть модельки, представляющие собой описание юзеровых типов и их членов. Осталось только прикрутить генерацию именно этих самых моделек (вынеся их в public api) в output инструмента "source" generators.
А тел методов можно и через делегаты реализовывать.
Есть System.Reflection.Emit, но он будет работать в run time. Можно придумать что-нибудь с реализацией интерфейсов или абстрактным базовым классом, чтобы в compile time работал itellisense.
Кажется что в compile time без хоть каких то исходников не обойтись никак:-)
Спасибо большое за статью. Неделю назад тоже озаботился написанием генератора для рабочего проекта. Столкнулся с тем, что прекрасно работает на простом проекте, на рабочем же просто уходил в загрузку и ничего не происходило) Так же переписал на инкрементальный генератор и результат получился таким же. Жду с нетерпением новой части, хотя и в этой узнал много новых нюансов, с которыми буду экспериментировать в своем генераторе.
Так же для поиска по атрибуту можно воспользоваться SyntaxValueProvider.ForAttributeWithMetadataName https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.syntaxvalueprovider.forattributewithmetadataname?view=roslyn-dotnet-4.3.0
Современные (инкрементные) Source Generators в .NET