Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools

Prawdopodobnie, Zaćmienie już dawno nie potrzebował specjalnego przedstawiania. Wiele osób zna Eclipse dzięki narzędziom programistycznym Eclipse Java (JDT). To popularne środowisko Java IDE o otwartym kodzie źródłowym, które większość programistów kojarzy ze słowem „Eclipse”. Jednak Eclipse jest zarówno rozszerzalną platformą do integracji narzędzi programistycznych (Eclipse Platform), jak i szeregiem zbudowanych na jej bazie IDE, w tym JDT. Eclipse to zarówno projekt Eclipse, projekt najwyższego poziomu koordynujący rozwój platformy Eclipse i JDT, jak i zestaw SDK Eclipse, będący rezultatem tego rozwoju. Wreszcie Eclipse to fundacja typu open source z ogromną społecznością projektów, z których nie wszystkie są napisane w Javie lub powiązane z narzędziami programistycznymi (na przykład projekty Zaćmienie Internetu Rzeczy и Nauka o zaćmieniach). Świat Eclipse jest bardzo różnorodny.

W tym artykule, który ma charakter przeglądowy, postaramy się przyjrzeć niektórym podstawom architektury Eclipse jako platformy do budowania zintegrowanych narzędzi programistycznych i dać wstępne wyobrażenie o komponentach Eclipse, które stanowią podstawę technologii platforma dla „nowego konfiguratora” 1C: Enterprise. 1C: Narzędzia rozwoju przedsiębiorstwa. Oczywiście taka recenzja będzie nieuchronnie w dużej mierze powierzchowna i raczej ograniczona, między innymi dlatego, że skupiamy się nie tylko na programistach Eclipse jako docelowej grupie odbiorców. Mamy jednak nadzieję, że nawet doświadczeni programiści Eclipse będą mogli znaleźć w artykule interesujące informacje. Na przykład porozmawiamy o jednym z „sekretów Eclipse”, stosunkowo nowym i mało znanym projekcie Zaćmienie pod ręką, która została założona i wspierana przez 1C.
Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools

Wprowadzenie do architektury Eclipse

Przyjrzyjmy się najpierw niektórym ogólnym aspektom architektury Eclipse na przykładzie Narzędzia programistyczne Eclipse Java (JDT). Wybór JDT jako przykładu nie jest przypadkowy. Jest to pierwsze zintegrowane środowisko programistyczne, które pojawia się w Eclipse. Inne projekty *DT Eclipse, takie jak Eclipse C/C++ Development Tooling (CDT), powstały później i zapożyczają zarówno podstawowe zasady architektury, jak i indywidualne fragmenty kodu źródłowego z JDT. Podstawy architektury określone w JDT są aktualne do dziś dla prawie każdego IDE zbudowanego na platformie Eclipse, w tym 1C: Enterprise Development Tools.

Przede wszystkim należy zauważyć, że Eclipse charakteryzuje się dość przejrzystym nawarstwieniem architektonicznym, z oddzieleniem funkcjonalności niezależnej od języka od funkcjonalności przeznaczonej do obsługi konkretnych języków programowania oraz oddzieleniem niezależnych od UI komponentów „rdzeniowych” od komponentów powiązanych z obsługą interfejsu użytkownika.

W ten sposób platforma Eclipse definiuje wspólną, niezależną od języka infrastrukturę, a narzędzia programistyczne Java dodają do Eclipse w pełni funkcjonalne środowisko Java IDE. Zarówno platforma Eclipse, jak i JDT składają się z kilku komponentów, z których każdy należy albo do „rdzenia” niezależnego od interfejsu użytkownika, albo do warstwy interfejsu użytkownika (rysunek 1).

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 1. Platforma Eclipse i JDT

Wymieńmy główne komponenty platformy Eclipse:

  • Czas pracy — Definiuje infrastrukturę wtyczek. Eclipse charakteryzuje się modułową architekturą. Zasadniczo Eclipse to zbiór „punktów rozszerzeń” i „rozszerzeń”.
  • Workspace — Zarządza jednym lub większą liczbą projektów. Projekt składa się z folderów i plików mapowanych bezpośrednio do systemu plików.
  • Standardowy zestaw narzędzi do widżetów (SWT) - Zapewnia podstawowe elementy interfejsu użytkownika zintegrowane z systemem operacyjnym.
  • JFace — Zapewnia szereg frameworków interfejsu użytkownika zbudowanych na bazie SWT.
  • Workbench — Definiuje paradygmat interfejsu użytkownika Eclipse: edytory, widoki, perspektywy.

Trzeba powiedzieć, że platforma Eclipse zapewnia także wiele innych przydatnych komponentów do budowania zintegrowanych narzędzi programistycznych, w tym Debugowanie, Porównywanie, Wyszukiwanie i Zespół. Na szczególną uwagę zasługuje JFace Text - podstawa do budowy „inteligentnych edytorów” kodu źródłowego. Niestety, nawet pobieżne zbadanie tych komponentów, a także komponentów warstwy interfejsu użytkownika, nie jest możliwe w ramach tego artykułu, dlatego w pozostałej części tej sekcji ograniczymy się do przeglądu głównych „podstawowych” komponentów Platforma Eclipse i JDT.

Rdzeń wykonawczy

Na nim opiera się infrastruktura wtyczek Eclipse OSGi i zapewnione przez projekt Równonoc zaćmienia. Każda wtyczka Eclipse jest pakietem OSGi. Specyfikacja OSGi definiuje w szczególności mechanizmy wersjonowania i rozwiązywania zależności. Oprócz tych standardowych mechanizmów firma Equinox wprowadza tę koncepcję punkty ekspansji. Każda wtyczka może definiować własne punkty rozszerzeń, a także wprowadzać do systemu dodatkowe funkcjonalności („rozszerzenia”) za pomocą punktów rozszerzeń zdefiniowanych przez tę samą lub inne wtyczki. Szczegółowy opis mechanizmów OSGi i Equinox wykracza poza zakres tego artykułu. Zauważmy tylko, że modularyzacja w Eclipse jest całkowita (każdy podsystem, łącznie z Runtime, składa się z jednej lub większej liczby wtyczek), a prawie wszystko w Eclipse jest rozszerzeniem. Co więcej, zasady te zostały osadzone w architekturze Eclipse na długo przed wprowadzeniem OSGi (wówczas korzystano z własnej technologii, bardzo podobnej do OSGi).

Podstawowy obszar roboczy

Prawie każde zintegrowane środowisko programistyczne zbudowane na platformie Eclipse współpracuje z obszarem roboczym Eclipse. Jest to obszar roboczy, w którym zazwyczaj znajduje się kod źródłowy aplikacji opracowanej w środowisku IDE. Obszar roboczy jest odwzorowywany bezpośrednio na system plików i składa się z projektów zawierających foldery i pliki. Te projekty, foldery i pliki nazywane są Surowce obszar roboczy. Implementacja obszaru roboczego w Eclipse pełni funkcję pamięci podręcznej w stosunku do systemu plików, co pozwala znacznie przyspieszyć poruszanie się po drzewie zasobów. Dodatkowo Workspace udostępnia szereg dodatkowych usług, m.in mechanizm powiadamiania o zmianach zasobów и przyrostową infrastrukturę deweloperską.

Komponent Core Resources (wtyczka org.eclipse.core.resources) odpowiada za obsługę obszaru roboczego i jego zasobów. W szczególności komponent ten zapewnia programowy dostęp do obszaru roboczego w formularzu modele zasobów. Aby efektywnie pracować z tym modelem, klienci potrzebują prostego sposobu przedstawienia łącza do zasobu. W takim przypadku pożądane byłoby ukrycie obiektu bezpośrednio przechowującego stan zasobu w modelu przed dostępem klienta. W przeciwnym razie w przypadku np. usunięcia pliku klient mógłby w dalszym ciągu przetrzymywać obiekt, którego nie ma już w modelu, co wiązałoby się z problemami. Eclipse rozwiązuje ten problem za pomocą czegoś o nazwie uchwyt ratunek. Handle pełni rolę klucza (zna jedynie ścieżkę do zasobu w obszarze roboczym) i całkowicie kontroluje dostęp do obiektu modelu wewnętrznego, który bezpośrednio przechowuje informację o stanie zasobu. Ten projekt jest odmianą wzoru Uchwyt/korpus.

Ryż. Rysunek 2 ilustruje idiom Handle/Body zastosowany do modelu zasobów. Interfejs IResource reprezentuje uchwyt zasobu i jest interfejsem API, w przeciwieństwie do klasy Resource, która implementuje ten interfejs, i klasy ResourceInfo, która reprezentuje treść, a które nie są interfejsami API. Podkreślamy, że uchwyt zna jedynie ścieżkę do zasobu w stosunku do katalogu głównego obszaru roboczego i nie zawiera łącza do informacji o zasobach. Obiekty informacji o zasobach tworzą tak zwane „drzewo elementów”. Ta struktura danych jest całkowicie materializowana w pamięci. Aby znaleźć instancję informacji o zasobie odpowiadającą uchwytowi, drzewo elementów jest przeglądane zgodnie ze ścieżką zapisaną w tym uchwycie.

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 2. IResource i ResourceInfo

Jak zobaczymy później, podstawowy projekt modelu zasobów (możemy nazwać go opartym na uchwytach) jest używany w Eclipse także w innych modelach. Na razie wymieńmy niektóre charakterystyczne właściwości tego projektu:

  • Uchwyt jest obiektem wartościowym. Obiekty wartości to obiekty niezmienne, których równość nie jest oparta na tożsamości. Takie obiekty można bezpiecznie wykorzystać jako klucz w zaszyfrowanych kontenerach. Wiele wystąpień uchwytu może odwoływać się do tego samego zasobu. Aby je porównać, należy użyć metody równości(Object).
  • Uchwyt określa zachowanie zasobu, ale nie zawiera informacji o stanie zasobu (jedyne dane, jakie przechowuje to „klucz”, czyli ścieżka do zasobu).
  • Uchwyt może odnosić się do zasobu, który nie istnieje (albo zasobu, który nie został jeszcze utworzony, albo zasobu, który został już usunięty). Istnienie zasobu można sprawdzić za pomocą metody IResource.exists().
  • Niektóre operacje można zrealizować wyłącznie w oparciu o informacje zapisane w samym handle (tzw. operacje handle-only). Przykładami są IResource.getParent(), getFullPath() itp. Zasób nie musi istnieć, aby taka operacja zakończyła się sukcesem. Operacje wymagające istnienia zasobu, aby zakończyć się pomyślnie, zgłaszają wyjątek CoreException, jeśli zasób nie istnieje.

Eclipse zapewnia wydajny mechanizm powiadamiania o zmianach w zasobach obszaru roboczego (rysunek 3). Zasoby mogą ulec zmianie w wyniku działań wykonanych w samym środowisku Eclipse IDE lub w wyniku synchronizacji z systemem plików. W obu przypadkach klienci subskrybujący powiadomienia otrzymują szczegółową informację o zmianach w postaci „delt zasobów”. Delta opisuje zmiany między dwoma stanami (pod)drzewa zasobów obszaru roboczego i sama jest drzewem, którego każdy węzeł opisuje zmianę w zasobie i zawiera listę delt na następnym poziomie, które opisują zmiany w zasobach podrzędnych.

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 3. IResourceChangeEvent i IResourceDelta

Mechanizm powiadamiania oparty na deltach zasobów charakteryzuje się następującymi cechami:

  • Pojedynczą zmianę i wiele zmian opisano przy użyciu tej samej struktury, ponieważ delta jest budowana w oparciu o zasadę kompozycji rekurencyjnej. Klienci subskrybenci mogą przetwarzać powiadomienia o zmianie zasobów przy użyciu rekurencyjnego opadania przez drzewo delt.
  • Delta zawiera pełną informację o zmianach w zasobie, w tym o jego ruchu i/lub zmianach w powiązanych z nim „znacznikach” (na przykład błędy kompilacji są reprezentowane jako znaczniki).
  • Ponieważ odniesienia do zasobów są tworzone poprzez uchwyt, delta może naturalnie odwoływać się do zdalnego zasobu.

Jak wkrótce się przekonamy, główne elementy projektu mechanizmu powiadamiania o zmianach w modelu zasobów mają zastosowanie także w przypadku innych modeli opartych na uchwytach.

Rdzeń JDT

Model zasobów obszaru roboczego Eclipse jest podstawowym modelem niezależnym od języka. Komponent JDT Core (wtyczka org.eclipse.jdt.core) udostępnia API do nawigacji i analizowania struktury obszaru roboczego z perspektywy Java, tzw. „model Java” (Model Javy). Ten interfejs API jest zdefiniowany w kategoriach elementów Java, w przeciwieństwie do podstawowego interfejsu API modelu zasobów, który jest zdefiniowany w kategoriach folderów i plików. Główne interfejsy drzewa elementów Java pokazano na rys. 4.

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 4. Elementy modelu Java

Model Java wykorzystuje ten sam idiom uchwytu/treści co model zasobów (rysunek 5). IJavaElement jest uchwytem, ​​a JavaElementInfo pełni rolę treści. Interfejs IJavaElement definiuje protokół wspólny dla wszystkich elementów Java. Niektóre z jego metod obsługują tylko uchwyt: getElementName(), getParent() itp. Obiekt JavaElementInfo przechowuje stan odpowiedniego elementu: jego strukturę i atrybuty.

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 5. IJavaElement i JavaElementInfo

Model Java ma pewne różnice w implementacji podstawowego projektu uchwytu/korpusu w porównaniu z modelem zasobów. Jak zauważono powyżej, w modelu zasobów drzewo elementów, którego węzły są obiektami informacji o zasobach, jest w całości zawarte w pamięci. Jednak model Java może mieć znacznie większą liczbę elementów niż drzewo zasobów, ponieważ reprezentuje również wewnętrzną strukturę plików .java i .class: typy, pola i metody.

Aby uniknąć całkowitej materializacji całego drzewa elementów w pamięci, implementacja modelu Java wykorzystuje pamięć podręczną LRU o ograniczonym rozmiarze zawierającą informacje o elementach, gdzie kluczem jest uchwyt IJavaElement. obiekty informacji o elementach są tworzone na żądanie podczas nawigacji po drzewie elementów. W takim przypadku najrzadziej używane elementy są usuwane z pamięci podręcznej, a zużycie pamięci przez model pozostaje ograniczone do określonego rozmiaru pamięci podręcznej. To kolejna zaleta projektowania opartego na uchwytach, które całkowicie ukrywa takie szczegóły implementacji przed kodem klienta.

Mechanizm powiadamiania o zmianach w elementach Java jest ogólnie podobny do mechanizmu śledzenia zmian w zasobach obszaru roboczego omówionego powyżej. Klient chcący monitorować zmiany w modelu Java subskrybuje powiadomienia, które są reprezentowane jako obiekt ElementChangedEvent zawierający obiekt IJavaElementDelta (rysunek 6).

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 6. ElementChangedEvent i IJavaElementDelta

Model Java nie zawiera informacji o treściach metod ani rozpoznawaniu nazw, dlatego do szczegółowej analizy kodu napisanego w Javie JDT Core udostępnia dodatkowy (nieoparty na uchwytach) model: abstrakcyjne drzewo składni (abstrakcyjne drzewo składni, AST). AST reprezentuje wynik analizy tekstu źródłowego. Węzły AST odpowiadają elementom struktury modułu źródłowego (deklaracje, operatory, wyrażenia itp.) i zawierają informację o współrzędnych odpowiedniego elementu w tekście źródłowym oraz (opcjonalnie) informację o rozpoznawaniu nazw w w formie linków do tzw wiązania. Powiązania to obiekty reprezentujące nazwane jednostki, takie jak typy, metody i zmienne, znane kompilatorowi. W przeciwieństwie do węzłów AST, które tworzą drzewo, powiązania obsługują odniesienia i ogólnie tworzą wykres. Klasa abstrakcyjna ASTNode jest wspólną klasą bazową dla wszystkich węzłów AST. Podklasy ASTNode odpowiadają określonym konstrukcjom składniowym języka Java.

Ponieważ drzewa składni mogą zużywać znaczną ilość pamięci, JDT buforuje tylko jedną funkcję AST dla aktywnego edytora. W przeciwieństwie do modelu Java, AST jest zwykle postrzegany jako model „pośredni”, „tymczasowy”, do którego elementów klienci nie powinni odwoływać się poza kontekstem operacji, która doprowadziła do utworzenia AST.

Wymienione trzy modele (model Java, AST, powiązania) razem tworzą podstawę do budowy „inteligentnych narzędzi programistycznych” w JDT, w tym potężnego edytora Java z różnymi „pomocnikami”, różnymi akcjami przetwarzania kodu źródłowego (w tym organizowaniem listy importowanych nazwy i formatowanie według indywidualnego stylu), narzędzia wyszukiwania i refaktoryzacji. W tym przypadku model Java odgrywa szczególną rolę, ponieważ to na nim opiera się wizualna reprezentacja struktury tworzonej aplikacji (na przykład w Eksploratorze pakietów, Konspekcie, Wyszukiwaniu, Hierarchii połączeń i Hierarchia typów).

Komponenty Eclipse używane w 1C:Enterprise Development Tools

Na ryc. Rysunek 7 przedstawia komponenty Eclipse, które stanowią podstawę platformy technologicznej dla 1C:Enterprise Development Tools.

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 7. Eclipse jako platforma dla 1C:Enterprise Development Tools

Platforma Zaćmienie zapewnia podstawową infrastrukturę. Niektórym aspektom tej infrastruktury przyjrzeliśmy się w poprzedniej sekcji.

Framework modelowania Eclipse (EMF) zapewnia ogólny sposób modelowania danych strukturalnych. EMF jest zintegrowany z platformą Eclipse, ale może być również używany oddzielnie w zwykłych aplikacjach Java. Dość często nowi programiści Eclipse są już dobrze zaznajomieni z EMF, chociaż nie rozumieją jeszcze w pełni zawiłości platformy Eclipse. Jednym z powodów tak zasłużonej popularności jest uniwersalna konstrukcja, która obejmuje między innymi ujednolicone API na poziomie meta, które pozwala na ogólną pracę z dowolnym modelem EMF. Podstawowe implementacje obiektów modelowych dostarczone przez EMF oraz podsystem generowania kodu modelu na podstawie metamodelu znacznie zwiększają szybkość rozwoju i zmniejszają liczbę błędów. EMF zawiera także mechanizmy serializacji modeli, śledzenia zmian w modelu i wiele więcej.

Jak każde narzędzie naprawdę ogólnego przeznaczenia, EMF nadaje się do rozwiązywania szerokiego zakresu problemów modelowania, ale niektóre klasy modeli (na przykład omówione powyżej modele oparte na uchwytach) mogą wymagać bardziej wyspecjalizowanych narzędzi do modelowania. Opowiadanie o PEM jest niewdzięcznym zadaniem, zwłaszcza w ramach jednego artykułu, gdyż jest to temat na osobną książkę, i to dość obszerną. Zauważmy tylko, że wysokiej jakości system uogólnień leżący u podstaw EMF pozwolił na narodziny całej gamy projektów poświęconych modelowaniu, które zaliczają się do projektu najwyższego poziomu Modelowanie zaćmień wraz z samym polem elektromagnetycznym. Jednym z takich projektów jest Eclipse Xtext.

Xtekst zaćmienia zapewnia infrastrukturę „modelowania tekstu”. Xtext używa Mrówka do analizowania tekstu źródłowego i EMF do reprezentowania powstałego ASG (abstrakcyjny wykres semantyczny, który jest zasadniczo kombinacją AST i powiązań), zwany także „modelem semantycznym”. Gramatyka języka modelowanego przez Xtext jest opisana we własnym języku Xtext. Pozwala to nie tylko wygenerować opis gramatyczny dla ANTLR, ale także uzyskać mechanizm serializacji AST (tj. Xtext udostępnia zarówno parser, jak i unparser), wskazówkę kontekstową i szereg innych komponentów językowych. Z drugiej strony język gramatyczny używany w Xtext jest mniej elastyczny niż, powiedzmy, język gramatyczny używany w ANTLR. Dlatego czasami konieczne jest „nagięcie” zaimplementowanego języka do Xtext, co zwykle nie stanowi problemu, jeśli mówimy o języku tworzonym od podstaw, ale może być nie do przyjęcia w przypadku języków o ustalonej już składni. Mimo to Xtext jest obecnie najbardziej dojrzałym, bogatym w funkcje i wszechstronnym narzędziem w Eclipse do budowania języków programowania i narzędzi programistycznych dla nich. W szczególności jest to idealne narzędzie do szybkiego prototypowania języki specyficzne dla domeny (język specyficzny dla domeny, DSL). Oprócz wyżej wspomnianego „rdzenia językowego” opartego na ANTLR i EMF, Xtext zapewnia wiele przydatnych komponentów wyższego poziomu, w tym mechanizmy indeksowania, konstrukcję przyrostową, „inteligentny edytor” i wiele, wiele więcej, ale pomija obsługę oparte na modelach językowych. Podobnie jak EMF, Xtext jest tematem godnym osobnej książki i trudno nam obecnie nawet pokrótce omówić wszystkie jego możliwości.

1C: Enterprise Development Tools aktywnie wykorzystuje zarówno sam EMF, jak i wiele innych projektów Eclipse Modeling. W szczególności Xtext jest jednym z fundamentów narzędzi programistycznych dla takich języków 1C:Enterprise, jak wbudowany język programowania i język zapytań. Kolejną podstawą tych narzędzi programistycznych jest projekt Eclipse Handly, który omówimy bardziej szczegółowo (spośród wymienionych komponentów Eclipse jest on wciąż najmniej znany).

Zaćmienie pod ręką, podprojekt najwyższego poziomu projektu Eclipse Technology, powstał w wyniku wstępnego wkładu kodu do Fundacji Eclipse wniesionego przez 1C w 2014 roku. Od tego czasu 1C nadal wspiera rozwój projektu: Osoby odpowiedzialne za Handly są pracownikami firmy. Projekt jest niewielki, ale zajmuje dość wyjątkową niszę w Eclipse: jego głównym celem jest wspieranie rozwoju modeli opartych na uchwytach.

Podstawowe zasady architektury modeli opartych na uchwytach, takie jak idiom uchwyt/treść, zostały omówione powyżej na przykładach modelu zasobów i modelu Java. Zauważono również, że zarówno model zasobów, jak i model Java stanowią ważne podstawy narzędzi programistycznych Eclipse Java (JDT). A ponieważ prawie wszystkie projekty *DT Eclipse mają architekturę podobną do JDT, nie będzie wielką przesadą stwierdzenie, że modele oparte na uchwytach leżą u podstaw wielu, jeśli nie wszystkich IDE zbudowanych na platformie Eclipse. Na przykład narzędzie programistyczne Eclipse C/C++ Development Tooling (CDT) ma model C/C++ oparty na uchwytach, który odgrywa tę samą rolę w architekturze CDT, co model Java w JDT.

Przed Handly Eclipse nie oferował wyspecjalizowanych bibliotek do budowania modeli językowych opartych na uchwytach. Obecnie istniejące modele powstały głównie poprzez bezpośrednią adaptację kodu modelu Java (tzw. kopiuj/wklej), w przypadkach, gdy na to pozwala Licencja publiczna Eclipse (EPL). (Oczywiście zwykle nie jest to problem prawny w przypadku, powiedzmy, samych projektów Eclipse, ale nie w przypadku produktów o zamkniętym kodzie źródłowym.) Oprócz nieodłącznej przypadkowości, technika ta wprowadza dobrze znane problemy: duplikację kodu wprowadzaną podczas dostosowywania się do błędów, itp. Co gorsza, powstałe modele pozostają „rzeczami samymi w sobie” i nie wykorzystują potencjału unifikacji. Jednak wyodrębnienie wspólnych koncepcji i protokołów dla modeli języków opartych na uchwytach mogłoby doprowadzić do stworzenia komponentów wielokrotnego użytku do pracy z nimi, podobnie jak to miało miejsce w przypadku EMF.

To nie tak, że Eclipse nie rozumiał tych problemów. W 2005 roku Martina Aeschlimanna, podsumowując doświadczenia związane z opracowywaniem prototypu CDT, argumentował potrzeba stworzenia wspólnej infrastruktury dla modeli językowych, w tym modeli opartych na uchwytach. Jednak, jak to często bywa, ze względu na zadania o wyższym priorytecie, wdrożenie tych pomysłów nigdy nie doszło do skutku. Tymczasem faktoryzacja kodu *DT jest wciąż jednym z słabo rozwiniętych tematów w Eclipse.

W pewnym sensie projekt Handly ma na celu rozwiązanie w przybliżeniu tych samych problemów, co EMF, ale dla modeli opartych na uchwytach, i to przede wszystkim językowych (czyli reprezentujących elementy struktury jakiegoś języka programowania). Poniżej wymieniono główne cele stawiane sobie przy projektowaniu Handly:

  • Identyfikacja głównych abstrakcji z obszaru tematycznego.
  • Zmniejszenie wysiłku i poprawa jakości wdrażania modeli języków opartych na uchwytach poprzez ponowne wykorzystanie kodu.
  • Zapewnienie ujednoliconego interfejsu API na poziomie meta dla wynikowych modeli, umożliwiając tworzenie wspólnych komponentów IDE, które współpracują z modelami opartymi na uchwytach językowych.
  • Elastyczność i skalowalność.
  • Integracja z Xtext (w osobnej warstwie).

Aby podkreślić wspólne koncepcje i protokoły, przeanalizowano istniejące implementacje modeli opartych na uchwytach językowych. Główne interfejsy i podstawowe implementacje udostępniane przez Handly pokazano na rys. 8.

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 8. Wspólne interfejsy i podstawowe implementacje elementów Handly

Interfejs IElement reprezentuje uchwyt elementu i jest wspólny dla elementów wszystkich modeli opartych na Handly. Klasa abstrakcyjna Element implementuje uogólniony mechanizm uchwyt/korpus (rys. 9).

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 9. IElement i ogólna implementacja uchwytu/korpusu

Dodatkowo Handly udostępnia uogólniony mechanizm powiadamiania o zmianach w elementach modelu (rys. 10). Jak widać, jest on zasadniczo podobny do mechanizmów powiadamiania zaimplementowanych w modelu zasobów i modelu Java i wykorzystuje IElementDelta w celu zapewnienia ujednoliconej reprezentacji informacji o zmianie elementu.

Eclipse jako platforma technologiczna dla 1C:Enterprise Development Tools
Ryż. 10. Ogólne interfejsy i podstawowe implementacje mechanizmu powiadomień Handly

Omówioną powyżej część Handly (rys. 9 i 10) można wykorzystać do przedstawienia niemal dowolnych modeli opartych na uchwytach. Do tworzenia lingwistyczny modele, projekt oferuje dodatkową funkcjonalność – w szczególności wspólne interfejsy i podstawowe implementacje elementów struktury tekstu źródłowego, tzw. elementy źródłowe (ryc. 8). Interfejs ISourceFile reprezentuje plik źródłowy, a ISourceConstruct reprezentuje element w pliku źródłowym. Klasy abstrakcyjne SourceFile i SourceConstruct implementują uogólnione mechanizmy wspierające pracę z plikami źródłowymi i ich elementami, na przykład pracę z buforami tekstowymi, wiązanie ze współrzędnymi elementu w tekście źródłowym, uzgadnianie modeli z bieżącą zawartością bufora kopii roboczej itp. Implementacja tych mechanizmów jest zwykle sporym wyzwaniem, a Handly może znacznie zmniejszyć wysiłek związany z opracowywaniem modeli języków opartych na uchwytach, zapewniając wysokiej jakości implementacje podstawowe.

Oprócz podstawowych mechanizmów wymienionych powyżej, Handly zapewnia infrastrukturę dla buforów tekstu i migawek, obsługę integracji z edytorami kodu źródłowego (w tym gotową integrację z edytorem Xtext), a także niektóre typowe komponenty interfejsu użytkownika, które współpracuj z edytorami kodu źródłowego.Poręczne modele, takie jak framework konspektu. Aby zilustrować jego możliwości, projekt podaje kilka przykładów, w tym implementację modelu Java w Handly. (W porównaniu z pełną implementacją modelu Java w JDT, model ten został celowo nieco uproszczony dla większej przejrzystości.)

Jak wspomniano wcześniej, podczas początkowego projektowania i późniejszego rozwoju Handly skupiano się i nadal skupia się na skalowalności i elastyczności.

W zasadzie modele oparte na uchwytach całkiem dobrze skalują się „z założenia”. Na przykład idiom uchwyt/treść pozwala ograniczyć ilość pamięci zużywanej przez model. Ale są też niuanse. Tym samym, testując Handly pod kątem skalowalności, odkryto problem w implementacji mechanizmu powiadomień – przy zmianie dużej liczby elementów konstruowanie delt zajmowało zbyt dużo czasu. Okazało się, że ten sam problem występował w modelu Java JDT, z którego kiedyś zaadaptowano odpowiedni kod. Naprawiliśmy błąd w Handly i przygotowaliśmy podobną łatkę dla JDT, która została przyjęta z wdzięcznością. To tylko jeden przykład, gdzie wprowadzenie Handly do istniejących implementacji modeli mogłoby być potencjalnie przydatne, ponieważ w tym przypadku taki błąd można by naprawić w jednym miejscu.

Aby wdrożenie Handly w istniejących implementacjach modeli było technicznie wykonalne, biblioteka musi charakteryzować się znaczną elastycznością. Głównym problemem jest utrzymanie kompatybilności wstecznej w całym modelu API. Problem ten został rozwiązany w Poręczny 0.5 poprzez wyraźne oddzielenie interfejsu API specyficznego dla modelu, zdefiniowanego i w pełni kontrolowanego przez programistę, od ujednoliconego interfejsu API na poziomie meta dostarczonego przez bibliotekę. To nie tylko sprawia, że ​​technicznie możliwe jest wdrożenie Handly w istniejących wdrożeniach, ale także daje twórcy nowego modelu znaczną swobodę podczas projektowania API.

Elastyczność ma także inne aspekty. Na przykład Handly nie nakłada prawie żadnych ograniczeń na strukturę modelu i może być używany do modelowania zarówno języków ogólnego przeznaczenia, jak i języków specyficznych dla domeny. Konstruując strukturę pliku źródłowego, Handly nie zaleca żadnej szczególnej formy reprezentacji AST i w zasadzie nie wymaga nawet obecności samego AST, zapewniając w ten sposób kompatybilność z niemal każdym mechanizmem analizowania. Wreszcie Handly obsługuje pełną integrację z obszarem roboczym Eclipse, ale może także pracować bezpośrednio z systemami plików dzięki integracji z System plików Eclipse (EFS).

Obecna wersja Poręczny 0.6 ukazał się w grudniu 2016 r. Pomimo faktu, że projekt jest obecnie w fazie inkubacji, a interfejs API nie został jeszcze ostatecznie naprawiony, Handly jest już wykorzystywany w dwóch dużych produktach komercyjnych, które zaryzykowały wystąpienie w roli „wczesnych użytkowników” i, muszę przyznać, jeszcze tego nie żałuj.

Jak wspomniano powyżej, jednym z takich produktów jest 1C:Enterprise Development Tools, gdzie Handly jest używany od samego początku do modelowania elementów struktury wysokiego poziomu takich języków 1C:Enterprise jako wbudowany język programowania i język zapytań . Kolejny produkt jest mniej znany ogółowi społeczeństwa. Ten Studio Codasip, zintegrowane środowisko projektowe dla procesora zestawu instrukcji specyficznego dla aplikacji (ASIP), wykorzystywane zarówno w samej czeskiej firmie Codasip, jak i przez jej klientów, m.in. AMD, AVG, Meble, Sigma Designs. Codasip używa Handly w produkcji od 2015 roku, począwszy od wersji Handly 0.2. Najnowsza wersja Codasip Studio korzysta z wersji 0.5, wydanej w czerwcu 2016 r. Ondřej Ilčík, który kieruje rozwojem IDE w Codasip, jest w kontakcie z projektem i przekazuje istotne informacje zwrotne w imieniu „strony trzeciej”. Udało mu się nawet znaleźć trochę wolnego czasu, aby bezpośrednio wziąć udział w rozwoju projektu, wdrażając warstwę UI (~4000 linii kodu) dla jednego z przykładów Handly, modelu Java. Bardziej szczegółowe informacje z pierwszej ręki na temat korzystania z Handly przez osoby adoptujące można znaleźć na stronie Historie Sukcesu projekt.

Mamy nadzieję, że po wydaniu wersji 1.0 z gwarancją stabilności API i wyjściu projektu ze stanu inkubacji, Handly zyska nowych zwolenników. W międzyczasie projekt kontynuuje testowanie i dalsze ulepszanie interfejsu API, wypuszczając dwie „główne” wydania rocznie – w czerwcu (w tym samym dniu, co jednoczesne wydanie Eclipse) i w grudniu, zapewniając przewidywalny harmonogram, na którym mogą polegać użytkownicy. Możemy również dodać, że „wskaźnik błędów” projektu utrzymuje się na niezmiennie niskim poziomie, a Handly niezawodnie współpracuje z produktami wczesnych użytkowników już od pierwszych wersji. Aby dokładniej poznać Eclipse Handly, możesz użyć Samouczek dla początkujących и Przegląd architektury.

Źródło: www.habr.com

Dodaj komentarz