更新:09 年 8 月 15 日:評論現已關閉。 如果您需要安裝幫助、提供反饋或提問,請加入郵件列表(存檔)
在過去幾個月裡,SpringSource 一直積極參與開發下一版本的 Eclipse Groovy Tools。 最初的目標是讓它們在現有基礎上進一步發展,成為用於程式碼開發、構建和測試等關鍵開發者任務的高度最佳化的環境。理想情況下,處理混合 Groovy/Java 專案時的體驗應該像在 Eclipse 中處理純 Java 專案一樣流暢。
本週,第一個版本的程式碼已提交到 codehaus 倉庫,並且里程碑 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 下,導航到
Help >
Software Updates。 在
Available Software 選項卡上,點選
Add Site 並輸入更新站點 URL:
http://dist.codehaus.org/groovy/distributions/greclipse/snapshot/e3.4。 點選
OK。 現在更新站點將出現在列表中,開啟它並標記條目 'Groovy-Eclipse plugin'。 最後,在右上角,點選
Install 並按照對話方塊完成安裝。 安裝完成後,有三種方法可以開始使用 Groovy:
- 建立新的 Groovy 專案。 就像建立 Java 專案一樣,有一個 Groovy 專案建立嚮導。 所有 Groovy 專案都實際支援 .java 和 .groovy 檔案的混合。
- 修改現有 Java 專案以包含 groovy 程式碼。 在包資源管理器中選擇您的 Java 專案,右鍵單擊並向下導航到上下文選單中的 Groovy,然後選擇 Add Groovy Nature。 完成後,您的專案圖示將改變,從那時起,該專案中的任何 .groovy 檔案都將與 .java 檔案一起構建。
- 遷移現有 Groovy 專案。 如果您有使用舊版外掛建立的 Groovy 專案,則必須將其遷移到新版本。 要遷移專案,選擇您要遷移的專案,然後右鍵單擊並導航到 Groovy,然後選擇 Convert legacy groovy projects。 此選項僅在選定的專案需要遷移時出現。
就是這樣!只需像處理 Java 一樣開始建立和使用 Groovy 型別。 FAQ
http://groovy.codehaus.org/Eclipse+Plugin+V2+FAQ 嘗試回答我們認為關於此 alpha 版本將出現的常見問題,幷包含有關報告您遇到的任何問題或提出進一步問題的連結。
現有外掛的編譯策略
在描述此版本使用的新編譯器技術之前,值得簡要回顧一下現有版本使用的技術。 當前釋出的 Groovy Eclipse 外掛利用了現有 groovy 編譯器 '聯合編譯' 的支援。聯合編譯使得混合 Java/Groovy 程式碼庫能夠構建,其中 Java 和 Groovy 型別之間存在引用。 其工作原理基本如下:
- 讓 groovy 編譯器 (groovyc) 解析 .groovy 檔案
- 在磁碟上建立存根,這些存根是這些 groovy 檔案的 Java 類似表示。
- 呼叫 javac 構建 .java 檔案,這些檔案可以透過存根看到 groovy 檔案。
- 完成對 groovy 檔案的處理 - 現在可以解析對 Java 型別的 .class 檔案的引用
然後使用者的所有原始檔都被構建成二進位制的 .class 檔案。
簡化專案構建策略
我知道包括我在內的一些使用者在設定使用聯合編譯的 eclipse 外掛版本構建專案時遇到了麻煩——它使用的雙構建器設定配置起來可能很棘手。 當我們開始設計下一版本的工具時,我想知道是否有一種更最佳化的方法,即只有一個構建器負責,並且它知道要呼叫誰來處理 Java 或 Groovy 檔案。擁有一個單一的構建器將消除配置專案構建的複雜性。
我最初的想法是讓 Eclipse Compiler 負責構建程式碼,但在必要時應 melibatkan groovyc 處理任何 groovy 程式碼。 由於我在編譯器方面的背景(研究 AspectJ),我對 Eclipse Java 編譯器已經很熟悉。 然後在與 Jochen Theodorou (groovy 技術負責人) 討論 groovyc 編譯器的結構後,看起來可以在 Eclipse 編譯器和 groovyc 之間實現更緊密的整合,從而避免使用存根。 在正常的聯合編譯中,磁碟上的存根本質上是 groovyc 告訴 javac 它正在做什麼的一種方式,類似地,javac 生成的 .class 檔案是 javac 告訴 groovyc 它剛剛做了什麼的一種方式。 最佳化編譯器之間的通訊將意味著它們直接對話而不是透過磁碟上的檔案(存根 .java 檔案或 .class 檔案)進行。 然而,編譯器之間通訊方式的任何改變都不能影響現有聯合編譯策略提供的最重要的功能——它允許在兩種語言定義的型別之間完全自由地引用。 例如,考慮在單個專案中定義的這三種類型:
'什麼應該首先完全編譯?' 這個問題沒有正確答案。 如果 Groovy 程式碼全部先編譯,它將找不到 Apple Java 型別。 如果 Java 程式碼先編譯,它將找不到 Fruit Groovy 型別。 顯然,當將 Eclipse 編譯器和 groovyc 連線在一起時,它們需要在整個編譯過程中互相瞭解,並能夠互相提問(最重要的是:你能解析這個型別嗎?)。 為了支援這種方法,Eclipse 編譯器和 groovyc 可能都需要進行更改,但會盡量減少這些更改,並希望將這些更改貢獻回兩個編譯器專案。
除了將兩個編譯器“簡單地”粘合在一起的任務外,新版本還有一些額外的要求:
- 使 Eclipse 為 Java 提供的增量編譯行為適用於 Groovy 程式碼。
- 在任何情況下,都不能改變 Eclipse 編譯器構建純 Java 專案的方式。 它必須像以往一樣快速可靠。
- 儘量避免在 Eclipse Compiler 中引入任何 Groovy 特定的依賴。 相反,使用抽象並擴充套件 Eclipse 以支援“某種其他語言”,在這種情況下首先是 groovy。
實現後一個目標將使我們處於有利位置,可以將 Eclipse 編譯器更改貢獻回 Eclipse。
不只是關於效能
當然,最佳化編譯器之間的通訊應該會提高效能,讓增量編譯適用於 Groovy 會很棒,但遷移到這種新的單一構建器策略(由 Eclipse Compiler 主導)還有一個非常好的理由。如果 Eclipse 能更好地理解 groovy,那麼 Eclipse 的一些功能就會“自然而然地”工作。 JUnit 支援就是一個很好的例子。 在 Eclipse 中執行測試用例,通常使用上下文選單
RunAs > JUnit 或快捷鍵
Alt+Shift+X, T。 使用當前版本的 groovy 外掛,這不會起作用,因為 Eclipse 不知道編輯器中顯示的是什麼。 在新的體系中,編譯器之間的整合層使 Eclipse 能夠理解該 groovy 檔案的結構——它能看到測試類,能看到任何
@Test 註解,甚至能看到任何
@RunWith 註解來選擇測試執行器。 因此,JUnit 啟動就自然而然地工作了。 這只是一個無需任何努力就能煥發新生的例子。 這裡需要理解的是,Eclipse 編譯器本身並沒有被修改來直接處理 groovy 程式碼,它總是委託 groovy 編譯器來處理 groovy 程式碼,但編譯器之間的整合層使 eclipse 能夠理解 groovyc 呼叫的結果。
內部結構
使整合層在短時間內可行的是兩個編譯器現有的靈活結構。 編譯的各個階段在 Eclipse Compiler 中清晰可見且易於訪問,在 groovyc 中可能甚至更清晰(它們被稱為階段)。 將編譯器整合在一起基本上是定義一個流程,協調和控制每個編譯器透過各個階段/階段的進展。 儘管實際編譯中有許多階段,但為了理解新設計,可以將其簡單地視為一個三個階段的過程:解析/解析/生成。
在解析階段,將輸入資料從純文字形式處理成某種內部資料結構——不對該結構進行任何推斷。
在解析階段,追溯結構中名稱所引用的實際實體。 例如,如果在原始碼中使用了 'Foo',必須確定使用者指的是哪個 Foo——這透過適當的解析規則來完成:我的匯入有哪些?此包中有什麼?類路徑上有什麼?在 groovy 的情況下,還有額外的規則,例如:我的別名匯入有哪些?
在生成階段,建立實際的 .class 檔案。
下圖顯示了新構建器在編譯專案時的體系結構。 所有原始檔(.java 和 .groovy)都被傳遞給 Eclipse 編譯器。 根據副檔名,Eclipse 編譯器要麼自己解析檔案,要麼要求 groovyc 解析檔案。 完成後,對發現的所有型別(Groovy 和 Java 型別)執行解析。 兩個編譯器中的解析策略都經過調整,以便它們能夠看到彼此的型別。 最後,在解析之後,執行生成階段以建立 .class 檔案。
[caption id="attachment_2593" align="aligncenter" width="624" caption="新編譯系統的結構"]
[/caption]
通常在生成 .class 檔案後,groovy 編譯過程會立即將檔案寫入磁碟,但在新設計中,它們會返回給 Eclipse 編譯器。 這最後一步是實現增量編譯工作的關鍵。 Eclipse 分析 groovyc 生成的類檔案,就像分析它自己建立的類檔案一樣。 類之間引用的資訊以與常規 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 程式碼的泛型警告"]
[/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 示例"]
[/caption]
是的,對於“知情者”來說,這張截圖確實表明這個新的構建器支援 groovy AST 轉換,因為 Spock 就是這樣實現的。
IDE 之外
我知道很多人在他們的構建系統中使用 Eclipse 編譯器作為 Java 編譯器。 這讓他們對構建系統正在做的事情更有信心,因為它是他們 IDE 中使用的同一個編譯器。 沒有什麼可以阻止本文描述的整合的 Eclipse/Groovy 編譯器以類似的方式使用,無論是直接在命令列上還是透過 Ant。 在最終釋出時,我們將提供有關如何做到這一點的文件。
Alpha 釋出版
到目前為止所有工作的結果現已可供下載。 下載包括一個用於 Eclipse JDT 編譯器的補丁,以暴露適當的擴充套件點,一個略有修改的 Groovy 1.7 構建版本,將它們連線在一起的整合程式碼,以及最後提供 UI 的其他外掛。
它工作得怎麼樣? 這是里程碑 1 之前的釋出版本,所以請理解它尚未達到生產就緒水平! Groovy 和 Java 型別之間的互動方式可能有很多種,儘管我們已經測試了很多,但您嘗試的第一個東西可能就會把它弄壞! 我們強烈建議您透過報告任何問題來幫助我們,以便我們在邁向第一個釋出版本時提高質量。 FAQ (http://groovy.codehaus.org/Eclipse+Plugin+V2+FAQ) 提供了更多資訊,包括提問和報告問題的連結。 目前唯一可用的下載是針對 Eclipse 3.4.2 的。 對 Eclipse 3.5 的支援將很快跟進。 最近的重點是編譯和增量編譯。 我們知道 UI 的某些部分仍然有點慢(例如程式碼輔助),並將積極努力加快它們的速度,FAQ 討論了這種情況的原因。
未來
使用這種新編譯器技術的 Eclipse 外掛的第一個釋出版本旨在成為最有意義併為使用者提供價值的最小一致功能集,因此主題是提供最佳化的編輯/儲存/編譯/測試體驗。 我們認為第一個釋出版本可以在幾個月內釋出。 在即將到來的第一個里程碑釋出之後,我們將積極提供更頻繁的開發構建版本,以邁向 M2 和最終版本。 其中可能還會包含一些與 Grails 相關的功能。