獨家專訪Scala IDE三劍客:探秘IDE插件開發
原創【51CTO獨家特稿】Eclipse、NetBeans和IntelliJ是IDE領域的三大巨頭,尤其是在Java開發方面。而Scala編程語言,則是一個基于Java平臺的、比Java語言更好的新語言(參考閱讀:Scala簡介),這個語言在過去的幾年間得到了越來越多的認可,并且有越來越多的項目開始接觸、嘗試并使用它(比如:Twitter,法國電力,西門子等等。詳見Scala官方網站)。然而現在一個普遍的問題就是:Scala的IDE支持情況。
#t#大部分Scala項目都是從Java項目開始的,而項目轉型的成本和效率與是否有優秀的IDE支持緊密相關。Eclipse、NetBeans和IntelliJ這三大IDE的插件機制各自不同,因此在實現這一共同的功能上,都會有不同的思路,遇到不同的問題,最終帶來不同的解決方法。
51CTO編輯近日通過網絡途徑對三個Scala IDE插件的開發者進行了采訪,目的有以下兩個:
1.總結Scala插件的現狀。BASE小組在今年8月曾組織過一次吹風會交流Scala插件的情況,此次訪談也是希望延伸那次會議的交流成果,跟蹤Scala插件在之后這三個月的發展情況。
2.展示IDE語言支持插件的開發過程。相信很多開發者對于開發Eclipse、NetBeans和IntelliJ的插件很感興趣,但也許不知道要從何入手,那么最好的方法就是從其他插件開發者的開發經驗當中學習。語言支持插件是IDE插件當中最難的一種,因此從中能夠獲得的經驗也是最多的。
概述
目前Scala插件的開發者情況如下(參考Scala官網的介紹):
Eclipse的Scala插件:Scala IDE for Eclipse
這個插件最初由Sean McDirmid(Scala創始人Martin Odersky的學生)開發,現在由Miles Sabin來負責此項目。51CTO編輯聯系到了Miles Sabin進行采訪。Miles開展了一家專門做Scala相關咨詢的公司,為客戶提供Scala工具、Scala開發、培訓和其他咨詢的服務。
Miles Sabin的個人主頁(即他公司的主頁):http://www.chuusai.com/
NetBeans的Scala插件:Scala Plugin for NetBeans
這個插件由鄧草原在其業余時間開發。鄧草原,現加盟宏爵財經資訊(北京)有限公司。他是開源軟件AIOTrade項目的主創者,同時也是NetBeans的Erlang插件的開發者,以及NetBeans夢之隊成員。
鄧草原的個人主頁:http://blogtrader.net/dcaoyuan/
IntelliJ的Scala插件:Scala Plugin for IntelliJ IDEA
這個插件由Jetbrains IntelliJIDEA的一個小團隊進行開發,團隊成員包括Ilya Sergey,Eugene Vigdorchik以及Alexander Podkhalyuzin。51CTO編輯對Ilya Sergey進行了采訪。IntelliJ在幾個星期前終于也加入了開源的行列,這將幫助它擴展更多的用戶。
Ilya Sergey在信件中表示,希望使用IntelliJ的Scala插件的開發者都能仔細閱讀這個wiki頁面,這樣可以減少很多有關插件安裝和使用的問題。
訪談內容
此次訪談主要以電子郵件的形式進行,51CTO編輯向三位開發者發送了一組問卷。問卷包括六個問題:
1.您是如何開始進入Scala插件開發這項工作的?
2.進行IDE插件開發需要具備哪些知識?
3.能否介紹一下您計劃讓Scala插件提供哪些功能?現在都實現了么?
4.IDE插件開發的主要瓶頸在哪些方面?與其他插件開發者進行交流對您的進程是否有幫助?
5.您認為Scala插件現在已經足夠成熟到投入實際的開發中去?開發者在使用中需要注意哪些問題?
6.您對于Scala 2.8的正式推出抱有怎樣的期待?
希望三位開發者對這些問題的回答能夠對您有所幫助。下面請進入正文部分——
#p#
Eclipse的Scala插件開發者,Miles Sabin
#t#Eclipse的Scala插件的現任開發者Miles Sabin由于工作繁忙的關系,難以抽出太多時間來完整的回復我們的郵件,不過Miles十分熱心的提供了幾條很有用的信息,并對一些具體的問題進行了細致的回復,幫助我們成功完成這次訪談。
1.您是如何開始進入Scala插件開發這項工作的?
我一開始并非是被Scala所吸引。大約在1998年的時候,我是JCP工作團隊的一員,負責NIO事件驅動網絡IO API這一塊的設計(這一功能在Java 1.4版本中開始出現)。我們的團隊工作的很出色,但不得不承認,要充分利用Java的特性來建造高性能網絡應用并不是個容易的事情。你會發現你陷入了一個周圍遍布手工制造的狀態機這樣的尷尬情況。如果沒有順手工具的支持,這將很快變得非??菰?,非常困難。
直覺告訴我語言級的支持是正確的方向。我啟動了一個長期項目:尋找或創造一個合適的語言。2003年我興奮的發現了Funnel語言。這個語言基于聯合演算,來自EPFL(編者注:洛桑聯邦理工學院,瑞士的兩所聯邦理工學院之一)的Martin Odersky的團隊。后來Funnel項目被停止,取而代之的就是Scala項目。
雖然與Funnel有很大不同,但我第一眼看到Scala就喜歡上它了。當時我是Codefarm公司的技術總監,專門經營基于Java與OSGi基礎設施的分布式受限優化方面的技術。我們的產品包含一個復雜的特定領域語言(DSL),而Scala在這方面很理想。當時我們就想轉移到Scala上,但在2004年那個時候Scala還不夠成熟,把公司押上去風險太大。不過現在就不同了,我會毫不猶豫的向新客戶推薦Scala。
我建立了一個咨詢公司,在很多項目上尋找商業機會;同時我一直在關注Scala電子郵件群的動向,尋找機會表達我對Scala的愛。當時EDF(électricité de France,法國電力)貿易部門的一個團隊宣布要將大量Java代碼庫址(大約有30萬行代碼)遷移至Scala。他們很喜歡Scala,同時也非常需要在Eclipse的Scala插件中有更加強大的對Java/Scala混合項目的支持。結果是,EDFT團隊實現了絕大多數代碼庫址到Scala的遷移,并使用Scala編寫了幾個新的能源產量推導價格的應用。在這個過程中,Scala IDE也經歷了巨大的成長。
Eclipse的Scala插件最初是由Sean McDirmid(Martin Odersky的學生)開發的。當時EDFT團隊希望實現更多功能,不過同時也希望這是個可靠的生產工具。他們從Sean的成果中看到了這個插件的潛力,并愿意在他們需要的功能上投資。我為他們提出了一個計劃,由此確定了項目進展的方向。主要的目標定位為對Scala/Java混合項目的無縫支持,以及與Eclipse Java工具的集成。很明顯,極大多數Scala項目將從現有的Java代碼庫起步,而無縫集成對于逐步遷移項目而言是絕對必要的。
2.進行Eclipse插件開發需要具備哪些知識?
雖然Miles表示難以回答這個問題,不過讀者們可以看看Miles對其他問題的回答,里面可能有您想知道的內容。另外,Groovy Eclipse插件的開發團隊也對這個問題表達過自己的見解:Groovy Eclipse開發團隊訪談。
3.能否介紹一下您計劃讓Scala插件提供哪些功能?現在都實現了么?
Scala Eclipse插件的開發基本上經歷了七個階段:
◆2005年初:使用Java完成了第一版Scala Eclipse插件,在基本語法高亮和build invocation之外幾乎沒有什么功能。當時還有一個類似的工具叫做Scaliptor。
◆2005年12月-2006年2月:插件用Scala重新編寫,添加了一些語義功能(如有限的自動完成代碼功能)。此時已經出現了對Scala/Java混合項目無縫支持的需求。
◆2007年6月-2008年2月:更加深入的與Scala編譯器集成:
= 互交式錯誤報告
= 語法高亮
= 增量編譯
= 依賴管理
◆2008年5月:我加入項目,EDF貿易部門投入資金用于協助開發。主要目標為
= 簡易的Scala/Java遷移
– scalac中Scala/Java混合編譯
– Eclipse中的Scala/Java混合項目
= 更好的Eclipse穩定性以及發布周期
這些目標在2009年11月基本實現,當時發布了Scala 2.7.2。不過,JDT集成仍然有限,而穩定性依然是個問題。
◆JDT集成成為嚴重的瓶頸。提交了一個用于開放JDT的patch,不過被拒絕了。不過,通過AspectJ和Equinox Aspects,找到了另一個解決方案,打破了JDT的瓶頸。之后,解決了很多bug,增強了很多功能。在2009年4月時,新的插件與Scala 2.7.4一起亮相。然而,這個插件有一些安裝問題,一些JDT特性也不太穩定
◆我繼續全速解決JDT集成的問題,并增添了幾個幫手。然而,大多代碼庫址很復雜,過于抽象,將人拒之門外
= 對于大多數來幫忙的開發者而言,學習曲線太高
= 編譯器過于脆弱:
-很小的錯誤會導致所有代碼高亮消失
-不靠譜的依賴管理
=對scalac的副作用:很多脆弱的“if(inIDE)”塊
于是,徹底重寫了所有語法和build相關的功能。這項工作在今年5月間與EPFL的Martin Odersky和lulian Dragos共同完成。
這個新的互交式編譯器有了如下改進:
= 將舊的可視化編譯器全部重寫
= 編譯單元被整合為一個源文件
- 性能即使沒有提升,至少實現了均衡。原先的做法是“過早優化”
= 所有“inIDE”條件從scalac中移除
= 到AST節點的信息的精確定位
- 支持新的功能(折疊)
- 支持新的工具(重構,格式化)
= 新的增量構建管理
= 可靠性大幅增長
= 使用了scalac的文件系統抽象功能
= 支持所有的JDT構建路徑功能,如多源,多輸出目錄等
不過,由于整個重寫,原先scalac的集成支持被全部移除。Eclipse中所有的語法特性也整個重來了一遍,對于2.7.x一支的新功能和bug修復也沒有了可行的回移方案。
◆到今年9月,又有了如下進展:
= 新的build管理器已經完全集成,基本解決了打開/關閉項目時出現的問題
= Scala編輯器現在和Java編輯器基本相同
= 新的輕量語法高亮器基于Java的JDT,在語法錯誤面前十分穩固
= 超鏈接導航接近完成
= 底層機制支持更多JDT特性
= 標準庫的導航性大大增強
= Scala源和雙字節組件的全映射令Scala元素的完全JDT索引成為可能
= 實時錯誤提示
= 實時更新大綱視圖和包瀏覽器的改變
= 自動代碼完成
4.插件開發的主要瓶頸在哪些方面?與其他插件開發者進行交流對您的進程是否有幫助?
最大的瓶頸就是JDT代碼庫址不支持無縫集成JDT。于是,雖然有源代碼,我仍然需要花費大量的時間進行逆向工程并破壞其行為。AspectJ在這里幫了大忙,而我在這個過程中感覺我們終于找到了將Aspects工具用于正當軟件工程的方法。通常情況下我不會提出這樣的建議,不過其帶來的結果十分有價值——它使得原本不堪忍受的痛苦變得可以忍受了。
是的,與其他團隊和開發者合作十分重要。我一直在與IBM和Eclipse進行溝通,希望未來發布的JDT在集成其他JVM語言時可以避免我所走的那些彎路。我與Andrew Eisenberg(AspectJ),Andy Clement(Groovy)以及Neil Bartlett(JavaFX)一直在這個話題上進行交流。另外很明顯,我與Martin Odersky以及EPFL團隊的其他成員也有著緊密的聯系。
最近我在EPFL與Martin和lulian Dragos一起,重新研究了一下scalac與工具(并不限于工具)的接口方面的一些問題。這包括將Scala Eclipse插件的大塊功能重寫移植到scalac自身上去。這樣就可以讓其他開發者也能夠使用這些功能,而最令人興奮的一點就是可以與其他IDE插件開發者分享代碼,特別是NetBeans插件的開發者鄧草原。
5.您是否認為Scala插件現在已經足夠成熟到投入實際的開發中去?開發者在使用中需要注意哪些問題?
很多開發者在使用IDE的當前穩定版(針對Scala 2.7.7),情況十分理想。當然了這個插件現在還是有一些問題,用戶心里要有所準備。
現在的所有開發工作都是針對即將到來的Scala 2.8,這個版本投入了大量的開發精力,并且已經比當前的穩定版更加穩定,更加函數式。如果你可以忍受其底層編譯器和語言更新之頻繁,那么我建議你使用IDE的nightly builds。
6.您對于Scala 2.8的正式推出抱有怎樣的期待?
Scala 2.8的Eclipse插件已經支持了大部分主要功能。我希望能夠在Scala 2.8.0正式發布之前將缺失的重構、代碼格式化等功能補齊,不過是否能完成還不好說。
在Scala 2.8正式發布之前,最重要的是不斷的測試,提高插件的穩定性。其他的功能,如語法注解,對無來源的雙字節元素的支持,Maven支持,恢復JDT特性支持,對Eclipse擴展的兼容性矩陣等等,都需要到Scala 2.8正式發布之后再考慮了。這個過程中我們需要更多支持,比如來自社區的代碼、bug報告、開發者文檔、使用體驗報告等等。
#p#
NetBeans的Scala插件開發者,鄧草原
#t#1.您是如何開始進入Scala NetBeans插件開發這項工作的?
通常在開始使用一種語言時,我首先要找到合適的IDE。大約從2007年起,在使用過Java,JavaScript,Ruby,Python等一系列語言后,我開始尋找能更好地處理并行、并發問題的語言。首先是Erlang,因為沒有合手的IDE,就先花了一個月寫了Erlang的NetBeans插件,順便熟悉了一下Erlang的語法,這就是后來的ErlyBird。在這期間對Scala也一直保持關注。到了2007年年底,Scala終于接近穩定,于是一樣,先寫個IDE。
Scala的IDE難寫的多,一方面是Scala的編譯器對源碼作了非常多步的轉換,使得定位標識符與其語義的關系很困難,另一方面,開始的編譯器對IDE的支持不夠。所以,現在的NetBeans
Scala插件經過了四個階段:
* 2007年,LL(K)語法解析器+自寫的類型標注器
* 2008年上半年,PEGs語法解析器+自寫的類型標注器
* 2008年下半年,Scala自身的編譯器+Hacking,NetBeans Innovation Grant 金獎
* 2009年8月,全部用Scala改寫,Scala自身的編譯器+Martin為IDE支持所做的改進
每個階段實際上都是全部重寫。
2.進行NetBeans插件開發需要具備哪些知識?
如果指的是對新的編程語言的支持插件,需要了解的知識包括:
1、編譯原理(包括詞法、語法、AST樹的產生及轉換)
2、NetBeans的語言擴展框架(包括Parsing API,Common Language Scripting Framework等)
3、NetBeans Platform的APIs(包括NetBeans的Module System,File System
APIs,Lookup APIs,Javac APIs, Debugger APIs, Project APIs等)
3.能否介紹一下您計劃讓Scala NetBeans插件提供哪些功能?現在都實現了么?
* 代碼高亮
* 語法錯誤即時提示
* 大綱導航
* 代碼折疊
* 引用處處標注
* 跳轉到定義處
* 即時重命名
* 重構:重命名和引用查找(跨打開的項目)
* 代碼自動縮進和格式化
* 輸出到HTML文件,保持代碼高亮
* 自動代碼提示、補齊
* 文擋提示
* Java/Scala混合項目
* 重載標記和跳轉到被重載的定義處
* 自動修正import
* 代碼模版
* 斷點處處可設的調試器
* 與Maven項目的結合
這些功能基本上都實現,有些還不完整,有些還有少許Bug,但到目前,應該是支持Scala-2.8.0的功能最全、最好的Scala IDE
4.NetBeans插件開發的主要瓶頸在哪些方面?與其他插件開發者進行交流對您的進程是否有幫助?
開發瓶頸我前面提到過一些,但最困難的還是性能。Scala的編譯器從詞法分析到最后產生JVM的Bytecode大約要做24遍掃描。而IDE必須考慮用戶鍵入時的反應速度,但又要提供盡可能多的信息,那么對于IDE來說,掃描的步驟什么時候做、做到哪一步,都必須仔細權衡。比如為了判斷debugger的斷點應該設置到哪個位置(類名、源文件名、行號等),可能需要做到第13遍掃描才能得到全部的信息,但那樣的話,性能就很差了。還有就是Java/Scala混合的項目中的互可見性,也需要做一系列的映射,這些工作也不能等到全部掃描完成才做。
新的NetBeans插件中,我比較好地解決了大部分問題?,F在用戶鍵入代碼時的反應速度,包括完成代碼提示時的速度都相當不錯了。
我跟Eclipse的插件作者有過交流,包括原來的開發者,Martin的學生Sean McDirmid,他現在在北京工作,我跟他見過兩次,就是他說服我使用Scala自身的編譯器,而不是自己重寫?,F在的Eclipse插件的主力Miles Sabin,我跟他也有交流,包括提交了一些也能幫助Eclipse插件開發的patches。
最重要的是Martin本人前段花了一些時間對Scala的編譯器作了不少改進,這些改進對于減少Scala的IDE支持的重復勞動很有意義,我第一時間就把Martin的這些工作集成到NetBeans中了,并且,我現在的一些工作可以同時作為patches提交給Scala開發團隊,一起提高Scala IDE水平。
5.您認為Scala NetBeans插件現在已經足夠成熟到投入實際的開發中去?開發者在使用中需要注意哪些問題?
NetBeans的插件現在完全可以應用到實際開發中了,NetBeans的Scala插件的一個重要特點是很穩定,當然在最新的版本中,功能和性能都大大增強了。我現在用這個插件開發NetBeans的插件本身和一個實際的大型項目。而且我知道Liftweb社區的很多人都在用NetBeans的插件。
6.您對于Scala 2.8的正式推出抱有怎樣的期待?
我非常希望2.8早日正式推出,一方面是大幅提升后的NetBeans插件只能用于Scala-2.8,另一方面,2.8中的新特性對于我現在的實際項目來說很重要。當然,Scala-2.8的正式推出還需要一些時間,我估計在11月應該能推出一個Beta版。
對于我來說,我天天都在用Scala-2.8的Trunk code,所以也報告了不少Bugs,我希望剛開始對Scala感興趣的人現在就使用Scala-2.8的nightly built版本,一來可以使用NetBeans的最新插件,二來,只有一定數量的人開始使用Scala-2.8才能早日發現和修復bugs。
#p#
IntelliJ的Scala插件開發者,Ilya Sergey
#t#1. 您是如何開始進入IntelliJ的Scala插件開發這項工作的?
最開始,IntelliJ的Scala插件完全是一個實驗性項目。最初提出這個設想的人是Eugene Vigdorchik,而當時的挑戰則是為另外一個非Java語言的基于JVM的語言提供一個成熟的插件。我們從2006年開始開發,當時的Scala版本是2.1.8。當時同時開始開發的還有Ruby插件,這個差距在兩年后成為了一個名為RubyMine的獨立Ruby IDE。在這個Scala插件開始開發的七個月之后,曾經因為商業原因中斷過,而我們則轉而投向Groovy IntelliJ插件的開發。不過到了2007年底,開發社區對于Scala技術的興趣有著顯著的增長,因此我們又回去繼續開發Scala插件。這個項目現在由好幾個人共同承擔:我,來自JetBrains的Alexander Podkhalyuzin,以及Jason Zaugg——他為這個項目貢獻了很多。
2. 進行IntelliJ插件開發需要具備哪些知識?
IntelliJ中用于實現語言插件的開放API現在已經十分豐富,并仍然在不斷地發展。下面這篇文章雖然有點老,不過很好的介紹了如何在IntelliJ中實現語言插件:
http://www.jetbrains.com/idea/documentation/idea_5.0.html
還有一些IntelliJ開放API的其他有用信息如下:
http://www.jetbrains.com/idea/documentation/documentation.html
為選定的語言開發插件通常需要先實現一個詞法分析程序(我們這里使用了JFlex)。然后,我們通過遞歸下降分析法實現一個解析器。到這個階段,開發者已經有了一個我們稱之為程序結構接口(PSI)的東西,它可以實現簡單的代碼轉換,檢查,格式程序,重構等功能。通常如果需要更高級的功能,那么類型推斷和控制流分析的實現則是必須的。對此沒有現成的API,因此需要自行尋找最合適的方法來實現。
3. 能否介紹一下您計劃讓IntelliJ的Scala插件提供哪些功能?現在都實現了么?
近期我們計劃在插件中完全實現Scala的類型系統,這樣就可以實現高級的重構,比如提取方法、閉包、參與者,以及引入結構類型。同時我們也希望對Lift web框架提供更好的支持?,F在,我們可以在IntelliJ中部署、運行并調試Lift項目,不過我們在考慮為項目工件提供更好的導航。在下面有關插件的維基頁面上介紹了更多計劃中的功能:
http://www.jetbrains.net/confluence/display/SCA/
4. 插件開發的主要瓶頸在哪些方面?與其他插件開發者進行交流對您的進程是否有幫助?
大家或許能夠猜到,為IntelliJ開發任何一個語言插件的最大問題在于必須要自己實現一個解析器以及類型檢查器。這個做法有利有弊。大多數情況下我們無法重復利用一個現成的編譯器(比如Scala的Eclipse插件和NetBeans插件)。不過與此同時,我們在代碼分析和轉換上擁有更大的靈活性。比如說,鑒于IntelliJ支持的所有語言在頂層都共享同一組PSI接口,我們可以簡單的處理不同語言之間的重命名,或者“轉移類”重構。也就是說,我們提供了自由的Scala/Java/Groovy/Clojure多語言互操作性。
對于Scala而言,在閱讀Scala語言規范時最大的收獲就是其精確的實現。閱讀Scala編譯器的代碼,與Scala團隊的交流,這些都非常有幫助。有些原本為了IntelliJ插件而實現的功能后來也加入到了Scala發行版當中,比如scalap類反編譯器。我們迫切的需要分析被編譯的Scala類,因為它們是Scala而不是Java。
5. 您認為IntelliJ的Scala插件現在已經足夠成熟到投入實際的開發中去?開發者在使用中需要注意哪些問題?
就我們所知,IntelliJ的Scala插件已經在大量的應用以及項目當中被使用。核心Scala團隊也有不少人在使用IntelliJ來開發Scala編譯器。當然,插件本身正是使用Scala實現的,我們的項目中每天都要用到。另外,Bill Venners開發的ScalaTest框架也使用Scala插件來實現,而這個插件也是支持ScalaTest框架的。目前IntelliJ的Scala插件也支持其他一些Scala框架。
當然了,我們仍然會遇到很多問題需要修復,如果有任何反饋,請隨時在我們的論壇和bug跟中上匯報,謝謝!
http://www.jetbrains.net/devnet/community/idea/scala
http://youtrack.jetbrains.net/issues/SCL
6. 您對于Scala 2.8的正式推出是否期待?
當然了!我們已經使用Scala 2.8進行了好幾個月的插件開發,而最新的build都配備有最新的Scala 2.8類庫。現在已經支持如打包對象這樣的主要功能,而插件本身現在主要針對Scala 2.8而非2.7。目前我建議Scala 2.7開發使用IDEA 8的插件,而使用最新的build在IDEA 9下進行Scala 2.8的開發。
總結
你希望學習Scala么?你想要和其他的Scala學習者與開發者們一起交流么?請持續關注51CTO的Scala編程語言專題,并加入Scala中文社區的Google Group(您也可以訂閱社區的電子郵件群)進行討論。感謝關注!