独家专访Scala IDE三剑客:探秘IDE插件开发

大部分Scala项目都是从Java项目开始的,而项目转型的成本和效率与是否有优秀的IDE支持紧密相关。Eclipse、NetBeans和IntelliJ这三大IDE的插件机制各自不同,因此在实现这一共同的功能上,都会有不同的思路,遇到不同的问题,最终带来不同的解决方法。

1.总结Scala插件的现状BASE小组在今年8月曾组织过一次吹风会交流Scala插件的情况,此次访谈也是希望延伸那次会议的交流成果,跟踪Scala插件在之后这三个月的发展情况。

2.展示IDE语言支持插件的开发过程。相信很多开发者对于开发Eclipse、NetBeans和IntelliJ的插件很感兴趣,但也许不知道要从何入手,那么最好的方法就是从其他插件开发者的开发经验当中学习。语言支持插件是IDE插件当中最难的一种,因此从中能够获得的经验也是最多的。

概述

目前Scala插件的开发者情况如下(参考Scala官网的介绍):

Eclipse的Scala插件:Scala IDE for Eclipse

独家专访Scala IDE三剑客:探秘IDE插件开发 这个插件最初由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

独家专访Scala IDE三剑客:探秘IDE插件开发 这个插件由邓草原在其业余时间开发。邓草原,现加盟宏爵财经资讯(北京)有限公司。他是开源软件AIOTrade项目的主创者,同时也是NetBeans的Erlang插件的开发者,以及NetBeans梦之队成员。

邓草原的个人主页:http://blogtrader.net/dcaoyuan/

IntelliJ的Scala插件:Scala Plugin for IntelliJ IDEA

独家专访Scala IDE三剑客:探秘IDE插件开发 这个插件由Jetbrains IntelliJIDEA的一个小团队进行开发,团队成员包括Ilya Sergey,Eugene Vigdorchik以及Alexander Podkhalyuzin。51CTO编辑对Ilya Sergey进行了采访。IntelliJ在几个星期前终于也加入了开源的行列,这将帮助它扩展更多的用户。

Ilya Sergey在信件中表示,希望使用IntelliJ的Scala插件的开发者都能仔细阅读这个wiki页面,这样可以减少很多有关插件安装和使用的问题。

访谈内容

1.您是如何开始进入Scala插件开发这项工作的?

2.进行IDE插件开发需要具备哪些知识?

3.能否介绍一下您计划让Scala插件提供哪些功能?现在都实现了么?

4.IDE插件开发的主要瓶颈在哪些方面?与其他插件开发者进行交流对您的进程是否有帮助?

5.您认为Scala插件现在已经足够成熟到投入实际的开发中去?开发者在使用中需要注意哪些问题?

6.您对于Scala 2.8的正式推出抱有怎样的期待?

希望三位开发者对这些问题的回答能够对您有所帮助。下面请进入正文部分――

独家专访Scala IDE三剑客:探秘IDE插件开发Eclipse的Scala插件开发者,Miles Sabin

Eclipse的Scala插件的现任开发者Miles Sabin由于工作繁忙的关系,难以抽出太多时间来完整的回复我们的邮件,不过Miles十分热心的提供了几条很有用的信息,并对一些具体的问题进行了细致的回复,帮助我们成功完成这次访谈。

以下部分内容来自Miles提供的这个链接这个PDF

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迁移
C scalac中Scala/Java混合编译
C 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报告、开发者文档、使用体验报告等等。

独家专访Scala IDE三剑客:探秘IDE插件开发NetBeans的Scala插件开发者,邓草原

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插件中,我比较好地解决了大部分问题。现在用户键入代码时的反应速度,包括完成代码提示时的速度都相当不错了。

我跟Eclipse的插件作者有过交流,包括原来的开发者,Martin的学生Sean McDirmid,他现在在北京工作,我跟他见过两次,就是他说服我使用Scala自身的编译器,而不是自己重写。现在的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。

独家专访Scala IDE三剑客:探秘IDE插件开发IntelliJ的Scala插件开发者,Ilya Sergey

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框架提供更好的支持。现在,我们可以在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的开发。

相关推荐