- PVSM.RU - https://www.pvsm.ru -

Анализаторы Roslyn: повадки и места обитания

На днях объяснял одному товарищу что такое анализаторы Roslyn и как их писать. Ответ получился массивным, и я решил вынести его в отдельную публикацию.

Что такое анализаторы Roslyn? Если коротко — это отличный способ писать рефакторинги вроде Решарперовских. Постоянно встречаете одну и ту же ошибку в процессе ревью? Напишете анализатор с фиксером и забудьте про эту ошибку. Техническая сторона довольно проста, для первоначального знакомства отлично подойдут вот эта статья [1], вот это видео [2], вот эта серия постов [3], и вот этот туториал [4]. Я же попытаюсь описать грабли моменты, которые лично у меня вызывали затруднение.

Первое — это Syntax Vizualizer. Любой анализатор содержит парсинг синтаксического дерева. Типичная задача — есть узел и надо отыскать его предка с типом «Объявление класса», или «найти все узлы объявления методов в которых используются строковые литералы». Синтаксическое дерево может быть с десятком уровней вложенности, и для его анализа хотелось бы заиметь визуализацию. Два популярных инструмента: Syntax Vizualizer и LINQPad. Первый идет по дефолту, выдает тонну технической информации по каждому узлу, и значительно тормозит на моем компьютере. Плюс, когда я набираю код анализатора Syntax Vizualizer начинает визуализировать непосредственно печатаемый код, что сбивает с толку. LINQPad дает чуть меньше информации, но зато красивее и нагляднее, так что рекомендую.

Следующий момент — тесты. Без них никуда. По факту, есть два варинта тестирования. Первый: написать анализатор, открыть второй экземпляр студии, создать там проект с написанным анализатором, подключиться из первой студии к процессу второй (Attach Process), начать дебаг. Правильный вариант тестирования: открыть тестовый класс, написать код, который должен подсвечиваться анализатором, задебажить тест.

Также порекомендую Test First подход. Сначала пишем неверный код, имплементируем анализатор. Когда анализатор готов — пишем тест для фикса, думаем как перейти от первоначального состояния к пофикшеному, пишем фикс. Конкретно в случае анализаторов такой пошаговый подход отлично заходит.

Слышали когда-нибудь о защитном программировании? В анализаторах пихайте его во все возможные места, ибо отвалившийся по NRE анализатор может уже не заработать до перезагрузки студии.

Учитывайте, большую часть анализаторов губит ненужность. Когда я впервые услышал про анализаторы — мне захотелось написать свой. Идеи возникали постоянно, но реализация выходила слишком сложнойзатратной. Первый боевой анализатор был написан только через полгода после знакомства с Roslyn. Следующий — еще через три месяца. Могу предположить, что при работе с мелкими проектами (2 человека в команде) технология не особо полезна — задачитехнологии типовые, все разумное уже покрыто R# или VS.

После перехода на новый проект (6 человек в команде) 3 подходящих места для анализа нашлись буквально сразу. Два были отклонены командой как ненужные. Мораль: советуйтесь с коллегами, они с удовольствием объяснят почему вы идиот анализатор не нужен и вам не придется тратить время на бесполезную работу. Кстати, коллеги оказались самыми профессиональными моими заказчиками — объясняется все четко, на пальцах, с примерами.

Менеджеры иногда требуют цифры: сколько мы потратим, что получим. Тут оценка довольно проста: разработка занимает 2 дня на анализатор «под ключ» (с тестами интеграцией инфраструктурой). Разработчики PVS-Studio упоминали что могут потратить 2 недели на один анализатор не верьте им, но они свои анализаторы продают. Если вы пилите анализатор для внутреннего проекта (и уже доводилось писать анализаторы, хотя бы учебные) — 2 дней должно быть достаточно. Оценить профит сложнее. Тривиальный случай — регулярно всплывающая на Code Review ошибка: кто-то LINQ использует в ядре, кто-то дату сериализует без указания формата. Соответственно, профит считается как частота ошибки помноженную на цену фикса помноженную на год.

Встречаются случаи пооригинальнее. Например, есть сервис агрегирующий данные с десятка банков. У каждого банка свои правила сравненияокругления цен, для каждого банка написан свой класс Price, с кастом к decimal. Как только разработчик деплоит на прод сравнение типа

return localBankPrice == centralBankPrice; 

менеджер достает из сейфа две баночки вазелина. Так вот, Roslyn — не самое плохое лекарство при аллергии на вазелин.

В принципе, анализаторы могут быть полезны еще в нескольких ситуациях. Тривиальная — продукт на продажу. Мороки с написанием больше, но и (возможный) профит погуще. Если интересно узнать про промышленную разработку — зовем pavsenin [5] Irina_DevExpress [6] (DevExpress) и Andrey2008 [7] (PVS-Studio).

Чуть менее тривиальный случай — анализаторы поставляемые с собственной библиотекой, этакая защита от некорректного использования.

Есть еще товарищи вроде eugenebb [8], творящие [9] особую [10] плагинную [11] магию [12], но это совсем другая история.

Суммируя — анализаторы штука крайне интересная, особенно если не возлагать на них больших надежд. Если у вас есть десяток свободных вечеров для неспешного изучения чего-нибудь интересного — потыкайте Roslyn.

Автор: Oxoron

Источник [13]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/c-2/268746

Ссылки в тексте:

[1] статья: https://sergeyteplyakov.blogspot.lt/2015/10/simple-roslyn-based-analyzer.html

[2] видео: https://www.youtube.com/watch?v=4W4KhZvrAaI&t=845s

[3] постов: https://joshvarty.wordpress.com/learn-roslyn-now/

[4] туториал: https://habrahabr.ru/company/pvs-studio/blog/301204/

[5] pavsenin: https://habrahabr.ru/users/pavsenin/

[6] Irina_DevExpress: https://habrahabr.ru/users/irina_devexpress/

[7] Andrey2008: https://habrahabr.ru/users/andrey2008/

[8] eugenebb: https://habrahabr.ru/users/eugenebb/

[9] творящие: https://habrahabr.ru/company/jugru/blog/314524/#comment_9899470

[10] особую: https://habrahabr.ru/company/jugru/blog/314524/#comment_9901602

[11] плагинную: https://habrahabr.ru/company/jugru/blog/314524/#comment_9903212

[12] магию: https://habrahabr.ru/post/331328/#comment_10299682

[13] Источник: https://habrahabr.ru/post/334582/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best