Eclipse 作為 1C 的技術平台:企業開發工具

或許, 日食 早就不需要特別介紹了。 由於 Eclipse Java 開發工具(傑德)。 大多數開發人員將這種流行的開源 Java IDE 與“Eclipse”一詞聯繫在一起。 然而,Eclipse既是一個用於整合開發工具的可擴展平台(Eclipse Platform),也是在其基礎上建構的許多IDE,包括JDT。 Eclipse 既是 Eclipse 專案(協調 Eclipse 平台和 JDT 開發的頂級專案),也是 Eclipse SDK(此開發的交付結果)。 最後,Eclipse 是一個開源基金會,擁有龐大的專案社區,但並非所有專案都是用 Java 編寫的或與開發工具相關(例如,專案 Eclipse物聯網 и 日食科學)。 Eclipse 的世界非常多元。

在這篇本質上是概述的文章中,我們將嘗試了解 Eclipse 架構作為構建集成開發工具的平台的一些基礎知識,並給出構成該技術基礎的 Eclipse 組件的初步想法“新配置器”1C 的平台:企業版。 1C:企業開發工具。 當然,這樣的評論將不可避免地在很大程度上是膚淺的並且相當有限,因為我們不僅關注作為目標受眾的 Eclipse 開發人員。 然而,我們希望即使是經驗豐富的 Eclipse 開發人員也能夠在本文中找到有趣的資訊。 例如,我們將談論「Eclipse 的秘密」之一,這是一個相對較新且鮮為人知的項目 日蝕得心應手,由 1C 創立並支持。
Eclipse 作為 1C 的技術平台:企業開發工具

Eclipse 架構簡介

讓我們先使用範例來了解 Eclipse 架構的一些一般方面 Eclipse Java 開發工具 (JDT)。 選擇 JDT 作為例子並非偶然。 這是Eclipse中出現的第一個整合開發環境。 其他 *DT Eclipse 項目,例如 Eclipse C/C++ 開發工具 (CDT),是後來創建的,並借用了 JDT 的基本架構原則和單獨的原始碼片段。 JDT 中規定的體系結構的基本原理至今仍適用於建構在 Eclipse 平台之上的幾乎所有 IDE,包括 1C:企業開發工具。

首先,應該指出的是,Eclipse 的特點是具有相當清晰的架構分層,獨立於語言的功能與旨在支援特定程式語言的功能分離,獨立於 UI 的「核心」元件與相關元件分離。具有支援的使用者介面。

因此,Eclipse 平台定義了一個通用的、獨立於語言的基礎結構,並且 Java 開發工具為 Eclipse 添加了功能齊全的 Java IDE。 Eclipse 平台和 JDT 都由多個元件組成,每個元件都屬於獨立於 UI 的「核心」或 UI 層(圖 1)。

Eclipse 作為 1C 的技術平台:企業開發工具
米。 1.Eclipse平台和JDT

讓我們列出 Eclipse 平台的主要元件:

  • 運行時 — 定義插件基礎架構。 Eclipse 的特色是模組化架構。 本質上,Eclipse 是「擴展點」和「擴展」的集合。
  • 工作區 — 管理一個或多個專案。 項目由直接對應到檔案系統的資料夾和檔案組成。
  • 標準小工具工具包 (SWT) - 提供與作業系統整合的基本使用者介面元素。
  • 傑面 — 提供了許多建構在 SWT 之上的 UI 框架。
  • 工作台 — 定義 Eclipse UI 範例:編輯器、檢視、透視圖。

必須指出的是,Eclipse 平台還提供了許多其他有用的元件來建立整合開發工具,包括 Debug、Compare、Search 和 Team。 特別值得一提的是 JFace Text——建立原始碼「智慧編輯器」的基礎。 不幸的是,即使對這些元件以及 UI 層元件進行粗略的檢查,在本文的範圍內也是不可能的,因此在本節的其餘部分中,我們將僅限於概述主要「核心」元件Eclipse 平台和JDT 。

核心運行時

Eclipse 外掛程式基礎架構是基於 操作系統Gi 並由項目提供 日食春分。 每個 Eclipse 外掛程式都是一個 OSGi 套件。 OSGi 規格特別定義了版本控制和相依性解析的機制。 除了這些標準機制之外,Equinox 還引入了以下概念 擴充點。 每個插件都可以定義自己的擴充點,並且還可以使用由相同或其他插件定義的擴充點向系統引入附加功能(“擴充”)。 OSGi 和 Equinox 機制的任何詳細描述超出了本文的範圍。 我們只需要注意,Eclipse 中的模組化是完全的(任何子系統,包括運行時,都由一個或多個插件組成),並且 Eclipse 中的幾乎所有內容都是擴充。 而且,這些原則早在 OSGi 推出之前就已經嵌入了 Eclipse 架構中(當時他們使用了自己的技術,與 OSGi 非常相似)。

核心工作區

幾乎所有建置在 Eclipse 平台之上的整合開發環境都可以與 Eclipse 工作區搭配使用。 它是通常包含在 IDE 中開發的應用程式的原始程式碼的工作區。 工作區直接對應到檔案系統,由包含資料夾和檔案的項目組成。 這些項目、資料夾和文件稱為 資源 工作區。 Eclipse 中的工作區實作可作為與檔案系統相關的緩存,這使得可以顯著加快資源樹的遍歷速度。 此外,Workspace 還提供許多附加服務,包括 資源變更通知機制 и 增量建設者基礎設施.

核心資源元件(org.eclipse.core.resources 外掛程式)負責支援工作區及其資源。 特別是,該組件以以下形式提供對工作區的程式存取: 資源模型。 為了有效地使用此模型,客戶需要一種簡單的方法來呈現資源連結。 在這種情況下,需要隱藏模型中直接儲存資源狀態的物件以防止客戶端存取。 否則,在刪除檔案等情況下,客戶端可能會繼續保留模型中不再存在的對象,從而產生隨之而來的問題。 Eclipse 使用稱為 處理 資源。 Handle 充當金鑰(它只知道工作區中資源的路徑)並完全控制對內部模型物件的訪問,該物件直接儲存有關資源狀態的資訊。 此設計是該圖案的變體 手柄/主體.

米。 圖 2 說明了應用於資源模型的 Handle/Body 習慣用法。 IResource 介面代表資源的句柄,是一個 API,與實作此介面的 Resource 類別和代表主體的 ResourceInfo 類別不同,它們不是 API。 我們強調,句柄只知道相對於工作空間根目錄的資源路徑,不包含資源資訊的連結。 資源資訊對象形成所謂的「元素樹」。 此資料結構在記憶體中完全具體化。 為了找到句柄對應的資源資訊實例,根據句柄中儲存的路徑遍歷元素樹。

Eclipse 作為 1C 的技術平台:企業開發工具
米。 2.IResource和ResourceInfo

正如我們稍後將看到的,資源模型的基本設計(我們可以稱之為基於句柄)在 Eclipse 中也用於其他模型。 現在,讓我們列出該設計的一些獨特屬性:

  • 句柄是一個值物件。 值對象為不可變的對象,其相等性不基於身分。 此類物件可以安全地用作雜湊容器中的金鑰。 句柄的多個實例可以引用相同資源。 要比較它們,您需要使用 equals(Object) 方法。
  • Handle 定義了資源的行為,但不包含有關資源狀態的資訊(它儲存的唯一資料是“鍵”,即資源的路徑)。
  • 句柄可能引用不存在的資源(尚未建立的資源,或已刪除的資源)。 可以使用 IResource.exists() 方法檢查資源是否存在。
  • 某些操作可以僅基於句柄本身中儲存的資訊來實現(所謂的僅句柄操作)。 範例有 IResource.getParent()、getFullPath() 等。 此類操作無需存在資源即可成功。 如果資源不存在,則需要資源存在才能成功的操作會拋出 CoreException。

Eclipse 提供了一個有效的機制來通知工作區資源變更(圖 3)。 資源可能會因 Eclipse IDE 本身內執行的操作或與檔案系統同步而發生變更。 在這兩種情況下,訂閱通知的客戶都會以「資源增量」的形式獲得有關變更的詳細資訊。 增量描述工作區資源(子)樹的兩個狀態之間的變化,並且其本身是一棵樹,其每個節點描述對資源的更改,並包含下一個級別的增量列表,描述對子資源的更改。

Eclipse 作為 1C 的技術平台:企業開發工具
米。 3.IResourceChangeEvent和IResourceDelta

基於資源增量的通知機制具有以下特點:

  • 由於增量是使用遞歸組合原理建構的,因此使用相同的結構來描述單一變更和多個變更。 訂閱者用戶端可以使用增量樹的遞歸下降來處理資源變更通知。
  • 增量包含有關資源變更的完整訊息,包括其移動和/或與其關聯的「標記」的變更(例如,編譯錯誤表示為標記)。
  • 由於資源引用是透過句柄進行的,因此 delta 自然可以引用遠端資源。

正如我們很快就會看到的,資源模型變更通知機制設計的主要組成部分也與其他基於句柄的模型相關。

JDT核心

Eclipse 工作區資源模型是一個與語言無關的基本模型。 JDT Core 元件(外掛程式 org.eclipse.jdt.core)提供了一個 API,用於從 Java 角度導航和分析工作空間結構,即所謂的「Java 模型」(Java模型)。 該 API 是根據 Java 元素定義的,而不是根據資料夾和檔案定義的底層資源模型 API。 Java元素樹的主要介面如圖4所示。 XNUMX.

Eclipse 作為 1C 的技術平台:企業開發工具
米。 4.Java 模型元素

Java 模型使用與資源模型相同的句柄/主體習慣用法(圖 5)。 IJavaElement 是句柄,JavaElementInfo 扮演主體的角色。 IJavaElement 介面定義了所有 Java 元素通用的協定。 它的一些方法是僅有句柄的:getElementName()、getParent() 等。 JavaElementInfo 物件儲存對應元素的狀態:其結構和屬性。

Eclipse 作為 1C 的技術平台:企業開發工具
米。 5.IJavaElement 和 JavaElementInfo

與資源模型相比,Java 模型在基本句柄/主體設計的實作方面存在一些差異。 如上所述,在資源模型中,其節點是資源資訊物件的元素樹完全包含在記憶體中。 但 Java 模型可以擁有比資源樹多得多的元素,因為它也表示 .java 和 .class 檔案的內部結構:類型、欄位和方法。

為了避免在記憶體中完全具體化整個元素樹,Java 模型實作使用元素資訊的有限大小的 LRU 緩存,其中鍵是句柄 IJavaElement。 元素資訊物件是在元素樹導航時按需建立的。 在這種情況下,最不常用的項目將從快取中逐出,並且模型的記憶體消耗仍然限制在指定的快取大小內。 這是基於句柄的設計的另一個優點,它對客戶端程式碼完全隱藏了此類實作細節。

用於通知 Java 元素變更的機制通常類似於上面討論的追蹤工作空間資源變更的機制。 希望監視 Java 模型中的變更的客戶端訂閱通知,這些通知表示為包含 IJavaElementDelta 的 ElementChangedEvent 物件(圖 6)。

Eclipse 作為 1C 的技術平台:企業開發工具
米。 6.ElementChangedEvent 和 IJavaElementDelta

Java 模型不包含有關方法體或名稱解析的信息,因此為了詳細分析用 Java 編寫的程式碼,JDT Core 提供了一個附加的(非基於句柄的)模型: 抽象語法樹 (抽象語法樹,AST)。 AST 表示解析來源文字的結果。 AST 節點對應於源模組結構的元素(聲明、運算符、表達式等),並包含有關源文本中相應元素的坐標的信息,以及(作為選項)有關名稱解析的信息所謂的鏈接形式 綁定。 綁定是表示編譯器已知的命名實體的對象,例如類型、方法和變數。 與形成樹的 AST 節點不同,綁定支援交叉引用並且通常形成圖。 抽象類別 ASTNode 是所有 AST 節點的公共基底類別。 ASTNode 子類別對應於 Java 語言的特定語法結構。

由於語法樹會消耗大量內存,因此 JDT 僅為活動編輯器緩存一個 AST。 與 Java 模型不同,AST 通常被視為「中間」、「臨時」模型,其成員不應由導致 AST 建立的操作上下文之外的客戶端引用。

列出的三個模型(Java 模型、AST、綁定)共同構成了在JDT 中建立「智慧開發工具」的基礎,包括具有各種「助理」的強大Java 編輯器、處理原始程式碼的各種操作(包括組織匯入清單)根據自訂樣式的名稱和格式)、搜尋和重構工具。 在這種情況下,Java 模型扮演著特殊的角色,因為它被用作正在開發的應用程式結構的可視化表示的基礎(例如,在 Package Explorer、Outline、Search、Call Hierarchy 和類型層次結構)。

1C:企業開發工具中使用的Eclipse元件

在圖中。 圖 7 顯示了構成 1C:企業開發工具技術平台基礎的 Eclipse 元件。

Eclipse 作為 1C 的技術平台:企業開發工具
米。 7. Eclipse作為1C的平台:企業開發工具

Eclipse 平台 提供基礎設施。 我們在上一節中研究了該基礎設施的某些方面。

Eclipse 建模框架 (EMF)提供了結構化資料建模的通用方法。 EMF 與 Eclipse 平台集成,但也可以在常規 Java 應用程式中單獨使用。 很多時候,新的 Eclipse 開發人員已經非常熟悉 EMF,儘管他們還沒有完全理解 Eclipse 平台的複雜性。 如此受歡迎的原因之一是通用設計,其中包括統一的元級 API,它允許您以通用方式使用任何 EMF 模型。 EMF 提供的模型物件的基本實現以及基於元模型生成模型程式碼的子系統顯著提高了開發速度並減少了錯誤數量。 EMF 還包含用於序列化模型、追蹤模型變更等的機制。

與任何真正的通用工具一樣,EMF 適合解決各種建模問題,但某些類型的模型(例如,上面討論的基於句柄的模型)可能需要更專業的建模工具。 談論 EMF 是一項吃力不討好的任務,尤其是在一篇文章的有限範圍內,因為這是另一本書的主題,而且是一本相當厚的書。 我們只需要注意的是,EMF 背後的高品質泛化系統催生了一系列致力於建模的項目,這些項目都包含在頂級項目中 日食建模 以及 EMF 本身。 Eclipse Xtext 就是這樣的一個專案。

Eclipse Xtext 提供「文字建模」基礎設施。 Xtext 使用 螞蟻金服 用於解析來源文本,EMF 用於表示生成的 ASG(抽象語義圖,本質上是 AST 和綁定的組合),也稱為「語義模型」。 Xtext建模的語言的語法是用Xtext自己的語言描述的。 這不僅允許您產生 ANTLR 的語法描述,還可以獲得 AST 序列化機制(即 Xtext 提供解析器和解解析器)、上下文提示和許多其他語言元件​​。 另一方面,Xtext 中使用的語法語言不如 ANTLR 中使用的語法語言靈活。 因此,有時需要將已實現的語言「彎曲」為Xtext,如果我們談論的是從頭開始開發的語言,這通常不是問題,但對於具有已經建立的語法的語言來說可能是不可接受的。 儘管如此,Xtext 仍然是 Eclipse 中目前最成熟、功能最豐富、用途最廣泛的用於建立程式語言及其開發工具的工具。 特別是,它是快速原型製作的理想工具 特定領域語言 (領域特定語言,DSL)。 除了上述基於 ANTLR 和 EMF 的「語言核心」之外,Xtext 還提供了許多有用的高階元件,包括索引機制、增量建置、「智慧編輯器」等等,但忽略了句柄——基於語言模型。 就像 EMF 一樣,Xtext 是一個值得單獨寫一本書的主題,我們現在甚至無法簡單地談論它的所有功能。

1C:企業開發工具積極使用 EMF 本身和許多其他 Eclipse 建模專案。 特別是,Xtext是內建程式語言和查詢語言等1C:企業語言的開發工具的基礎之一。 這些開發工具的另一個基礎是 Eclipse Handly 項目,我們將更詳細地討論該項目(在列出的 Eclipse 元件中,它仍然是最不為人所知的)。

日蝕得心應手是 Eclipse Technology 頂級專案的子項目,也是 1C 於 2014 年向 Eclipse 基金會貢獻初始程式碼的結果。 此後,1C持續支持計畫的發展:Handly committers是公司的員工。 該專案雖小,但在 Eclipse 中佔有相當獨特的地位:其主要目標是支持基於句柄的模型的開發。

上面以資源模型和 Java 模型為例討論了基於句柄的模型的基本架構原理,例如句柄/主體習慣用法。 它也指出,資源模型和 Java 模型都是 Eclipse Java 開發工具(JDT)的重要基礎。 由於幾乎所有 *DT Eclipse 專案都具有與 JDT 類似的體系結構,因此可以毫不誇張地說,基於句柄的模型是許多(如果不是全部)構建在 Eclipse 平台之上的 IDE 的基礎。 例如,Eclipse C/C++ 開發工具 (CDT) 具有基於句柄的 C/C++ 模型,該模型在 CDT 體系結構中的作用與 Java 模型在 JDT 中的作用相同。

在 Handly 之前,Eclipse 不提供用於建立基於句柄的語言模型的專門庫。 目前存在的模型主要是透過直接改編Java模型程式碼(又稱複製/貼上)來創建的, 在允許的情況下 Eclipse 公共授權 (EPL)。 (顯然,對於Eclipse 專案本身來說,這通常不是一個法律問題,但對於閉源產品來說則不然。)除了其固有的隨意性之外,這種技術還引入了眾所周知的問題:在適應錯誤時引入的程式碼重複, ETC。 更糟糕的是,最終的模型仍然是“事物本身”,並且沒有利用統一的潛力。 但是,隔離基於句柄的語言模型的通用概念和協定可能會導致創建可重複使用的元件來使用它們,類似於 EMF 的情況。

Eclipse 並不是不懂這些問題。 時間回到2005年 馬丁·埃施利曼,總結開發CDT原型機的經驗, 爭論 需要為語言模型(包括基於句柄的模型)建立通用基礎架構。 但是,正如經常發生的那樣,由於任務優先順序較高,這些想法的實施從未得到解決。 同時,*DT 程式碼的分解仍然是 Eclipse 中尚未開發的主題之一。

從某種意義上說,Handly 專案旨在解決與 EMF 大致相同的問題,但針對的是基於句柄的模型,並且主要是語言模型(即表示某些程式語言的結構元素)。 設計 Handly 時設定的主要目標如下:

  • 識別主題領域的主要抽象。
  • 透過程式碼重複使用,減少工作量並提高基於句柄的語言模型的實作品質。
  • 為產生的模型提供統一的元級 API,從而可以建立與基於語言句柄的模型一起使用的通用 IDE 元件。
  • 靈活性和可擴展性。
  • 與 Xtext 整合(在單獨的層中)。

為了突出常見的概念和協議,分析了基於語言句柄的模型的現有實現。 Handly提供的主要介面和基本實作如圖8所示。 XNUMX.

Eclipse 作為 1C 的技術平台:企業開發工具
米。 8.Handly元素常用介面及基本實現

IElement 介面表示元素的句柄,並且對於所有基於 Handly 的模型的元素都是通用的。 抽象類別 Element 實作了通用句柄/主體機制(圖 9)。

Eclipse 作為 1C 的技術平台:企業開發工具
米。 9. IElement 和通用句柄/主體實現

此外,Handly 還提供了一種通用機制來通知模型元素的變更(圖 10)。 正如您所看到的,它與資源模型和Java模型中實現的通知機制大致相似,並使用IElementDelta來提供元素變更資訊的統一表示。

Eclipse 作為 1C 的技術平台:企業開發工具
米。 10、Handly通知機制的通用介面與基本實現

上面討論的 Handly 部分(圖 9 和 10)可用於表示幾乎任何基於手把的模型。 用於創建 語言學的 模型,該專案提供了附加功能 - 特別是源文本結構元素的通用介面和基本實現,即所謂的 來源元素 (圖8)。 ISourceFile 介面表示來源文件,ISourceConstruct 表示來源檔案中的元素。 抽象類別 SourceFile 和 SourceConstruct 實作通用機制來支援處理原始檔案及其元素,例如,處理文字緩衝區、綁定到原始文字中元素的座標、使模型與工作副本緩衝區的當前內容協調一致, ETC。 實現這些機制通常是一個相當大的挑戰,而 Handly 可以透過提供高品質的基礎實現來顯著減少開發基於句柄的語言模型的工作量。

除了上面列出的核心機制之外,Handly 還提供了文字緩衝區和快照的基礎設施,支援與原始程式碼編輯器整合(包括與 Xtext 編輯器的開箱即用整合),以及一些常見的 UI 元件與原始碼編輯器一起工作,方便地使用大綱框架等模型。 為了說明其功能,專案提供了幾個範例,包括 Handly 中 Java 模型的實作。 (與 JDT 中 Java 模型的完整實作相比,為了更加清晰,該模型有意進行了一些簡化。)

如前所述,Handly 的初始設計和後續開發期間的主要關注點始終是可擴展性和靈活性。

原則上,基於手柄的模型“通過設計”可以很好地擴展。 例如,句柄/主體習慣用法可讓您限制模型消耗的記憶體量。 但也存在細微差別。 因此,在測試Handly的可擴展性時,發現了通知機制實作中的一個問題——當大量元素發生變化時,建構增量需要花費太多時間。 事實證明,JDT Java模型也存在同樣的問題,也曾經改編過對應的程式碼。 我們修復了 Handly 中的錯誤,並為 JDT 準備了類似的補丁,我們非常高興地收到了該補丁。 這只是將 Handly 引入現有模型實作可能有用的範例,因為在這種情況下,此類錯誤可以僅在一個地方修復。

為了使 Handly 實現到現有模型實作中在技術上可行,該函式庫必須具有顯著的靈活性。 主要問題是保持 API 模型的向後相容性。 這個問題已解決 方便0.5 透過將由開發人員定義和完全控制的特定於模型的 API 與庫提供的統一元級 API 明確分開。 這不僅使得在現有實作中實現 Handly 在技術上成為可能,而且還為新模型開發人員在設計 API 時提供了巨大的自由度。

靈活性還有其他面向。 例如,Handly 對模型的結構幾乎沒有限制,可用於對通用語言和特定領域語言進行建模。 在建立原始檔案的結構時,Handly 沒有規定 AST 表示的任何特定形式,原則上甚至不需要 AST 本身的存在,從而確保與幾乎任何解析機制的兼容性。 最後,Handly 支援與 Eclipse 工作區完全集成,但由於它與 Eclipse 檔案系統 (EFS)。

當前版本 方便0.6 於 2016 年 XNUMX 月推出。 儘管該專案目前處於孵化狀態,API尚未最終確定,但Handly已經在兩個冒著「早期採用者」風險的大型商業產品中使用,而且,我必須說,不要後悔。

如上所述,這些產品之一是 1C:Enterprise Development Tools,其中 Handly 從一開始就用於對 1C:Enterprise 語言的高級結構元素進行建模,作為內建程式語言和查詢語言。 另一種產品則較不為公眾所知。 這 科達西普工作室,一個針對特定應用指令集處理器 (ASIP) 的整合設計環境,捷克公司 Codasip 本身及其客戶都在使用,包括 AMD, AVG, 家具類, Sigma Designs。 Codasip 自 2015 年以來一直在生產中使用 Handly,從 Handly 0.2 版本開始。 Codasip Studio 最新版本使用 0.5 版本,於 2016 年 4000 月發布。 Ondřej Ilčík 是 Codasip IDE 開發的負責人,他正在與該專案保持聯繫,代表「第三方採用者」提供重要的回饋。 他甚至能夠找到一些空閒時間直接參與專案的開發,為 Handly 範例之一(Java 模型)實作 UI 層(約 XNUMX 行程式碼)。 更詳細的採用者使用Handly的第一手資料可以在頁面找到 成功案例 專案.

我們希望在保證API穩定性、專案脫離孵化狀態的1.0版本發布後,Handly會有新的採用者。 同時,該專案繼續測試並進一步改進 API,每年發布兩個「主要」版本 - XNUMX 月(與同時 Eclipse 版本相同的日期)和 XNUMX 月,提供了採用者可以依賴的可預測的時間表。 我們還可以補充一點,該專案的「錯誤率」始終保持在較低水平,並且自第一個版本以來,Handly 一直在早期採用者的產品中可靠地工作。 要進一步探索 Eclipse Handly,您可以使用 入門教學 и 建築概述.

來源: www.habr.com

添加評論