Курсовая работа на тему: "Портирование инструментов автоматизации Visual Studio в Rider"

У нас на сайте представлено огромное количество информации, которая сможет помочь Вам в написании необходимой учебной работы. 

Но если вдруг:

Вам нужна качественная учебная работа (контрольная, реферат, курсовая, дипломная, отчет по практике, перевод, эссе, РГР, ВКР, диссертация, шпоры...) с проверкой на плагиат (с высоким % оригинальности) выполненная в самые короткие сроки, с гарантией и бесплатными доработками до самой сдачи/защиты - ОБРАЩАЙТЕСЬ!

Курсовая работа на тему:

"Портирование инструментов автоматизации Visual Studio в Rider"

Porting Visual Studio automation tools to Rider

Course Work

 

Оглавление

Введение                                                                                      4

1.      Постановка задачи                                                                6

2.      Обзор предметной области                                                  7

2.1.  Структура EnvDTE . . . . . . . . . . . . . . . . . . . . . .        7

2.2.  Версии EnvDTE  . . . . . . . . . . . . . . . . . . . . . . . .        7

2.3.   Существующие решения   . . . . . . . . . . . . . . . . . . .        7

2.4.   Rider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      10

2.4.1.   Архитектура  . . . . . . . . . . . . . . . . . . . . . .      10

2.4.2.   Протокол межпроцессного взаимодействия   .  . . .      11

2.4.3.   Проектная модель . . . . . . . . . . . . . . . . . . .      11

2.4.4.   Подсистемы, нуждающиеся в EnvDTE  .  .  .  .  . . .      11

3.      Предлагаемое решение                                                       12

3.1.   Архитектура решения . . . . . . . . . . . . . . . . . . . . .      12

3.1.1.         Передача данных между процессами  .  .  .  .  .  . . .      12

3.1.2.         Передача абстрактных синтаксических деревьев .      13

3.1.3.         Делегирование в Rider   . . . . . . . . . . . . . . . .      14

3.2.   Интеграция в Rider  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  . . .      15

3.2.1.   Редактирование кода  .  .  .  .  .  .  .  .  .  .  .  .  .  .  . . .      15

3.2.2.   Кодогенерация, компиляция, исполнение    .  .  . . .      17

3.3.   Ограничения . . . . . . . . . . . . . . . . . . . . . . . . . .      17

Заключение                                                                               18

Список литературы                                                                  19

Введение

При разработке программного обеспечения может возникать по- требность многократно выполнять однотипные действия над кодом; ав- томатизация этого процесса может значительно увеличить производи- тельность труда программиста. Один из способов автоматизировать это

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

Visual Studio — среда разработки от компании Microsoft — предо- ставляет программный интерфейс для этого. Это библиотека под назва- нием „EnvDTE“. Используя её, можно получить доступ к абстракциям, значительно упрощающим работу, например, к информации о структу- ре проекта и абстрактным синтаксическим деревьям, построенным по файлам с кодом. Важная черта этой библиотеки в том, что она исполь- зуется при создании расширений к среде разработки, но она позволяет взаимодействовать с моделью кода и подсистемами среды разработки без написания плагинов к ней. Например, в T41 существует простой способ получить доступ к объектам EnvDTE и взаимодействовать со средой разработки напрямую из пользовательского кода [12]. Благода- ря такому удобству этот механизм используется во многих2 проектах на платформе .NET.

Но у этой технологии есть важный недостаток: она не универсальна. Код из этой библиотеки может быть исполнен только во время работы Visual Studio, из-за чего эти инструменты невозможноиспользовать в окружениях, в которых эта среда разработки недоступна. В частности, при работе в Rider — среде разработки, созданной компанией JetBrains. В связи с этим разработчики проектов, использующих этот инстру- мент, оказываются привязаны к Visual Studio и не могут использовать Rider. Поэтому в компании JetBrains появилась потребность в решении

1T4 — шаблонный язык, используемый в .NET для генерации текста или кода. Он состоит из спе- цифичных директив, частей текста и кода на C#. Этот код исполняется до сборки основногопроекта. 2Согласно сервису по обмену кодом NuGet,  на  настоящий  момент  (2020  год)  библиотека EnvDTE скачивается 850 раз в день и используется в таких  проектах,  как  Roslyn,  ILSpy,gitextensions.  Актуальную  информацию  об  использовании  этой  сборки  можно  найти  на  странице

https://www.nuget.org/packages/EnvDTE/

этой проблемы.

Возникла идея сделать альтернативный инструмент, который предоставлял бы те же абстракции работы с кодом, но не опирался  бы на Visual Studio.

Rider при работе с кодом использует абстракции, схожие с абстрак- циями EnvDTE, поэтому ключевой шаг в реализации предлагаемой библиотеки — получение модели кода, идентичной модели кода Visual Studio, на основе данных из Rider.

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

1.       Постановка задачи

Цель данной работы заключается в создании библиотеки, предостав- ляющей такой же интерфейс проектной и кодовой модели, как EnvDTE, но способной работать в среде разработки Rider.

Для того, чтобы достичь поставленную цель, необходимо решить следующие задачи:

  создание библиотеки, имитирующей внешний программный ин- терфейс EnvDTE;

  создание плагина к среде разработки Rider, позволяющего полу- чать информацию, необходимую для реализации абстракций, ана- логичных абстракциям из EnvDTE;

  организация передачи данных между библиотекой, загруженной в пользовательский процесс, и средой разработки;

  интеграция созданного инструмента в подсистемы среды разра- ботки Rider, нуждающиеся в работе с EnvDTE.

2.       Обзор предметной области

2.1.      Структура EnvDTE

EnvDTE позволяет взаимодействовать со многими подсистемами IDE (рис. 1), например, отладчиком, процессом сборки решения, графи- ческим интерфейсом и так далее. Такое богатство обусловлено тем, что EnvDTE может быть использована для создания расширений к среде разработки.

Но в проектах, опирающихся на эту библиотеку, направленных на автоматизацию работы с кодом, эти абстракции не требуются. Для них достаточно обращаться к абстракциям проектноймодели. Они включа- ют в себя такие интерфейсы, как Solution, Project, CodeElement и так да- лее. EnvDTE также позволяет взаимодействовать и с деревьями разбо- ра файлов. Доступны такиеинтерфейсы, как CodeType, CodeNamespace, CodeFunction и так далее. Примечательно, что данная библиотека рас- крывает не только синтаксическую структуру кода, но и, частично, его семантику. Так,CodeClass позволяет получить список классов и интер- фейсов, от которых он наследуется, а CodeFunction – её тип.

 

2.2.      Версии EnvDTE

В целях сохранения обратной совместимости разработчики исход- ной библиотеки не меняли существующие интерфесы EnvDTE, а созда- вали новые сборки. Поэтому в настоящее время одновременно суще- ствуют пять различных версий библиотеки; предлагаемая альтернати- ва должна позволять работать через любую версию интерфейсов.

 

2.3.      Существующие решения

Потребность в использовании EnvDTE вне Visual Studioсуществует уже давно, и найдены следующие пути её решения:

  находить при помощи методов межпроцессного взаимодействия

 

 

 

 

 

 

 

 

 

 

Рис. 1: Ключевые классы EnvDTE [11].

экземпляр Visual Studio, уже исполняющийся на машине, и полу- чать инструменты автоматизации из него [13];

  запускать новый экземпляр Visual Studio без пользовательского интерфейса и получать инструменты автоматизации из него [14].

Оба эти варианта, однако, не универсальны. Первый вариант подразу- мевает необходимость вручную открывать среду разработки, что может быть нежелательно. Второй вариант не оптимален с точки зрения про- изводительности: даже для небольших проектов инициализация про- цесса Visual Studio может занять некоторое время. Результаты измере- ния времени инициализации этого процесса представлены в таблице 1. И они оба не применимы в окружениях, в которых запуск Visual Studio невозможен. Например, на машинах, на которых не установлена эта IDE, и на всех операционных системах, кроме Windows. Ограниче- ния на платформу вызваны тем, что библиотека EnvDTE специфична для операционной системы Windows и не может быть использована,

например, в Visual Studio for Mac.

Наконец, можно удалить из проекта все завязки на EnvDTE и ис- пользовать другие инструменты для автоматизации работы с кодом. Это можно сделать, например, на основе инструмента Scripty [5]. Но для крупных проектов эта работа может оказаться трудозатратной и чреватой ошибками, поэтому этот вариант тоже применим не всегда.

 

Таблица 1: Результаты  измерения  времени  инициализации  Visual  Studio при помощи методов межпроцессного взаимодействия [14]. E

    математическое ожидание. σ — стандартное отклонение. Решение, открытие которого измерялось, содержало 500 строк кода на C# и не находилось в системе контроля версий. Никакие плагины к среде разра- ботки установлены не были. Измерения проводились на персональном компьютере с процессором i7-8750H CPU 2.20GHz (Coffee Lake) при по- мощи инструмента BenchmarkDotNet [1].

 

Рис. 2: Архитектура среды разработки Rider [3].

2.4.      Rider

2.4.1.     Архитектура

Rider [10] — кроссплатформенная среда разработки для .NET от компании JetBrains. Она состоит из двух основных процессов опера- ционной системы: фронтенда и бэкенда. Данная схема изображена  на рис. 2.

Фронтенд — видимая часть, пользовательский интерфейс — создан на основе платформы IntelliJ, благодаря чему внешний вид среды раз- работки имеет много общего с внешним видом многих других продук- тов компании JetBrains. Эта часть исполняется на виртуальной машине Java.

Бэкенд — процесс без пользовательского интерфейса, в котором со- средоточена основная логика по работе с кодом — основан на другом продукте компании JetBrains — ReSharper [4]. ReSharper — плагин к среде разработки Visual Studio [9]; для использования его в качестве бэ- кенда для среды разработки Rider ReSharper был модифицирован – код этого проекта был отвязан от программных интерфейсов Visual Studio. Эта часть исполняется на виртуальной машине .NET. Поскольку эти две части используют различные виртуальные машины, они были вы- делены в отдельные процессы.

2.4.2.     Протокол межпроцессного взаимодействия

Взаимодействие между двумя процессами, составляющими Rider — ключевой момент в работе среды разработки, поэтому для упрощения этой задачи существует библиотека RD [8]. Аббревиатура RD расшиф- ровывается как „Reactive Distributed“, что точно отражает её суть: она предоставляет реактивные сущности (то есть объекты, позволяющие реагировать на изменения, подписываясь на события) и способна рабо- тать в распределённых системах. Другое важное свойство этого меха- низма заключается в том, что он позволяет иметь  изменяемое состоя- ние, разделяемое между процессами, и гарантировать его консистент- ность.

Этот же механизм можно использовать и для того, чтобы обеспечить

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

 

2.4.3.     Проектная модель

Модель проекта в Rider имеет много общего с моделью в EnvDTE. Как и Visual Studio, Rider оперирует такими понятиями, как решение, документ, тип, а так же их составляющими: проект, каретка, метод и так далее. Близость этих моделей значительно упрощает задачу данной работы.

 

2.4.4.     Подсистемы, нуждающиеся в EnvDTE

Особенность EnvDTE в том, что её можно использовать не толь- ко при написании плагинов к Visual Studio. Например, технология T4 позволяет обращаться к EnvDTE из пользовательского кода. В среде разработки Rider уже есть подсистема, реализующая поддержку T4. Эта система корректно работает в тех случаях, когда пользовательский код не использует EnvDTE, но выдаёт сообщение об ошибке в случае использования этой технологии. Поэтому её применимость несколько ограничена.

3.       Предлагаемое решение

В ходе данной работы была реализована часть публичных ин- терфейсов EnvDTE. Эта реализация была названа JetBrains.EnvDTE. Исходный код был выложен на сервис GitHub по адресу https:// github.com/kirillgla/JetBrains.EnvDTE. Данное решение поддержи- вает ключевые функции по работе с моделью проекта и абстрактными синтаксическими деревьями.

 

3.1.      Архитектура решения

Предлагаемое решение (рис. 3) состоит из трёх основных частей:

  сборки, содержащие интерфейсы EnvDTE;

  EnvDTE.Client – сборка, содержащая реализацию этих интерфей- сов и логику по отправке запросов;

  EnvDTE.Host – сборка, содержащая логику по обработке запросов.

Сборки с интерфейсами EnvDTE и их реализациями рассчитаны на загрузку в процесс с пользовательским кодом. Сборка с логикой по обработке запросов – на загрузку в процесс бэкенда среды разработки Rider. Предлагаемое решение дублирует версии существующих библио- тек и содержит проекты с интерфейсами каждой из версий.

 

3.1.1.     Передача данных между процессами

Существуют разные механизмы, которыми можно воспользоваться для того, чтобы передавать данные между процессом бэкенда Rider     и процессом, нуждающемся в EnvDTE. Например, Google gRPC [6] и Apache Thrift [2] являются возможными вариантами. Была выбрана библиотека RD [8]. Её достаточно для того, чтобы создавать соединение между процессом бэкенда Rider ипользовательским кодом; весомым ар- гументом в её пользу является то, что этот механизм уже используется

 

Рис. 3: Архитектура предлагаемой библиотеки.

 

в Rider. Библиотека RD подразумевает использование rdgen – инстру- мента для генерации фрагментов кода – классов, которые будут общи- ми  для  сторон,  осуществляющих  обмен  данными  [7].  В  предлагаемой библиотеке  при  помощи  него  создаются  классы  модели  кода.  Напри- мер,  классы,  представляющие  проекты  и  файлы,  и  узлы  абстрактных синтаксических деревьев.Библиотека RD загружается в пользователь- ский процесс вместе с JetBrains.EnvDTE и передаёт запросы и ответы по каналу связи, работающему на основе сокетов.

Задача передачи информации об абстрактных синтаксических де- ревьях была разделена на конвертацию конкретного синтаксического дерева в абстрактное и передачу его в другой процесс, поэтому узлы промежуточного дерева дублируют узлы абстрактного синтаксическо- го дерева, строящегося на стороне EnvDTE.

 

3.1.2.     Передача абстрактных синтаксических деревьев

В Rider есть инфраструктура для видонезависимого анализа фай- лов. Она позволяет построить конкретное синтаксическое дерево, кото- рое называется PSI – Program Structure Interface. При необходимости требуемые узлы преобразуются в промежуточное представление, ко- торое затем передается в пользовательский процесс и преобразуется в

узлы абстрактного синтаксического дерева EnvDTE.

Класс промежуточного представления узлов дерева, используемый обеими сторонами, генерируется при сборке предлагаемой библиотеки. Он хранит идентификатор типа узла и идентификатор узла. Иденти- фикатор типа позволяет процессу-получателю определить, к какому типу относится полученный узел, какой интерфейс он предоставляет, и соответственно, какой узел абстрактного синтаксического дерева необ- ходимо создать для него. Идентификатор узла используется при по- следующих обращениях к процессу Rider: при обработке запроса этот идентификатор позволяет однозначно определить, какой узел послу- жил основой для узла AST.

Наличие промежуточного представления позволяет ослабить связ-

ность кода: ни одна из сторон не имеет информации о том, какое пред- ставление дерева используется на другой стороне. Так, на стороне Rider невозможно использовать PSI при обращении кабстрактным синтакси- ческим деревьям классов из библиотек, и приходится использовать дру- гое представление данных, которое строится на основе метаданных из библиотек при помощимеханизмов, уже реализованных в Rider, и такая замена происходит прозрачно для стороны, использующей EnvDTE. Это также позволяет не загружать в пользовательский процесс сборки, содержащие определение PSI, что уменьшает риск коллизий. Другим ключевым моментом является ленивость преобразований и неотдели- мость передачи дерева от его построения. Благодаряэтому обе стороны не только никогда не строят деревья, используемые другой стороной, но и никогда не строят промежуточные деревья; передаются только отдельные узлы.

3.1.3.     Делегирование в Rider

Получение информации о семантике кода тоже делается при помо- щи запроса из пользовательского процесса в процесс Rider. Каждый узел абстрактного синтаксического дерева хранит узел промежуточно- го представления, по которому он был построен. По узлу промежуточ- ного представления всегда можно однозначно определить, какой узел

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

 

3.2.      Интеграция в Rider

Была реализована интеграция библиотеки в уже существующую подсистему поддержки языка T4. Исходный код  этой  подсисте-  мы с поддержкой EnvDTE выложен на сервис GitHub по адресу https://github.com/JetBrains/ForTea/tree/net202-envdte. Все сборки из JetBrains.EnvDTE сделаны частью плагина к среде разработки и могут быть загружены в её рантайм. Это сделано для того, чтобы иметьвоз- можность гарантировать, что на машине конечного пользователя эти сборки будут доступны, и код, опирающийся на них, можно будет ис- полнить.

 

3.2.1.     Редактирование кода

При редактировании в T4-файлах распознаются типы из этих сбо- рок и присутствует ряд интеллектуальных функций редактора для сим- волов, специфичных для EnvDTE, например, автодополнение, подсвет- ка синтаксиса, показ документации и подсказки типов. (рис. 4). Это ре- ализовано при помощи стандартного для Rider механизма: метаданные из созданных в ходе данной работы сборок загружаются в процесс сре- ды разработки и разбираются при помощи инструментов, уже исполь- зующихся в среде разработки; интеллектуальные механизмы предо- ставляются на основе этих метаданных. Благодаря этому функции ре- дактора всегда соответствуют наиболее актуальной версии библиотеки.

 

 

 

 

 

Рис. 4: Пример инттеллектуальных функций редактора для символов EnvDTE в файле на языке T4.

3.2.2.     Кодогенерация, компиляция, исполнение

Для того, чтобы исполнить пользовательский код на языке T4, сре- да разработки транслирует его в C#, затем компилирует и исполняет получившийся код. Кодогенерация была изменена так, чтобы к поль- зовательскому коду добавлялись строчки, при необходимости инициа- лизирующие все структуры, специфичные для данной реализации биб- лиотеки, и устанавливали соединение с процессом бэкенда Rider. При компиляции сгенерированного кода на C# пути до сборок интерфей- сов EnvDTE, являющихся частью плагина, добавляющего поддержку языка T4, передаютсякомпилятору в числе остальных библиотек, необ- ходимых для компиляции этого кода. При кодогенерации в код также добавляются строки, позволяющие виртуальной машине .NET найти и загрузить сборки из плагина в тот момент, когда пользовательский код впервые обратится к типам из них. При исполнении T4-файла процесс бэкенда Rider открывает порт, к которому пользовательский код мо- жет подключиться и отправить EnvDTE-специфичные запросы. Адрес этого порта затем передаётся дочернему процессу с пользовательским кодом в качестве переменной среды.

 

3.3.      Ограничения

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

Заключение

В рамках данной работы были выполнены следующие задачи:

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

  был создан плагин к среде разработки Rider, позволяющий по- лучать информацию, необходимую для реализации абстракций,аналогичных абстракциям из EnvDTE;

  была организована передача данных между библиотекой, загру- женной в пользовательский процесс, и средой разработки;

  был написан код, добавляющий поддержку EnvDTE в одну из под- систем Rider при помощи созданной библиотеки.

Список литературы

[1]     Akinshin Andrey. BenchmarkDotNet // article. 2019. URL: https://benchmarkdotnet.org/articles/overview.html (дата об- ращения: 13.10.2019).

[2]     Apache. Apache Thrift // Web page. 2017. URL: https:// thrift.apache.org/ (дата обращения: 27.11.2019).

[3]     Balliauw  Maarten.  Rider  front  end  plugin   development   //  blog. –  2017. URL: https://blog.jetbrains.com/dotnet/2017/02/ 07/rider-front-end-plugin-development/ (дата обращения: 28.10.2019).

[4]     Ellis Matt. Project Rider — C# IDE //  JetBrains  .NET  Tools  Blog.  2016. URL:https://blog.jetbrains.com/dotnet/2016/01/13/ project-rider-a-csharp-ide/ (дата обращения: 28.10.2019).

[5]     Glick  Dave.  Announcing  Scripty  // blog. –    2016. –   URL: https:

//daveaglick.com/posts/announcing-scripty (дата обращения: 13.10.2019).

[6]     Google. Google gRPC // Web page. 2019. URL: https://www. grpc.io (дата обращения: 27.11.2019).

[7]     JetBrains.  Protocol   extension   //   ReSharper   DevGuide. –   2018. URL: https://www.jetbrains.com/help/resharper/sdk/Products/Rider.html#protocol-extension.

[8]     JetBrains. RD // GitHub. 2019. URL: https://github.com/ JetBrains/rd (дата обращения: 27.10.2019).

[9]     JetBrains. ReSharper // overview. 2019. URL: https://www. jetbrains.com/resharper/ (дата обращения: 28.10.2019).

[10]     JetBrains. Rider // overview. 2019. URL: https://www. jetbrains.com/rider/ (дата обращения: 28.10.2019).

[11]     Microsoft.   Automation   Model    Overview    //   MSDN. –    2016. URL: https://docs.microsoft.com/en-us/visualstudio/extensibility/internals/automation-model-overview (дата обращения: 06.10.2019).

[12]     Microsoft.      Getting       data       from       Visual       Studion       //  MSDN. 2016. –                          URL:                         https://docs.microsoft.com/en-us/visualstudio/modeling/

design-time-code-generation-by-using-t4-text-templates? view=vs-2019#getting-data-from-visual-studio (дата обраще- ния: 23.11.2019).

[13]     Osenkov   Kiril.   How    to    get    DTE    from    Visual    Studio process       ID?       //     blog. –                                          2011. –           URL: https:// blogs.msdn.microsoft.com/kirillosenkov/2011/08/10/

how-to-get-dte-from-visual-studio-process-id/   (дата      об- ращения: 13.10.2019).

[14]     Warren Genevieve. Launch Visual Studio using  DTE  // MSDN. 2019. URL: https://docs.microsoft.com/en-us/visualstudio/ extensibility/launch-visual-studio-dte (дата обращения: 13.10.2019).