Наверное, Eclipse давно уже не нуждается в особом представлении. Многие знакомы с Eclipse благодаря Eclipse Java development tools (JDT). Именно эта популярная open-source Java IDE ассоциируется у большинства разработчиков со словом “Eclipse”. Однако Eclipse – это и расширяемая платформа для интеграции средств разработки (Eclipse Platform), и целый ряд IDE, построенных на ее основе, в том числе JDT. Eclipse – это и Eclipse Project, проект верхнего уровня, координирующий разработку Eclipse Platform и JDT, и Eclipse SDK – поставляемый результат этой разработки. Наконец, Eclipse – это open-source Foundation с огромным сообществом проектов, далеко не все из которых написаны на Java или имеют отношение к средствам разработки (например, проекты Eclipse IoT и Eclipse Science). Мир Eclipse очень многообразен.
В данной статье, обзорной по своему характеру, мы попробуем рассмотреть некоторые основы архитектуры Eclipse как платформы для построения интегрированных средств разработки и дать начальное представление о компонентах Eclipse, образующих фундамент технологической платформы для «нового Конфигуратора» 1C: Предприятие, 1C:Enterprise Development Tools. Разумеется, такое рассмотрение неизбежно будет во многом поверхностным и довольно ограниченным, в том числе и потому, что мы ориентируемся не только на Eclipse-разработчиков в качестве целевой аудитории. Впрочем, надеемся, что даже опытные разработчики Eclipse смогут найти в статье интересную для себя информацию. Например, мы расскажем об одном из «секретов Eclipse», относительно новом и малоизвестном пока проекте Eclipse Handly, который был основан и поддерживается фирмой 1C.
Рассмотрим вначале некоторые общие аспекты архитектуры Eclipse на примере Eclipse Java development tools (JDT). Выбор именно JDT в качестве примера не случаен. Это первая интегрированная среда разработки, появившаяся в Eclipse. Остальные *DT проекты Eclipse, такие как Eclipse C/C++ Development Tooling (CDT), были созданы позднее и заимствовали как основные архитектурные принципы, так и отдельные фрагменты исходного кода из JDT. Основы архитектуры, заложенные в JDT, актуальны по сей день для практически любой IDE, построенной поверх Eclipse Platform, в том числе и для 1C:Enterprise Development Tools.
В первую очередь следует отметить, что для Eclipse характерно достаточно четкое архитектурное расслоение, с отделением языково-независимой функциональности от функциональности, предназначенной для поддержки конкретных языков программирования, и отделением UI-независимых «ядерных» (core) компонент от компонент, связанных с поддержкой пользовательского интерфейса.
Так, Eclipse Platform определяет общую, языково-независимую инфраструктуру, а Java development tools добавляют к Eclipse полнофункциональную Java IDE. Как Eclipse Platform, так и JDT состоят из нескольких компонент, каждая из которых относится либо к UI-независимому «ядру», либо к слою UI (рис. 1).
Рис. 1. Eclipse Platform и JDT
Перечислим основные компоненты Eclipse Platform:
Нужно сказать, что Eclipse Platform предоставляет и множество других полезных компонент для построения интегрированных средств разработки, среди которых можно отметить Debug, Compare, Search, и Team. Отдельно следует упомянуть JFace Text – основу для построения «умных редакторов» исходного кода. К сожалению, даже беглое рассмотрение этих компонент, равно как и компонент UI-слоя не представляется возможным в рамках данной статьи, поэтому в оставшейся части этого раздела мы ограничимся обзором основных «ядерных» компонент Eclipse Platform и JDT.
Инфраструктура плагинов Eclipse основана на OSGi и предоставляется проектом Eclipse Equinox. Каждый плагин Eclipse является OSGi-бандлом. Спецификация OSGi определяет, в частности, механизмы версионирования и разрешения зависимостей. В дополнение к этим стандартным механизмам, Equinox вводит понятие точки расширения. Каждый плагин может определять свои точки расширения, а также привносить в систему дополнительную функциональность («расширения»), используя точки расширения, определенные этим же или другими плагинами. Хоть сколько-нибудь подробное описание механизмов OSGi и Equinox выходит за рамки данной статьи. Отметим только, что модуляризация в Eclipse имеет тотальный характер (любая подсистема, включая Runtime, состоит из одного или нескольких плагинов), и практически все в Eclipse является расширением. Причем эти принципы были заложены в архитектуру Eclipse еще задолго до внедрения OSGi (в то время использовалась собственная технология, во многом аналогичная OSGi).
Практически любая интегрированная среда разработки, построенная на основе Eclipse Platform, работает с Eclipse workspace. Именно workspace обычно содержит исходный код разрабатываемого в IDE приложения. Workspace напрямую отображается на файловую систему и состоит из проектов, которые содержат папки и файлы. Эти проекты, папки, и файлы называются ресурсами workspace. Реализация workspace в Eclipse служит как бы кэшем по отношению к файловой системе, что позволяет заметно ускорить обход дерева ресурсов. Кроме того, workspace предоставляет ряд дополнительных сервисов, включая механизм нотификации об изменении ресурсов и инфраструктуру инкрементальных билдеров.
За поддержку workspace и его ресурсов отвечает компонента Core Resources (плагин org.eclipse.core.resources). В частности, эта компонента предоставляет программный доступ к workspace в виде модели ресурсов. Для эффективной работы с этой моделью клиентам нужен простой способ представления ссылки на ресурс. При этом объект, непосредственно хранящий состояние ресурса в модели, было бы желательно спрятать от клиентского доступа. Иначе, в случае, например, удаления файла, клиент мог бы продолжать удерживать объект, которого уже нет в модели, с вытекающими отсюда проблемами. Eclipse решает эту задачу, используя так называемый handle ресурса. Handle выступает в роли ключа (он знает только путь к ресурсу в workspace) и полностью контролирует доступ к внутреннему объекту модели, который непосредственно хранит информацию о состоянии ресурса. Данный дизайн является вариацией паттерна Handle/Body.
Рис. 2 иллюстрирует идиому Handle/Body применительно к модели ресурсов. Интерфейс IResource представляет handle ресурса и является API, в отличие от класса Resource, реализующего этот интерфейс, а также класса ResourceInfo, представляющего body, которые API не являются. Подчеркнем, что handle знает только путь к ресурсу относительно корня workspace и не содержит в себе ссылку на resource info. Объекты resource info образуют так называемое «дерево элементов» (element tree). Эта структура данных полностью материализована в памяти. Чтобы найти экземпляр resource info, соответствующий некоторому handle, element tree обходится в соответствии с путем, хранящимся в этом handle.
Рис. 2. IResource и ResourceInfo
Как мы увидим в дальнейшем, базовый дизайн модели ресурсов (можно назвать его handle-based) используется в Eclipse и для других моделей. А пока перечислим некоторые отличительные свойства этого дизайна:
Eclipse предоставляет эффективный механизм нотификации об изменениях ресурсов workspace (рис. 3). Ресурсы могут изменяться как в результате действий, выполняемых в самой Eclipse IDE, так и в результате выполнения синхронизации с файловой системой. В обоих случаях подписавшимся на нотификации клиентам предоставляется детальная информация об изменениях в виде «ресурсных дельт» (resource delta). Дельта описывает изменения между двумя состояниями (под-)дерева ресурсов workspace и сама является деревом, каждый узел которого описывает изменение некоторого ресурса и содержит список дельт следующего уровня, описывающих изменения дочерних ресурсов.
Рис. 3. IResourceChangeEvent и IResourceDelta
Основанный на ресурсных дельтах механизм нотификации обладает следующими характеристиками:
Как мы вскоре увидим, основные составляющие дизайна механизма нотификации об изменении модели ресурсов актуальны и для других handle-based моделей.
Модель ресурсов Eclipse workspace является фундаментальной языково-независимой моделью. Компонента JDT Core (плагин org.eclipse.jdt.core) предоставляет API для навигации и анализа структуры workspace с точки зрения Java, так называемую «модель Java» (Java model). Этот API определен в терминах элементов Java, в отличие от нижележащего API модели ресурсов, который определен в терминах папок и файлов. Основные интерфейсы дерева элементов Java изображены на рис. 4.
Рис. 4. Элементы модели Java
Модель Java использует ту же идиому handle/body, что и модель ресурсов (рис. 5). IJavaElement – это handle, а JavaElementInfo играет роль body. Интерфейс IJavaElement определяет протокол, общий для всех элементов Java. Некоторые из его методов являются handle-only: getElementName(), getParent(), и т.п. Объект JavaElementInfo хранит состояние соответствующего элемента: его структуру и атрибуты.
Рис. 5. IJavaElement и JavaElementInfo
Модель Java имеет некоторые отличия в реализации базового дизайна handle/body по сравнению с моделью ресурсов. Как отмечалось выше, в модели ресурсов element tree, узлами которого являются объекты resource info, полностью содержится в памяти. Но в модели Java может быть значительно большее число элементов, чем в дереве ресурсов, ведь в ней представлена, в том числе, и внутренняя структура .java и .class файлов: типы, поля, и методы.
Чтобы избежать полной материализации всего дерева элементов в памяти, реализация модели Java использует ограниченный по размеру LRU-кэш element info, где ключом является handle IJavaElement. Объекты element info создаются по запросу по мере того как происходит навигация дерева элементов. При этом наименее часто используемые элементы вытесняются из кэша, и потребление памяти моделью остается ограниченным заданным размером кэша. Это еще одно преимущество handle-based дизайна, который полностью скрывает такие подробности реализации от клиентского кода.
Механизм нотификации об изменении элементов Java в общих чертах аналогичен рассмотренному выше механизму отслеживания изменений ресурсов workspace. Клиент, желающий отслеживать изменения в модели Java, подписывается на нотификации, которые представляются в виде объекта ElementChangedEvent, который содержит IJavaElementDelta (рис. 6).
Рис. 6. ElementChangedEvent и IJavaElementDelta
Модель Java не содержит информацию о теле методов или разрешении имен, поэтому для детального анализа кода, написанного на Java, JDT Core предоставляет дополнительную (не handle-based) модель: абстрактное синтаксическое дерево (abstract syntax tree, AST). AST представляет результат синтаксического анализа исходного текста. Узлы AST соответствуют элементам структуры исходного модуля (объявлениям, операторам, выражениям, и т.п.) и содержат информацию о координатах соответствующего элемента в исходном тексте, а также (в качестве опции) информацию о разрешении имен в виде ссылок на так называемые bindings. Bindings являются объектами, представляющими именованные сущности, такие как типы, методы, и переменные, известные компилятору. В отличие от узлов AST, образующих дерево, bindings поддерживают перекрестные ссылки и в общем случае образуют граф. Абстрактный класс ASTNode является общим базовым классом для всех узлов AST. Подклассы ASTNode соответствуют определенным синтаксическим конструкциям языка Java.
Поскольку синтаксические деревья могут потреблять значительное количество памяти, JDT кэширует только одно AST, для активного редактора. В отличие от модели Java, AST обычно рассматривается как «промежуточная», «временная» модель, на элементы которой клиентам не следует удерживать ссылки вне контекста операции, приведшей к созданию AST.
Перечисленные три модели (Java model, AST, bindings) совместно являются основой для построения «интеллектуальных средств разработки» в JDT, среди которых мощный редактор Java с разнообразными «помощниками», различные действия по обработке исходного кода (среди которых организация списка импорта имен и форматирование в соответствии с настроенным стилем), инструменты поиска и рефакторинга. При этом модель Java играет особую роль, поскольку именно она используется в качестве основы для визуального представления структуры разрабатываемого приложения (например, в Package Explorer, Outline, Search, Call Hierarchy, и Type Hierarchy).
На рис. 7 показаны компоненты Eclipse, образующие фундамент технологической платформы для 1C:Enterprise Development Tools.
Рис. 7. Eclipse как платформа для 1С:Enterprise Development Tools
Eclipse Platform предоставляет базовую инфраструктуру. Мы рассмотрели некоторые аспекты этой инфраструктуры в предыдущем разделе.
Eclipse Modeling Framework (EMF) предоставляет общие средства моделирования структурированных данных. EMF интегрирован с Eclipse Platform, но может использоваться и отдельно, в обычных приложениях Java. Довольно часто, начинающие Eclipse-разработчики уже хорошо знакомы с EMF, хотя еще не совсем разбираются в тонкостях Eclipse Platform. Одной из причин такой заслуженной популярности является универсальный дизайн, включающий, в том числе, и унифицированный API мета-уровня, который позволяет обобщенно работать с любой EMF моделью. Предоставляемые EMF базовые реализации для объектов модели и подсистема генерации кода модели по мета-модели существенно увеличивают скорость разработки и снижают количество ошибок. Также EMF содержит механизмы сериализации моделей, отслеживания изменений в модели, и многое другое.
Как любой по-настоящему универсальный инструмент, EMF подходит для решения широкого спектра задач, связанных с моделированием, но некоторые классы моделей (например, рассмотренные выше handle-based модели) могут нуждаться в более специализированных средствах моделирования. Рассказывать об EMF – занятие неблагодарное, особенно в ограниченных рамках одной статьи, поскольку это предмет отдельной книги, и довольно толстой. Отметим только, что качественная система обобщений, положенная в основу EMF, позволила появиться на свет целому спектру проектов, посвященных моделированию, которые входят в проект верхнего уровня Eclipse Modeling наряду с самим EMF. Одним из таких проектов является Eclipse Xtext.
Eclipse Xtext предоставляет инфраструктуру «текстового моделирования». Xtext использует ANTLR для синтаксического анализа исходного текста и EMF для представления результирующего ASG (abstract semantic graph, который, по сути, является комбинацией AST и bindings), называемого также «семантической моделью». Грамматика моделируемого с помощью Xtext языка описывается на собственном языке Xtext. Это позволяет не только генерировать описание грамматики для ANTLR, но и получать механизм сериализации AST (т.е. Xtext предоставляет и parser, и unparser), контекстную подсказку, и ряд других языковых компонент. С другой стороны, язык описания грамматики, используемый в Xtext, менее гибок по сравнению, скажем, с языком описания грамматики в ANTLR. Поэтому иногда приходится «подгибать» под Xtext реализуемый язык, что обычно не является проблемой, если речь идет о разрабатываемом с нуля языке, но может быть неприемлемым для языков с уже сложившимся синтаксисом. Несмотря на это, Xtext является в настоящее время наиболее зрелым, функционально полным, и универсальным инструментом в Eclipse для построения языков программирования и средств разработки для них. В частности, он является идеальным инструментом для быстрого прототипирования предметно-ориентированных языков (domain-specific language, DSL). Кроме упомянутого выше «языкового ядра» на основе ANTLR и EMF, Xtext предоставляет множество полезных компонент более высокого уровня, включая механизмы индексации, инкрементального построения, «умный редактор», и многое, многое другое, но оставляет за скобками языковые handle-based модели. Как и EMF, Xtext является предметом достойным отдельной книги, и мы вряд ли сможем даже бегло рассказать сейчас обо всех его возможностях.
1С:Enterprise Development Tools активно используют как EMF сам по себе, так и ряд других проектов Eclipse Modeling. В частности, Xtext является одной из основ средств разработки для таких языков 1С:Предприятие, как встроенный язык программирования и язык запросов. Другой основой этих средств разработки является проект Eclipse Handly, на котором мы остановимся более подробно (из перечисленных компонент Eclipse он пока наименее известен).
Eclipse Handly, подпроект проекта верхнего уровня Eclipse Technology, появился в результате начальной контрибуции кода в Eclipse Foundation, осуществленной фирмой 1C в 2014 году. С тех пор фирма 1С продолжает поддерживать разработку проекта: committer’ы Handly являются сотрудниками фирмы. Проект небольшой, но занимает достаточно уникальную нишу в Eclipse: главной его целью является поддержка разработки handle-based моделей.
Основные архитектурные принципы handle-based моделей, такие как идиома handle/body, рассматривались выше на примере модели ресурсов и Java-модели. Там же отмечалось, что и модель ресурсов, и модель Java являются важными основами для Eclipse Java development tools (JDT). А поскольку практически все *DT проекты Eclipse имеют архитектуру аналогичную JDT, то не будет большим преувеличением сказать, что handle-based модели лежат в основе многих, если не всех IDE, построенных поверх Eclipse Platform. Например, в Eclipse C/C++ Development Tooling (CDT) имеется handle-based модель C/C++, играющая в архитектуре CDT ту же самую роль, что и Java-модель в JDT.
До появления Handly, Eclipse не предлагал специализированных библиотек для построения языковых handle-based моделей. Существующие сейчас модели создавались в основном с помощью непосредственной адаптации кода Java-модели (a.k.a. copy/paste), в тех случаях, когда это позволяет Eclipse Public License (EPL). (Понятно, что, скажем, для проектов самого Eclipse это обычно не является проблемой с юридической точки зрения, чего не скажешь о продуктах с закрытым исходным кодом.) Помимо характерной для нее бессистемности, такая методика приводит к хорошо известным проблемам: дублированию кода, привнесенным при адаптации ошибкам, и т.п. Что еще хуже, результирующие модели остаются «вещью в себе» и не используют имеющийся потенциал для унификации. А ведь выделение общих понятий и протоколов для языковых handle-based моделей могло бы привести к созданию повторно используемых компонент для работы с ними, аналогично тому, как это произошло в случае с EMF.
Нельзя сказать, что в Eclipse не было понимания этих проблем. Еще в 2005 году Martin Aeschlimann, обобщая опыт разработки прототипа CDT, аргументировал необходимость создания общей инфраструктуры для языковых моделей, включая и handle-based модели. Но, как это часто бывает, из-за более приоритетных задач до реализации этих идей тогда так и не дошли руки. Между тем, факторизация кода *DT-проектов по-прежнему остается одной из недостаточно проработанных тем в Eclipse.
В определенном смысле, проект Handly призван решать примерно те же задачи, что и EMF, но для handle-based моделей, и в первую очередь языковых (т.е. представляющих элементы структуры некоторого языка программирования). Ниже перечислены основные цели, ставившиеся при проектировании Handly:
Для выделения общих понятий и протоколов были проанализированы существующие реализации языковых handle-based моделей. Основные интерфейсы и базовые реализации, предоставляемые Handly, показаны на рис. 8.
Рис. 8. Общие интерфейсы и базовые реализации элементов Handly
Интерфейс IElement представляет handle элемента и является общим для элементов всех моделей, основанных на Handly. Абстрактный класс Element реализует обобщенный механизм handle/body (рис. 9).
Рис. 9. IElement и обобщенная реализация handle/body
Кроме того, Handly предоставляет обобщенный механизм нотификации об изменении элементов модели (рис. 10). Как можно видеть, в общих чертах он аналогичен механизмам нотификации, реализованным в модели ресурсов и Java-модели, и использует IElementDelta для унифицированного представления информации об изменении элемента.
Рис. 10. Общие интерфейсы и базовые реализации механизма нотификации Handly
Рассмотренная выше часть Handly (рис. 9 и 10) может использоваться для представления практически любых handle-based моделей. Для создания языковых моделей проект предлагает дополнительную функциональность – в частности, общие интерфейсы и базовые реализации для элементов структуры исходного текста, так называемых source elements (рис. 8). Интерфейс ISourceFile представляет исходный файл, а ISourceConstruct – элемент внутри исходного файла. Абстрактные классы SourceFile и SourceConstruct реализуют обобщенные механизмы для поддержки работы с исходными файлами и их элементами, например, работу с текстовыми буферами, привязку к координатам элемента в исходном тексте, reconciling модели с текущим содержимым буфера working copy, и т.п. Реализация этих механизмов обычно является достаточно непростой задачей, и Handly может существенно сократить усилия по разработке языковых handle-based моделей за счет предоставления качественных базовых реализаций.
Помимо перечисленных выше основных механизмов, Handly предоставляет инфраструктуру текстовых буферов и «снимков» (snapshots), поддержку интеграции с редакторами исходного кода (включая реализованную «из коробки» интеграцию с Xtext editor), а также некоторые общие UI-компоненты, работающие с основанными на Handly моделями, такие как outline framework. Для иллюстрации своих возможностей проект предоставляет несколько примеров, в том числе и реализацию модели Java на Handly. (По сравнению с полной реализацией Java-модели в JDT, данная модель намеренно несколько упрощена для большей наглядности.)
Как было отмечено ранее, серьезное внимание при начальном проектировании Handly и дальнейшем развитии уделялось и продолжает уделяться масштабируемости и гибкости.
В принципе, handle-based модели достаточно хорошо масштабируются “by design”. Например, идиома handle/body позволяет ограничить количество потребляемой моделью памяти. Но есть и нюансы. Так, при испытаниях Handly на масштабируемость была обнаружена проблема в реализации механизма нотификации – при изменении большого числа элементов построение дельт занимало слишком много времени. Оказалось, что та же самая проблема присутствует и в Java-модели JDT, из которой был в свое время адаптирован соответствующий код. Мы исправили ошибку в Handly и подготовили аналогичный патч для JDT, который был с благодарностью принят. Это всего лишь один из примеров, когда внедрение Handly в существующие реализации моделей могло бы быть потенциально полезным, ведь в этом случае такую ошибку можно было бы исправить всего в одном месте.
Чтобы сделать внедрение Handly в существующие реализации моделей технически возможным, библиотека должна обладать значительной гибкостью. Основная проблема состоит в том, чтобы сохранить обратную совместимость по API модели. Эта задача была решена в Handly 0.5 посредством четкого отделения специфичного для модели API, определяемого и полностью контролируемого разработчиком, от унифицированного API мета-уровня, предоставляемого библиотекой. Это не только делает технически возможным внедрение Handly в существующие реализации, но также дает разработчику новой модели значительную свободу при проектировании API.
Гибкость имеет и другие аспекты. Например, Handly почти не накладывает ограничений на структуру модели и может использоваться как для моделирования языков общего назначения, так и предметно-ориентированных языков. При построении структуры исходного файла, Handly не предписывает какую-то определенную форму представления AST и в принципе не требует даже самого наличия AST, обеспечивая, таким образом, совместимость с практически любыми механизмами синтаксического анализа. Наконец, Handly поддерживает полноценную интеграцию с Eclipse workspace, но также может работать и непосредственно с файловыми системами, благодаря интеграции с Eclipse File System (EFS).
Текущая версия Handly 0.6 вышла в декабре 2016 года. Несмотря на то, что в настоящее время проект находится в состоянии инкубации и API окончательно еще не зафиксирован, Handly уже используется в двух крупных коммерческих продуктах, которые рискнули выступить в роли «ранних адоптеров», и, надо сказать, пока не жалеют об этом.
Как отмечалось выше, один из этих продуктов – 1C:Enterprise Development Tools, где Handly с самого начала используется для моделирования элементов высокоуровневой структуры таких языков 1С:Предприятие, как встроенный язык программирования и язык запросов. Другой продукт менее известен широкой публике. Это Codasip Studio, интегрированная среда проектирования проблемно-ориентированных процессоров (application-specific instruction-set processor, ASIP), используемая как внутри самой чешской компании Codasip, так и ее клиентами, среди которых AMD, AVG, Mobileye, Sigma Designs. Codasip использует Handly в production c 2015 года, начиная с версии Handly 0.2. Последний на данный момент релиз Codasip Studio использует версию 0.5, выпущенную в июне 2016 года. Ondrej Ilcik, возглавляющий разработку IDE в Codasip, находится в контакте с проектом, обеспечивая крайне важную обратную связь от лица «стороннего адоптера». Он даже смог найти немного свободного времени, чтобы непосредственно поучаствовать в разработке проекта, реализовав слой UI (~ 4000 строк кода) для одного из примеров Handly, модели Java. Более подробную информацию «из первых уст» об использовании Handly адоптерами можно получить на странице Success Stories проекта.
Надеемся, что после выпуска версии 1.0 с гарантией стабильности API и выходом проекта из состояния инкубации, у Handly появятся и новые адоптеры. Пока же проект продолжает обкатку и дальнейшее совершенствование API, выпуская по два «больших» релиза в год – в июне (в ту же дату, что и одновременный релиз Eclipse) и декабре, обеспечивая предсказуемый график, на который могут полагаться адоптеры. Можно еще добавить, что показатель “bug rate” проекта остается на стабильно низком уровне и Handly с самых первых версий надежно работает в продуктах ранних адоптеров. Для дальнейшего знакомства с Eclipse Handly можно использовать Getting Started Tutorial и Architectural Overview.
В данной статье, обзорной по своему характеру, мы попробуем рассмотреть некоторые основы архитектуры Eclipse как платформы для построения интегрированных средств разработки и дать начальное представление о компонентах Eclipse, образующих фундамент технологической платформы для «нового Конфигуратора» 1C: Предприятие, 1C:Enterprise Development Tools. Разумеется, такое рассмотрение неизбежно будет во многом поверхностным и довольно ограниченным, в том числе и потому, что мы ориентируемся не только на Eclipse-разработчиков в качестве целевой аудитории. Впрочем, надеемся, что даже опытные разработчики Eclipse смогут найти в статье интересную для себя информацию. Например, мы расскажем об одном из «секретов Eclipse», относительно новом и малоизвестном пока проекте Eclipse Handly, который был основан и поддерживается фирмой 1C.
Введение в архитектуру Eclipse
Рассмотрим вначале некоторые общие аспекты архитектуры Eclipse на примере Eclipse Java development tools (JDT). Выбор именно JDT в качестве примера не случаен. Это первая интегрированная среда разработки, появившаяся в Eclipse. Остальные *DT проекты Eclipse, такие как Eclipse C/C++ Development Tooling (CDT), были созданы позднее и заимствовали как основные архитектурные принципы, так и отдельные фрагменты исходного кода из JDT. Основы архитектуры, заложенные в JDT, актуальны по сей день для практически любой IDE, построенной поверх Eclipse Platform, в том числе и для 1C:Enterprise Development Tools.
В первую очередь следует отметить, что для Eclipse характерно достаточно четкое архитектурное расслоение, с отделением языково-независимой функциональности от функциональности, предназначенной для поддержки конкретных языков программирования, и отделением UI-независимых «ядерных» (core) компонент от компонент, связанных с поддержкой пользовательского интерфейса.
Так, Eclipse Platform определяет общую, языково-независимую инфраструктуру, а Java development tools добавляют к Eclipse полнофункциональную Java IDE. Как Eclipse Platform, так и JDT состоят из нескольких компонент, каждая из которых относится либо к UI-независимому «ядру», либо к слою UI (рис. 1).
Рис. 1. Eclipse Platform и JDT
Перечислим основные компоненты Eclipse Platform:
- Runtime — Определяет инфраструктуру плагинов. Для Eclipse характерна модульная архитектура. По сути, Eclipse является коллекцией «точек расширения» и «расширений».
- Workspace — Управляет одним или несколькими проектами. Проект состоит из папок и файлов, которые отображаются непосредственно на файловую систему.
- Standard Widget Toolkit (SWT) — Предоставляет базовые элементы пользовательского интерфейса, интегрированные с операционной системой.
- JFace — Предоставляет ряд UI фреймворков, построенных поверх SWT.
- Workbench — Определяет UI-парадигму Eclipse: редакторы, представления, перспективы.
Нужно сказать, что Eclipse Platform предоставляет и множество других полезных компонент для построения интегрированных средств разработки, среди которых можно отметить Debug, Compare, Search, и Team. Отдельно следует упомянуть JFace Text – основу для построения «умных редакторов» исходного кода. К сожалению, даже беглое рассмотрение этих компонент, равно как и компонент UI-слоя не представляется возможным в рамках данной статьи, поэтому в оставшейся части этого раздела мы ограничимся обзором основных «ядерных» компонент Eclipse Platform и JDT.
Core Runtime
Инфраструктура плагинов Eclipse основана на OSGi и предоставляется проектом Eclipse Equinox. Каждый плагин Eclipse является OSGi-бандлом. Спецификация OSGi определяет, в частности, механизмы версионирования и разрешения зависимостей. В дополнение к этим стандартным механизмам, Equinox вводит понятие точки расширения. Каждый плагин может определять свои точки расширения, а также привносить в систему дополнительную функциональность («расширения»), используя точки расширения, определенные этим же или другими плагинами. Хоть сколько-нибудь подробное описание механизмов OSGi и Equinox выходит за рамки данной статьи. Отметим только, что модуляризация в Eclipse имеет тотальный характер (любая подсистема, включая Runtime, состоит из одного или нескольких плагинов), и практически все в Eclipse является расширением. Причем эти принципы были заложены в архитектуру Eclipse еще задолго до внедрения OSGi (в то время использовалась собственная технология, во многом аналогичная OSGi).
Core Workspace
Практически любая интегрированная среда разработки, построенная на основе Eclipse Platform, работает с Eclipse workspace. Именно workspace обычно содержит исходный код разрабатываемого в IDE приложения. Workspace напрямую отображается на файловую систему и состоит из проектов, которые содержат папки и файлы. Эти проекты, папки, и файлы называются ресурсами workspace. Реализация workspace в Eclipse служит как бы кэшем по отношению к файловой системе, что позволяет заметно ускорить обход дерева ресурсов. Кроме того, workspace предоставляет ряд дополнительных сервисов, включая механизм нотификации об изменении ресурсов и инфраструктуру инкрементальных билдеров.
За поддержку workspace и его ресурсов отвечает компонента Core Resources (плагин org.eclipse.core.resources). В частности, эта компонента предоставляет программный доступ к workspace в виде модели ресурсов. Для эффективной работы с этой моделью клиентам нужен простой способ представления ссылки на ресурс. При этом объект, непосредственно хранящий состояние ресурса в модели, было бы желательно спрятать от клиентского доступа. Иначе, в случае, например, удаления файла, клиент мог бы продолжать удерживать объект, которого уже нет в модели, с вытекающими отсюда проблемами. Eclipse решает эту задачу, используя так называемый handle ресурса. Handle выступает в роли ключа (он знает только путь к ресурсу в workspace) и полностью контролирует доступ к внутреннему объекту модели, который непосредственно хранит информацию о состоянии ресурса. Данный дизайн является вариацией паттерна Handle/Body.
Рис. 2 иллюстрирует идиому Handle/Body применительно к модели ресурсов. Интерфейс IResource представляет handle ресурса и является API, в отличие от класса Resource, реализующего этот интерфейс, а также класса ResourceInfo, представляющего body, которые API не являются. Подчеркнем, что handle знает только путь к ресурсу относительно корня workspace и не содержит в себе ссылку на resource info. Объекты resource info образуют так называемое «дерево элементов» (element tree). Эта структура данных полностью материализована в памяти. Чтобы найти экземпляр resource info, соответствующий некоторому handle, element tree обходится в соответствии с путем, хранящимся в этом handle.
Рис. 2. IResource и ResourceInfo
Как мы увидим в дальнейшем, базовый дизайн модели ресурсов (можно назвать его handle-based) используется в Eclipse и для других моделей. А пока перечислим некоторые отличительные свойства этого дизайна:
- Handle является объектом-значением (value object). Объекты-значения – это немутабельные (immutable) объекты, равенство которых не основывается на идентичности. Такие объекты могут безопасно использоваться в качестве ключа в хешированных контейнерах. Несколько экземпляров handle могут ссылаться на один и тот же ресурс. Для их сравнения нужно использовать метод equals(Object).
- Handle определяет поведение ресурса, но не содержит информацию о состоянии ресурса (единственные данные, которые он хранит, это «ключ», путь к ресурсу).
- Handle может ссылаться на несуществующий ресурс (либо ресурс, который еще не создан, либо ресурс, который уже удален). Существование ресурса можно проверить с помощью метода IResource.exists().
- Некоторые операции могут быть реализованы исходя исключительно из информации, хранящейся в самом handle (так называемые handle-only операции). Примерами являются IResource.getParent(), getFullPath(), и т.п. Ресурс не обязательно должен существовать для успешного выполнения такой операции. Операции, для успешного выполнения которых требуется, чтобы ресурс существовал, выбрасывают исключение (CoreException), если ресурс не существует.
Eclipse предоставляет эффективный механизм нотификации об изменениях ресурсов workspace (рис. 3). Ресурсы могут изменяться как в результате действий, выполняемых в самой Eclipse IDE, так и в результате выполнения синхронизации с файловой системой. В обоих случаях подписавшимся на нотификации клиентам предоставляется детальная информация об изменениях в виде «ресурсных дельт» (resource delta). Дельта описывает изменения между двумя состояниями (под-)дерева ресурсов workspace и сама является деревом, каждый узел которого описывает изменение некоторого ресурса и содержит список дельт следующего уровня, описывающих изменения дочерних ресурсов.
Рис. 3. IResourceChangeEvent и IResourceDelta
Основанный на ресурсных дельтах механизм нотификации обладает следующими характеристиками:
- Единственное изменение и множество изменений описываются с помощью одной и той же структуры, поскольку дельта строится по принципу рекурсивной композиции. Клиенты-подписчики могут обрабатывать нотификации об изменении ресурсов с помощью рекурсивного спуска по дереву дельт.
- Дельта содержит полную информацию об изменении ресурса, включая его перемещение и/или изменение ассоциированных с ним «маркеров» (в виде маркеров представляются, например, ошибки компиляции).
- Поскольку ссылки на ресурс делаются через handle, дельта может естественным образом ссылаться на удаленный ресурс.
Как мы вскоре увидим, основные составляющие дизайна механизма нотификации об изменении модели ресурсов актуальны и для других handle-based моделей.
JDT Core
Модель ресурсов Eclipse workspace является фундаментальной языково-независимой моделью. Компонента JDT Core (плагин org.eclipse.jdt.core) предоставляет API для навигации и анализа структуры workspace с точки зрения Java, так называемую «модель Java» (Java model). Этот API определен в терминах элементов Java, в отличие от нижележащего API модели ресурсов, который определен в терминах папок и файлов. Основные интерфейсы дерева элементов Java изображены на рис. 4.
Рис. 4. Элементы модели Java
Модель Java использует ту же идиому handle/body, что и модель ресурсов (рис. 5). IJavaElement – это handle, а JavaElementInfo играет роль body. Интерфейс IJavaElement определяет протокол, общий для всех элементов Java. Некоторые из его методов являются handle-only: getElementName(), getParent(), и т.п. Объект JavaElementInfo хранит состояние соответствующего элемента: его структуру и атрибуты.
Рис. 5. IJavaElement и JavaElementInfo
Модель Java имеет некоторые отличия в реализации базового дизайна handle/body по сравнению с моделью ресурсов. Как отмечалось выше, в модели ресурсов element tree, узлами которого являются объекты resource info, полностью содержится в памяти. Но в модели Java может быть значительно большее число элементов, чем в дереве ресурсов, ведь в ней представлена, в том числе, и внутренняя структура .java и .class файлов: типы, поля, и методы.
Чтобы избежать полной материализации всего дерева элементов в памяти, реализация модели Java использует ограниченный по размеру LRU-кэш element info, где ключом является handle IJavaElement. Объекты element info создаются по запросу по мере того как происходит навигация дерева элементов. При этом наименее часто используемые элементы вытесняются из кэша, и потребление памяти моделью остается ограниченным заданным размером кэша. Это еще одно преимущество handle-based дизайна, который полностью скрывает такие подробности реализации от клиентского кода.
Механизм нотификации об изменении элементов Java в общих чертах аналогичен рассмотренному выше механизму отслеживания изменений ресурсов workspace. Клиент, желающий отслеживать изменения в модели Java, подписывается на нотификации, которые представляются в виде объекта ElementChangedEvent, который содержит IJavaElementDelta (рис. 6).
Рис. 6. ElementChangedEvent и IJavaElementDelta
Модель Java не содержит информацию о теле методов или разрешении имен, поэтому для детального анализа кода, написанного на Java, JDT Core предоставляет дополнительную (не handle-based) модель: абстрактное синтаксическое дерево (abstract syntax tree, AST). AST представляет результат синтаксического анализа исходного текста. Узлы AST соответствуют элементам структуры исходного модуля (объявлениям, операторам, выражениям, и т.п.) и содержат информацию о координатах соответствующего элемента в исходном тексте, а также (в качестве опции) информацию о разрешении имен в виде ссылок на так называемые bindings. Bindings являются объектами, представляющими именованные сущности, такие как типы, методы, и переменные, известные компилятору. В отличие от узлов AST, образующих дерево, bindings поддерживают перекрестные ссылки и в общем случае образуют граф. Абстрактный класс ASTNode является общим базовым классом для всех узлов AST. Подклассы ASTNode соответствуют определенным синтаксическим конструкциям языка Java.
Поскольку синтаксические деревья могут потреблять значительное количество памяти, JDT кэширует только одно AST, для активного редактора. В отличие от модели Java, AST обычно рассматривается как «промежуточная», «временная» модель, на элементы которой клиентам не следует удерживать ссылки вне контекста операции, приведшей к созданию AST.
Перечисленные три модели (Java model, AST, bindings) совместно являются основой для построения «интеллектуальных средств разработки» в JDT, среди которых мощный редактор Java с разнообразными «помощниками», различные действия по обработке исходного кода (среди которых организация списка импорта имен и форматирование в соответствии с настроенным стилем), инструменты поиска и рефакторинга. При этом модель Java играет особую роль, поскольку именно она используется в качестве основы для визуального представления структуры разрабатываемого приложения (например, в Package Explorer, Outline, Search, Call Hierarchy, и Type Hierarchy).
Компоненты Eclipse, используемые в 1С:Enterprise Developments Tools
На рис. 7 показаны компоненты Eclipse, образующие фундамент технологической платформы для 1C:Enterprise Development Tools.
Рис. 7. Eclipse как платформа для 1С:Enterprise Development Tools
Eclipse Platform предоставляет базовую инфраструктуру. Мы рассмотрели некоторые аспекты этой инфраструктуры в предыдущем разделе.
Eclipse Modeling Framework (EMF) предоставляет общие средства моделирования структурированных данных. EMF интегрирован с Eclipse Platform, но может использоваться и отдельно, в обычных приложениях Java. Довольно часто, начинающие Eclipse-разработчики уже хорошо знакомы с EMF, хотя еще не совсем разбираются в тонкостях Eclipse Platform. Одной из причин такой заслуженной популярности является универсальный дизайн, включающий, в том числе, и унифицированный API мета-уровня, который позволяет обобщенно работать с любой EMF моделью. Предоставляемые EMF базовые реализации для объектов модели и подсистема генерации кода модели по мета-модели существенно увеличивают скорость разработки и снижают количество ошибок. Также EMF содержит механизмы сериализации моделей, отслеживания изменений в модели, и многое другое.
Как любой по-настоящему универсальный инструмент, EMF подходит для решения широкого спектра задач, связанных с моделированием, но некоторые классы моделей (например, рассмотренные выше handle-based модели) могут нуждаться в более специализированных средствах моделирования. Рассказывать об EMF – занятие неблагодарное, особенно в ограниченных рамках одной статьи, поскольку это предмет отдельной книги, и довольно толстой. Отметим только, что качественная система обобщений, положенная в основу EMF, позволила появиться на свет целому спектру проектов, посвященных моделированию, которые входят в проект верхнего уровня Eclipse Modeling наряду с самим EMF. Одним из таких проектов является Eclipse Xtext.
Eclipse Xtext предоставляет инфраструктуру «текстового моделирования». Xtext использует ANTLR для синтаксического анализа исходного текста и EMF для представления результирующего ASG (abstract semantic graph, который, по сути, является комбинацией AST и bindings), называемого также «семантической моделью». Грамматика моделируемого с помощью Xtext языка описывается на собственном языке Xtext. Это позволяет не только генерировать описание грамматики для ANTLR, но и получать механизм сериализации AST (т.е. Xtext предоставляет и parser, и unparser), контекстную подсказку, и ряд других языковых компонент. С другой стороны, язык описания грамматики, используемый в Xtext, менее гибок по сравнению, скажем, с языком описания грамматики в ANTLR. Поэтому иногда приходится «подгибать» под Xtext реализуемый язык, что обычно не является проблемой, если речь идет о разрабатываемом с нуля языке, но может быть неприемлемым для языков с уже сложившимся синтаксисом. Несмотря на это, Xtext является в настоящее время наиболее зрелым, функционально полным, и универсальным инструментом в Eclipse для построения языков программирования и средств разработки для них. В частности, он является идеальным инструментом для быстрого прототипирования предметно-ориентированных языков (domain-specific language, DSL). Кроме упомянутого выше «языкового ядра» на основе ANTLR и EMF, Xtext предоставляет множество полезных компонент более высокого уровня, включая механизмы индексации, инкрементального построения, «умный редактор», и многое, многое другое, но оставляет за скобками языковые handle-based модели. Как и EMF, Xtext является предметом достойным отдельной книги, и мы вряд ли сможем даже бегло рассказать сейчас обо всех его возможностях.
1С:Enterprise Development Tools активно используют как EMF сам по себе, так и ряд других проектов Eclipse Modeling. В частности, Xtext является одной из основ средств разработки для таких языков 1С:Предприятие, как встроенный язык программирования и язык запросов. Другой основой этих средств разработки является проект Eclipse Handly, на котором мы остановимся более подробно (из перечисленных компонент Eclipse он пока наименее известен).
Eclipse Handly, подпроект проекта верхнего уровня Eclipse Technology, появился в результате начальной контрибуции кода в Eclipse Foundation, осуществленной фирмой 1C в 2014 году. С тех пор фирма 1С продолжает поддерживать разработку проекта: committer’ы Handly являются сотрудниками фирмы. Проект небольшой, но занимает достаточно уникальную нишу в Eclipse: главной его целью является поддержка разработки handle-based моделей.
Основные архитектурные принципы handle-based моделей, такие как идиома handle/body, рассматривались выше на примере модели ресурсов и Java-модели. Там же отмечалось, что и модель ресурсов, и модель Java являются важными основами для Eclipse Java development tools (JDT). А поскольку практически все *DT проекты Eclipse имеют архитектуру аналогичную JDT, то не будет большим преувеличением сказать, что handle-based модели лежат в основе многих, если не всех IDE, построенных поверх Eclipse Platform. Например, в Eclipse C/C++ Development Tooling (CDT) имеется handle-based модель C/C++, играющая в архитектуре CDT ту же самую роль, что и Java-модель в JDT.
До появления Handly, Eclipse не предлагал специализированных библиотек для построения языковых handle-based моделей. Существующие сейчас модели создавались в основном с помощью непосредственной адаптации кода Java-модели (a.k.a. copy/paste), в тех случаях, когда это позволяет Eclipse Public License (EPL). (Понятно, что, скажем, для проектов самого Eclipse это обычно не является проблемой с юридической точки зрения, чего не скажешь о продуктах с закрытым исходным кодом.) Помимо характерной для нее бессистемности, такая методика приводит к хорошо известным проблемам: дублированию кода, привнесенным при адаптации ошибкам, и т.п. Что еще хуже, результирующие модели остаются «вещью в себе» и не используют имеющийся потенциал для унификации. А ведь выделение общих понятий и протоколов для языковых handle-based моделей могло бы привести к созданию повторно используемых компонент для работы с ними, аналогично тому, как это произошло в случае с EMF.
Нельзя сказать, что в Eclipse не было понимания этих проблем. Еще в 2005 году Martin Aeschlimann, обобщая опыт разработки прототипа CDT, аргументировал необходимость создания общей инфраструктуры для языковых моделей, включая и handle-based модели. Но, как это часто бывает, из-за более приоритетных задач до реализации этих идей тогда так и не дошли руки. Между тем, факторизация кода *DT-проектов по-прежнему остается одной из недостаточно проработанных тем в Eclipse.
В определенном смысле, проект Handly призван решать примерно те же задачи, что и EMF, но для handle-based моделей, и в первую очередь языковых (т.е. представляющих элементы структуры некоторого языка программирования). Ниже перечислены основные цели, ставившиеся при проектировании Handly:
- Выделение основных абстракций предметной области.
- Сокращение усилий и повышение качества реализации языковых handle-based моделей за счет повторного использования кода.
- Предоставление унифицированного API мета-уровня к результирующим моделям, делающее возможным создание общих компонент IDE, работающих с языковыми handle-based моделями.
- Гибкость и масштабируемость.
- Интеграция с Xtext (в отдельном слое).
Для выделения общих понятий и протоколов были проанализированы существующие реализации языковых handle-based моделей. Основные интерфейсы и базовые реализации, предоставляемые Handly, показаны на рис. 8.
Рис. 8. Общие интерфейсы и базовые реализации элементов Handly
Интерфейс IElement представляет handle элемента и является общим для элементов всех моделей, основанных на Handly. Абстрактный класс Element реализует обобщенный механизм handle/body (рис. 9).
Рис. 9. IElement и обобщенная реализация handle/body
Кроме того, Handly предоставляет обобщенный механизм нотификации об изменении элементов модели (рис. 10). Как можно видеть, в общих чертах он аналогичен механизмам нотификации, реализованным в модели ресурсов и Java-модели, и использует IElementDelta для унифицированного представления информации об изменении элемента.
Рис. 10. Общие интерфейсы и базовые реализации механизма нотификации Handly
Рассмотренная выше часть Handly (рис. 9 и 10) может использоваться для представления практически любых handle-based моделей. Для создания языковых моделей проект предлагает дополнительную функциональность – в частности, общие интерфейсы и базовые реализации для элементов структуры исходного текста, так называемых source elements (рис. 8). Интерфейс ISourceFile представляет исходный файл, а ISourceConstruct – элемент внутри исходного файла. Абстрактные классы SourceFile и SourceConstruct реализуют обобщенные механизмы для поддержки работы с исходными файлами и их элементами, например, работу с текстовыми буферами, привязку к координатам элемента в исходном тексте, reconciling модели с текущим содержимым буфера working copy, и т.п. Реализация этих механизмов обычно является достаточно непростой задачей, и Handly может существенно сократить усилия по разработке языковых handle-based моделей за счет предоставления качественных базовых реализаций.
Помимо перечисленных выше основных механизмов, Handly предоставляет инфраструктуру текстовых буферов и «снимков» (snapshots), поддержку интеграции с редакторами исходного кода (включая реализованную «из коробки» интеграцию с Xtext editor), а также некоторые общие UI-компоненты, работающие с основанными на Handly моделями, такие как outline framework. Для иллюстрации своих возможностей проект предоставляет несколько примеров, в том числе и реализацию модели Java на Handly. (По сравнению с полной реализацией Java-модели в JDT, данная модель намеренно несколько упрощена для большей наглядности.)
Как было отмечено ранее, серьезное внимание при начальном проектировании Handly и дальнейшем развитии уделялось и продолжает уделяться масштабируемости и гибкости.
В принципе, handle-based модели достаточно хорошо масштабируются “by design”. Например, идиома handle/body позволяет ограничить количество потребляемой моделью памяти. Но есть и нюансы. Так, при испытаниях Handly на масштабируемость была обнаружена проблема в реализации механизма нотификации – при изменении большого числа элементов построение дельт занимало слишком много времени. Оказалось, что та же самая проблема присутствует и в Java-модели JDT, из которой был в свое время адаптирован соответствующий код. Мы исправили ошибку в Handly и подготовили аналогичный патч для JDT, который был с благодарностью принят. Это всего лишь один из примеров, когда внедрение Handly в существующие реализации моделей могло бы быть потенциально полезным, ведь в этом случае такую ошибку можно было бы исправить всего в одном месте.
Чтобы сделать внедрение Handly в существующие реализации моделей технически возможным, библиотека должна обладать значительной гибкостью. Основная проблема состоит в том, чтобы сохранить обратную совместимость по API модели. Эта задача была решена в Handly 0.5 посредством четкого отделения специфичного для модели API, определяемого и полностью контролируемого разработчиком, от унифицированного API мета-уровня, предоставляемого библиотекой. Это не только делает технически возможным внедрение Handly в существующие реализации, но также дает разработчику новой модели значительную свободу при проектировании API.
Гибкость имеет и другие аспекты. Например, Handly почти не накладывает ограничений на структуру модели и может использоваться как для моделирования языков общего назначения, так и предметно-ориентированных языков. При построении структуры исходного файла, Handly не предписывает какую-то определенную форму представления AST и в принципе не требует даже самого наличия AST, обеспечивая, таким образом, совместимость с практически любыми механизмами синтаксического анализа. Наконец, Handly поддерживает полноценную интеграцию с Eclipse workspace, но также может работать и непосредственно с файловыми системами, благодаря интеграции с Eclipse File System (EFS).
Текущая версия Handly 0.6 вышла в декабре 2016 года. Несмотря на то, что в настоящее время проект находится в состоянии инкубации и API окончательно еще не зафиксирован, Handly уже используется в двух крупных коммерческих продуктах, которые рискнули выступить в роли «ранних адоптеров», и, надо сказать, пока не жалеют об этом.
Как отмечалось выше, один из этих продуктов – 1C:Enterprise Development Tools, где Handly с самого начала используется для моделирования элементов высокоуровневой структуры таких языков 1С:Предприятие, как встроенный язык программирования и язык запросов. Другой продукт менее известен широкой публике. Это Codasip Studio, интегрированная среда проектирования проблемно-ориентированных процессоров (application-specific instruction-set processor, ASIP), используемая как внутри самой чешской компании Codasip, так и ее клиентами, среди которых AMD, AVG, Mobileye, Sigma Designs. Codasip использует Handly в production c 2015 года, начиная с версии Handly 0.2. Последний на данный момент релиз Codasip Studio использует версию 0.5, выпущенную в июне 2016 года. Ondrej Ilcik, возглавляющий разработку IDE в Codasip, находится в контакте с проектом, обеспечивая крайне важную обратную связь от лица «стороннего адоптера». Он даже смог найти немного свободного времени, чтобы непосредственно поучаствовать в разработке проекта, реализовав слой UI (~ 4000 строк кода) для одного из примеров Handly, модели Java. Более подробную информацию «из первых уст» об использовании Handly адоптерами можно получить на странице Success Stories проекта.
Надеемся, что после выпуска версии 1.0 с гарантией стабильности API и выходом проекта из состояния инкубации, у Handly появятся и новые адоптеры. Пока же проект продолжает обкатку и дальнейшее совершенствование API, выпуская по два «больших» релиза в год – в июне (в ту же дату, что и одновременный релиз Eclipse) и декабре, обеспечивая предсказуемый график, на который могут полагаться адоптеры. Можно еще добавить, что показатель “bug rate” проекта остается на стабильно низком уровне и Handly с самых первых версий надежно работает в продуктах ранних адоптеров. Для дальнейшего знакомства с Eclipse Handly можно использовать Getting Started Tutorial и Architectural Overview.
Поделиться с друзьями
artbear
Что за «адоптер»?
PeterG
https://ru.wiktionary.org/wiki/early_adopter
resun1971
Это калька с английского, есть стандартный термин «early adopter», те, кто раньше всех пробуют и осваивают технологию