zoukankan      html  css  js  c++  java
  • 实例分析SharpDevelop代码完成功能(续)——添加对Boo语言的支持

    接着上一篇《实例分析SharpDevelop代码完成功能》里添加的InsightWindow的功能。这回将要为那个CSharpCodeCompletionDemo添加Boo语言的代码自动完成功能的支持。

     

    Boo语言,可能不少人还没有听说过。好像是语言使用的排行榜上100名之外的一种编程语言。语法接近Python。就连Wiki上对它的介绍也少得可怜。目前支持这种语言的IDE只有SharpDevelop以其衍生的IDE

     

    SharpDevelop支持BooCodeCompletion,但是给的Sample里,只支持C#VB.NET。下面就来介绍,如何一步步地让Sample支持Boo

     

    C#不同,Boo是一种弱类型的语言,所以(也许不充分)不能像C#VB那样用一个Parser进行分析来得到语法树。SD通过插件的方式,提供了对于PythonBoo等语言的支持。如图1所示。

     

    1. SharpDevelop中的Backends Bindings

     

    BooBinding里,应该就提供了SD对于支持Boo所需要的全部代码。再来看BooBinding

     

    2. BooBinding Project

     

    里面居然专门有一个文件夹叫CodeCompletion,看来我们要找的东西都在里面了。下一步就是支持Boo了,其实说起来还是很容易的,不就是等价类替换一下嘛。在上一篇里介绍的用于CodeCompletion的类不少,但是语言相关的大约有5个类。3种语言的的这5 个类如表1所示。

     

    C#

    VB

    Boo

    Parser

    ParserFactory

    ParserFactory

    BooParser

    Ambience

    CSharpAmbience

    VBNetAmbience

    BooAmbience

    Resolver

    NRefactoryResolver

    NRefactoryResolver

    BooResolver

    Expression Finder

    CSharpExpressionFinder

    VBExpressionFinder

    ExpressionFinder

    LanguageProperties

    LanguageProperties

    LanguageProperties

    BooLanugageProperties

    1. 三种语言对于CodeCompletion功能的等价类

     

    在进行无味的等价类替换工作之前先分别大致介绍一下3个类的用途。

     

    1.       Ambience:词典里的是“环境,气氛”。从名字看不出什么用途,图3是其定义。

    3. IAmbience

    从这个接口里的方法大致就能猜个八九不离十了。就是将Parse出来的类啊,变量啊转化成用户可读的文本。因为不同的编程语言有不同的语言和专有名词,所以转化出来的文本也应该根据语言有所不同喽。这个接口,就分离了不同语言间这种可读性的不同。

    2.       ExpressionFinder:感觉图4IExpressionFinder的定义没有给出比这个名字更多的信息了。

    4. IExpressionFinder

    这个就是源代码里找表达式的接口。通过这个接口里定义的方法,就可以知道当前位置上应该是个什么东西,以及当前位置上是个什么东西。是个数字,还是变量等等。它找到的结果是个这么个东西。如图5

    5. ExpressionResult

    有兴趣的话,可以去看看它的内部结构。这里就不展开了。

    3.       IParser:这个就是最重要的部分。可以叫解析器吧。图6里把函数的参数也显示了出来,更能清楚地表达IParser接口的作用。(C#VBParser接口与此略有不同)

    6. IParser

    其中Parse函数的stringfileContent就是要Parse的源文件。Demo的注释里就说明了fileName参数不一定就是源文件在磁盘上的文件名,就当是一个GUID就可以。再来看一下图7所示的这个函数的返回类型的结构就一目了然了。

     

    7. ICompilationUnit

     

    很强大的样子,从源文件直接得到了里面的Class,Attribute,Usings……,这些数据就可以用来做CodeCompletion了。如果看一下CSharpBooParser的源代码就可以知道这两个Parser是完全不一样的。CSharpParser是完全的对源文件进行分析的结果。而BooParser只是搭了Boo Compiler的便车,在使用BooCompiler编译源文件的过程中让Compiler“顺便”帮它把它想要的语法树给它了。所以CSharpParser的效率会高不少。例子里就是用这个Parser在后台每2秒做一次Parser,用结果对ProjectContent进行更新。Resolver就是用Parser进行表达式类型的分析的。SharpDevelop的运行时也与此类似。

    4.       Resolver:用ExpressionFinder找到当前的Expression之后,就会用Resolver去知道当前的Expression倒底是个什么东西。Resolver的接口如图8所示。非常简单。

    8. IResolver

    Resolve出来的Result也很简单。如图9所示。

     

    9. ResolveResult

     

    有了上面的分析,解理这个图应该不成问题了吧。

     

    5.       LanguageProperties:这个在DEMO里的作用就是指示当前语言是什么。

    基于上面的分析,我们知道BooParser使用到了Boo的编译器,所以先把要用到的Library找到。如下:

    1.       BooBinding

    2.       Boo语言编译支持:Boo.Lang, Boo.Lang.Compiler, Boo.Lange.Parser, Boo.Lang.Useful

    3.       还有一些其它的SharpDeveloprLibraryICSharpCode.SharpDevelop….

    为了提供BooCodeCompletion的支持居然要多加这么多库,一开始也没有想到。因为C#CodeCompletion只有34个就足够了。(而且这些库都是必需的)

     

    终于到了更改源代码的时候了。先要把Demo里的所有实例化这些Resolver, Ambience, Parser, ExpressionFinder的所有代码进行重构。把实例化过程分离出来,并交给MainForm来做。然后,添加Boo语言支持的工作就变成了——给四个工厂方法添加一个Else if分支——这么简单。其中一个工厂方法的代码如下。

     

     1//应该不需要注释了吧
     2public static IAmbience GetAmbience()
     3{
     4     if (CurrentLanguageProperties == LanguageProperties.VBNet)
     5          return new VBNetAmbience();
     6     else if (CurrentLanguageProperties == LanguageProperties.CSharp)
     7          return new CSharpAmbience();
     8     else if (CurrentLanguageProperties == BooLanguageProperties.Instance)
     9          return new BooAmbience();
    10     else
    11          throw new NotSupportedException();
    12}

    13

     

    修改完成之后。运行一下。如图10所示。

     

    图10. Boo代码完成功能

    表面上是成功了,可以分析出类和方法。但是事实上运行一会儿就会Crash,而且如果改了方法名,给的Code Completion还是原来的结果。可见后台的Parse线程成功地走了一次,然后就死掉了。还把整个程序搞死了。

    后来经过向Output输出消息,找出了出错的地方,是BooParser在调用Boo compiler的时候有一个编译步骤出现了StackOverflowException。这个问题可以通过稍稍修改BooParser的方式实现。有兴趣的读者可以自己尝试一下。修复版的代码将会在下一个续文中给出。这里是添加了Boo语言支持的CodeCompletionDemo的源代码。

     

  • 相关阅读:
    DotNetNuke 5 C#版本解读之1--架构介绍
    关于加入外包公司
    《深入浅出WPF》视频列表
    倒序输出字符串
    C#基础—— check、lock、using语句归纳
    Asp.net页面之间传递参数的几种方法
    sual C#中编写多线程程序之起步
    Head.First.ObjectOriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(一)
    索引分类
    表单提交中Get和Post方式的区别
  • 原文地址:https://www.cnblogs.com/nankezhishi/p/1343572.html
Copyright © 2011-2022 走看看