study log

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  8 随笔 :: 6 文章 :: 132 评论 :: 2 引用


SharpDevelop浅析_4_TextEditor_自动完成、代码折叠……

Parser及其应用: Code Completion, Method Insight, Class Scout ...


1、Demo界面及功能解释
2、Parser实现概述
3、Parser应用: MouseHover Tooltip
4、Parser应用: CodeCompletion & MethodInsight
5、Parser应用: QuickClassBrowserPanel
6、Parser应用: Folding
7、总结
Demo下载

1、Demo界面及功能解释
启动并打开任一 .cs 文件后,界面如下:

自动完成界面如下:

可见新增功能如下(仅支持.cs文件):
a, 鼠标停留在方法、属性等位置时,会显示出相关的文档描述tooltip
b, 输入时支持自动完成
c, 编辑窗口顶部有类列表和成员(方法、变量等)列表下拉框用以快速浏览、定位
d, 编辑窗口左侧有折叠线用以方法、类等的代码折叠
相应的Demo工程中新增项目如下:
a, SharpEditor:   包含扩展TextEditor的控件, Dom结构, ParserService, 自动完成功能代码等
b, NRefactor :    代码解析功能
c, CSharpBinding: 对应 .cs 文件的具体实现支持

[题外话]:
关于代码解析(Parser)相关的代码,我没看懂,所以在这里只说个大概,更多地谈谈Parser的使用;抛砖引玉,希望有相关经验的网友提供详尽的分析。
前两周工作上的项目实施,每天都搞得比较累,所以这篇文章到现在才写了出来,明天是大年三十了,这个系列的文章也只剩下一篇Windows Form Designer,只能等过了年再放上来喽。
另外,这个系列写完后,暂不打算深究一些没明白的细节,接下来想看下os workflow 或 CommunityServer...


2、Parser实现概述

(1)首先,SharpEditor项目中的Dom下定义了以下重要类:
a, IDecoration及其子类:   代码表现的辅助对象,如IClass, IMethod, IProperty等
b, ResolveResult及其子类: 分析结果对象,如MethodResolveResult, TypeResolveResult等
c, 其它重要类:           IExpressionFinder, IParser, IResolve, ICompilationUnit 等

(2)重要服务类:
ParserService:   提供 GetExpressionFinder(), Resolve(), ParseFile()等重要方法,相关重要类: ProjectContentRegistry, DefaultProjectContent, ReflectionProjectContent等
AmbienceService: 提供 IAmbience的实现类用以将分析结果转换为相应的字符描述

(3)Parser分析步骤:
以鼠标悬浮的Tooltip显示为例:DebuggerService根据文件类型返回对应的IExpressionFinder实现类,再根据鼠标位置找到并返回ExpressionResult对象,然后找到适当的IResolver实现类调用Resolve()方法返回结果ResolveResult对象,最后由相应的IAmbience实现类转换成结果字符,并调用e.ShowToolTip(toolTipText);显示。

(4)对于.NET默认类库的分析转换:
默认引进的命名空间的类结构和文档说明一般可以在"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\"目录下找到(如System.dll和System.xml),但是如果每次都要重新分析dll代码结构和xml注释显然是比较花费时间的,于是SharpDevelop采用的方式是将分析过的数据(Dom下的类结构表示数据?,二进制的.dat文件)存储到"C:\Documents and Settings\michael\Local Settings\Temp\SharpDevelop"下,代码结构存储到DomCacheDebug目录下,文档注释存储到DocumentationCacheDebug目录下。
首先在ParserService的CreateDefaultProjectContent()中加载默认命名空间的引用:

CreateDefaultProjectContent()

其中ProjectContentRegistry的GetProjectContentForReference()方法如下:

GetProjectContentForReference()

可以看到DomPersistence类的作用即在加载或保存dll的代码结构数据, 如果尚未有分析过的数据,则在ReflectionProjectContnet类的构造函数中加以分析,同时调用XmlDoc类的相关方法加载、保存文档注释数据。

(5)对于文件的转换:
[略]


3、Parser应用: MouseHover Tooltip

注意在SharpEditor项目中有个DebuggerService类,它提供了一个重要方法如下:

BindTextAreaEvent()

此方法即用以绑定需要鼠标悬浮提示的TextEditor控件,在SharpPad项目的Open菜单类方法中调用此类绑定编辑控件。
注意上面的方法中可以看到ICSharpCode.TextEditor控件是通过其TextArea的ToolTipRequest事件公开给外部,用以分析并由外部提供ToolTip数据,而TextArea_ToolTipRequest(object sender, ToolTipRequestEventArgs e)方法中根据鼠标位置分析出要显示的数据后,最终调用e.ShowToolTip(toolTipText);用以设置提供数据。

TextArea_ToolTipRequest()


4、Parser应用: CodeCompletion & MethodInsight

ICSharpCode.TextEditor控件使用ICompletionData类以及ICompletionDataProvider接口(GenerateCompletionData()方法)定义数据自动完成列表的数据及其提供者: SharpEditor项目中的AbstractCodeCompletionDataProvider类中由GetExpression()及AddResolveResults()两个辅助方法生成数据,代码如下:

AbstractCodeCompletionDataProvider 类

CommentCompletionDataProvider类提供注释的自动完成,相关代码如下:

CommentCompletionDataProvider 类

类似地,ICSharpCode.TextEditor控件提供了IInsightDataProvider接口(GetInsightData()方法),SharpEditor项目中实现类MethodInsightDataProvider和IndexerInsightDataProvider提供相关数据。

除了上面需要提供数据的类外,还要绑定TextEditor的TextArea的KeyEventHandler事件(详见SharpEditor项目的SharpDevelopTextAreaControl.cs),其中辅助类的处理代码如下:

KeyEventHandler 事件响应


5、Parser应用: QuickClassBrowserPanel

QuickClassBrowserPanel即编辑窗口顶部的类及成员快速浏览窗口,其实现如下:
首先在SharpDevelopTextAreaControl类中重写override void OnFileNameChanged(EventArgs e)方法,即打开新文件时,调用ActivateQuickClassBrowserOnDemand()来根据是否有能够分析此文件的Parser来决定是否显示控件,如果可以显示,则实例化出一个新对象,并添加进来。实例化QuickClassBrowserPanel对象的相关代码如下:

QuickClassBrowserPanel

可以看到类、成员列表的ComboBox数据的填充是在textAreaControl.ActiveTextAreaControl.Caret.PositionChanged事件后执行,因为光标位置的改变可能需要同步更新顶部列表框的显示;注意两个列表的列表项使用自定义类ComboBoxItem, 包括成员的Line, Column等信息;该类中绑定两个列表的SelectedIndexChange事件用以在编辑器中定位相应的类或成员位置:

ComboBoxSelectedIndexChanged()


6、Parser应用: Folding

ICSharpCode.TextEditor控件提供了IFoldingStrategy接口用以定义代码折叠需实现的方法:

IFoldingStrategy 接口

SharpEditor项目中,SharpDevelopTextAreaControl在构造函数中指明了FoldingStrategy:

SharpDevelopTextAreaControl 构造函数

同样需要在打开新文件时调用更新代码折叠标签,代码折叠FoldMarker生成的具体实现详见SharpEditor项目的ParserFoldingStrategy.cs


7、总结

上面简要介绍了Parser的部分实现, 期待有相关经验的网友指定我的理解错误或给予补充解释。
以及Parser的部分应用:MouseHover Tooltip, CodeCompletion & MethodInsight, QuickClassBrowserPanel, Folding;SharpDevelop中的其它应用如类视图ClassBrowser, 对象浏览AssemblyPad(SharpDevelop2.0源码中未见到?).




 

posted on 2007-02-17 01:20 lin-zhang 阅读(6627) 评论(22)  编辑 收藏

评论

#1楼 2007-02-20 12:04 yunhuasheng      
that's very good!
 回复 引用 查看   

#2楼[楼主] 2007-02-21 13:35 lin-zhang      
@yunhuasheng
thanks very much :)
 回复 引用 查看   

您真是奇才!
 回复 引用   

#4楼 2007-02-25 17:59 乐章      
好文
 回复 引用 查看   

看到有点糊糊的。
 回复 引用   

#6楼[楼主] 2007-02-26 13:37 lin-zhang      
@匆匆的过客
过奖了,写下这些是需要付出的,对我来说也不轻松

@乐章
:)

@jj[匿名]
?
 回复 引用 查看   

#7楼 2007-03-18 20:46 ImpHiker[未注册用户]
写得很好,谢谢共享
 回复 引用   

#8楼 2007-03-22 21:14 stormelf[未注册用户]
非常好的文章!不过为什么该章的demo里没有QuickClassBrowserPanel, 也没有folding和code completion?跟截图上的不一样。
 回复 引用   

#9楼 2007-03-27 14:35 biean[未注册用户]
代码好
共享的举动更好
 回复 引用   

#10楼[楼主] 2007-04-03 20:45 lin-zhang      
@ImpHiker
@biean
thanks

@stormelf
任打开一个.cs文件即可
 回复 引用 查看   

#11楼 2007-04-10 17:40 porener[未注册用户]
据我分析SharpDevelop的TextEditor好象没有折行功能?
楼主能帮我看看么?
我想用他的这个组件,可是没有折行功能实在是非常不好用。
但是我也不知道该从哪里入手能够构建这个功能。
如楼主能够有所发现,敬请发邮件给我:porener@gmail.com
 回复 引用   

#12楼 2007-04-29 20:42 Ben[未注册用户]
似乎还是不行。哥们再在一个干净的环境里试试?
 回复 引用   

楼主人不错啊
 回复 引用   

谢谢楼主了
太感激了
 回复 引用   

楼主好厉害,对我帮助很大,那如果是vb文件,代码自动完成好像不起作用。我把代码中C#,CSharp的标示都换成VBNet了,好像也不行,请教!! emial:vincehsu@126.com
 回复 引用   

受益匪浅, 谢谢搂主
 回复 引用   

终于都让我找到了,呵呵呵!!!!
谢谢楼主
顶顶顶
 回复 引用   

#18楼 2008-07-25 15:45 welcome[未注册用户]
谢谢楼主
 回复 引用   

好棒的东东,很喜欢这种清爽的感觉。
 回复 引用   

楼主:
问一下SharpDevelop的关键字之类是不是不能自动完成,代码提示,就像输入点后有提示一样。
 回复 引用   

#21楼 2009-06-29 15:36 laoda[未注册用户]
正需要这样的东东,谢谢了!
 回复 引用   

#22楼 2009-09-30 10:49 Armoric[未注册用户]
很好,很强大。。
 回复 引用