Pull to refresh

Visual Studio Solution Pivot Viewer. Аддон к Visual Studio 2010 для визуализации структуры и метрик кода

Reading time 7 min
Views 1.9K
Некоторое время назад Сергей Звездин (sergun) анонсировал мозговой штурм для того, что бы сгенерировать некоторое количество идей для возможной реализации в виде аддонов для Visual studio 2010. Я описал свой Xaps Minifier и предложил ещё одну. Идея заключалась в том, что бы использовать Silverlight PivotViewer контрол для визуализации исходного кода.

Теория


PivotViewer контрол может использоваться для визуализации большого объёма данных и позволяет их фильтровать и сортировать по любому критерию. Исходный код может быть использован как данные, которые могут быть проанализированы разработчиками/руководителями команды для того, что бы найти потенциально проблемные места. Под такими местами я понимаю классы, методы, которые должны пройти рефакторинг. К примеру, очень трудно осуществлять поддержку большого класса, метода и т.д. Очевидно, что такой код подлежит рефакторингу.

Таким образом, мой аддон должен анализировать исходный код проекта, подготавливать данные для PivotViewer контрола и отображать сам контрол и данные в нём.

Высокоуровневая архитектура



Существует несколько ограничений при использовании PivotViewer контрола.
  • Следует использовать Silverlight версию контрола, т.к. не существует отдельной WPF версии этого контрола. Это происходит потому, что WPF не включает механизм MultiScaleImage (Deep Zoom).
  • Следует использовать отдельный веб сервер, для того, что бы хостить в нём Silverlight приложение, т.к. PivotViewer контрол не поддерживает локальные коллекции.

Опишу каждый шаг, представленный на диаграмме.
  1. Мне следует обойти все проекты, классы, методы для того, что бы получить всю информацию об исходном коде приложения. Эта информация будет использована для того, что бы построить картинку в PivotViewer.
  2. Мне следует развернуть инфраструктуру веб сервера. Это означает, создать папки для веб сервера и для результатов обработки исходного кода, а также разместить сам веб-сервер на диске.
  3. Мне следует сериализовать и сохранить данные, которые были получены в процессе обработки исходного кода.
  4. Мне следует запустить веб-сервер, в котором будет размещаться Silverlight приложение с PivotViewer контролом на борту. Я собираюсь использовать Cassini (веб сервер, который используется для разработки и отладки веб приложений в Visual Studio). Он легковесный и поставляется совместно с Visual Studio.
  5. Приложение запускается и открывается в закладке Web Browser внутри Visual Studio.
  6. PivotViewer контрол начинает загружать данные и трансформирует их во внутренние коллекции, которые затем визуализируются.

Особенности реализации


Обработка исходного кода

Я использую ту же технику, что применяю в XapsMinifier дополнении к Visual Studio. Я обхожу все проект в рамках текущего загруженного солюшена, все файлы в рамках проекта, все элементы в рамках файла — классы, интерфейсы, структуры и т.д. Я создаю один большой набор данных, который содержит все необходимые элементы:
  • Является ли класс абстрактным
  • Число частей, из которых состоит partial class/interface/structure
  • Число строк кода класса/интерфейса/структуры
  • Число членов (методов, свойств и т.д.), которое содержит класс/интерфейс/структура
  • Имя элемента данных
  • Полное имя элемента (namespace + name)
  • Путь к файлу, который содержит этот элемент данных
  • Имя проекта, где элемент размещён
  • Язык программирования, на котором написан этот элемент (C#, VB, Managed C++ и т.д.)

Развёртывание веб сервера

В соответствии с моей задумкой следует размещать веб сервер для каждого проекта, который подвергается обработке данной утилитой. Таким образом, я должен создать папку для Silverlight приложения и для файла, который содержит сериализованные данные для PivotViewer контрола. Я создаю _PivotViewer папку в том же самом каталоге, где размещается файл солюшена. Эта папка будет содержать файл с сериализованными данными (PivotClassData.bin) и папку Server с готовым Silverlight проектом.

Я могу полагаться на post-build событие проекта WebServer для того, что бы заархивировать все требуемые файлы для публикации веб сервера (*.dll, *.aspx и т.д.). Этот архив подключён к проекту PackageTools как embedded resource.

Пример:
$(SolutionDir)Externals\7z.exe a -r -tzip -mx9 <br> $(SolutionDir)PackageTools\Resources\WebServer.zip $(ProjectDir)* -x!obj <br> -x!properties -x!.svn -x!_svn -x!*.csproj -x!*.csproj.user <br> -x!*.publish.xml -x!*.bat -x!*.cs -x!*.designer.cs -x!*.pdb<br><br>* This source code was highlighted with Source Code Highlighter.

Я распаковываю архив в папку Server используя библиотеку ICSharpCode.SharpZipLib.

Сериализация данных

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

Запуск веб сервера

Я использую следующую командную строку, что бы запустить Cassini.

Пример:
"C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\WebDev.WebServer40.EXE" <br> /port:8899 /path:"<path_to_solution_folder>\_PivotViewer\Server" /vpath:"/"<br><br>* This source code was highlighted with Source Code Highlighter.

Эта команда запустит веб сервер относительно папки <путь_к_папке_solution>\_PivotViewer\Server и веб сайт будет доступен по адресу http://localhost:8899.

Запуск приложения

Я использую стандартный интерфейс расширения Visual studio для того, что бы открыть вкладку Web Browser и перейти по требуемому пути (http://localhost:8899).

Пример:
IVsWindowFrame frame;<br>IVsWebBrowsingService webVrowserService = this.GetService(typeof(SVsWebBrowsingService))<br>   as IVsWebBrowsingService;<br>webVrowserService.Navigate("http://localhost:8899/SilverlightPivotViewerTestPage.aspx",<br>   (uint)__VSCREATEWEBBROWSER.VSCWB_FrameMdiChild, out frame);<br><br>* This source code was highlighted with Source Code Highlighter.

Загрузка данных

Я не использую простые или связанные коллекции т.к. они требуют множество предварительных шагов. Я использую just-in time коллекции и Pivot_JIT_Sample приложение для того, что бы построить JIT collection сервер. Я реализую класс CollectionFactoryBase который зачитывает сериализованные данные из файла и строит JIT коллекции.

Пример:
private void MakeCollectionItem(PivotClassElementsData item, Collection collection)<br>{<br>  Guard.ArgumentNotNull(item, "item");<br>  Guard.ArgumentNotNull(collection, "collection");<br><br>  collection.AddItem(item.Name, null, null,<br>      null<br>      , new Facet("Lines count", item.CodeLinesCount)<br>      , new Facet("Is Static Class", item.IsStatic.ToString())<br>      , new Facet("File path", item.Path)<br>      , new Facet("Parts count", item.PartsCount)<br>      , new Facet("Full name", item.FullName)<br>      , new Facet("Language", item.Language)<br>      , new Facet("Members count", item.MembersCount)<br>      , new Facet("Class Name", item.Name)<br>      , new Facet("Project name", item.ProjectName)<br>      //, new Facet("# of switch statements", item.SwitchCount)<br>      );<br><br>  collection.SetFacetDisplay("File path", false, true, true);<br>  collection.SetFacetDisplay("Full name", false, true, true);<br>  collection.SetFacetFormat("Lines count", "0");<br>  collection.SetFacetFormat("Parts count", "0");<br>  collection.SetFacetFormat("Members count", "0");<br>}<br><br>* This source code was highlighted with Source Code Highlighter.

Я не отображаю некоторые параметры в области фильтрации (“File path”, “Full name”), но они доступны на информационной панели.

Инсталляция и использование


Это расширение может быть инсталлировано через Visual Studio Extension Manager (Main menu-Tools-Extension Manager-Online Gallery) с использованием online хранилища расширений. Текущая версия приложения 0.9 beta.

Для того, что бы запустить визуализацию солюшена, следует открыть его в Visual studio, кликнуть правой кнопкой мыши на сам солюшен в Solution Explorer и выбрать пункт меню Solution Pivot Viewer.



Как только это действие будет вызвано, расширение начнёт разбирать исходный код, получать данные для PivotViewer контрола, разворачивать веб приложение с Silverlight PivotViewer контролом и откроет веб страницу приложения.



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

Известные проблемы/ограничения


Так как это бета версия, расширение имеет определённые ограничения и известные проблемы.
  • Поддерживается только одна коллекция — классы/интерфейсы/структуры
  • Расширение не может определить, запущен ли сервер Cassini или нет, и поэтому может происходить exception, который, тем не менее, не влияет на основную функцию приложения
  • Используется жёстко заданный порт для Cassini — 8899. Это значит, что для работы расширения следует убедиться, что порт открыт и не занят
  • Требуется наличие установленного сервера Cassini на компьютере
  • Приложение не имеет никакого интерфейса для того, что бы отобразить прогресс операции или вывести настройки

Будущие планы


  • Добавить визард для настройки приложения
  • Добавить новые типы коллекций (файлы, члены)
  • Добавить возможность печати экрана
  • Добавить поддержку расширений на основе MEF для поддержки вычисления различных метрик

Исходные тексты


Исходники этого расширения доступны здесь.

Оставьте своё мнение


Мне будет очень интересно узнать ваше мнение по поводу этого расширения, какие функции стоит добавить, что изменить и т.д. Обращайтесь!
Tags:
Hubs:
+3
Comments 3
Comments Comments 3

Articles