实例分析SharpDevelop代码完成功能

介绍

SharpDevelop源代码里自带一个CSharp代码自动完成功能(Code Completion)的例子。如下图所示:

 

 

1. 代码完成

 

看上去似乎好像挺不好做的,理论上要做词法分析、语法分析,还要解析一些如mscorlib之类的DLL。但是事实上SharpDevelop已经为我们做了这些,上面的例子只要写几个类就可以完成。整个Solution如下图所示:

 

2. 代码完成例子的Solution

 

3. Code Metrics Results

 

直接使用SharpDevelop里的分析器,就可以很简单地完成Code Completion的功能。平均每个文件只有100行的代码。也许有人要说这样没有意思,但是我们不应该“重新做个轮子”对吗?而且就算要深入地学习,也要先来把这个例子弄明白的。

 

这个例子里的Code Completion并不象SharpDevelop里的那么完成,没有提供下面的功能。

 

4. 缺失的ToolTip提示

 

在输入左括号时,应该在ToolTip中给出这个函数的所有重载,但是这个例子里并没有给出这个功能的实现。下面在介绍代码完成的同时,会给出这个ToolTip的实现。

 

博客园的Michael Zhang在其SharpDevelop浅析系列文章中也介绍了代码完成功能。如果对整个SharpDevelop有兴趣可以参考一下。下面进入正题……

 

第一部分 Code Completion的实现

下图是这个例子里的类体系

 

5. 整个例子的类体系

 

从类的结构来看,其实与SharpDevelop本身的实现不是一个层次的,这个类结构的耦合性很强,还好要看的是如何实现Code Completion,而不是它的设计。要看设计,还是看SharpDevelop好了。

 

下面逐个介绍一下里面的类。

 

CodeCompletionData类:是用于表示代码完成列表中每个项的Visual Object。看看它的父类会更明显一些。

 

6. DefaultCompletionData类图

 

MainForm类:就是看到的整个窗体。里面有三个控件,一个是SharpDevelopTextEditorControl,一个状态栏,一个ImageList。主窗体加载之后会开启一个Parser线程,每2秒对整个文档做一次Parse。(汗,用Stopwatch测试了一下,对一个很小的文件的一次Parse50ms左右。)Parse之后,用于做Code Completion的数据就有了。在哪儿?没去认真找过。应该是在ProjectContent里。下面是Parse的步骤:

 

Code

 

CodeCompletionKeyHandler类:看名字就知道,就是针对CodeCompletion处理窗体的键盘事件的,如果点了”.”,就实例化一个CodeCompletionProvider并显示CodeCompletion窗口。按VS的分析,这个只有22行代码的文件就不细介绍了。

 

ShowCodeCompletionList

 

HostCallbackImplementation类:这个更少,就13行代码。做的事件就是后台分析出错的时候,把消息显示出来。

CodeCompletionProvider类:虽然最重要的部分,却也只有51行代码。主要完成了两件事情:1. 生成CodeCompletion列表。2. 用户触发一个Item的时候把相应的内容插入(就2行)。

生成CodeCompletion列表的功能也十分简单,大致分成三个步骤:

a.       FindExpression:就是找到当前用户的点”.”之前的那个东西到底是个什么东西。

b.       Resolve:得到找到的那个东西的Memeber列表。

c.       GenerateData:从得到的列表生成用于在UI上显示的CodeCompletionData

ToolTipProvider类:这个可不是那个缺失的功能哦。这个只是在MouseOver一个Member时,显示出一些信息。在图1的上面的那个就是了。(好像ToolTip还错了……)这个过程和CodeCompletionProvider大致相同。就不再赘述了。

 

这样,整个CodeCompletion的功能就完成了。整个例子359行代码。(仔细看看代码,你会有信心把它到缩减到200行。)

 

第二部分 添加Code Insight功能

什么是Code Insight?就是之前提到的缺失的ToolTip啊。在SharpDevelop里给了它一个更专业的名字叫“Code Insight”。

 

一向奉行“Don’t recreate the wheel”,这次也不例外。Sample没有,SharpDevelop有啊。Ctrl+V过来不就行了?(当然商业项目不行哦,连Sample也不行。人家是GPL

 

然后就在SharpDevelop的源代码中找到了一个名为MethodInsightDataProvider的文件(在ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor名字空间下)加了进来,然后在KeyHandler里加入对InsightWindow的支持。

 

ShowInsightWindow

 

再把SharpDevelop里的CodeCompletionData里的GetDocumentation函数也Copy到这个SampleCodeCompletionData类中。

 

这样所有的类的准备完了。

 

然而在MethodInsightDataProvider中使用到的ParserServiceAmbienceServiceLoggingServiceMessageService都没有找到引用。又去看了一下SharpDevelop的运行流程,找到了开启这几个Service的地方,发现差不多也已经同时把整个IDE开启了。这个可不是我想要的。而且很多类都是protected sealed类。从外界是Call不到的。看来必须要”Recreate the wheel”,把那个DataProvider重新写一个了。还好那个Provider只有100多行代码,自己写一个并不复杂。把LoggingServiceMessageService的代码都删除。而ParserServiceAmbienceService的作用不过是ParserAmbience的工厂类,自己实例化一个不就得了?这样,DataProvider中所引用的所有Service都被剥离了。

整个MethodInsightDataProvider的代码如下所示:

 

MethodInsightDataProvider

 

运行一下。

 

 

7. Method Insight

 

大功告成。

 

其实还有一种Insight——IndexerInsight。就是在输入‘[’的时候给出ToolTip提示。这个就留给有兴趣的读者吧。

/Files/nankezhishi/source/CSharpCodeCompletion.zip这里是改版的代码完成的所有代码。

下一篇中,将为这个示例添加Boo语言的支持。

 

posted @ 2008-11-22 14:45 南柯之石 阅读(4187) 评论(14) 编辑 收藏

 回复 引用 查看   
#1楼 2008-11-22 14:56 谢慧琦      
很好,看看
 回复 引用 查看   
#2楼 2008-11-22 15:27 斯克迪亚      
强大哦
 回复 引用 查看   
#3楼 2008-11-22 17:43 xjb      
分析的很细
 回复 引用 查看   
#4楼 2008-11-22 20:13       
很好, 但是不知道有什么应用场合
 回复 引用 查看   
#5楼[楼主] 2008-11-22 20:19 南柯之石      
@蜂
正在做的一个项目就用到了Code Completion,不过是Boo语言的。用的正是SharpDevelop的。

 回复 引用 查看   
#6楼 2008-11-23 02:38 包建强      
很想看看您对SharpDevelop中调试器的实现思想!
 回复 引用 查看   
#7楼[楼主] 2008-11-23 09:04 南柯之石      
@包建强
在下不才,SharpDevelop里的调试器还没有了解过。项目里用的是MDBG的Sample做的调试器(比较简单)。功能应该是不如SharpDevelop的。这里是下载地址:
http://www.microsoft.com/downloads/details.aspx?familyid=38449A42-6B7A-4E28-80CE-C55645AB1310&displaylang=en

 回复 引用   
#8楼 2008-11-23 21:59 Rexzhou[未注册用户]
能不能从SharpDevelop中剥离出一个小巧的C# Editor?目前为止除了VS之外,其他编辑器都不理想
 回复 引用 查看   
#9楼[楼主] 2008-11-23 22:17 南柯之石      
@Rexzhou

上面的例子就有不少功能的,只不过没有具体介绍。如果上面的例子还不能满足你的要求的话,不知道这个是不是合适。

Actipro公司做的一个SyntaxEditor。支持非常多的语言的Code Completion。下面是下载地址。

http://www.actiprosoftware.com/Products/DotNet/WindowsForms/SyntaxEditor/default.aspx

不错,研究研究
 回复 引用   
#11楼 2008-12-31 11:32 IIM[未注册用户]
很好,用了.
 回复 引用   
#12楼 2009-04-24 15:58 fds[未注册用户]
傻B楼主自以为是
 回复 引用 查看   
#13楼 2009-10-23 10:57 一劍飄紅      
不错 用的到的
 回复 引用 查看   
#14楼 2012-01-16 22:53 Vincent.Q      
强大,我正找这个类似的东东