Probabil că nu mai are nevoie de o prezentare specială. Mulți cunosc Eclipse datorită Eclipse Java development tools (). Această populară IDE open-source de Java este asociată de majoritatea dezvoltatorilor cu cuvântul „Eclipse”. Totuși, Eclipse este și o platformă extensibilă pentru integrarea instrumentelor de dezvoltare (Eclipse Platform), precum și o întreagă serie de IDE-uri construite pe baza acesteia, inclusiv JDT. Eclipse este și Eclipse Project, un proiect de înalt nivel care coordonează dezvoltarea Eclipse Platform și JDT, și Eclipse SDK, rezultatul furnizat al acestei dezvoltări. În cele din urmă, Eclipse este o fundație open-source cu o comunitate uriașă de proiecte, dintre care nu toate sunt scrise în Java sau au legătură cu instrumentele de dezvoltare (de exemplu, proiectele și ). Lumea Eclipse este foarte diversificată.
În acest articol, care este de natură revizională, vom încerca să examinăm câteva aspecte fundamentale ale arhitecturii Eclipse ca platformă pentru construirea de instrumente de dezvoltare integrate și să oferim o primă impresie despre componentele Eclipse care constituie fundația platformei tehnologice pentru „noul Configurator” 1C:Enterprise, . Desigur, o astfel de examinare va fi inevitabil în mare măsură superficială și destul de limitată, și din acest motiv, pentru că ne orientăm nu doar la dezvoltatorii Eclipse ca public țintă. Totuși, sperăm că chiar și dezvoltatorii experimentați Eclipse vor putea găsi informații interesante în articol. De exemplu, ne vom referi la unul dintre „secretele Eclipse”, un proiect relativ nou și puțin cunoscut deocamdată, , care a fost fondat și susținut de firma 1C.

Introducere în arhitectura Eclipse
Să examinăm mai întâi câteva aspecte generale ale arhitecturii Eclipse pe exemplul (JDT). Alegerea exactă a JDT ca exemplu nu este întâmplătoare. Aceasta este prima mediu integrat de dezvoltare care a apărut în Eclipse. Celelalte proiecte *DT ale Eclipse, cum ar fi Eclipse C/C++ Development Tooling (CDT), au fost create mai târziu și au împrumutat atât principii arhitecturale de bază, cât și fragmente specifice de cod sursă din JDT. Principiile arhitecturale stabilite în JDT sunt actuale și astăzi pentru practic orice IDE construită pe baza Eclipse Platform, inclusiv pentru 1C:Enterprise Development Tools.
În primul rând, trebuie menționat că Eclipse are o arhitectură clar stratificată, separând funcționalitatea independentă de limbă de funcționalitatea destinată suportului pentru anumite limbaje de programare, precum și separând componentele 'de bază' (core) independente de UI de cele legate de suportul interfeței utilizator.
Astfel, Eclipse Platform definește o infrastructură generală, independentă de limbă, iar uneltele de dezvoltare Java adaugă o IDE Java complet funcțională la Eclipse. Atât Eclipse Platform, cât și JDT sunt compuse din mai multe componente, fiecare dintre acestea aparținând fie "nucleului" independent de UI, fie unei straturi UI (Fig. 1).

Fig. 1. Eclipse Platform și JDT
Să enumerăm cele mai importante componente ale Eclipse Platform:
- Runtime — Definește infrastructura pluginurilor. Eclipse are o arhitectură modulară. Practic, Eclipse este o colecție de "puncte de extensie" și "extensii".
- Workspace — Gestionează unul sau mai multe proiecte. Un proiect constă din foldere și fișiere, care sunt mapate direct pe sistemul de fișiere.
- Standard Widget Toolkit (SWT) — Oferă elementele de bază ale interfeței utilizator, integrate cu sistemul de operare.
- JFace — Oferă o serie de cadre UI construite pe baza SWT.
- Workbench — Definește paradigma UI a Eclipse: editori, vederi, perspective.
Trebuie spus că Eclipse Platform oferă și multe alte componente utile pentru construirea de instrumente integrate de dezvoltare, printre care se numără Debug, Compare, Search și Team. De asemenea, merită menționat JFace Text – baza pentru construirea de "editors inteligenți" pentru codul sursă. Din păcate, nici măcar o privire de ansamblu asupra acestor componente, precum și a celor din stratul UI nu poate fi făcută în cadrul acestui articol, așa că în restul acestei secțiuni ne vom limita la o prezentare generală a principalelor componente "de bază" ale Eclipse Platform și JDT.
Core Runtime
Infrastructura pluginurilor Eclipse se bazează pe și este furnizată de proiectul . Fiecare plugin Eclipse este un pachet OSGi. Specificația OSGi definește, printre altele, mecanismele de versionare și rezolvare a dependențelor. Pe lângă aceste mecanisme standard, Equinox introduce conceptul de punct de extensie. Fiecare plugin poate defini propriile sale puncte de extensie, precum și aduce funcționalitate suplimentară în sistem („extensii”), folosind punctele de extensie definite de acest plugin sau de altele. O descriere detaliată a mecanismelor OSGi și Equinox depășește scopul acestui articol. Merită menționat că modularizarea în Eclipse este totală (orice subsistem, inclusiv Runtime, constă dintr-unul sau mai multe pluginuri), și practic tot ce există în Eclipse este o extensie. Aceste principii au fost integrate în arhitectura Eclipse cu mult înainte de implementarea OSGi (atunci se folosea o tehnologie proprie, foarte asemănătoare cu OSGi).
Spațiul de lucru Core
Practically orice mediu integrat de dezvoltare, construit pe baza platformei Eclipse, lucrează cu spațiul de lucru Eclipse. Anume spațiul de lucru conține de obicei codul sursă al aplicației dezvoltate în IDE. Spațiul de lucru este mapat direct pe sistemul de fișiere și constă din proiecte care conțin foldere și fișiere. Aceste proiecte, foldere și fișiere sunt numite resurse spațiu de lucru. Implementarea spațiului de lucru în Eclipse servește ca un fel de cache în raport cu sistemul de fișiere, ceea ce permite accelerarea semnificativă a traversării arborelui de resurse. În plus, spațiul de lucru oferă o serie de servicii suplimentare, inclusiv și .
Componenta Core Resources (pluginul org.eclipse.core.resources) este responsabilă pentru suportul spațiului de lucru și al resurselor sale. În special, această componentă oferă acces programatic la spațiul de lucru sub formă de model de resurse. Pentru o utilizare eficientă a acestui model, clienții au nevoie de o modalitate simplă de a reprezenta un link către resursă. În acest caz, obiectul care stochează starea resursei în model ar fi de dorit să fie ascuns de accesul clientului. În caz contrar, de exemplu, în cazul ștergerii unui fișier, clientul ar putea continua să dețină un obiect care nu mai există în model, cu problemele derivante. Eclipse rezolvă această problemă folosind așa-numitul handle al resursei. Handle-ul joacă rolul de cheie (știe doar calea către resursă în spațiul de lucru) și controlează complet accesul la obiectul intern al modelului, care stochează direct informații despre starea resursei. Acest design este o variație a modelului .
Fig. 2 ilustrează idiomul Handle/Body aplicat modelului de resurse. Interfața IResource reprezintă handle-ul resursei și este API-ul, spre deosebire de clasa Resource, care implementează această interfață, și clasa ResourceInfo, care reprezintă body-ul, care nu este API. Subliniem că handle-ul cunoaște doar calea către resursă în raport cu rădăcina workspace-ului și nu conține o referință la resource info. Obiectele resource info formează așa-numitul „arbore de elemente” (element tree). Această structură de date este complet materializată în memorie. Pentru a găsi o instanță de resource info, care corespunde unui anumit handle, arborele de elemente este traversat conform căii stocate în acest handle.

Fig. 2. IResource și ResourceInfo
După cum vom vedea mai departe, designul de bază al modelului de resurse (pe care îl putem numi bazat pe handle) este utilizat în Eclipse și pentru alte modele. Între timp, să enumerăm câteva proprietăți distincte ale acestui design:
- Handle-ul este un obiect-valoare (value object). Obiectele-valoare sunt obiecte imuabile (immutable), egalitatea acestora nefiind bazată pe identitate. Aceste obiecte pot fi utilizate în siguranță ca cheie în containerele Hash. Mai multe instanțe de handle pot face referire la aceeași resursă. Pentru compararea acestora, trebuie folosit metoda equals(Object).
- Handle-ul definește comportamentul resursei, dar nu conține informații despre starea resursei (singurele date pe care le stochează sunt „cheia”, calea către resursă).
- Handle-ul poate face referire la o resursă inexistentă (fie la o resursă care nu a fost încă creată, fie la o resursă care a fost deja eliminată). Existența resursei poate fi verificată prin metoda IResource.exists().
- Anumite operații pot fi implementate având în vedere exclusiv informațiile stocate în handle (așa-numitele operații handle-only). Exemplele includ IResource.getParent(), getFullPath() etc. Resursa nu trebuie să existe pentru a finaliza cu succes o astfel de operație. Operațiile pentru care este necesară existența resursei aruncă o excepție (CoreException) dacă resursa nu există.
Eclipse oferă un mecanism eficient de notificare asupra modificărilor resurselor workspace (fig. 3). Resursele pot fi modificate atât ca urmare a acțiunilor efectuate în cadrul Eclipse IDE, cât și din executarea sincronizării cu sistemul de fișiere. În ambele cazuri, clienții abonați la notificări primesc informații detaliate despre modificări sub formă de „delta de resursă” (resource delta). Delta descrie modificările între două stări ale (sub-)arborelui de resurse din workspace și este ea însăși un arbore, fiecare nod al căruia descrie modificarea unei anumite resurse și conține o listă de delta de nivelul următor, descriind modificările resurselor fiice.

Fig. 3. IResourceChangeEvent și IResourceDelta
Mecanismul de notificare, bazat pe delta de resurse, are următoarele caracteristici:
- O singură modificare și multiple modificări sunt descrise folosind aceeași structură, deoarece delta este construită pe principiul compunerii recursive. Clienții abonați pot gestiona notificările despre modificările resurselor printr-o coborâre recursivă prin arborele delta.
- Delta conține informații complete despre modificarea resursei, inclusiv mutarea acesteia și/sau modificarea „markerilor” asociați (markerii pot reprezenta, de exemplu, erori de compilare).
- Deoarece referințele la resursă sunt realizate prin handle, delta poate face referințe naturale la o resursă îndepărtată.
După cum vom vedea în curând, componentele fundamentale ale designului mecanismului de notificare a modificărilor modelului de resurse sunt relevante și pentru alte modele bazate pe handle.
JDT Core
Modelul de resurse Eclipse workspace este un model fundamental independent de limbaj. Componenta JDT Core (pluginul org.eclipse.jdt.core) oferă API pentru navigarea și analiza structurii workspace-ului din perspectiva Java, denumit „modelul Java” (Java model). Acest API este definit în termeni de elemente Java, spre deosebire de API-ul de bază al modelului de resurse, care este definit în termeni de foldere și fișiere. Interfețele principale ale arborelui de elemente Java sunt ilustrate în fig. 4.

Fig. 4. Elementele modelului Java
Modelul Java utilizează aceeași idiomă handle/body ca modelul resurselor (fig. 5). IJavaElement este un handle, iar JavaElementInfo joacă rolul de body. Interfața IJavaElement definește un protocol comun pentru toate elementele Java. Unele dintre metodele sale sunt doar handle: getElementName(), getParent() etc. Obiectul JavaElementInfo păstrează starea elementului corespunzător: structura și atributele sale.

Fig. 5. IJavaElement și JavaElementInfo
Modelul Java are unele diferențe în implementarea designului de bază handle/body comparativ cu modelul resurselor. Așa cum s-a menționat mai sus, în modelul resurselor element tree, al cărei noduri sunt obiectele resource info, este complet păstrat în memorie. Dar în modelul Java poate exista un număr semnificativ mai mare de elemente decât în pomul resurselor, fiindcă în el se reprezintă, printre altele, și structura internă a fișierelor .java și .class: tipuri, câmpuri și metode.
Pentru a evita materializarea completă a întregului arbore de elemente în memorie, implementarea modelului Java utilizează un cache LRU de dimensiune limitată pentru element info, unde cheia este handle IJavaElement. Obiectele element info sunt create la cerere pe măsură ce se navighează prin arborele elementelor. În acest proces, cele mai puțin utilizate elemente sunt eliminate din cache, iar consumul de memorie al modelului rămâne limitat la dimensiunea stabilită a cache-ului. Aceasta este o altă avantaj al designului bazat pe handle, care ascunde complet astfel de detalii de implementare de codul client.
Mecanismul de notificare a modificărilor elementelor Java este, în linii mari, similar cu mecanismul de urmărire a modificărilor resurselor workspace discutat mai sus. Clientul care dorește să urmărească modificările în modelul Java se abonează la notificările care sunt prezentate sub formă de obiect ElementChangedEvent, care conține IJavaElementDelta (fig. 6).

Fig. 6. ElementChangedEvent și IJavaElementDelta
Modelul Java nu conține informații despre corpul metodelor sau rezolvarea numelui, astfel încât pentru o analiză detaliată a codului scris în Java, JDT Core oferă un model suplimentar (nu bazat pe handle): (abstract syntax tree, AST). AST reprezintă rezultatul analizei sintactice a textului sursă. Nodurile AST corespund elementelor structurii modulului sursă (declarări, operatori, expresii etc.) și conțin informații despre coordonatele elementului corespunzător în textul sursă, precum și (opțional) informații despre rezolvarea numelui sub formă de referințe la așa-numitele. bindings. Bindings sunt obiecte care reprezintă entități denumite, cum ar fi tipuri, metode și variabile, cunoscute compilatorului. Spre deosebire de nodurile AST, care formează un arbore, bindings susțin referințe încrucișate și, în general, formează un graf. Clasa abstractă ASTNode este clasa de bază comună pentru toate nodurile AST. Subclasele ASTNode corespund anumitor construcții sintactice din limbajul Java.
Deoarece arborii sintactici pot consuma o cantitate semnificativă de memorie, JDT cachează doar un singur AST pentru editorul activ. Spre deosebire de modelul Java, AST este de obicei considerat un model „intermediar”, „temporar”, la care clienții nu ar trebui să mențină referințe în afara contextului operațiunii care a dus la crearea AST-ului.
Cele trei modele enumerate (modelul Java, AST, bindings) constituie împreună baza pentru construirea „uneltelor inteligente de dezvoltare” în JDT, printre care un editor Java puternic cu diverse „asistente”, diverse acțiuni de procesare a codului sursă (printre care organizarea listei de importuri de denumiri și formatarea conform stilului configurat), instrumente de căutare și refactorizare. Modelul Java joacă un rol special, deoarece este folosit ca bază pentru reprezentarea vizuală a structurii aplicației în dezvoltare (de exemplu, în Package Explorer, Outline, Search, Call Hierarchy și Type Hierarchy).
Componentele Eclipse utilizate în 1C:Enterprise Developments Tools
În fig. 7 sunt prezentate componentele Eclipse care formează fundația platformei tehnologice pentru 1C:Enterprise Development Tools.

Fig. 7. Eclipse ca platformă pentru 1C:Enterprise Development Tools
Eclipse Platform oferă infrastructura de bază. Am examinat câteva aspecte ale acestei infrastructuri în secțiunea anterioară.
(EMF) oferă instrumente generale pentru modelarea datelor structurate. EMF este integrat cu Eclipse Platform, dar poate fi folosit și separat, în aplicații Java obișnuite. Adesea, dezvoltatorii începători de Eclipse sunt deja familiarizați cu EMF, chiar dacă nu înțeleg pe deplin subtilitățile platformei Eclipse. Una dintre cauzele popularității sale bine meritate este designul său universal, care include, printre altele, o API unificată la nivel meta, ce permite lucrul generic cu orice model EMF. Implementările de bază oferite de EMF pentru obiectele modelului și subsistemul de generare a codului modelului pe baza meta-modelului cresc semnificativ viteza de dezvoltare și reduc numărul de erori. De asemenea, EMF include mecanisme pentru serializarea modelelor, urmărirea modificărilor în model și multe altele.
Ca orice instrument cu adevărat universal, EMF se potrivește pentru o gamă largă de sarcini legate de modelare, dar unele clase de modele (de exemplu, modelele bazate pe handle discutate mai sus) pot necesita instrumente de modelare mai specializate. A vorbi despre EMF este o activitate neplăcută, mai ales în limitele unei singure articole, deoarece este un subiect de carte separată și destul de groasă. Să subliniem doar că sistemul de generalizări de calitate, pe care EMF se bazează, a permis apariția unui întreg spectru de proiecte dedicate modelării, care fac parte din proiectul de top. pe lângă EMF în sine. Un astfel de proiect este Eclipse Xtext.
oferă infrastructura pentru „modelarea textului”. Xtext folosește pentru analiza sintactică a textului sursă și EMF pentru reprezentarea ASG-ului (grafic abstract semantic, care, în esență, este o combinație între AST și bindings), cunoscut și sub denumirea de „model semantic”. Gramatica limbajului modelat cu ajutorul Xtext este descrisă într-un limbaj propriu Xtext. Acest lucru permite nu doar generarea unei descrieri a gramaticii pentru ANTLR, ci și obținerea unui mecanism de serializare AST (adică Xtext oferă atât parser, cât și unparser), sugestii contextuale și o serie de alte componente lingvistice. Pe de altă parte, limbajul de descriere a gramaticii utilizat în Xtext este mai puțin flexibil în comparație, să zicem, cu limbajul de descriere a gramaticii din ANTLR. Prin urmare, uneori trebuie să „îndoi” limbajul implementat pentru Xtext, ceea ce de obicei nu constituie o problemă atunci când este vorba despre un limbaj dezvoltat de la zero, dar poate fi inacceptabil pentru limbaje cu o sintaxă deja stabilită. Cu toate acestea, Xtext este în prezent cel mai matur, complet funcțional și universal instrument din Eclipse pentru construirea limbajelor de programare și a instrumentelor de dezvoltare pentru acestea. În special, acesta este un instrument ideal pentru prototiparea rapidă. (domain-specific language, DSL). Pe lângă menționatul „nuclee lingvistice” bazate pe ANTLR și EMF, Xtext oferă o multitudine de componente utile de nivel superior, inclusiv mecanisme de indexare, construire incrementală, „editor inteligent” și multe, multe altele, dar lasă deoparte modelele lingvistice bazate pe handle. Ca și EMF, Xtext este un subiect care merită o carte separată, și greu putem să discutăm chiar și în treacăt despre toate capacitățile sale.
1C:Enterprise Development Tools utilizează activ atât EMF-ul în sine, cât și o serie de alte proiecte Eclipse Modeling. În special, Xtext este una dintre bazele instrumentelor de dezvoltare pentru limbajele 1C:Enterprise, precum limbajul de programare încorporat și limbajul de interogare. O altă bază a acestor instrumente de dezvoltare este proiectul Eclipse Handly, la care ne vom opri mai în detaliu (dintre componentele enumerate ale Eclipse, acesta este în prezent cel mai puțin cunoscut).
, subproiectul proiectului de nivel superior Eclipse Technology, a apărut ca urmare a contribuției inițiale a codului în cadrul Eclipse Foundation, realizată de compania 1C în 2014. De atunci, compania 1C continuă să susțină dezvoltarea proiectului: committers-ii Handly sunt angajați ai companiei. Proiectul este mic, dar ocupă o nișă suficient de unică în Eclipse: principalul său obiectiv este sprijinirea dezvoltării modelelor bazate pe handle.
Principiile arhitecturale de bază ale modelelor bazate pe handle, cum ar fi idiomul handle/body, au fost discutate mai sus folosind modelul resurselor și modelul Java ca exemple. S-a menționat de asemenea că atât modelul resurselor, cât și modelul Java sunt fundamente importante pentru uneltele de dezvoltare Java Eclipse (JDT). Și, având în vedere că practic toate proiectele *DT din Eclipse au o arhitectură similară cu JDT, nu ar fi o exagerare să spunem că modelele bazate pe handle stau la baza multor, dacă nu tuturor IDE-urilor construite pe platforma Eclipse. De exemplu, în Eclipse C/C++ Development Tooling (CDT) există un model bazat pe handle pentru C/C++, care joacă în arhitectura CDT aceeași rol ca și modelul Java în JDT.
Înainte de apariția Handly, Eclipse nu oferea biblioteci specializate pentru construirea modelelor lingvistice bazate pe handle. Modele existente acum au fost create în principal prin adaptarea directă a codului modelului Java (a.k.a. copy/paste), în acele cazuri în care acest lucru este permis Eclipse Public License (EPL). (Este clar că, de exemplu, pentru proiectele în sine ale Eclipse aceasta nu reprezintă, de obicei, o problemă din punct de vedere juridic, ceea ce nu se poate spune despre produsele cu cod sursă închis.) Pe lângă caracteristica sa dezorganizată, această metodă conduce la probleme bine cunoscute: duplicarea codului, erorile introdusă prin adaptare etc. Ce este și mai rău, modelele rezultate rămân „obiecte în sine” și nu utilizează potențialul existent pentru unificare. Totuși, identificarea conceptelor și protocoalelor generale pentru modelele lingvistice bazate pe handle ar putea duce la crearea unor componente reutilizabile pentru a lucra cu ele, similar cu ceea ce s-a întâmplat în cazul EMF.
Nu se poate spune că în Eclipse nu a existat o înțelegere a acestor probleme. Încă din 2005 , generalizând experiența dezvoltării prototipului CDT, necesitatea creării unei infrastructuri comune pentru modelele lingvistice, inclusiv modelele bazate pe handle. Dar, după cum se întâmplă adesea, din cauza unor sarcini mai prioritare, aceste idei nu au fost puse în aplicare. Între timp, factorizarea codului DT-proiectelor rămâne în continuare unul dintre subiectele insuficient explorate în Eclipse.
Într-un anumit sens, proiectul Handly are scopul de a aborda aproximativ aceleași probleme ca și EMF, dar pentru modelele bazate pe handle, având ca prioritate modelele lingvistice (adică cele care reprezintă elementele structurii unui anumit limbaj de programare). Mai jos sunt enumerate principalele obiective stabilite la proiectarea Handly:
- Identificarea principalelor abstracții din domeniul de aplicare.
- Reducerea eforturilor și îmbunătățirea calității implementării modelelor lingvistice bazate pe handle prin reutilizarea codului.
- Oferirea unui API unificat la nivel meta pentru modelele rezultante, care să faciliteze crearea de componente comune pentru IDE-uri ce lucrează cu modelele lingvistice bazate pe handle.
- Flexibilitate și scalabilitate.
- Integrarea cu Xtext (într-un strat separat).
Pentru a identifica conceptele și protocoalele comune, au fost analizate implementările existente ale modelelor lingvistice bazate pe handle. Interfețele cheie și implementările de bază oferite de Handly sunt prezentate în fig. 8.

Fig. 8. Interfețele comune și implementările de bază ale elementelor Handly
Interfața IElement reprezintă handle-ul unui element și este comună pentru elementele tuturor modelelor bazate pe Handly. Clasa abstractă Element implementează un mecanism generalizat handle/body (fig. 9).

Fig. 9. IElement și implementarea generalizată handle/body
În plus, Handly oferă un mecanism generalizat de notificare a modificărilor elementelor modelului (fig. 10). Așa cum se poate observa, în linii mari, este similar mecanismelor de notificare implementate în modelul de resurse și modelul Java și folosește IElementDelta pentru a prezenta informațiile despre modificarea unui element într-un mod unificat.

Fig. 10. Interfețele comune și implementările de bază ale mecanismului de notificare Handly
Partea discutată anterior a Handly (fig. 9 și 10) poate fi utilizată pentru a reprezenta practic orice modele bazate pe handle. Pentru a crea modele lingvistice proiectul oferă funcționalitate suplimentară – în special, interfețe comune și implementări de bază pentru elementele structurii textului sursă, denumite elemente sursă (fig. 8). Interfața ISourceFile reprezintă fișierul sursă, iar ISourceConstruct – un element din interiorul fișierului sursă. Clasele abstracte SourceFile și SourceConstruct implementează mecanisme generalizate pentru a sprijini lucrul cu fișierele sursă și cu elementele acestora, cum ar fi gestionarea bufferelor de text, legarea la coordonatele unui element din textul sursă, reconcilierea modelului cu conținutul actual al bufferului de lucru etc. Implementarea acestor mecanisme este de obicei o sarcină destul de complexă, iar Handly poate reduce semnificativ eforturile de dezvoltare a modelelor bazate pe handle, oferind implementări de bază de calitate.
Pe lângă mecanismele principale menționate mai sus, Handly oferă infrastructura pentru bufferurile de text și «instantanee» (snapshots), suport pentru integrarea cu editoarele de cod sursă (inclusiv integrarea realizată „din cutie” cu editorul Xtext), precum și unele componente UI comune care funcționează cu modelele bazate pe Handly, cum ar fi framework-ul outline. Pentru a ilustra capabilitățile sale, proiectul oferă câteva exemple, inclusiv implementarea unui model Java pe Handly. (Comparativ cu implementarea completă a modelului Java în JDT, acest model este intenționat doar ușor simplificat pentru o mai bună claritate.)
După cum s-a menționat anterior, un accent serios în proiectarea inițială a Handly și în dezvoltarea continuă a fost și rămâne pus pe scalabilitate și flexibilitate.
În principiu, modelele bazate pe handle se scalază destul de bine „prin design”. De exemplu, idiomul handle/body permite restricționarea cantității de memorie consumate de model. Dar există și subtilități. Astfel, la testarea Handly pentru scalabilitate a fost descoperită o problemă în implementarea mecanismului de notificare – la modificarea unui număr mare de elemente, construirea delta dura prea mult timp. S-a dovedit că aceeași problemă există și în modelul Java JDT, din care codul respectiv a fost adaptat. Am corectat eroarea în Handly și am pregătit un patch similar pentru JDT, care a fost primit cu recunoștință. Aceasta este doar unul dintre exemplele în care implementarea Handly în realizările existente ale modelelor ar putea fi potențial benefică, deoarece în acest caz o asemenea eroare ar putea fi corectată dintr-un singur loc.
Pentru a face integrarea Handly în implementările existente de modele tehnic posibilă, biblioteca trebuie să aibă o flexibilitate semnificativă. Principala problemă constă în păstrarea compatibilității API-ului modelului. Această sarcină a fost rezolvată prin prin separarea clară a API-ului specific modelului, definit și controlat complet de dezvoltator, de API-ul unificat de nivel meta, furnizat de bibliotecă. Aceasta nu doar că face tehnic posibilă integrarea Handly în implementările existente, dar oferă, de asemenea, dezvoltatorului unui model nou o libertate semnificativă în proiectarea API-ului.
Flexibilitatea are și alte aspecte. De exemplu, Handly impune aproape niciun fel de restricții asupra structurii modelului și poate fi utilizat atât pentru modelarea limbajelor de programare de uz general, cât și pentru limbaje orientate pe subiect. În construirea structurii fișierului sursă, Handly nu impune o anumită formă de reprezentare AST și nu necesită, în principiu, nici măcar existența unui AST, asigurând astfel compatibilitatea cu practic orice mecanism de analiză sintactică. În cele din urmă, Handly suportă integrarea completă cu spațiul de lucru Eclipse, dar poate funcționa și direct cu sistemele de fișiere, datorită integrării cu (EFS).
Versiunea curentă a fost lansată în decembrie 2016. Deși în prezent proiectul se află în stare de incubare și API-ul nu este definitiv stabilit, Handly este deja utilizat în două produse comerciale mari, care au îndrăznit să se apuce de rolul de «pionieri» și, trebuie spus, până acum nu regretă acest lucru.
După cum s-a menționat mai sus, unul dintre aceste produse este 1C:Enterprise Development Tools, unde Handly este folosit de la început pentru modelarea elementelor structurii de înalt nivel a limbajelor 1C:Enterprise, cum ar fi limbajul de programare încorporat și limbajul de interogare. Celălalt produs este mai puțin cunoscut publicului larg. Este , un mediu integrat de proiectare pentru procesoare specific pentru aplicații (application-specific instruction-set processor, ASIP), utilizat atât în cadrul companiei cehe Codasip, cât și de clienții săi, printre care se numără , , , . Codasip folosește Handly în producție din 2015, începând cu versiunea Handly 0.2. Ultima versiune a Codasip Studio utilizează versiunea 0.5, lansată în iunie 2016. Ondřej Ilčík, care conduce dezvoltarea IDE-ului la Codasip, este în contact cu proiectul, oferind un feedback esențial din partea „adoptrilor externi”. Chiar a reușit să găsească puțin timp liber pentru a participa direct la dezvoltarea proiectului, implementând un strat UI (~ 4000 de linii de cod) pentru unul dintre exemplele Handly, un model Java. Informații mai detaliate „din prima mână” despre utilizarea Handly de către adoptri pot fi găsite pe pagina a proiectului.
Sperăm că după lansarea versiunii 1.0, cu o garanție a stabilității API-ului și ieșirea proiectului din starea de incubare, Handly va atrage și noi adoptri. Până atunci, proiectul continuă să-și testeze și să îmbunătățească API-ul, lansând câte două „lansări mari” pe an – în iunie (în aceeași dată cu lansarea simultană Eclipse) și în decembrie, asigurând un program predictibil pe care adoptri se pot baza. De asemenea, se poate menționa că rata de erori a proiectului rămâne constant scăzută și Handly funcționează fiabil în produsele adoptrilor timpurii încă din primele sale versiuni. Pentru o familiarizare suplimentară cu Eclipse Handly, se poate utiliza și .
Sursa: habr.com
