Что такое NDepend уже было рассказано на хабре — это статический анализатор кода на .NET'е. Недавно вышла новая — 6-я версия этой замечательной утилиты, о новых возможностях которой рассказывается ниже. Это перевод, оригинальная статья здесь.

Правильный выбор новых возможностей


Недавно вышел NDepend 6. До сих пор выход главных релизов назначался на время после выхода Visual Studio, и сейчас Visual Studio 2015 в предрелизном состоянии. NDepend 6 это результат напряжённых работ в течении 18 месяцев. После 11 лет разработки NDepend достиг определённого уровня зрелости, но всё ещё остаётся много возможностей и улучшений, которые возможно сделать. И для версии 6 самым деликатным вопросом оказался выбор новых возможностей и улучшений для пользователей. С тех пор как в 2013 году была выпущена версия 5, были получены идеи с Visual Studio User Voices и NDepend User Voices. Собственно говоря, новые возможности 6-й версии хорошо отражают наиболее востребованные возможности, которые были завершены.

Интеграция в процесс сборки


Пользователи просили о большей интеграции NDepend в процесс автоматической сборки. Они запускали NDepend.Console.exe для сбора информации и отчёта о том, не нарушаются ли важные правила, по которым процесс сборки считается неудачным (эту информацию можно получить по коду возврата от NDepend.Console.exe). Пользователи просили показать больше информации непосредственно в инструментах сборки. Существует много технологий сборки, самые запрашиваемые из которых это TFS, TeamCity и SonarQube. В результате разработчики сотрудничали с высококлассными экспертами этих технологий, чтобы сделать встроенную интеграцию, которая, предположительно, включает большинство сценариев использования, и которая будет поддерживаться для будущих версий и получать новые возможности.

Улучшенная интеграция с Visual Studio


Т.к. пользователи хотели большей интеграции с процессом сборки, то в течении последнего года усилия в основном были посвящены инструментам для Visual Studio. NDepend был интегрирован в Visual Studio с помощью технологии VS Addin — это решение было принято командой разработки в 2009 году. В то время VSIX (другой стопоб разработки расширений для студии) был сырой, а также надо было поддерживать VS2008 и VS2005, поэтому VS Addin был правильным выбором. Со времененем VS Addin становился всё менее актуальным, не получал улучшений от Microsoft, и приводил к сбоям, но самое главное — не было возможности запомнить расположение окон NDepend во время выполнения. Это доставляло пользователям большие неудобства и заканчивалось просьбами на User Voice запомнить расположение окон.

Начиная с версии 6 NDepend основывается на технологии VSIX для интеграции в VS 2015, 2013, 2012 и 2010. Кроме того, Microsoft запретил использовать VS Addin в 2015 студии. В любом случае, благодаря VSIX стало возможным сделать более гладкую и надёжную интеграцию с Visual Studio, с запоминанием окон, новыми возможностями (например, прикрепление проекта NDepend к .suo (а не только к .sln), и полную поддержку горячих клавиш).

Также, были три возможности, представленные бесплатными расширениями для студии, которые были включены в NDepend, чтобы они всегда были под рукой.



Улучшения правил


Правила для кода на .NET'е — основная возможность NDepend'а. Пользователи оставили много отзывов о способах как улучшить существующие правила, в основном уменьшить ложные срабатывания. Поэтому было переделано около трети правил по умолчанию в соответствии с их рекомендациями.

Это здорово, что правила для кода — изменяемые LINQ-запросы на C#, которые содержат немного комментариев. Но для многих пользователей они были недостаточно информативны о том, почему правило создаёт предупреждение, почему соблюдение конкретного правила улучшит код, и как исправить нарушение правила. Поэтому была добавлена возможность добавлять 2 форматированных текста в исходный код правила NDepend через теги <Description> и <HowToFix>. Это хорошая возможность описать каждое правило по умолчанию и более подробно объяснить его пользователю. И в интерфейсе и в отчёте пользователь может выбрать что смотреть — Description/HowToFix или исходный код правила на C# LINQ.



Другая потребность пользователей была, чтобы делать доступными правила между несколькими проектами NDepend. Обычно у компании есть несколько проектов, анализируемых с помощью NDepend, и пользователи хотят управлять ими всеми сразу. И беря во внимание, что на NDepend писать свои правила для кода на .NET проще чем где либо ещё, пользователи хотели возможность использовать один профиль для разных проектов. Поэтому в NDepend 6 есть возможность определить список правил, которые можно использовать совместно в проектах NDepend.



Визуализация метрик кода


В NDepend уже была визуализация метрик кода с помощью treemap, и было решено добавить раскраску. Идея в том, что можно показать две метрики кода. Одна представлена прямоугольной областью, а другая цветом прямоугольника. Например, на следующей картинке показано покрытие кода NDepend 6 тестами специфичным, но удобным и точным способом.

  • Прямоугольники — методы,
  • Прямоугольные области пропорциональны количеству строк кода,
  • Цвет прямоугольника — процент покрытия кода тестами.



Взглянув, сразу понятно что цветной treemap может помочь понять информацию, которую было бы сложно понять другим способом. Несмотря на то, что код NDepend покрыт тестами на 82%, можно увидеть скопления красных прямоугольников которые показывают код, недостаточно покрытый тестами. Вероятно, больше нет инструмента, который может показать это с такой точностью.

Разработчики NDepend стараются делать возможности продукта связными. Поэтому можно визуализировать не только любые две из многих метрик NDepend'а, а и свои метрики кода, описанные через LINQ-запросы на C#, а также можно подсветить конечный код правила или запроса. В результате если запросить сложные методы, то их можно отобразить на цветном treemap:



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



Что ещё должно было быть сделано


Продукт находится в постоянно меняющейся среде. Это значит, некоторые возможности, хорошо работающие раньше, должны быть пересмотрены. Некоторые из этих нужных улучшений были сделаны в NDepend 6-й версии.

Вспомогательный код, сгенерированный компилятором C# и VB.NET: От версии к версии в C# и VB.NET появлялось всё больше сахара. Это началось с анонимных методов и итераторов в C# 2.0. Затем появились лямбды и анонимные типы в C# 3.0, а затем async/await в C# 5.0. Эти конструкции заставляют компилятор генерировать дополнительные методы и типы. И т.к. эти конструкции довольно часто используются, эти сгенерированные элементы накапливаются в коде IL. А NDepend в основном полагается на IL код для получения информации о коде. Поэтому модель кода NDepend включает все сгенерированные методы и типы и это раздражает пользователя, которому в основном интересен только его код. Теперь NDepend исправляет это. Просто избавиться от всех этих сгенерированных элементов не выход, т.к. они, на самом деле, содержат некоторый пользовательский код. Поэтому были разработаны некоторые эвристики, чтобы объединить эти сгенерированные элементы с пользовательскими классами и методами, которые содержат код, из-за которого это генерируется компилятором. Таким образом не пришлось идти на компромисс — все данные модели кода сохранены, включая метрики кода (количество строк, процент покрытия, цикломатическая сложность, ...), зависимости и различия.

Улучшенная поддержка async: Асинхронные конструкции имеют специфичность, что вызвало некоторые затруднения у NDepend. Пользовательский код, на самом деле, встраивается компилятором в сгенерированный метод, который переопределяет виртуальный метод IAsyncStateMachine.MoveNext(). Поэтому IL код, вызывающий этот сгенерированный метод MoveNext() связан с абстрактным методом интерфейса, а не с реализацией. Вызовы асинхронного метода теряются в IL коде… и, следовательно, в модели кода NDepend. Благодаря эвристикам, написанным для предыдущего пункта, NDepend теперь способен анализировать и выявлять правильных вызывающих асинхронных методов.

Поддержка высокого разрешения: Сейчас мониторы с высоким разрешением (такие как 4K) становятся доступными и, как следствие, всё больше разработчиков работают с соответствующими настройками Windows. Это значит, что плотность пикселей выше и, следовательно, для отображения графического элемента (текст, картинка) используется больше пикселей. Интерфейс NDepend'а в основном основан на Windows Form и GDI+, и эти технологии по умолчанию не очень хорошо масштабируются когда Windows настроена на высокое разрешение. Когда пользователи начали сообщать об этой проблеме, то было решено переделать весь интерфейс NDepend'а, чтобы он мог работать с настройками разрешения от 100% до 250%. Это была возможность улучшить некоторые графические элементы и научиться некоторым способам работы с Windows Form и GDI+ при высоком разрешении. Результаты этого будут описаны в будущей статье в блоге NDepend, т.к. в интернете видно, что это является проблемой для многих разработчиков.

Темы в Visual Studio: Из статистики видно, что большинство пользователей используют NDepend из Visual Studio. Поэтому темы интерфейса NDepend не очень хорошо сочетаются со стандартными темами Visual Studio, такими как Светлая (Light), Тёмная (Dark), Синяя (Blue) и стандартной темой VS2010. К счастью в NDepend элементы меню, панели, привязки… основаны на библиотеке DevExpress WinForm и их последняя версия включает эти темы (и не только). Поэтому помогло простое обновление до последней версии.

Улучшение анализа: Некоторые улучшения должны были быть сделаны в отношении анализа. Проект NDepend'а ссылается на некоторые каталоги и имена сборок (без расширения файла). Во время анализа расположение сборок для анализа находилось следующими двумя способами. Если найдено много копий сборки, то если они все одинаковые, то NDepend брал одну из них, а если они различались, то NDepend сообщал об ошибке, т.к. эта ситуация считается серьёзной проблемой разворачивания решения. Но со временем появлялись новые технологии, такие как Windows Phone или Portable Class Libraries, и они приводили к такой ситуации во время исправной работы. Поэтому при обнаружении такой ситуации теперь NDepend 6 использует эвристический анализ для нахождения правильной сборки, основываясь на её версии, зависимостях и размере файла.

Комментарии (3)


  1. VenomBlood
    01.07.2015 23:19
    +5

    NDepend полноценным статическим анализатором кода можно назвать только в умах маркетологов.
    Это именно что визуализатор различных метрик, сравните список фич с тем же PVS (хотя, отдать должное, PVS на порядок дороже) или другими анализаторами для C++, на ихнем фоне NDepend гораздо ближе к Resharper+stylecop чем к ним.


  1. ilyabreev
    02.07.2015 08:40

    Заинтересовался, решил зайти на сайт и узнать больше. А сайт не работает.


  1. dymanoid
    02.07.2015 20:29

    Как насчёт SonarQube?