IDE的现实分析 - 答“开发一个IDE难度有多大”

版权声明:所有博客文章除特殊声明外均为原创,允许转载,但要求注明出处。

Lines of code

本文是看到知乎问题 开发一个IDE难度多大? 之后产生的想法。古人云:与其坐而论道,不如起而躬行。世界上已经有很多开源的 IDE 了,我们完全可以拿一个现实的例子来分析,知道实现一个 IDE 到底有多大的难度。

如何定义“难度”是一个问题。一个开源项目比较容易看到的指标是规模,从一般常识认为,规模越大的项目,在成本和时间上花费应该更大,沟通成本也更高,从而难度也应该更大。而衡量规模最明显的指标是源代码行数。虽然不是绝对的,但我相信代码行数从总体上可以代表一个项目的规模。

我希望知道的另一点,也是这个问题的关注点之一是:在 IDE 项目中究竟哪个部分是最复杂的。这同样面临一个用什么指标来衡量的问题。代码行数在这里同样是一个明显的选择,另外针对源代码还可以用圈复杂度来衡量。以前分析代码的经验告诉我,圈复杂度通常和代码行数是正相关的,即基本上代码行数多的代码,圈复杂度也越高。我希望通过 IDE 项目的分析能够看到相似的结果。如果这两者真的是正相关的话,那么我们不论用代码行还是圈复杂度作为指标都应当得到差不多的结果。

我也考虑了是否应当引入其他一些指标,例如类或函数的数量和大小。但是一个类或函数的粒度多大才合适是一个比较主观的选择,各个项目都不太一样。甚至在某些语言(比如 Javascript)里连类的概念都不是必须的。所以最后我决定不纳入其他的指标。

接下来的项目是选择哪个项目来分析。起初我的倾向是用 IntelliJ Community Edition ,但是尝试以后发现代码库相当大,应该有上G的级别吧,clone了半天只拉下来百分之十几,按照我的网速,光取代码可能就要花几小时时间。于是转而寻找其他稍小一些的IDE项目,最后决定用 SharpDevelop,因为它的代码比较小(压缩包 30 多MB),很容易下载,同时这是一个发展了 10 多年的项目,在代表性方面应该是没有问题的。

说到这里忍不住吐槽一下微软。我知道 Visual Studio 内置有统计源码行数和圈复杂度的分析工具,用来做简单的分析应该是完全没有问题的,没想到在 VS2015 SP1 中分析项目竟然报错。而且只告诉你出错了,根本不知道问题在哪。本来我已经想要放弃了,后来意外发现用 VS2013 分析却完全没有问题,这是软件质量一年不如一年的节奏吗?

题外话就说到这里。下面是分析结果。

我取的是 SharpDevelop 5.1.0.5134 RC 版的源码,放到 VS2013 中分析,总代码行数大约是 28 万行(281,979)。这个结果比我预想的要少一些(直观上觉得 IDE 怎么也要近百万行吧)。

分析了一下整个项目的源码行数和圈复杂度。如下图。可以看到两者确实是正相关的。

Lines of code

接下来分析第二个问题。把解决方案中包含的所有项目按复杂度排一下序,可以发现:整个 SharpDevelop 中最复杂的部分是一个名为 NRefactory 的组件(如下图),该组件无论是按代码行数还是圈复杂度的标准都占了整个项目最大的部分。这个结果也符合我自己的经验:项目的复杂性分布极不均衡,大部分复杂性通常集中在一个很小的区域,而其他部分很多都比较简单。

Lines of code

这个 NRefactory 我还真的没有听说过,于是去搜了一下。NRefactory 是一个.Net代码库,主要用于分析和处理代码语意,和微软的 Roslyn性质比较接近。SharpDevelopMonoDevelopILSpy 等一些知名项目用到了它。

知道这个组件的作用后,我把 SharpDevelop 中包含的各个项目大概分了类,这个分类可能不是非常严格,但是对于观察代码分布的目的应该是足够的。分类如下:

分类 包含内容 源码行数
Code Analysis 代码模型、分析和生成相关 123957
IDE IDE程序和界面相关 62940
Visual Editor 可视化编辑器 30760
Text Editor 文本编辑器 20264
Tools 版本控制和帮助等辅助工具 11556
Language 语言绑定,包括C#,VB等 9292
Debugger 调试器 9238
Framework Asp.Net Mvc等框架支持 8513
Misc 杂项 2289
Builder 构建和 MsBuild 相关 1774
Data 数据库支持 1396

对应的图表:

Lines of code

可见整个 IDE 最复杂的部分在于代码模型的处理,代码数量几乎是第二名(IDE)的两倍之多,占整个项目代码的比例也接近 50% 了。我没有进一步分析,不过大概可以想象,代码编辑时的文本着色、语法提示、代码生成、辅助分析、重构等功能应该都与此相关。如果真的想自己写一个 IDE 的话,这一部分肯定是个难啃的硬骨头。

其他内容基本上不出意料。程序的界面和控制部分内容也相当不少,因为 IDE 基本上都需要定义一个完整的插件体系,所以这部分也是相当复杂的。可视化编辑器的代码比我想象的要少,也许是因为 SharpDevelop 可视化部分还不够完善的原因?

再说一点稍微跑题的话。曾看到有许多人问 IDE 和文本编辑器的区别到底在哪。看这个表就知道了:文本编辑器涵盖的范围主要是表中的 IDEText Editor 的部分, 其他要么不支持,要么只是简单的外部调用。而最耗资源的 Code AnalysisVisual Editor 这两部分,文本编辑器都是不支持的。所以实现一个文本编辑器还是比 IDE 简单多了,通常性能和资源占用也要好得多。所以问题就在于,你愿不愿意牺牲代码辅助和可视化功能的代价,来换取编辑器的性能呢?