Комментарии 11
Если я правильно понял проблему, то чтобы пакет не вылез зависимостью к проекту куда анализатор добавляется, нужно устанавливать PrivateAssets="all"
. Пример:
<ItemGroup>
<PackageReference Include="LightMock" Version="2.0.0" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
В вышеприведённом примере LightMock будет добавлен в проект зависимостью, а остальные пакеты нет. То же самое со ссылками на проекты в решении.
Правильно ли я понимаю, что вам нужно тестировать не сам генератор (статус/ошибки/синтаксис), а именно сгенерированный код?
В таком случае, зачем делать первые три шага из вашего пути:
• Создадим компиляцию;
• Создадим и запустим генератор;
• Выполним сборку библиотеки и загрузим её в текущий процесс;
• Найдём там полученный код и выполним его.
если можно просто подключить генератор к тестовой сборке, и эти шаги выполнит компилятор? Генератор отработает один раз вместо компиляции и загрузки сборки в каждом отдельном тесте, что как мне кажется сильно влияет на общую их длительность.
Генератор тоже надо отлаживать, конечно же. Разница тут в том в каком контексте будет выполнятся генератор. В контексте компилятора/студии или в контексте юнит теста. Я предпочитаю второй вариант. На мой взгляд так проще отлаживать генератор.
А можете раскрыть, чем именно проще отладка в вашем варианте? По моему опыту JIT отладчик спокойно подключается вызовом из кода генератора, никогда с этим проблем не испытывал.
Более того, когда генерация кода происходит отдельно от прогона тестов, в коде сгенерированных файлов можно расставлять брейкпоинты. Не знаю как это возможно с вашим подходом, когда сборка после генератора находится только в памяти, каждый раз новая и файлы не генерируются на диск.
Меньше костыльности. Всё происходит внутри одного экземпляра студии. Если в результате генерации получается сложный код, то его можно и, на мой взгляд нужно, вынести в библиотеку поддержки. В этой библиотеке можно ставить брейкпоинты. Остальное становится более или менее тривиальным.
Про сборку. Важна не сборка, а исходный код, который получается и то как он работает. Исходный код всегда можно добыть по брейкпоинту в точке, где он добавляется в текущую компиляцию, в генераторе. Он детерминирован, если генератор и источник для него не менялись. То же самое для прогона тестов на получившейся сборке. Сборка может каждый раз и меняется, но вот результат нет.
Также можно тестировать юнитами, например параметры, ошибки и предупреждения генератора.
Я спросил вас про простоту, а не костыльность. Спорить насчет того, что более костыльно — вызывать отладчик из кода генератора или использовать ваш подход, я пожалуй не буду, но то, что разместить три строки в коде генератора — это проще, чем писать предложенную вами инфраструктуру — факт.
Всё происходит внутри одного экземпляра студии.
JIT отладчик при запуске спрашивает вас, в каком экземпляре студии вы ходите ее производить, текущем или новом:
Кому-то возможно проще и удобнее использовать отдельный экземпляр студии для отладки.
Если в результате генерации получается сложный код, то его можно и, на мой взгляд нужно, вынести в библиотеку поддержки. В этой библиотеке можно ставить брейкпоинты. Остальное становится более или менее тривиальным.
Важна не сборка, а исходный код, который получается и то как он работает.
Факт остается фактом, с вашим подходом отладить сгенерированный код нельзя.
Исходный код всегда можно добыть по брейкпоинту в точке, где он добавляется в текущую компиляцию, в генераторе.
Сомневаюсь, что искать точку добавления исходного кода в генераторе и досматривать переменную проще, чем открыть файл, сразу с подсветкой синтаксиса. Плюс файл может висеть вкладкой в той же студии и обновляться в реальном времени с каждой генерацией.
Так в чем же простота отладки?
Возможно мой подход подходит мне, а не, например, вам. Тот код, который у меня получается в генераторе, отладки не требует, а требует синтаксической проверки на отсутствие ошибок сборки и на корректность генерации (генератор и компилятор отработали успешно но сгенерировалось что-то не то). Как-то не было надобности ставить бряки внутрь сгенерированного кода, поэтому возможно я несколько неправильно понял, что конкретно имелось в виду.
В любом случае наличие выбора лучше чем его отсутствие. Для кого-то это будет полезно, для кого-то бесполезно, но возможно интересно.
Тестирование генератора исходного кода