更棒的 Groovy Eclipse 體驗

工程 | Andy Clement | 2009 年 7 月 30 日 | ...

更新:2009 年 8 月 15 日:評論現已關閉。 如果您需要安裝方面的協助、提供意見回饋或提出問題,請加入郵件清單 (封存)


過去幾個月,SpringSource 積極參與開發下一版本的 Eclipse Groovy Tools。 最初的目標是將它們從現有狀態發展成為一個高度優化的環境,用於程式碼開發、建置和測試等關鍵開發人員任務。 理想情況下,在使用混合 Groovy/Java 專案時的體驗,應該和在 Eclipse 中處理純 Java 專案一樣順暢。

本週,第一個版本的程式碼已提交到 codehaus 儲存庫,並且很快將發佈 milestone 1。 提供了一個更新站點(適用於 Eclipse 3.4.2),其中包含當前的開發版本:http://dist.codehaus.org/groovy/distributions/greclipse/snapshot/e3.4。 是的,目前還沒有適用於此程式碼的 Eclipse 3.5 版本,但很快就會有。(更新! 09 年 7 月 31 日,Eclipse 3.5 更新站點現已在 http://dist.codehaus.org/groovy/distributions/greclipse/snapshot/e3.5 上提供)

在這篇文章中,我將簡要介紹如何開始使用新的外掛程式,然後重點介紹支援它的新技術以及它所帶來的可能性。

開始使用

從更新站點安裝的方式與其他 Eclipse 功能相同。 在 Eclipse 3.4.2 下,導覽至「說明」>「軟體更新」。 在「可用的軟體」標籤上,按一下「新增站點」,然後輸入更新站點 URL:http://dist.codehaus.org/groovy/distributions/greclipse/snapshot/e3.4。 按一下「確定」。 現在,更新站點將在清單上,打開它並標記條目「Groovy-Eclipse plugin」。 最後,在右上角,按一下「安裝」並按照對話方塊完成安裝。 安裝完成後,有三種方式可以開始使用 Groovy:
  1. 建立新的 Groovy 專案。 就像您可以建立 Java 專案一樣,有一個 Groovy 專案建立精靈。 所有 Groovy 專案實際上都支援 .java 和 .groovy 檔案的混合。
  2. 修改現有的 Java 專案,以便您可以包含 Groovy 程式碼。 在套件瀏覽器中選取您的 Java 專案,按一下滑鼠右鍵並導覽至上下文選單中的「Groovy」,然後選取「新增 Groovy Nature」。 完成後,專案的圖示將變更,從那時起,除了 .java 檔案之外,還會建置該專案中的任何 .groovy 檔案。
  3. 移轉現有的 Groovy 專案。 如果您使用舊版外掛程式建立了 Groovy 專案,則必須將它們移轉到新版本。 若要移轉專案,請選取您要移轉的專案,然後按一下滑鼠右鍵並導覽至「Groovy」,然後選取「轉換舊版 Groovy 專案」。 僅當選取的專案需要移轉時,才會顯示此選項。
就是這樣! 只需開始建立 Groovy 類型並像使用 Java 一樣使用它們。 FAQ http://groovy.codehaus.org/Eclipse+Plugin+V2+FAQ 試圖回答我們認為圍繞此 alpha 版本的常見問題,並包含在遇到任何問題或想要提出其他問題時,可以提出問題的連結。

現有外掛程式編譯策略

在描述此版本使用的新編譯器技術之前,值得簡要介紹一下現有版本所使用的技術。 目前發佈的 Groovy Eclipse 外掛程式利用了現有的 Groovy 編譯器「聯合編譯」支援。 聯合編譯支援建置一個混合的 java/groovy 程式碼庫,其中 Java 和 Groovy 類型之間存在參考。 基本上,它的工作原理如下:
  • 讓 Groovy 編譯器 (groovyc) 剖析 .groovy 檔案
  • 建立磁碟上的 stub,這些 stub 是這些 Groovy 檔案的類似 Java 的表示形式。
  • 呼叫 javac 來建置 .java 檔案,這些檔案能夠透過 stub 看到 Groovy 檔案。
  • 完成 Groovy 檔案的處理 - 現在可以針對 Java 類型的 .class 檔案解析參考
使用者可以將所有來源建置到二進位 .class 檔案中。

簡化專案建置策略

我知道一些使用者(包括我自己)在設定專案以使用使用聯合編譯的 Eclipse 外掛程式版本進行建置時遇到問題 - 它使用的雙重建置器設定可能難以正確配置。 當我們開始設計下一版本的工具時,我想知道是否有更優化的方法,其中只有一個建置器負責,並且它知道該呼叫誰來處理 Java 或 Groovy 檔案。 擁有單一建置器將消除配置專案以進行建置的任何複雜性。

我的最初想法是應該讓 Eclipse 編譯器負責建置程式碼,但在必要時應該涉及 groovyc 來處理任何 Groovy 程式碼。 由於我在編譯器方面的背景(在 AspectJ 上工作),我已經非常了解 Eclipse Java 編譯器。 然後,在與 Jochen Theodorou(Groovy 技術主管)討論 groovyc 編譯器的結構後,看起來可以在 Eclipse 編譯器和 groovyc 之間實現更緊密的整合,從而避免使用 stub。 在正常的聯合編譯中,磁碟上的 stub 本質上是 groovyc 告訴 javac 它在做什麼的一種方式,類似地,javac 產生的 .class 檔案是 javac 告訴 groovyc 它剛做了什麼的一種方式。 優化編譯器之間的通訊,只需讓它們直接通訊,而不是透過磁碟上的檔案(stub .java 檔案或 .class 檔案)。 但是,編譯器之間通訊方式的任何變更都不得影響現有聯合編譯策略提供的最重要的功能 - 允許在兩種語言中定義的類型之間進行完全自由的參考。 例如,考慮在單一專案中定義的以下三種類型:

hierarchy

對於「應該首先完全編譯什麼?」沒有正確的答案。 如果首先編譯所有 Groovy 程式碼,則它將無法找到 Apple Java 類型。 如果首先編譯 Java 程式碼,則它將無法找到 Fruit Groovy 類型。 顯然,當將 Eclipse 編譯器和 groovyc 連接在一起時,它們需要在整個編譯過程中相互了解,並且能夠相互提問(最重要的是:您可以解析此類型嗎?)。 為了支援這種方法,可能需要對 Eclipse 編譯器和 groovyc 進行變更,但會小心地最小化這些變更,並希望將這些變更貢獻回這兩個編譯器專案。

除了將兩個編譯器連接在一起的「簡單任務」之外,新版本還有一些額外的要求:

  • 使 Eclipse 為 Java 提供的增量編譯行為適用於 Groovy 程式碼。
  • 在任何情況下,都不能變更 Eclipse 編譯器建置純 Java 專案的方式。 它必須像以往一樣快速可靠。
  • 盡量避免將特定於 Groovy 的依賴項引入 Eclipse 編譯器。 而是使用抽象並擴展 Eclipse 以支援「其他語言」,在第一個實例中,該語言將是 Groovy。
實現後一個目標將使我們處於一個良好的位置,以便將 Eclipse 編譯器變更貢獻回 Eclipse。

不僅僅是效能

當然,優化編譯器之間的通訊方式應該可以提高效能,並且讓 Groovy 的增量編譯能夠工作會很好,但是採用這種新的單一建置器策略(由 Eclipse 編譯器負責)還有另一個非常好的理由。 如果可以使 Eclipse 更好地理解 Groovy,那麼 Eclipse 的某些功能將會「正常工作」。 這方面的一個很好的例子是 JUnit 支援。 為了在 Eclipse 中執行測試案例,您通常使用上下文選單「執行為 > JUnit」或快捷方式 Alt+Shift+X, T。 使用當前版本的 Groovy 外掛程式,這不起作用,Eclipse 不知道它在編輯器中看到的是什麼。 在新世界中,編譯器之間的整合層使 Eclipse 能夠理解該 Groovy 檔案中的內容 - 它可以看到測試類別,它可以看到任何 @Test 註解,它甚至可以看到任何 @RunWith 註解來選擇測試執行器。 因此,JUnit 啟動就可以正常工作。 這只是零努力就可以實現的一個例子。 重要的是要理解,這裡的 Eclipse 編譯器沒有被修改為直接處理 Groovy 程式碼,它始終委派給 Groovy 編譯器來處理 Groovy 程式碼,但是編譯器之間的整合層使 Eclipse 能夠理解 groovyc 呼叫的結果。

內部結構

在短時間內實現整合層的原因是兩個編譯器現有的靈活結構。 編譯的各個階段在 Eclipse 編譯器中清晰可見且可訪問,並且在 groovyc 中可能更清晰(在 groovyc 中稱為階段)。 將編譯器整合在一起基本上是定義一個流程,該流程協調和控制每個編譯器在各個階段/階段中的進展。 雖然在實際編譯中有許多階段,但為了理解新設計,可以很容易地將其視為一個三階段過程:剖析/解析/產生。

剖析 (parse)階段,輸入資料會從純文字格式處理成某種內部資料結構 - 並不會推斷該結構的任何資訊。

解析 (resolve)階段,會追蹤結構中名稱所指的實際實體。例如,如果在原始碼中使用了 'Foo',則必須確定使用者指的是哪個 Foo - 這會使用適當的解析規則來完成:我的 imports 有哪些?這個 package 裡面有什麼?classpath 上有什麼?在 Groovy 的情況下,還有額外的規則,例如:我的 aliased imports 有哪些?

產生 (generate)階段,會建立實際的 .class 檔案。

下圖顯示了呼叫新建置器以編譯專案時的架構。所有原始碼(包括 .java 和 .groovy)都會傳遞給 Eclipse 編譯器。根據檔案副檔名,Eclipse 編譯器會自行剖析檔案,或者要求 groovyc 剖析檔案。完成後,解析會在所有已發現的類型(Groovy 和 Java 類型)上執行。兩個編譯器中的解析策略都經過調整,以便它們可以看到彼此的類型。最後,在解析後,會執行產生階段以建立 .class 檔案。

[caption id="attachment_2593" align="aligncenter" width="624" caption="新編譯系統的結構"]新編譯系統的結構[/caption]

通常,在產生 .class 檔案後,Groovy 編譯程序會立即將檔案寫入磁碟,但在新的設計中,它們會返回到 Eclipse 編譯器。這最後一步使增量編譯得以運作。Eclipse 分析 groovyc 產生的 class 檔案,就像分析它自己建立的 class 檔案一樣。類別之間參考的資訊會以與常規 Java 類型相同的結構保存 - 這就是我們「免費」獲得 Groovy 增量編譯支援的原因。由於此參考資訊以與 Java 類型相同的方式保存,因此會自動為每個專案持續保存,以避免在 Eclipse 重新啟動時遺失,並且其他相依專案可以使用它。對於 AspectJ 而言,後兩個功能仍然是一個問題,因為 AspectJ 採用了不同的 Eclipse 編譯器修改方法。

增量編譯

這確實值得寫一篇完整的博文,但值得在此處描述基礎知識。編譯後,Eclipse 編譯器會記錄它處理的所有類型之間的參考。增量編譯僅僅是在建置某些內容後,查詢參考列表,以查看誰受到變更的影響。如果沒有人受到影響,則編譯結束。如果某些類型確實依賴於剛建置的內容,則會編譯它們。此處描述的機制甚至將為純 Groovy 專案提供增量編譯。

意外的驚喜?

很早就變得明顯的一件事是,由於 Eclipse 現在可以看到 Groovy 類型的類 Java 結構,因此它會檢查該結構。某些檢查對於 Groovy 程式碼無效,因為 Groovy 在它允許的內容方面更具彈性,但有些檢查很有用。考慮到如果程式碼對泛型的利用不完全正確,Eclipse 編譯器將報告無數(可配置的)與泛型相關的警告。此螢幕截圖顯示 Eclipse 編譯器實際上在檢查 Groovy 程式碼。

[caption id="attachment_2594" align="aligncenter" width="708" caption="Groovy 程式碼的泛型警告"]Groovy 程式碼的泛型警告[/caption]

這些檢查的價值仍有待商榷,但目前它們已被保留為啟用狀態。

使用者介面 (UI)

到目前為止,我所談論的一切都是底層編譯策略。在 Eclipse UI 中,它僅作為用於編譯混合 Java/Groovy 專案的「建置器」出現。除此之外,Andrew Eisenberg(也和我一起在溫哥華 SpringSource 實驗室工作)一直在努力使 UI 煥發活力。
  • 引入(並發展)現有外掛程式中仍然需要在新世界中的元件,並根據新的編譯基礎架構對它們進行重新建置。
  • 開發/增強使用者在 IDE 中依賴的那些功能:編輯器、大綱視圖、程式碼輔助、導航、除錯等等。
最終結果是,在使用 Groovy 時,Eclipse UI 的外觀和行為與使用 Java 時相同。這是來自 Spock 測試框架的 PublisherSubscriberSpecification 範例 (http://code.google.com/p/spock/ )。它可以直接作為 JUnit 測試執行。

[caption id="attachment_2595" align="aligncenter" width="1088" caption="執行 Spock 範例"]執行 Spock 範例[/caption]

是的,對於那些「知情人士」來說,該截圖確實表明這個新的建置器支援 Groovy AST 轉換,因為 Spock 就是這樣實作的。

IDE 之外

我知道許多人在他們的建置系統中將 Eclipse 編譯器用作 Java 編譯器。這使他們對建置系統所做的事情更有信心,因為它與他們在 IDE 中使用的編譯器相同。沒有什麼可以阻止使用本文中描述的整合式 Eclipse/Groovy 編譯器以類似的方式使用,可以直接在命令列上或通過 Ant 使用。在最終版本中,我們將提供有關如何執行此操作的文檔。

Alpha 版本

到目前為止的所有工作成果現在都可以下載了。該下載包括 Eclipse JDT 編譯器的修補程式,用於公開適當的擴充點、稍微修改過的 Groovy 1.7 建置、將它們連接在一起的整合程式碼,以及最後提供頂層 UI 的其他外掛程式。

它運作得如何?這是一個 pre-milestone 1 版本,因此請理解它尚未準備好用於生產環境!定義 Groovy 和 Java 類型之間互動的方式有很多種,雖然已經測試了許多方式,但您嘗試的第一件事可能會破壞它!我們敦促您通過報告任何問題來幫助我們,以便我們在邁向第一個版本的過程中提高品質。 http://groovy.codehaus.org/Eclipse+Plugin+V2+FAQ上的 FAQ 提供了更多資訊,包括提出問題和提出問題的連結。目前唯一可用的下載適用於 Eclipse 3.4.2。Eclipse 3.5 支援將很快推出。最近的重點是編譯和增量編譯的故事。我們知道 UI 的某些部分仍然有點遲緩(例如程式碼輔助),並且將積極努力加速這些部分,FAQ 討論了為什麼會這樣。

未來

使用此新編譯器技術的 Eclipse 外掛程式的第一個版本旨在成為最小的一致功能集,該功能集有意義並為使用者提供價值,因此主題是提供最佳化的編輯/儲存/編譯/測試體驗。我們認為這個第一個版本可以在幾個月內推出。在即將到來的第一個里程碑版本之後,我們將積極提供更頻繁的開發版本,因為我們正邁向 M2 和最終版本。甚至可能會有與 Grails 相關的功能。

獲取 Spring 電子報

通過 Spring 電子報保持聯繫

訂閱

領先一步

VMware 提供培訓和認證,以加速您的進度。

了解更多

獲取支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔。

了解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

查看全部