77215

Язык для описания плагинов в среде программирования JetBrains MPS

Курсовая

Информатика, кибернетика и программирование

С каждым годом приложения становятся более объемными и сложными. В связи с этим, требуются все более изощренные подходы к программированию для создания новых программ. Попробуем проследить, как развивались средства программирования, чтобы удовлетворять нуждам программистов по написанию сложных проектов.

Русский

2015-02-02

347.5 KB

1 чел.

Санкт-Петербургский государственный университет

Математико-механический факультет

Кафедра системного программирования

Курсовая работа

Язык для описания плагинов в среде программирования JetBrains MPS

Работу выполнил

Михаил Мухин

445 группа

Научный руководитель

Константин Соломатов

JetBrains MPS Lead Developer

Санкт-Петербург

2008-2009


1.  Введение

С каждым годом приложения становятся более объемными и сложными. В связи с этим, требуются все более изощренные подходы к программированию для создания новых программ. Попробуем проследить, как развивались средства программирования, чтобы удовлетворять нуждам программистов по написанию сложных проектов.

  1.   Взгляд в прошлое

Рассмотрим основные аспекты развития систем программирования – смысловую емкость кода, независимость программ от окружения, в котором они исполняются и возможность совместной разработки. Одновременно посмотрим, какие идеи позволили достичь того уровня разработки ПО, который мы имеем сегодня.

идея

возможность совместной разработки

смысловая емкость кода

(уровень абстракции от вычислений)

независимость от

машины

архитектуры

ОС

интерфейса нижележащих уровней

машинный код

-

-

-

-

-

-

ассемблеры

-

оператор – одна машинная команда

+

-

-

-

процедурное программирование,

интерфейсы, библиотеки функций

по разные стороны интерфейса

вызов функции – одно законченное действие

языки высокого уровня

предложение – несколько машинных команд

+

+

-

-

ООП

по разным объектам

объект – сущность и набор операций для работы с ней

(способ организации, не делает код короче)

managed-языки

+

+

+

-

Посмотрим, какие недостатки есть у существующего на данный момент подхода, и какими могут быть средства для написания программ следующего уровня.

1.2  Какими будут системы будущего

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

Как следствие повышения абстрактности кода, происходило постепенное «отвязывание» программы от той среды, в которой она должна была выполняться.

Таким образом, для создания программирования «следующего поколения» необходимо еще усилить абстрактность программ; в идеале хотелось бы описывать компьютеру наши решения проблем (высокий уровень), по возможности избавляясь от объектов, циклов, функций, переменных (низкий уровень).

Рассмотрим простой пример: часто в приложениях используется понятие «команды» (для поддержки undo/redo, например). Обычно код выполнения команды выглядит приблизительно так (пример для языка Java):

CommandProcessor.getInstance().runCommand(new Runnable(){

public void run(){

  <body>

}

});

Реально смысловая нагрузка этого кода такова: «<body> выполняется в команде». Было бы гораздо удобнее и проще написать:

command{

    <body>

}

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

Каким образом эта идея реализуется в настоящее время? Есть несколько способов (мы не будем рассматривать языки с поддержкой делегатов, потому как делегаты – лишь частный случай сложной задачи).

Первый, он же самый распространенный – написание библиотек, предоставляющих функции обработки. В примере мы могли бы написать command(…). Но остается проблема синтаксиса – его мы поменять не можем. Поэтому нам все равно придется создавать анонимный класс – это ограничение языка.

Второй вариант решения той же проблемы – это embedded-языки (например, язык регулярных выражений в Java). Такое решение обладает очевидным недостатком – оно не расширяемо, кроме того, очень сложно, чаще даже невозможно, реализовать приличную поддержку таких языков на уровне среды программирования (подсветка и проверка синтаксиса, ошибок системы типов, рефакторинги). Чаще всего, такие языки являются интерпретируемыми, что негативно отражается на производительности. В примере такое решение не проходит.

И, наконец, последней вариант – использование в одном проекте нескольких языков. Например, в web-приложениях используются обычно как минимум 3-4 языка (SQL для БД, язык общего назначения или скриптовый – для бизнес-логики, HTML+JS/Flash/… для client-side). Недостаток этого подхода – статичность всех используемых языков, решение опять же неприменимо в примере.

1.3 Идея

Однако, несмотря на все недостатки, во всех подходах заложена правильная идея. Заключается она в том, что для каждой проблемной области (domain) нужен свой язык высокого уровня (DSL, domain-specific language). В примере мы могли бы внутри нашего проекта просто определить новое предложение command{…}, которое было бы синонимично указанному коду.

Фактически это означает, что следующий шаг в развитии программирования – LOP, language-oriented programming. Это принципиально новый подход, заключающийся в том, что для каждой проблемной области создается свой язык высокого уровня. Каждый такой язык, безусловно,  не будет являться универсальным, зато лаконично и точно будет описывать проблемную область на высоком уровне абстракции.

1.4  Обзор существующих решений и их недостатков.

Для того, чтобы осуществить идею LOP, для новых языков нужно описать как минимум: их структуру (синтаксис) и генератор (принцип трансляции данного DSL). Рассмотрим существующие программные комплексы для решения задачи LOP.

Решения типа «lex+yacc»

XText

Eclipse Language Tools

JetBrains MPS

Структура языка

+

+

+

+

Генератор

-

+

+

+

Не-контескстно-зависимые языки

-

-

+

+

Не-текстовые языки

-

-

+

+

Система типов

-

?

?

+

Расширяемость языков

-

-

-

+

Интегрируемость языков

-

-

-

+

Поддержка IDE

-

+

+

+

Таким образом, первое решение непригодно для поставленной задачи, второе и третье пригодны только для standalone-языков.

Примечание: существует и еще один проект – компании Intentional Software, под предводительством Чарльза Симони, который использует идеи, очень похожие на идеи проекта MPS. Однако, кроме пресс-релизов об этом продукте ничего не известно, в отличие от среды MPS, код которой открыт, а пре-версии выходят уже более года. Из-за отсутствия информации его нет в таблице.

1.5 Почему именно JetBrains MPS?

Почему LOP не используется широко в наше время? Ответ очевиден – мы хотели писать программу на нескольких языках сразу, а доступные средства предлагают в лучшем случае возможность создания standalone-языков без поддержки со стороны среды.

Почему так происходит? Ответ достаточно прост. Если использовать независимо разработанные языки совместно в одной программе, возникнут принципиально неразрешимые синтаксические неоднозначности.

Выход состоит в том, чтобы не использовать text-based представление программ. Тут есть несколько возможных решений – генерация кода по диаграммам, по блок-схемам и т.п., но на практике все эти способы исключительно малоэффективны (условно говоря, потому что вместо написания слова if программист должен совершить порядка десятка действий).

То есть необходима среда программирования, которая бы позволяла редактировать программу как текст, при этом реально храня ее в виде AST (abstract syntax tree).

Среда JetBrains MPS работает именно таким образом, причем текст в ней можно вводить как в text-based средах с тем только отличием, что в местах синтаксических неоднозначностей программисту будет предложен выбор альтернативы (при помощи широко используемого механизма code completion).

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

Помимо синтаксиса языка JetBrains MPS позволяет определить такие аспекты языков как систему типов, редакторы, тесты и некоторые другие (список периодически расширяется).

Разработка в этой среде происходит следующим образом: сначала в ней при помощи встроенных DSL (на высоком уровне абстракции) описываются языки, после чего в ней же на этих языках пишутся проекты. Из-за написания проектов в существующей среде, появляется автоматическая поддержка огромного количества инструментов - описав только структуру языка, программист сразу получает code completion, smart code completion, поддержку различных систем контроля версий, развитое IDE и др. Фактически, язык работает просто как надстройка над существующим IDE.


2. Задача и решение

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

Для введения возможности такой «улучшенной» интеграции языка в среду, в MPS было решено ввести плагины. Изначально, они писались на языке Java и были доступны только разработчикам среды. Такой подход имел ряд отрицательных черт:

  •  Не-DSL решение
  •  Плагины доступны только разработчикам
  •  Отсутствие переносимости между платформами
  •  Длинный код
  •  Плохая структурированность кода
  •  Низкая читаемость кода

Несколько пояснений, относящихся к первой проблеме (не-DSL решение). С точки зрения среды в целом это было очень большой проблемой, потому что выливалось в привязку к конкретному языку (Java), что недопустимо для столь глобального проекта (разработчики языков в МПС не обязаны знать Java). Кроме того, при изменении плагина каждый раз требовался перезапуск среды, что отрицательно сказывалось на производительности разработчиков плагинов (для кода, сгенерированного в MPS, есть поддержка изменений путем перегрузки классов).  Если бы такой подход (плагины на языке общего назначения) был бы предложен сторонним пользователям MPS, то при любых изменениях в библиотеках MPS всем пользователям пришлось бы менять все написанные плагины.  А из-за «молодости» системы, такие измененя библиотек – явление практически неотвратимое.

Вследствие всех указанных недостатков было принято решение о введении нового аспекта языка – плагинов, а также о создании нового языка для их описания. Данная курсовая работа посвящена созданию  этого языка.

Язык создавался «с чистого листа»; на момент начала написания не было известно, какими именно возможностями он должен обладать.

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

В рамках проводимой работы было необходимо

  •  Определить необходимые пользователям возможности языка. То есть определить возможные и необходимые точки расширения среды
  •  Реализовать поддержку точек расширения со стороны среды. То есть изменить исходный код MPS таким образом, чтобы в требуемых местах она стала расширяема
  •  Спроектировать структуру языка. Это означает – понять, каким образом можно максимально полно и сжато описать необходимые возможности для каждого из компонентов.
  •  Реализовать язык: структуру, реакторы, контекстно-зависимые ограничения синтаксиса, систему типов.
  •  Реализовать генератор языка
  •  Определить несинтаксические ограничения языка и реализовать их как часть системы типов.
  •  Переписать существующие плагины MPS на новом языке

2.2 Выяснение требований

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

Из-за того что язык разрабатывался в течение длительного времени, необходимо было обеспечить непрерывную работу плагинов. Решение: обеспечить одновременную работу двух подсистем плагинов, с последовательным переводом компонентов из одной в другую. Таким образом, плагины постепенно, без потери функциональности, переводились в новый вид, а язык расширялся.

2.3 Качество полученного языка

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

В тот момент, когда реализация языка была практически завершена, было принято решение о переводе MPS на новую платформу. Это означало в частности, что старые библиотеки для поддержки UI должны были быть заменены новыми. В случае плагинов, написанных на любом универсальном языке, пришлось бы переписывать огромное количество кода. В нашем случае, удалось обойтись изменением генератора и перегенерацией кода существующих плагинов, несмотря на несовместимость нижележащих библиотек и принципиальные различия в них. Этот факт косвенно подтверждает, что разработанный язык имеет принципиально более высокий уровень абстракции по сравнению с языками общего назначния, а значит, говорит о высоком качестве полученного языка.


3. Результат

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

  •  Actions & Action Groups

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

  •  Tools

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

  •  Persistent Settings Components

Подсистема описания хранимых настроек среды и компонентов для их редактирования.

  •  Editor Tabs

Позволяет описывать связанные редакторы (редакторы для аспектов одного и того же явления, используется для аспектно-ориентированных частей языков)

  •  File Generators

Позволяет настроить последний этап генерации – генерацию выходных файлов

  •  Generation Listeners

Позволяет компонентам прослушивать события генерации (используется для написания «долгоживущих» сервисов)

  •  Custom Plugin Parts

Позволяет писать части плагинов, не релизуемые при помощи остальных подсистем

Рассмотрим эти подсистемы подробнее. Полное их описание можно найти на станице MPS в Интернете: http://www.jetbrains.net/confluence/display/MPS/Plugin. Здесь же будут рассмотрены только особенности, позволившие сделать код переносимым (в смысле нижележащих библиотек) и компактным.


3.1 Actions & Action Groups

На скриншоте видно описание одного пункта контекстного меню (это пример реального кода из MPS на plugin language). Для того, чтобы написать этот текст, программисту нужно ввести (помимо 1 строчки исполнимого кода) около 50 (!) символов (остальное – шаблон, вводить его как текст не нужно). Для сравнения – тот же код, написанный вручную на Java (или сгенерированный) – это более 110 строк кода, приблизительно 2-3 Кб по объему. Код вводится без участия мышки, что делает процесс исключительно быстрым.

Такого сокращения объема удалось достичь за счет автоматической генерации кода, связанного с типичными для этой области задачами – регистрацией плагина (полностью автоматическая генерация), регистрацией группы (автоматически), регистрацией пункта меню и изменением существующих групп (2 слова на правой картинке), извлечением данных об окружении (раздел action context parameters, по 2 слова на каждый запрос), описанием shortcut и другими.

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


3.2
Tools

Внешний вид Tool Window и его описание:

Типичные задачи – регистрация, визуальные свойства и шорткаты, интерфейс (для интерфейсов в MPS есть отдельный язык – UI language, предмет курсовой работы автора предыдущего года). Также введены специальные операции для нахождения экземпляра Tool Window.

3.3 Persistent Settings Components

 Описание компонентов для настройки среды; данные автоматически сохраняются между сессиями и между перегрузками классов. Внешний вид такого компонента и его описание:

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

3.4 Editor Tabs

 Предоставляют возможность описывать связанные аспекты одного объекта (в текущей реализации – при помощи вкладок в редакторе снизу, описание позволяет в принципе генерировать, в частности, код для визуализации диаграмм зависимостей, без изменения исходного кода).

 

3.5 File Generators, Generation Listeners

 Автоматически генерируется код регистрации/отрегистрации, Java-интерфейсы, код для поддержки перегружаемых классов.

3.6 Custom Plugin Parts

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


4. Заключение

 

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

Этот факт может повлиять на более широкое распространение самой прогрессивной среды для LOP, а значит, и концепции в целом. На данный момент язык использован для описания около 200 сущностей в основных языках среды, а также в сторонних языках, использующихся для разработки коммерческих продуктов.

Побочным фактом стало улучшение кода среды MPS в части плагинов.


 

А также другие работы, которые могут Вас заинтересовать

48380. Основы бухгалтерского учета 252.67 KB
  Цель нашего курса - познакомить Вас с основами системы ведения бухгалтерского учета которая ежедневно используется на предприятии. Вы овладеете основами бухгалтерского учета и научитесь практически применять полученные знания. Материалы курса выходят за рамки только бухгалтерского учета.
48381. Кримінальне право. Курс лекцій 546.71 KB
  Курс лекцій містить зміст лекційного курсу, завдання до самостійного вивчення теоретичного матеріалу курсу, що вивчається в позааудиторний час, список рекомендованої літератури і ресурсів Інтернет, ілюстративний матеріал до лекцій
48382. Хіммотологія. Курс лекцій 1.35 MB
  Курс лекцій з дисципліни: Хіммотологія для студентів які навчаються за програмою підготовки офіцерів для проходження військової служби за контрактом кафедри військової підготовки ІваноФранківського національного технічного університету нафти і газу з напряму підготовки: В результаті вивчення блоку змістових модулів розділу Основи отримання та властивості пального студенти курсанти повинні знати: походження та властивості нафти склад нафти будову та властивості вуглеводнів основні процеси переробки та очистки нафти...
48385. Мотивы апокалипсиса культуры в романе Т.Толстой «Кысь». Черты постмодернистской поэтики в произведении 38.81 KB
  Мотивы апокалипсиса культуры в романе Т.Толстой «Кысь». Черты постмодернистской поэтики в произведении. Татьяна Толстая родилась в очень известной литературной семье. Её дед по отцовской линии Алексей Николаевич Толстой, бабушка по отцовской линии — Наталья Толстая-Крандиевская была известной поэтессой. Прадед с материнской стороны Борис Михайлович Шапиров — военный врач, деятель Красного креста, лейб-медик Николая II, действительный тайный советник
48386. Экономическая оценка инвестиций, введение в проектный анализ 667.23 KB
  Материальные инвестиции -– движимое и недвижимо имущество приобретенное или построенное до начала реализационного проекта. инвестиции пакеты акций налоговые льготы налоги Объект применения Материальные в имущество финансовые в финансовое имущество нематериальные в исследования и разработки подготовку кадров и тд Назначение На основание проекта неттоинвестиции на расширение проекта экстенсивные инвестиции реинвестиции на замену модернизацию диверсификацию на обеспечение выживаемости предприятия бруттоинвестиции...
48387. УЧАСТИЕ В ЛЕЧЕБНО-ДИАГНОСТИЧЕСКОМ И РЕАБИЛИТАЦИОННОМ ПРОЦЕССАХ 189.57 KB
  Забелин в своих трудах описал правила вскармливания ребенка грудью и показал значение грудного вскармливания для развития здорового ребенка. Была разработана государственная программа улучшения здоровья детей которая содержит следующие приоритетные направления: Улучшение качества жизни ребенка создание условий наиболее полного использования жизненного потенциала физического интеллектуального и эмоционального. Систематическое наблюдение за развитием ребенка. Совершенствование системы охраны здоровья матери и ребенка.
48388. Совместное применение нескольких фундаментальных законов 449.75 KB
  Совместное применение нескольких фундаментальных законов Законы сохранения массы импульса энергии используем для построения математической модели описывающей течение сжимаемого газа. Газообразные среды гораздо легче подвергаются сжатию: при перепаде давления в одну атмосферу плотность газа первоначально находившегося при атмосферном давлении уменьшается или увеличивается на величину сопоставимую с начальной его плотностью. Уравнение неразрывности для сжимаемого газа. По оси через грань с координатой в кубик за время поступает масса...