美文网首页React Native实践
Javascript代码分析引擎-Tern

Javascript代码分析引擎-Tern

作者: 墙角儿的花 | 来源:发表于2017-03-03 11:24 被阅读1007次

    Tern

    Tern 是一个javascript代码分析引擎,其目标是被代码编辑插件使用以增强编辑器的javascript代码智能编辑能力。其提供的主要特征如下:

    • 变量和属性的自动完成
    • 函数参数提示
    • 查询一个表达式的类型
    • 查找定义
    • 重构

    Tern是开源项目(MIT),使用javascript编写,能运行于node.js和浏览器中。

    Editor plugins

    Tern当前支持的编辑器如下:

    • Emacs
    • Vim
    • Sublime Text
    • Brackets
    • Light Table
    • Eclipse(提供了一般性通用api)
    • TextMate

    社区支持

    有一个论坛用于讨论和问有关Tern的论坛,并会有一些最新消息的通告,比如新版本的发行。可以通过github issue tracker来报告缺陷。

    欢迎通过pull requests来进行代码分发。

    如果你正从中获取收益,特别是用于盈利目的,考虑为更多的开发提供资金,Marijn Haverbeke将会为你提供咨询。

    文档

    了解如何安装Tern,阅读参考手册是你需要进行的第一步。

    如果你对这个系统的内容工作比较感兴趣,可以查看下blog和一些会议上的视频

    Tern 使用手册##

    Tern又几个组件组成,依赖你利用它来做什么,你将关注Tern的不同层次。Editor Plugins,它位于最高的层次。Tern server,它是在Server模块(提供编程接口)的基础上实现,利用推断引擎inference engine来做真正的类型推断。

    Tern server

    bin/tern用来启动Tern server,你会经常使用一个Editor plugin来启动它,但是也可以手动启动它,这样比较方便调试。(注意server的基础是通过编程接口提供出来的,对于使用在浏览器中的场景,将直接使用编程接口而不是这里描述的http方式)。

    Server启动时将在当前文件夹或者其子文件夹下寻找.tern-project文件,读取里面的内容作为配置。如果没有project文件,默认配置将创建失败。你可以通过放置一个.tern-config文件来改变默认配置,该文件的配置格式和.tern-project文件一致,并将该文件放在你的HOME目录下。

    Server在启动时将其监听的端口(默认随机)写入标准输出,Server通过http方式和json格式数据进行交互,客户端可以通过http上传代码并询问一些关于代码的问题。

    以下命令行标识将得到支持:

    --port <number>

    指定监听端口,通过这种方式可以取代默认的随机端口方式

    --host <host>

    指定监听的host,默认127.0.0.1

    --persistent

    默认情况下,Server将在五分钟没有交互的情况下自动关闭,通过该选项可以禁用自动关闭

    --ignore-stdin

    默认情况下,在标准输入流关闭时Server将自动关闭,通过该选项可以禁用该行为

    --verbose

    Server将输出请求和返回的信息,以及错误信息,这有助于调试

    --no-port-file

    Server将不会输出.tern-port文件

    JSON格式协议

    向Tern发送查询请求要通过POST方式发送,请求体以json格式传送。请求提有三个可选字段:query,files,timeout。

    query描述了你所请求的信息类型,如果请求只是为了推送新的代码,那该字段可以忽略。files用于指定一组文件,如果请求所操作的代码Server上已经存在,并没有添加新的文件,那么该字段将被忽略。timeout用于指定该请求的最大工作时长(cpu时间),毫秒。

    query是一个对象,至少有一个type属性,用以标识请求类型,其他属性依赖于不同的类型而不同。

    以下是Tern server所能理解的请求。(插件可能添加自定义的类型)

    1. completions

      在给定的位置,询问代码完成

      字段:

      • file,end(required)

        指定代码完成的位置

      • types(optional,默认false)

        是否在结果数据中包含代码完成的类型

      • depths(optional,默认false)

      • docs,urls,origins(optional,默认false)

      • filter(optional,默认true)

        是否只返回符合当前位置的词语的完成列表,否则返回全部

      • caseInsensitive(optional,默认false)

        当前位置的词语和潜在完成列表是否采用大小写敏感性比较

      • guess(optional,默认true)

        当找不到匹配的完成结果时,是否返回启发式的建议

      • sort(optional,默认true)

        结果是否排序

      • expandWordForward(optional,默认true)

        true,鼠标所在的整个变量名将被包含,false,只有指定位置前的文本内容会被考虑

      • omitObjectPrototype(optional,默认true)

        是否忽略Object.prototype的属性

      • includeKeywords(optional,默认false)

        当代码完成发生在一个属性上,是否包含javascript的关键字

      • inLiteral(optional,默认true)

        字面量上是否返回完成内容

      返回结果包含两个属性,start和end,表示完成的词语的偏移量,isProperty是布尔类型,表示完成的是否为一个属性或者一个变量,completions包含一组完成

    2. define

      询问表达式的定义。

      略。

    3. documentation

    4. refs

      获取一个变量或属性的所有引用。

      file,end(required)

      start(optional)

      返回:一个对象,包含name属性,变量或属性的名字,refs是一个数组,包含{file,start,end},如果是变量,将包含type:"global"或"local"

    5. rename

      重命名一个变量

      file,end(required)

      start(optional)

      返回:一个对象,changes属性是一个数组,该数组包含{file,start,end,text},客户端需要根据这个结果做真正的修改。

    6. properties

      获取一个对象的所有属性名

    7. files

      获取server当前持有的文件

    编程接口

    基础Server是没有http交互也没有配置文件的,其实现在lib/tern.js中。

    该包提供了一个Server构造器,通过它我们可以创建一个server对象。它使用一个对象作为配置,该配置包含的选项如下(都有默认值):

    • defs(array of strings)

      类型定义对象,加入到sever

    • plugins(object)

      指定server需要加载的插件

    • ecmaVersion(number)

      按ECMAScript哪个版本进行解析。应该选择5或6,默认6.

    • getFile(function)

      为server提供一个获取文件内容的方式。如果async选项为false,该函数接收filename作为参数,并返回一个字符串,或者接收一个filename参数和一个callback参数,callback接收error信息作为第一个参数,第二个参数为字符串类型的文件内容。

    • async(bool)

      指定getFile是否为异步,默认为false.

    • fetchTimeout(number)
      指定异步getFile最大等待时间,单位为毫秒。默认1000。

    Server对象拥有以下方法:

    • addFile(name:string,text?:string,parent?:string)

      向server注册一个文件。注意文件也可包含在请求中,如果需要通过这个方法加载一个依赖,就在第三个参数中指定文件名称(如果Tern理解这个文件)。该文件将计入依赖预算。

    • delFile(name:string)

      注销一个文件。

    • request(doc:object,callback:fn(error,response))

      执行一个请求。doc是一个json文档,其格式在JSON格式协议中有所描述。请求执行完毕后,callback将得到执行,如果有错误发生将在第一个参数中传入,返回内容将以第二个参数传入。

      当server并没有配置为异步方式,callcack

    • flush(callback:fn())

      强行读取并解析所有文件,然后调用callback。

    • on(eventType:string,handler:fn())

      注册事件处理器

    • off(eventType:string,handler:fn())

      注销事件处理器

    • addDefs(defs:object,atFront?:bool)

      添加类型定义,atFront表示是否添加在已有定义之前

    • deleteDefs(name:string)

      删除类型定义

    • loadPlugin(name:string,options?:object)

      加载一个server plugin

    Server会触发以下类型的事件:

    • reset

      当server抛弃已有的分析并开始新的运行状态时

    • beforeLoad(file)

      分析一个文件前,file是个对象包含{name,text,scope}属性

    • afterLoad(file)

      分析一个文件后

    • preParse(text,options)

      在一个文件解析之前,将传入给定的text和options

    • postParse(ast,text)

      在一个文件解析之后,传入ast树和被解析的文件

    • preInfer(ast,scope)

      在类型推断之前,传入ast树和scope对象

    • postInfer(ast,scope)

      在类型推断之后

    • typeAt(file,end,expr,type)

      在查找文件的指定点end处的类型后触发

    • completion(file,query)

      代码完成开始时执行,可以返回一个代码完成结果来替换默认算法

    相关文章

      网友评论

        本文标题:Javascript代码分析引擎-Tern

        本文链接:https://www.haomeiwen.com/subject/weilgttx.html