Sannsynligvis,
I denne artikkelen, som er oversiktlig i naturen, vil vi prøve å se på noe av det grunnleggende i Eclipse-arkitekturen som en plattform for å bygge integrerte utviklingsverktøy og gi en innledende idé om Eclipse-komponentene som danner grunnlaget for teknologien plattform for den "nye konfiguratoren" 1C: Enterprise.
Introduksjon til Eclipse Architecture
La oss først se på noen generelle aspekter ved Eclipse-arkitekturen ved å bruke eksempelet
Først av alt bør det bemerkes at Eclipse er preget av en ganske tydelig arkitektonisk lagdeling, med separasjon av språkuavhengig funksjonalitet fra funksjonalitet designet for å støtte spesifikke programmeringsspråk, og separasjon av UI-uavhengige "kjerne"-komponenter fra komponenter tilknyttet med støttende brukergrensesnitt.
Dermed definerer Eclipse-plattformen en felles, språkuavhengig infrastruktur, og Java-utviklingsverktøyene legger til en fullverdig Java IDE til Eclipse. Både Eclipse Platform og JDT består av flere komponenter, som hver tilhører enten en UI-uavhengig "kjerne" eller et UI-lag (Figur 1).
Ris. 1. Eclipse Platform og JDT
La oss liste hovedkomponentene til Eclipse Platform:
- Runtime — Definerer plugin-infrastrukturen. Eclipse er preget av en modulær arkitektur. Eclipse er i hovedsak en samling av "utvidelsespunkter" og "utvidelser".
- Arbeidsområde — Styrer ett eller flere prosjekter. Et prosjekt består av mapper og filer som er tilordnet direkte til filsystemet.
- Standard Widget Toolkit (SWT) - Gir grunnleggende brukergrensesnittelementer integrert med operativsystemet.
- JFace — Gir en rekke UI-rammeverk bygget på toppen av SWT.
- Workbench — Definerer Eclipse UI-paradigmet: redaktører, synspunkter, perspektiver.
Det må sies at Eclipse Platform også gir mange andre nyttige komponenter for å bygge integrerte utviklingsverktøy, inkludert Debug, Compare, Search og Team. Spesielt bør nevnes JFace Text - grunnlaget for å bygge "smarte editorer" av kildekode. Dessverre er selv en overfladisk undersøkelse av disse komponentene, så vel som UI-lagkomponentene, ikke mulig innenfor rammen av denne artikkelen, så i resten av denne delen vil vi begrense oss til en oversikt over de viktigste "kjerne"-komponentene i Eclipse Platform og JDT.
Kjernekjøring
Eclipse-plugin-infrastrukturen er basert på
Kjernearbeidsområde
Nesten alle integrerte utviklingsmiljøer bygget på toppen av Eclipse-plattformen fungerer med Eclipse-arbeidsområdet. Det er arbeidsområdet som vanligvis inneholder kildekoden til applikasjonen utviklet i IDE. Arbeidsområde tilordnes direkte til filsystemet og består av prosjekter som inneholder mapper og filer. Disse prosjektene, mappene og filene kalles ressurser arbeidsområde. Arbeidsområdeimplementeringen i Eclipse fungerer som en cache i forhold til filsystemet, noe som gjør det mulig å øke hastigheten på gjennomgangen av ressurstreet betydelig. I tillegg gir workspace en rekke tilleggstjenester, bl.a
Core Resources-komponenten (org.eclipse.core.resources plugin) er ansvarlig for å støtte arbeidsområdet og dets ressurser. Spesielt gir denne komponenten programmatisk tilgang til arbeidsområdet i skjemaet ressursmodeller. For å jobbe effektivt med denne modellen trenger klienter en enkel måte å presentere en lenke til en ressurs på. I dette tilfellet vil det være ønskelig å skjule objektet som direkte lagrer tilstanden til ressursen i modellen fra klienttilgang. Ellers, i tilfelle av for eksempel sletting av en fil, kan klienten fortsette å holde et objekt som ikke lenger er i modellen, med påfølgende problemer. Eclipse løser dette problemet ved å bruke noe som heter håndtere ressurs. Håndtaket fungerer som en nøkkel (det kjenner bare banen til ressursen i arbeidsområdet) og kontrollerer fullstendig tilgangen til det interne modellobjektet, som direkte lagrer informasjon om ressursens tilstand. Dette designet er en variant av mønsteret
Ris. Figur 2 illustrerer håndtak/kroppsformspråket brukt på ressursmodellen. IResource-grensesnittet representerer håndtaket til en ressurs og er et API, i motsetning til Resource-klassen, som implementerer dette grensesnittet, og ResourceInfo-klassen, som representerer kroppen, som ikke er APIer. Vi understreker at handle bare kjenner banen til ressursen i forhold til arbeidsområderoten og ikke inneholder en lenke til ressursinfo. Ressursinfoobjekter danner et såkalt «elementtre». Denne datastrukturen er fullstendig materialisert i minnet. For å finne ressursinfo-forekomsten som tilsvarer et håndtak, krysses elementtreet i henhold til banen som er lagret i det håndtaket.
Ris. 2. IResource og ResourceInfo
Som vi skal se senere, brukes den grunnleggende utformingen av ressursmodellen (vi kan kalle den håndtaksbasert) i Eclipse også for andre modeller. For nå, la oss liste noen av de karakteristiske egenskapene til dette designet:
- Håndtak er et verdiobjekt. Verdiobjekter er uforanderlige objekter hvis likhet ikke er basert på identitet. Slike gjenstander kan trygt brukes som nøkkel i hashbehandlede containere. Flere forekomster av håndtak kan referere til samme ressurs. For å sammenligne dem, må du bruke equals(Object)-metoden.
- Handle definerer oppførselen til en ressurs, men inneholder ikke informasjon om tilstanden til ressursen (de eneste dataene den lagrer er "nøkkelen", banen til ressursen).
- Handle kan referere til en ressurs som ikke eksisterer (enten en ressurs som ennå ikke er opprettet, eller en ressurs som allerede er slettet). Eksistensen av en ressurs kan kontrolleres ved å bruke IResource.exists()-metoden.
- Noen operasjoner kan implementeres utelukkende basert på informasjon som er lagret i selve håndtaket (såkalte handle-only-operasjoner). Eksempler er IResource.getParent(), getFullPath() osv. Ressursen trenger ikke å eksistere for at en slik operasjon skal lykkes. Operasjoner som krever at en ressurs eksisterer for å lykkes, kaster et CoreException hvis ressursen ikke eksisterer.
Eclipse gir en effektiv mekanisme for å varsle endringer i arbeidsområderessurs (figur 3). Ressurser kan endres enten som et resultat av handlinger utført i selve Eclipse IDE eller som et resultat av synkronisering med filsystemet. I begge tilfeller får kunder som abonnerer på varsler detaljert informasjon om endringene i form av "ressursdeltaer". Et delta beskriver endringer mellom to tilstander til et arbeidsområderessurs (under)tre og er i seg selv et tre, hvor hver node beskriver en endring av en ressurs og inneholder en liste over deltaer på neste nivå som beskriver endringer i underordnede ressurser.
Ris. 3. IResourceChangeEvent og IResourceDelta
Varslingsmekanismen basert på ressursdeltaer har følgende egenskaper:
- En enkelt endring og mange endringer er beskrevet ved bruk av samme struktur, siden deltaet er bygget ved hjelp av prinsippet om rekursiv komposisjon. Abonnentklienter kan behandle varslinger om ressursendringer ved å bruke rekursiv nedstigning gjennom et tre med deltaer.
- Deltaet inneholder fullstendig informasjon om endringer i ressursen, inkludert dens bevegelse og/eller endringer i "markørene" knyttet til den (for eksempel er kompileringsfeil representert som markører).
- Siden ressursreferanser gjøres gjennom håndtaket, kan delta naturlig referere til en ekstern ressurs.
Som vi snart vil se, er hovedkomponentene i utformingen av varslingsmekanismen for ressursmodellendringer også relevante for andre håndtaksbaserte modeller.
JDT kjerne
Eclipse arbeidsområderessursmodellen er en grunnleggende språkagnostisk modell. JDT Core-komponenten (plugin org.eclipse.jdt.core) gir et API for å navigere og analysere arbeidsområdestrukturen fra et Java-perspektiv, den såkalte "Java-modellen" (Java-modell). Denne APIen er definert i form av Java-elementer, i motsetning til den underliggende ressursmodellen API, som er definert i form av mapper og filer. Hovedgrensesnittene til Java-elementtreet er vist i fig. 4.
Ris. 4. Java-modellelementer
Java-modellen bruker samme håndtak/kroppsformspråk som ressursmodellen (Figur 5). IJavaElement er håndtaket, og JavaElementInfo spiller rollen som kropp. IJavaElement-grensesnittet definerer en protokoll som er felles for alle Java-elementer. Noen av metodene er kun for håndtering: getElementName(), getParent(), etc. JavaElementInfo-objektet lagrer tilstanden til det tilsvarende elementet: dets struktur og attributter.
Ris. 5. IJavaElement og JavaElementInfo
Java-modellen har noen forskjeller i implementeringen av grunnleggende håndtak/kroppsdesign sammenlignet med ressursmodellen. Som nevnt ovenfor, i ressursmodellen, er elementtreet, hvis noder er ressursinformasjonsobjekter, fullstendig inneholdt i minnet. Men Java-modellen kan ha et betydelig større antall elementer enn ressurstreet, fordi den også representerer den interne strukturen til .java- og .class-filer: typer, felt og metoder.
For å unngå fullstendig materialisering av hele treet av elementer i minnet, bruker Java-modellimplementeringen en begrenset størrelse LRU-buffer med elementinfo, der nøkkelen er handle IJavaElement. elementinfoobjekter opprettes på forespørsel når elementtreet navigeres. I dette tilfellet blir de minst brukte elementene kastet ut av hurtigbufferen, og modellens minneforbruk forblir begrenset til den angitte bufferstørrelsen. Dette er en annen fordel med håndtaksbasert design, som fullstendig skjuler slike implementeringsdetaljer fra klientkoden.
Mekanismen for å varsle endringer i Java-elementer er generelt lik mekanismen for sporing av endringer i arbeidsområderessurser diskutert ovenfor. En klient som ønsker å overvåke endringer i Java-modellen abonnerer på varsler, som er representert som et ElementChangedEvent-objekt som inneholder en IJavaElementDelta (Figur 6).
Ris. 6. ElementChangedEvent og IJavaElementDelta
Java-modellen inneholder ikke informasjon om metodelegemer eller navneoppløsning, så for detaljert analyse av kode skrevet i Java, gir JDT Core en ekstra (ikke-håndtaksbasert) modell:
Fordi syntakstrær kan forbruke en betydelig mengde minne, cacher JDT bare én AST for den aktive editoren. I motsetning til Java-modellen, blir AST vanligvis sett på som en "mellomliggende", "midlertidig" modell hvis medlemmer ikke skal refereres til av klienter utenfor konteksten av operasjonen som førte til opprettelsen av AST.
De oppførte tre modellene (Java-modell, AST, bindinger) danner til sammen grunnlaget for å bygge "intelligente utviklingsverktøy" i JDT, inkludert en kraftig Java-editor med forskjellige "hjelpere", forskjellige handlinger for å behandle kildekode (inkludert organisering av en importliste navn og formatering i henhold til den tilpassede stilen), søke- og refaktoriseringsverktøy. I dette tilfellet spiller Java-modellen en spesiell rolle, siden det er den som brukes som grunnlag for en visuell representasjon av strukturen til applikasjonen som utvikles (for eksempel i Package Explorer, Outline, Search, Call Hierarchy, og Skriv hierarki).
Eclipse-komponenter brukt i 1C:Enterprise Developments Tools
I fig. Figur 7 viser Eclipse-komponentene som danner grunnlaget for teknologiplattformen for 1C:Enterprise Development Tools.
Ris. 7. Eclipse som plattform for 1C:Enterprise Development Tools
Eclipse-plattformen gir grunnleggende infrastruktur. Vi så på noen aspekter ved denne infrastrukturen i forrige avsnitt.
Som ethvert virkelig generellt verktøy er EMF egnet for å løse et bredt spekter av modelleringsproblemer, men noen klasser av modeller (for eksempel de håndtaksbaserte modellene diskutert ovenfor) kan kreve mer spesialiserte modelleringsverktøy. Å snakke om EMF er en utakknemlig oppgave, spesielt innenfor de begrensede rammene til én artikkel, siden dette er emnet for en egen bok, og en ganske tykk. La oss bare merke oss at høykvalitetssystemet med generaliseringer som ligger til grunn for EMF tillot fødselen av en hel rekke prosjekter dedikert til modellering, som er inkludert i toppnivåprosjektet
1C:Enterprise Development Tools bruker aktivt både EMF selv og en rekke andre Eclipse Modeling-prosjekter. Spesielt er Xtext et av grunnlaget for utviklingsverktøy for slike 1C:Enterprise-språk som det innebygde programmeringsspråket og spørringsspråket. Et annet grunnlag for disse utviklingsverktøyene er Eclipse Handly-prosjektet, som vi vil diskutere mer detaljert (av Eclipse-komponentene som er oppført, er det fortsatt minst kjent).
De grunnleggende arkitektoniske prinsippene for håndtaksbaserte modeller, som håndtak/kroppsformspråket, ble diskutert ovenfor ved å bruke ressursmodellen og Java-modellen som eksempler. Den bemerket også at både ressursmodellen og Java-modellen er viktige grunnlag for Eclipse Java-utviklingsverktøy (JDT). Og siden nesten alle *DT Eclipse-prosjekter har en arkitektur som ligner JDT, vil det ikke være en stor overdrivelse å si at håndtaksbaserte modeller ligger til grunn for mange, om ikke alle IDE-er bygget på toppen av Eclipse-plattformen. For eksempel har Eclipse C/C++ Development Tooling (CDT) en håndtaksbasert C/C++-modell som spiller samme rolle i CDT-arkitekturen som Java-modellen gjør i JDT.
Før Handly tilbød ikke Eclipse spesialiserte biblioteker for å bygge håndtaksbaserte språkmodeller. Modellene som for øyeblikket eksisterer ble hovedsakelig opprettet ved å direkte tilpasse Java-modellkoden (aka copy/paste), i tilfeller der det tillater det Eclipse Public License (EPL). (Selvfølgelig er dette vanligvis ikke et juridisk problem for for eksempel Eclipse-prosjekter selv, men ikke for produkter med lukket kildekode.) I tillegg til dens iboende tilfeldighet, introduserer denne teknikken velkjente problemer: kodeduplisering introdusert av ved tilpasning til feil, etc. Det som er verre er at de resulterende modellene forblir "ting i seg selv" og ikke utnytter potensialet for forening. Men å isolere vanlige konsepter og protokoller for håndtaksbaserte språkmodeller kan føre til opprettelse av gjenbrukbare komponenter for å jobbe med dem, på samme måte som det som skjedde i tilfellet med EMF.
Det er ikke det at Eclipse ikke forsto disse problemene. Tilbake i 2005
I en viss forstand er Handly-prosjektet designet for å løse omtrent de samme problemene som EMF, men for håndtaksbaserte modeller, og primært språklige (dvs. representerer elementer av strukturen til et programmeringsspråk). Hovedmålene som er satt når du designer Handly er listet opp nedenfor:
- Identifisering av hovedabstraksjonene i fagområdet.
- Redusere innsats og forbedre kvaliteten på implementering av håndtaksbaserte språkmodeller gjennom gjenbruk av kode.
- Gir et enhetlig meta-nivå API til de resulterende modellene, noe som gjør det mulig å lage vanlige IDE-komponenter som fungerer med språkhåndtaksbaserte modeller.
- Fleksibilitet og skalerbarhet.
- Integrasjon med Xtext (i et eget lag).
For å fremheve vanlige konsepter og protokoller, ble eksisterende implementeringer av språkhåndtaksbaserte modeller analysert. Hovedgrensesnittene og grunnleggende implementeringer levert av Handly er vist i fig. 8.
Ris. 8. Vanlige grensesnitt og grunnleggende implementeringer av Handly-elementer
IElement-grensesnittet representerer håndtaket til et element og er felles for elementer i alle Handly-baserte modeller. Den abstrakte klassen Element implementerer den generaliserte håndtak/kroppsmekanismen (fig. 9).
Ris. 9. IElement og generisk håndtak/kroppsimplementering
I tillegg gir Handly en generalisert mekanisme for å varsle om endringer i modellelementer (fig. 10). Som du kan se, ligner det stort sett på varslingsmekanismene implementert i ressursmodellen og Java-modellen, og bruker IElementDelta for å gi en enhetlig representasjon av informasjon om elementendring.
Ris. 10. Generelle grensesnitt og grunnleggende implementeringer av Handly-varslingsmekanismen
Handly-delen diskutert ovenfor (fig. 9 og 10) kan brukes til å representere nesten alle håndtaksbaserte modeller. For å skape språklig modeller, tilbyr prosjektet tilleggsfunksjonalitet – spesielt felles grensesnitt og grunnleggende implementeringer for elementer i kildetekststrukturen, den s.k. kildeelementer (Fig. 8). ISourceFile-grensesnittet representerer en kildefil, og ISourceConstruct representerer et element i kildefilen. De abstrakte klassene SourceFile og SourceConstruct implementerer generaliserte mekanismer for å støtte arbeid med kildefiler og deres elementer, for eksempel arbeid med tekstbuffere, binding til koordinatene til et element i kildeteksten, avstemming av modeller med gjeldende innhold i en arbeidskopibuffer , etc. Implementering av disse mekanismene er vanligvis en utfordring, og Handly kan redusere arbeidet med å utvikle håndtaksbaserte språkmodeller betydelig ved å tilby grunnleggende implementeringer av høy kvalitet.
I tillegg til kjernemekanismene som er oppført ovenfor, tilbyr Handly en infrastruktur for tekstbuffere og øyeblikksbilder, støtte for integrasjon med kildekoderedigerere (inkludert ut-av-boksen integrasjon med Xtext-editoren), samt noen vanlige brukergrensesnittkomponenter som arbeide med kildekoderedigerere. Handly modeller som skissere rammeverk. For å illustrere mulighetene, gir prosjektet flere eksempler, inkludert en implementering av Java-modellen i Handly. (Sammenlignet med den fullstendige implementeringen av Java-modellen i JDT, er denne modellen med hensikt noe forenklet for større klarhet.)
Som nevnt tidligere, var og fortsetter å være et stort fokus under Handlys første design og påfølgende utvikling på skalerbarhet og fleksibilitet.
I prinsippet skalerer håndtaksbaserte modeller ganske godt "ved design". For eksempel lar håndtak/kroppsformspråket deg begrense mengden minne som forbrukes av en modell. Men det er også nyanser. Når man testet Handly for skalerbarhet, ble det derfor oppdaget et problem i implementeringen av varslingsmekanismen - når et stort antall elementer ble endret, tok det for mye tid å konstruere deltaer. Det viste seg at det samme problemet var til stede i JDT Java-modellen, som den tilsvarende koden en gang ble tilpasset fra. Vi fikset feilen i Handly og utarbeidet en lignende oppdatering for JDT, som ble mottatt med takk. Dette er bare ett eksempel der det å introdusere Handly i eksisterende modellimplementeringer potensielt kan være nyttig, fordi i dette tilfellet kan en slik feil fikses på bare ett sted.
For å gjøre implementering av Handly i eksisterende modellimplementeringer teknisk mulig, må biblioteket ha betydelig fleksibilitet. Hovedproblemet er å opprettholde bakoverkompatibilitet på tvers av API-modellen. Dette problemet ble løst i
Fleksibilitet har også andre aspekter. For eksempel legger Handly nesten ingen begrensninger på strukturen til modellen og kan brukes til å modellere både generelle og domenespesifikke språk. Når du konstruerer strukturen til kildefilen, foreskriver ikke Handly noen spesiell form for AST-representasjon og krever i prinsippet ikke engang tilstedeværelsen av en AST i seg selv, og sikrer dermed kompatibilitet med nesten alle analyseringsmekanismer. Til slutt støtter Handly full integrasjon med Eclipse arbeidsområde, men kan også jobbe direkte med filsystemer takket være integrasjonen med
Gjeldende versjon
Som nevnt ovenfor er et av disse produktene 1C:Enterprise Development Tools, der Handly brukes helt fra begynnelsen til å modellere elementer i høynivåstrukturen til slike 1C:Enterprise-språk som det innebygde programmeringsspråket og spørringsspråket . Et annet produkt er mindre kjent for allmennheten. Dette
Vi håper at etter utgivelsen av versjon 1.0 med garanti for API-stabilitet og at prosjektet forlater inkubasjonstilstanden, vil Handly få nye brukere. I mellomtiden fortsetter prosjektet å teste og ytterligere forbedre API, og slippe to "store" utgivelser per år - i juni (samme dato som den samtidige Eclipse-utgivelsen) og desember, og gir en forutsigbar tidsplan som brukere kan stole på. Vi kan også legge til at prosjektets "feilfrekvens" forblir på et konsekvent lavt nivå, og Handly har jobbet pålitelig med produktene til tidlige brukere siden de aller første versjonene. For å utforske Eclipse Handly ytterligere, kan du bruke
Kilde: www.habr.com