Måske,
I denne artikel, som er oversigtsmæssigt, vil vi forsøge at se på nogle af det grundlæggende i Eclipse-arkitekturen som en platform til at bygge integrerede udviklingsværktøjer og give en indledende idé om Eclipse-komponenterne, der danner grundlaget for teknologien platform for den "nye Configurator" 1C: Enterprise.
Introduktion til Eclipse Architecture
Lad os først se på nogle generelle aspekter af Eclipse-arkitekturen ved hjælp af eksemplet
Først og fremmest skal det bemærkes, at Eclipse er karakteriseret ved en ret klar arkitektonisk lagdeling, med adskillelse af sproguafhængig funktionalitet fra funktionalitet designet til at understøtte specifikke programmeringssprog, og adskillelse af UI-uafhængige "kerne" komponenter fra komponenter tilknyttet med understøttende brugergrænseflade.
Eclipse-platformen definerer således en fælles, sproguafhængig infrastruktur, og Java-udviklingsværktøjerne tilføjer en komplet Java IDE til Eclipse. Både Eclipse Platform og JDT består af flere komponenter, som hver især tilhører enten en UI-uafhængig "kerne" eller et UI-lag (Figur 1).
Ris. 1. Eclipse Platform og JDT
Lad os liste hovedkomponenterne i Eclipse Platform:
- Runtime — Definerer plugin-infrastrukturen. Eclipse er kendetegnet ved en modulær arkitektur. Grundlæggende er Eclipse en samling af "udvidelsespunkter" og "udvidelser".
- Arbejdsområde - Leder et eller flere projekter. Et projekt består af mapper og filer, der er knyttet direkte til filsystemet.
- Standard Widget Toolkit (SWT) - Giver grundlæggende brugergrænsefladeelementer integreret med operativsystemet.
- JFace — Giver en række UI-frameworks bygget oven på SWT.
- Workbench — Definerer Eclipse UI-paradigmet: redaktører, synspunkter, perspektiver.
Det skal siges, at Eclipse Platformen også giver mange andre nyttige komponenter til at bygge integrerede udviklingsværktøjer, herunder Debug, Compare, Search og Team. Særligt skal nævnes JFace Text - grundlaget for at bygge "smarte editorer" af kildekode. Desværre er selv en overfladisk undersøgelse af disse komponenter, såvel som UI-lagkomponenterne, ikke mulig inden for rammerne af denne artikel, så i resten af dette afsnit vil vi begrænse os til en oversigt over de vigtigste "kerne" komponenter i Eclipse Platform og JDT.
Core Runtime
Eclipse plugin-infrastrukturen er baseret på
Kernearbejdsområde
Næsten ethvert integreret udviklingsmiljø bygget oven på Eclipse-platformen fungerer med Eclipse-arbejdsområdet. Det er arbejdsområdet, der normalt indeholder kildekoden til den applikation, der er udviklet i IDE. Workspace maps direkte til filsystemet og består af projekter, der indeholder mapper og filer. Disse projekter, mapper og filer kaldes ressourcer arbejdsrum. Workspace-implementeringen i Eclipse fungerer som en cache i forhold til filsystemet, hvilket gør det muligt at fremskynde traverseringen af ressourcetræet markant. Derudover yder workspace en række ekstra ydelser, bl.a
Core Resources-komponenten (org.eclipse.core.resources plugin) er ansvarlig for at understøtte arbejdsområdet og dets ressourcer. Især giver denne komponent programmatisk adgang til arbejdsområdet i formularen ressourcemodeller. For at arbejde effektivt med denne model har kunder brug for en enkel måde at præsentere et link til en ressource på. I dette tilfælde ville det være ønskeligt at skjule det objekt, der direkte gemmer ressourcens tilstand i modellen fra klientadgang. Ellers kan klienten i tilfælde af f.eks. sletning af en fil fortsætte med at holde et objekt, der ikke længere er i modellen, med de deraf følgende problemer. Eclipse løser dette problem ved at bruge noget kaldet håndtere ressource. Håndtaget fungerer som en nøgle (det kender kun stien til ressourcen i arbejdsområdet) og styrer fuldstændigt adgangen til det interne modelobjekt, som direkte gemmer information om ressourcens tilstand. Dette design er en variation af mønsteret
Ris. Figur 2 illustrerer Håndtag/Krop-formsproget som anvendt på ressourcemodellen. IResource-grænsefladen repræsenterer en ressources håndtag og er en API i modsætning til Resource-klassen, som implementerer denne grænseflade, og ResourceInfo-klassen, som repræsenterer kroppen, som ikke er API'er. Vi understreger, at handle kun kender stien til ressourcen i forhold til arbejdsområderoden og ikke indeholder et link til ressourceinfo. Ressourceinfo-objekter danner et såkaldt "elementtræ". Denne datastruktur er fuldstændig materialiseret i hukommelsen. For at finde den ressourceinfo-instans, der svarer til et håndtag, krydses elementtræet i overensstemmelse med stien, der er gemt i dette håndtag.
Ris. 2. IResource og ResourceInfo
Som vi vil se senere, bruges det grundlæggende design af ressourcemodellen (vi kunne kalde det håndtagsbaseret) i Eclipse også til andre modeller. Lad os indtil videre liste nogle af de karakteristiske egenskaber ved dette design:
- Håndtag er et værdiobjekt. Værdiobjekter er uforanderlige objekter, hvis lighed ikke er baseret på identitet. Sådanne genstande kan sikkert bruges som nøgle i hasherede containere. Flere forekomster af håndtag kan referere til den samme ressource. For at sammenligne dem skal du bruge equals(Object)-metoden.
- Handle definerer en ressources adfærd, men indeholder ikke information om ressourcens tilstand (de eneste data, den gemmer er "nøglen", stien til ressourcen).
- Handle kan referere til en ressource, der ikke eksisterer (enten en ressource, der endnu ikke er oprettet, eller en ressource, der allerede er blevet slettet). Eksistensen af en ressource kan kontrolleres ved hjælp af IResource.exists() metoden.
- Nogle operationer kan implementeres udelukkende baseret på information gemt i selve håndtaget (såkaldte handle-only operationer). Eksempler er IResource.getParent(), getFullPath() osv. Ressourcen behøver ikke at eksistere for at en sådan operation kan lykkes. Operationer, der kræver, at en ressource eksisterer for at lykkes, kaster en CoreException, hvis ressourcen ikke eksisterer.
Eclipse giver en effektiv mekanisme til at underrette ændringer i arbejdsområdets ressourcer (figur 3). Ressourcer kan ændres enten som et resultat af handlinger udført i selve Eclipse IDE eller som et resultat af synkronisering med filsystemet. I begge tilfælde får kunder, der abonnerer på notifikationer, detaljerede oplysninger om ændringerne i form af "ressourcedeltaer". Et delta beskriver ændringer mellem to tilstande i et arbejdsområde-ressourcetræ og er i sig selv et træ, hvis hver knude beskriver en ændring af en ressource og indeholder en liste over deltaer på det næste niveau, der beskriver ændringer af underordnede ressourcer.
Ris. 3. IResourceChangeEvent og IResourceDelta
Meddelelsesmekanismen baseret på ressourcedeltaer har følgende egenskaber:
- En enkelt ændring og mange ændringer er beskrevet ved hjælp af den samme struktur, da deltaet er bygget efter princippet om rekursiv sammensætning. Abonnentklienter kan behandle meddelelser om ressourceændringer ved hjælp af rekursiv nedstigning gennem et træ af deltaer.
- Deltaet indeholder fuldstændig information om ændringer af ressourcen, inklusive dens bevægelse og/eller ændringer i de "markører", der er knyttet til den (for eksempel er kompileringsfejl repræsenteret som markører).
- Da ressourcereferencer foretages gennem håndtaget, kan delta naturligvis referere til en ekstern ressource.
Som vi snart vil se, er hovedkomponenterne i designet af mekanismen for ændring af ressourcemodelændringer også relevante for andre håndtagsbaserede modeller.
JDT Core
Eclipse-arbejdspladsressourcemodellen er en grundlæggende sprogagnostisk model. JDT Core-komponenten (plugin org.eclipse.jdt.core) giver et API til at navigere og analysere arbejdsrumsstrukturen fra et Java-perspektiv, den såkaldte "Java-model" (Java model). Denne API er defineret i form af Java-elementer, i modsætning til den underliggende ressourcemodel API, som er defineret i form af mapper og filer. De vigtigste grænseflader i Java-elementtræet er vist i fig. 4.
Ris. 4. Java Model Elements
Java-modellen bruger det samme håndtag/kropsformsprog som ressourcemodellen (figur 5). IJavaElement er håndtaget, og JavaElementInfo spiller rollen som krop. IJavaElement-grænsefladen definerer en protokol, der er fælles for alle Java-elementer. Nogle af dens metoder er handle-only: getElementName(), getParent() osv. JavaElementInfo-objektet gemmer det tilsvarende elements tilstand: dets struktur og attributter.
Ris. 5. IJavaElement og JavaElementInfo
Java-modellen har nogle forskelle i implementeringen af det grundlæggende håndtag/kropsdesign sammenlignet med ressourcemodellen. Som nævnt ovenfor er elementtræet, hvis noder er ressourceinfo-objekter, i ressourcemodellen fuldstændig indeholdt i hukommelsen. Men Java-modellen kan have et betydeligt større antal elementer end ressourcetræet, fordi den også repræsenterer den interne struktur af .java- og .class-filer: typer, felter og metoder.
For at undgå fuldstændig at materialisere hele træet af elementer i hukommelsen, bruger Java-modelimplementeringen en begrænset størrelse LRU-cache med elementinfo, hvor nøglen er handle IJavaElement. element info-objekter oprettes efter behov, mens elementtræet navigeres. I dette tilfælde bliver de mindst hyppigt brugte elementer smidt ud af cachen, og modellens hukommelsesforbrug forbliver begrænset til den angivne cachestørrelse. Dette er en anden fordel ved håndtagsbaseret design, som fuldstændigt skjuler sådanne implementeringsdetaljer fra klientkoden.
Mekanismen til at underrette ændringer af Java-elementer svarer generelt til mekanismen til sporing af ændringer i arbejdsrumsressourcer beskrevet ovenfor. En klient, der ønsker at overvåge ændringer i Java-modellen, abonnerer på meddelelser, som er repræsenteret som et ElementChangedEvent-objekt, der indeholder en IJavaElementDelta (figur 6).
Ris. 6. ElementChangedEvent og IJavaElementDelta
Java-modellen indeholder ikke information om metodelegemer eller navneopløsning, så til detaljeret analyse af kode skrevet i Java, leverer JDT Core en ekstra (ikke-håndtag-baseret) model:
Fordi syntakstræer kan forbruge en betydelig mængde hukommelse, cacher JDT kun én AST for den aktive editor. I modsætning til Java-modellen ses AST typisk som en "mellemliggende", "midlertidig" model, hvis medlemmer ikke bør holdes refereret af klienter uden for konteksten af den operation, der førte til oprettelsen af AST.
De anførte tre modeller (Java-model, AST, bindinger) danner tilsammen grundlaget for opbygning af "intelligente udviklingsværktøjer" i JDT, herunder en kraftfuld Java-editor med forskellige "hjælpere", forskellige handlinger til behandling af kildekode (inklusive organisering af en liste over import navne og formatering i henhold til den tilpassede stil), søge- og refaktoreringsværktøjer. I dette tilfælde spiller Java-modellen en særlig rolle, da det er den, der bruges som grundlag for en visuel repræsentation af strukturen af den applikation, der udvikles (for eksempel i Package Explorer, Outline, Search, Call Hierarki og Typehierarki).
Eclipse-komponenter brugt i 1C:Enterprise Developments Tools
I fig. Figur 7 viser Eclipse-komponenterne, der danner grundlaget for teknologiplatformen for 1C:Enterprise Development Tools.
Ris. 7. Eclipse som platform for 1C:Enterprise Development Tools
Eclipse platform leverer grundlæggende infrastruktur. Vi så på nogle aspekter af denne infrastruktur i det foregående afsnit.
Som ethvert værktøj til virkelig generelle formål er EMF velegnet til at løse en lang række modelleringsproblemer, men nogle klasser af modeller (for eksempel de håndtagsbaserede modeller diskuteret ovenfor) kan kræve mere specialiserede modelleringsværktøjer. At tale om EMF er en utaknemmelig opgave, især inden for de begrænsede rammer for én artikel, da dette er emnet for en separat bog, og en ret tyk. Lad os kun bemærke, at det højkvalitetssystem af generaliseringer, der ligger til grund for EMF, tillod fødslen af en lang række projekter dedikeret til modellering, som er inkluderet i topniveauprojektet
1C:Enterprise Development Tools bruger aktivt både selve EMF og en række andre Eclipse Modeling-projekter. Især Xtext er et af grundlaget for udviklingsværktøjer til sådanne 1C:Enterprise-sprog som det indbyggede programmeringssprog og forespørgselssprog. Et andet grundlag for disse udviklingsværktøjer er Eclipse Handly-projektet, som vi vil diskutere mere detaljeret (af de nævnte Eclipse-komponenter er det stadig det mindst kendte).
De grundlæggende arkitektoniske principper for håndtagsbaserede modeller, såsom håndtag/krop formsproget, blev diskuteret ovenfor ved at bruge ressourcemodellen og Java-modellen som eksempler. Det bemærkede også, at både ressourcemodellen og Java-modellen er vigtige fundamenter for Eclipse Java-udviklingsværktøjer (JDT). Og da næsten alle *DT Eclipse-projekter har en arkitektur, der ligner JDT, ville det ikke være en stor overdrivelse at sige, at håndtagsbaserede modeller ligger til grund for mange, hvis ikke alle IDE'er, der er bygget oven på Eclipse-platformen. For eksempel har Eclipse C/C++ Development Tooling (CDT) en håndtagsbaseret C/C++-model, der spiller samme rolle i CDT-arkitekturen, som Java-modellen gør i JDT.
Før Handly tilbød Eclipse ikke specialiserede biblioteker til at bygge håndtagsbaserede sprogmodeller. De modeller, der i øjeblikket eksisterer, blev hovedsageligt skabt ved direkte at tilpasse Java-modelkoden (alias copy/paste), i de tilfælde, hvor det tillader det Eclipse Public License (EPL). (Det er klart, at dette normalt ikke er et juridisk problem for f.eks. Eclipse-projekter selv, men ikke for lukkede kildeprodukter.) Ud over dens iboende tilfældighed introducerer denne teknik velkendte problemer: kodeduplikering introduceret af ved tilpasning til fejl, etc. Hvad værre er, er, at de resulterende modeller forbliver "ting i sig selv" og ikke udnytter potentialet for ensretning. Men at isolere fælles koncepter og protokoller for håndtagsbaserede sprogmodeller kan føre til oprettelsen af genbrugelige komponenter til at arbejde med dem, svarende til hvad der skete i tilfældet med EMF.
Det er ikke fordi Eclipse ikke forstod disse problemer. Tilbage i 2005
I en vis forstand er Handly-projektet designet til at løse omtrent de samme problemer som EMF, men for håndtagsbaserede modeller, og primært sprog (dvs. repræsenterer elementer af strukturen af et programmeringssprog). De vigtigste mål, der er sat ved design af Handly, er angivet nedenfor:
- Identifikation af fagområdets hovedabstraktioner.
- Reduktion af indsatsen og forbedring af kvaliteten af implementering af håndtagsbaserede sprogmodeller gennem genbrug af kode.
- Giver en samlet meta-niveau API til de resulterende modeller, hvilket gør det muligt at skabe fælles IDE-komponenter, der fungerer med sproghåndtag-baserede modeller.
- Fleksibilitet og skalerbarhed.
- Integration med Xtext (i et separat lag).
For at fremhæve almindelige koncepter og protokoller blev eksisterende implementeringer af sproghåndtagsbaserede modeller analyseret. De vigtigste grænseflader og grundlæggende implementeringer leveret af Handly er vist i fig. 8.
Ris. 8. Fælles grænseflader og grundlæggende implementeringer af Handly-elementer
IElement-grænsefladen repræsenterer et elements håndtag og er fælles for elementer i alle Handly-baserede modeller. Det abstrakte klasseelement implementerer den generaliserede håndtag/kropsmekanisme (fig. 9).
Ris. 9. IElement og generisk håndtag/kroppsimplementering
Derudover giver Handly en generaliseret mekanisme til at underrette om ændringer i modelelementer (fig. 10). Som du kan se, ligner det stort set notifikationsmekanismerne implementeret i ressourcemodellen og Java-modellen og bruger IElementDelta til at give en samlet repræsentation af information om elementændringer.
Ris. 10. Generelle grænseflader og grundlæggende implementeringer af Handly-meddelelsesmekanismen
Handly-delen diskuteret ovenfor (fig. 9 og 10) kan bruges til at repræsentere næsten alle håndtagsbaserede modeller. Til at skabe sproglige modeller, byder projektet på yderligere funktionalitet - især fælles grænseflader og grundlæggende implementeringer for elementer af kildetekststrukturen, den såkaldte kildeelementer (Fig. 8). ISourceFile-grænsefladen repræsenterer en kildefil, og ISourceConstruct repræsenterer et element i kildefilen. De abstrakte klasser SourceFile og SourceConstruct implementerer generaliserede mekanismer til at understøtte arbejdet med kildefiler og deres elementer, for eksempel arbejde med tekstbuffere, binding til koordinaterne for et element i kildeteksten, afstemning af modeller med det aktuelle indhold af en arbejdskopibuffer , etc. Implementering af disse mekanismer er normalt noget af en udfordring, og Handly kan reducere indsatsen med at udvikle håndtagsbaserede sprogmodeller betydeligt ved at levere basisimplementeringer af høj kvalitet.
Ud over de kernemekanismer, der er anført ovenfor, leverer Handly en infrastruktur til tekstbuffere og snapshots, understøttelse af integration med kildekodeeditorer (herunder out-of-the-box integration med Xtext-editoren), samt nogle almindelige brugergrænsefladekomponenter, der arbejde med kildekode editorer.Håndlige modeller såsom outline framework. For at illustrere dets muligheder giver projektet flere eksempler, herunder en implementering af Java-modellen i Handly. (Sammenlignet med den fulde implementering af Java-modellen i JDT, er denne model bevidst noget forenklet for større klarhed.)
Som tidligere nævnt var og er et stort fokus under Handlys indledende design og efterfølgende udvikling på skalerbarhed og fleksibilitet.
I princippet skalerer håndtagsbaserede modeller ganske godt "ved design". For eksempel giver håndtag/krop formsprog dig mulighed for at begrænse mængden af hukommelse, der forbruges af en model. Men der er også nuancer. Når man testede Handly for skalerbarhed, blev der således opdaget et problem i implementeringen af notifikationsmekanismen - da et stort antal elementer blev ændret, tog det for lang tid at konstruere deltaer. Det viste sig, at det samme problem var til stede i JDT Java-modellen, hvorfra den tilsvarende kode engang blev tilpasset. Vi rettede fejlen i Handly og forberedte en lignende patch til JDT, som blev modtaget med tak. Dette er blot et eksempel, hvor det potentielt kan være nyttigt at introducere Handly i eksisterende modelimplementeringer, for i dette tilfælde kan en sådan fejl rettes ét sted.
For at gøre det teknisk muligt at implementere Handly i eksisterende modelimplementeringer, skal biblioteket have betydelig fleksibilitet. Hovedproblemet er at opretholde bagudkompatibilitet på tværs af API-modellen. Dette problem blev løst i
Fleksibilitet har også andre aspekter. For eksempel pålægger Handly næsten ingen begrænsninger på modellens struktur og kan bruges til at modellere både generelle og domænespecifikke sprog. Når man konstruerer kildefilens struktur, foreskriver Handly ikke nogen særlig form for AST-repræsentation og kræver i princippet ikke engang tilstedeværelsen af en AST i sig selv, hvilket sikrer kompatibilitet med næsten enhver parsingmekanisme. Endelig understøtter Handly fuld integration med Eclipse workspace, men kan også arbejde direkte med filsystemer takket være dets integration med
Nuværende version
Som nævnt ovenfor er et af disse produkter 1C:Enterprise Development Tools, hvor Handly bruges helt fra begyndelsen til at modellere elementer af højniveaustrukturen af sådanne 1C:Enterprise-sprog som det indbyggede programmeringssprog og forespørgselssprog . Et andet produkt er mindre kendt af offentligheden. Det her
Vi håber, at Handly efter udgivelsen af version 1.0 med garanti for API-stabilitet og projektet, der forlader inkubationstilstanden, vil have nye brugere. I mellemtiden fortsætter projektet med at teste og yderligere forbedre API'et, og udgive to "større" udgivelser om året - i juni (samme dato som den samtidige Eclipse-udgivelse) og december, hvilket giver en forudsigelig tidsplan, som brugere kan stole på. Vi kan også tilføje, at projektets "fejlrate" forbliver på et konsekvent lavt niveau, og Handly har arbejdet pålideligt i produkter fra early adopters siden de allerførste versioner. For yderligere at udforske Eclipse Handly, kan du bruge
Kilde: www.habr.com