Pravděpodobně
V tomto článku, který je svou povahou přehledový, se pokusíme podívat na některé základy architektury Eclipse jako platformy pro vytváření integrovaných vývojových nástrojů a poskytnout počáteční představu o komponentách Eclipse, které tvoří základ technologie. platformu pro „nový konfigurátor“ 1C: Enterprise.
Úvod do architektury Eclipse
Podívejme se nejprve na některé obecné aspekty architektury Eclipse na příkladu
Nejprve je třeba poznamenat, že Eclipse se vyznačuje poměrně jasným architektonickým vrstvením, s oddělením funkcí nezávislých na jazyce od funkcí navržených pro podporu konkrétních programovacích jazyků a oddělením „jádrových“ komponent nezávislých na uživatelském rozhraní od komponent souvisejících. s podpůrným uživatelským rozhraním.
Platforma Eclipse tedy definuje společnou, jazykově nezávislou infrastrukturu a vývojové nástroje Java přidávají do Eclipse plnohodnotné Java IDE. Platforma Eclipse i JDT se skládají z několika komponent, z nichž každá patří buď k „jádru“ nezávislému na uživatelském rozhraní, nebo k vrstvě uživatelského rozhraní (obrázek 1).
Rýže. 1. Eclipse Platform a JDT
Uveďme si hlavní součásti platformy Eclipse:
- Runtime — Definuje infrastrukturu zásuvných modulů. Eclipse se vyznačuje modulární architekturou. Eclipse je v podstatě sbírka „bodů rozšíření“ a „rozšíření“.
- Pracovní prostor — Řídí jeden nebo více projektů. Projekt se skládá ze složek a souborů, které jsou mapovány přímo do systému souborů.
- Standardní sada nástrojů pro widgety (SWT) - Poskytuje základní prvky uživatelského rozhraní integrované s operačním systémem.
- JFace — Poskytuje řadu rámců uživatelského rozhraní postavených na SWT.
- Workbench — Definuje paradigma uživatelského rozhraní Eclipse: editory, pohledy, perspektivy.
Je třeba říci, že platforma Eclipse také poskytuje mnoho dalších užitečných komponent pro vytváření integrovaných vývojových nástrojů, včetně Debug, Compare, Search a Team. Zvláštní zmínku si zaslouží JFace Text – základ pro vytváření „chytrých editorů“ zdrojového kódu. Bohužel ani zběžné prozkoumání těchto komponent, stejně jako komponent UI vrstvy, není v rámci tohoto článku možné, takže se ve zbytku této části omezíme na přehled hlavních „core“ komponent platformy Eclipse a JDT.
Core Runtime
Infrastruktura zásuvných modulů Eclipse je založena na
Základní pracovní prostor
Téměř každé integrované vývojové prostředí postavené na platformě Eclipse funguje s pracovním prostorem Eclipse. Je to pracovní prostor, který obvykle obsahuje zdrojový kód aplikace vyvinuté v IDE. Pracovní prostor se mapuje přímo na systém souborů a skládá se z projektů, které obsahují složky a soubory. Tyto projekty, složky a soubory se nazývají zdroje pracovní prostor. Implementace pracovního prostoru v Eclipse slouží jako cache ve vztahu k souborovému systému, což umožňuje výrazně urychlit procházení stromu zdrojů. Workspace navíc poskytuje řadu doplňkových služeb, včetně
Komponenta Core Resources (org.eclipse.core.resources plugin) je zodpovědná za podporu pracovního prostoru a jeho zdrojů. Tato komponenta zejména poskytuje programový přístup k pracovnímu prostoru ve formuláři zdrojové modely. Pro efektivní práci s tímto modelem potřebují klienti jednoduchý způsob, jak prezentovat odkaz na zdroj. V tomto případě by bylo žádoucí skrýt objekt, který přímo ukládá stav zdroje v modelu, před klientským přístupem. V opačném případě by v případě například smazání souboru mohl klient nadále držet objekt, který již není v modelu, s následnými problémy. Eclipse tento problém řeší pomocí tzv zacházet s zdroj. Handle funguje jako klíč (zná pouze cestu ke zdroji v pracovním prostoru) a zcela řídí přístup k objektu interního modelu, který přímo ukládá informace o stavu zdroje. Tento design je variací vzoru
Rýže. Obrázek 2 ilustruje idiom Handle/Body aplikovaný na model zdrojů. Rozhraní IResource představuje popisovač prostředku a je API, na rozdíl od třídy Resource, která implementuje toto rozhraní, a třídy ResourceInfo, která představuje tělo, což nejsou API. Zdůrazňujeme, že handle zná pouze cestu ke zdroji vzhledem ke kořenu pracovního prostoru a neobsahuje odkaz na informace o zdroji. Informační objekty zdrojů tvoří takzvaný „prvkový strom“. Tato datová struktura je zcela zhmotněna v paměti. Chcete-li najít instanci informací o zdroji odpovídající úchytu, projde se strom prvků podle cesty uložené v tomto úchytu.
Rýže. 2. IResource a ResourceInfo
Jak uvidíme později, základní návrh modelu prostředků (mohli bychom ho nazvat založený na rukojeti) se v Eclipse používá i pro jiné modely. Prozatím si uveďme některé z charakteristických vlastností tohoto designu:
- Rukojeť je hodnotový objekt. Hodnotové objekty jsou neměnné objekty, jejichž rovnost není založena na identitě. Takové objekty lze bezpečně použít jako klíč v hashovaných kontejnerech. Více instancí popisovače může odkazovat na stejný prostředek. Chcete-li je porovnat, musíte použít metodu equals(Object).
- Handle definuje chování zdroje, ale neobsahuje informace o stavu zdroje (jediná data, která ukládá, je „klíč“, cesta ke zdroji).
- Popisovač může odkazovat na zdroj, který neexistuje (buď zdroj, který ještě nebyl vytvořen, nebo prostředek, který již byl odstraněn). Existenci zdroje lze zkontrolovat pomocí metody IResource.exists().
- Některé operace mohou být implementovány pouze na základě informací uložených v samotném handle (tzv. handle-only operace). Příklady jsou IResource.getParent(), getFullPath() atd. Aby taková operace byla úspěšná, zdroj nemusí existovat. Operace, které k úspěchu vyžadují existenci prostředku, vyvolají výjimku CoreException, pokud prostředek neexistuje.
Eclipse poskytuje účinný mechanismus pro oznamování změn prostředků pracovního prostoru (obrázek 3). Prostředky se mohou měnit buď v důsledku akcí prováděných v samotném IDE Eclipse, nebo v důsledku synchronizace se systémem souborů. V obou případech jsou klientům, kteří se přihlásí k odběru upozornění, poskytnuty podrobné informace o změnách ve formě „rozdílů zdrojů“. Rozdíl popisuje změny mezi dvěma stavy (pod)stromu zdrojů pracovního prostoru a sám je stromem, jehož každý uzel popisuje změnu zdroje a obsahuje seznam rozdílů na další úrovni, které popisují změny podřízených zdrojů.
Rýže. 3. IResourceChangeEvent a IResourceDelta
Mechanismus oznámení založený na rozdílech prostředků má následující vlastnosti:
- Jediná změna a mnoho změn je popsáno pomocí stejné struktury, protože delta je postavena na principu rekurzivní kompozice. Klienti předplatitelů mohou zpracovávat oznámení o změně prostředků pomocí rekurzivního sestupu přes strom deltas.
- Delta obsahuje úplné informace o změnách zdroje, včetně jeho pohybu a/nebo změn v „značkách“ s ním spojených (například chyby kompilace jsou reprezentovány jako značky).
- Vzhledem k tomu, že se odkazy na prostředky provádějí prostřednictvím popisovače, může delta přirozeně odkazovat na vzdálený prostředek.
Jak brzy uvidíme, hlavní součásti návrhu mechanismu oznamování změny modelu zdrojů jsou relevantní i pro jiné modely založené na rukojeti.
Jádro JDT
Model prostředků pracovního prostoru Eclipse je základním jazykem agnostickým modelem. Komponenta JDT Core (plugin org.eclipse.jdt.core) poskytuje API pro navigaci a analýzu struktury pracovního prostoru z pohledu Java, tzv. „Java model“ (Java model). Toto API je definováno z hlediska prvků Java, na rozdíl od základního API modelu prostředků, které je definováno z hlediska složek a souborů. Hlavní rozhraní stromu prvků Java jsou znázorněna na Obr. 4.
Rýže. 4. Prvky modelu Java
Model Java používá stejný idiom handle/body jako model prostředků (obrázek 5). IJavaElement je rukojeť a JavaElementInfo hraje roli těla. Rozhraní IJavaElement definuje protokol společný pro všechny prvky Java. Některé z jeho metod jsou pouze pro manipulaci: getElementName(), getParent() atd. Objekt JavaElementInfo ukládá stav odpovídajícího prvku: jeho strukturu a atributy.
Rýže. 5. IJavaElement a JavaElementInfo
Java model má určité rozdíly v implementaci základního designu rukojeti/těla ve srovnání s modelem zdrojů. Jak bylo uvedeno výše, v modelu prostředků je strom elementů, jehož uzly jsou objekty informací o zdroji, zcela obsažen v paměti. Ale Java model může mít podstatně větší počet prvků než zdrojový strom, protože také představuje vnitřní strukturu souborů .java a .class: typy, pole a metody.
Aby se zabránilo úplnému zhmotnění celého stromu prvků v paměti, používá implementace modelu Java omezenou velikost mezipaměti LRU informací o prvku, kde klíčem je handle IJavaElement. Objekty info elementu jsou vytvářeny na požádání, když se prochází strom elementů. V tomto případě jsou nejméně často používané položky vyřazeny z mezipaměti a spotřeba paměti modelu zůstává omezena na zadanou velikost mezipaměti. To je další výhoda designu založeného na rukojeti, který zcela skryje takové detaily implementace před klientským kódem.
Mechanismus pro oznamování změn prvků Java je obecně podobný mechanismu pro sledování změn zdrojů pracovního prostoru, který je popsán výše. Klient, který si přeje sledovat změny v modelu Java, se přihlásí k odběru oznámení, která jsou reprezentována jako objekt ElementChangedEvent, který obsahuje IJavaElementDelta (obrázek 6).
Rýže. 6. ElementChangedEvent a IJavaElementDelta
Model Java neobsahuje informace o tělech metod nebo rozlišení názvů, takže pro podrobnou analýzu kódu napsaného v Javě poskytuje JDT Core další model (nezaložený na rukojeti):
Protože stromy syntaxe mohou spotřebovat značné množství paměti, JDT ukládá do mezipaměti pouze jeden AST pro aktivní editor. Na rozdíl od modelu Java je AST obvykle vnímán jako „přechodný“, „dočasný“ model, na jehož prvky by klienti neměli odkazovat mimo kontext operace, která vedla k vytvoření AST.
Uvedené tři modely (Java model, AST, vazby) společně tvoří základ pro budování „inteligentních vývojových nástrojů“ v JDT, včetně výkonného editoru Java s různými „pomocníky“, různými akcemi pro zpracování zdrojového kódu (včetně organizace seznamu importů názvy a formátování podle přizpůsobeného stylu), nástroje pro vyhledávání a refaktorování. V tomto případě hraje zvláštní roli Java model, protože právě on se používá jako základ pro vizuální znázornění struktury vyvíjené aplikace (například v Průzkumníku balíčků, Outline, Vyhledávání, Hierarchii volání a Hierarchie typů).
Komponenty Eclipse používané v 1C:Enterprise Developments Tools
Na Obr. Obrázek 7 ukazuje komponenty Eclipse, které tvoří základ technologické platformy pro 1C:Enterprise Development Tools.
Rýže. 7. Eclipse jako platforma pro vývojové nástroje 1C:Enterprise
Platforma Eclipse poskytuje základní infrastrukturu. Na některé aspekty této infrastruktury jsme se podívali v předchozí části.
Jako každý skutečně univerzální nástroj je EMF vhodný pro řešení široké škály modelovacích problémů, ale některé třídy modelů (například výše popsané modely založené na rukojeti) mohou vyžadovat specializovanější modelovací nástroje. Mluvit o EMF je nevděčný úkol, zvláště v omezeném rozsahu jednoho článku, protože toto je téma na samostatnou a poměrně tlustou knihu. Poznamenejme pouze, že kvalitní systém zobecnění, na kterém je EMF založen, umožnil zrod celé řady projektů věnujících se modelování, které jsou zařazeny do projektu nejvyšší úrovně
1C:Enterprise Development Tools aktivně využívají jak samotný EMF, tak řadu dalších projektů Eclipse Modeling. Zejména Xtext je jedním ze základů vývojových nástrojů pro takové jazyky 1C:Enterprise, jako je vestavěný programovací jazyk a dotazovací jazyk. Dalším základem pro tyto vývojové nástroje je projekt Eclipse Handly, kterému se budeme věnovat podrobněji (z uvedených komponent Eclipse je zatím nejméně známý).
Základní architektonické principy modelů založených na rukojeti, jako je idiom handle/body, byly diskutovány výše s použitím modelu prostředků a modelu Java jako příkladů. Rovněž poznamenal, že jak model zdrojů, tak model Java jsou důležitými základy pro vývojové nástroje Eclipse Java (JDT). A protože téměř všechny projekty *DT Eclipse mají architekturu podobnou JDT, nebylo by velkou nadsázkou tvrdit, že modely založené na rukojeti jsou základem mnoha, ne-li všech IDE postavených na platformě Eclipse. Například Eclipse C/C++ Development Tooling (CDT) má model C/C++ založený na rukojeti, který hraje stejnou roli v architektuře CDT jako model Java v JDT.
Před Handly nenabízelo Eclipse specializované knihovny pro vytváření jazykových modelů založených na ovladačích. Modely, které v současnosti existují, byly vytvořeny především přímou úpravou kódu modelu Java (také známým jako kopírování/vkládání), v případech, kdy to umožňuje Eclipse Public License (EPL). (Je zřejmé, že to obvykle není právní problém, řekněme pro samotné projekty Eclipse, ale ne pro produkty s uzavřeným zdrojovým kódem.) Kromě své přirozené nahodilosti tato technika přináší známé problémy: duplikaci kódu, kterou zavádí při přizpůsobování se chybám, atd. Horší je, že výsledné modely zůstávají „věci samy o sobě“ a nevyužívají potenciálu sjednocení. Ale izolace společných konceptů a protokolů pro jazykové modely založené na rukojeti by mohla vést k vytvoření opakovaně použitelných komponent pro práci s nimi, podobně jako tomu bylo v případě EMF.
Není to tak, že by Eclipse těmto problémům nerozuměl. Ještě v roce 2005
V určitém smyslu je projekt Handly navržen tak, aby řešil přibližně stejné problémy jako EMF, ale pro modely založené na rukojeti, a to především jazykové (tj. reprezentující prvky struktury nějakého programovacího jazyka). Hlavní cíle stanovené při navrhování Handly jsou uvedeny níže:
- Identifikace hlavních abstrakcí předmětové oblasti.
- Snížení úsilí a zlepšení kvality implementace jazykových modelů založených na rukojeti prostřednictvím opětovného použití kódu.
- Poskytování jednotného metaúrovňového API pro výsledné modely, což umožňuje vytvářet společné komponenty IDE, které pracují s modely založenými na jazykových popisovačích.
- Flexibilita a škálovatelnost.
- Integrace s Xtextem (v samostatné vrstvě).
Pro zvýraznění společných konceptů a protokolů byly analyzovány existující implementace modelů založených na ovládání jazyka. Hlavní rozhraní a základní implementace poskytované Handly jsou znázorněny na Obr. 8.
Rýže. 8. Běžná rozhraní a základní implementace prvků Handly
Rozhraní IElement představuje handle prvku a je společné pro prvky všech modelů založených na Handly. Abstraktní třída Element implementuje zobecněný mechanismus rukojeti/těla (obr. 9).
Rýže. 9. IElement a generická implementace rukojeti/těla
Handly navíc poskytuje zobecněný mechanismus pro upozorňování na změny prvků modelu (obr. 10). Jak můžete vidět, je v zásadě podobný oznamovacím mechanismům implementovaným v modelu prostředků a modelu Java a používá IElementDelta k poskytování jednotné reprezentace informací o změně prvku.
Rýže. 10. Obecná rozhraní a základní implementace oznamovacího mechanismu Handly
Část Handly diskutovaná výše (obr. 9 a 10) může být použita k reprezentaci téměř všech modelů založených na rukojeti. Pro tvoření lingvistické modelů, projekt nabízí další funkcionalitu - zejména běžná rozhraní a základní implementace pro prvky struktury zdrojového textu, tzv. zdrojové prvky (obr. 8). Rozhraní ISourceFile představuje zdrojový soubor a ISourceConstruct představuje prvek ve zdrojovém souboru. Abstraktní třídy SourceFile a SourceConstruct implementují zobecněné mechanismy pro podporu práce se zdrojovými soubory a jejich prvky, například práci s textovými buffery, vazbu na souřadnice prvku ve zdrojovém textu, sladění modelů s aktuálním obsahem vyrovnávací paměti pracovní kopie. , atd. Implementace těchto mechanismů je obvykle poměrně náročná a Handly může výrazně snížit úsilí o vývoj jazykových modelů založených na rukojeti poskytnutím vysoce kvalitních základních implementací.
Kromě výše uvedených základních mechanismů poskytuje Handly infrastrukturu pro textové vyrovnávací paměti a snímky, podporu integrace s editory zdrojového kódu (včetně integrované integrace s editorem Xtext) a také některé běžné komponenty uživatelského rozhraní, které práce s editory zdrojového kódu, praktické modely, jako je framework obrysů. Pro ilustraci svých schopností poskytuje projekt několik příkladů, včetně implementace modelu Java v Handly. (Ve srovnání s plnou implementací modelu Java v JDT je tento model záměrně poněkud zjednodušen pro větší přehlednost.)
Jak již bylo zmíněno dříve, hlavní důraz během počátečního návrhu a následného vývoje společnosti Handly byl a nadále bude kladen na škálovatelnost a flexibilitu.
Modely založené na rukojeti se v zásadě škálují docela dobře „by design“. Například idiom handle/body umožňuje omezit množství paměti spotřebované modelem. Ale existují také nuance. Při testování Handly na škálovatelnost byl tedy objeven problém v implementaci mechanismu upozornění – při změně velkého množství prvků zabralo vytváření delt příliš mnoho času. Ukázalo se, že stejný problém byl přítomen v modelu JDT Java, ze kterého byl kdysi přizpůsoben odpovídající kód. Opravili jsme chybu v Handly a připravili podobný patch pro JDT, který byl vděčně přijat. Toto je jen jeden příklad, kdy by zavedení Handly do existujících implementací modelu mohlo být potenciálně užitečné, protože v tomto případě by taková chyba mohla být opravena pouze na jednom místě.
Aby byla implementace Handly do stávajících implementací modelu technicky proveditelná, musí mít knihovna značnou flexibilitu. Hlavním problémem je zachování zpětné kompatibility napříč modelem API. Tento problém byl vyřešen v
Flexibilita má i další aspekty. Například Handly neukládá téměř žádná omezení na strukturu modelu a může být použit k modelování jak univerzálních, tak doménově specifických jazyků. Při konstrukci struktury zdrojového souboru Handly nepředepisuje žádnou konkrétní formu reprezentace AST a v zásadě ani nevyžaduje přítomnost samotného AST, čímž je zajištěna kompatibilita s téměř jakýmkoliv parsovacím mechanismem. A konečně, Handly podporuje plnou integraci s pracovním prostorem Eclipse, ale může také pracovat přímo se souborovými systémy díky integraci s
Současná verze
Jak je uvedeno výše, jedním z těchto produktů je 1C:Enterprise Development Tools, kde se Handly od samého začátku používá k modelování prvků vysoké úrovně struktury takových jazyků 1C:Enterprise jako vestavěného programovacího jazyka a dotazovacího jazyka. . Další produkt je širší veřejnosti méně známý. Tento
Doufáme, že po vydání verze 1.0 se zárukou stability API a opuštění projektu z inkubačního stavu bude mít Handly nové osvojitele. Mezitím projekt pokračuje v testování a dalším vylepšování API a vydává dvě „hlavní“ verze ročně – v červnu (stejné datum jako simultánní vydání Eclipse) a v prosinci, což poskytuje předvídatelný harmonogram, na který se mohou uživatelé spolehnout. Můžeme také dodat, že „chybovost“ projektu zůstává na trvale nízké úrovni a Handly spolehlivě funguje v produktech prvních osvojitelů již od prvních verzí. Chcete-li dále prozkoumat Eclipse Handly, můžete použít
Zdroj: www.habr.com