Javascript代码分析引擎-Tern

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)

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,601评论 18 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,869评论 6 13
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,748评论 6 342
  • 每到周末都会想要好好放松一下,骑车,打乒乓,踢足球,放风筝,^_^^_^^_^^_^,有好多的运动!就算是到公园去...
    小妖精的宝贝阅读 354评论 0 1
  • 天气微微开始升温了,穿一件衣服的我也觉得热了。哦多克,孕妇虚汗多,真心比原来怕热些了。又是一个人在家呆了一晚上。飞...
    Daa大琳阅读 274评论 0 0