Tern
Tern 是一個javascript代碼分析引擎,其目標是被代碼編輯插件使用以增強編輯器的javascript代碼智能編輯能力。其提供的主要特征如下:
- 變量和屬性的自動完成
- 函數(shù)參數(shù)提示
- 查詢一個表達式的類型
- 查找定義
- 重構(gòu)
Tern是開源項目(MIT),使用javascript編寫,能運行于node.js和瀏覽器中。
Editor plugins
Tern當前支持的編輯器如下:
- Emacs
- Vim
- Sublime Text
- Brackets
- Light Table
- Eclipse(提供了一般性通用api)
- TextMate
社區(qū)支持
有一個論壇用于討論和問有關(guān)Tern的論壇,并會有一些最新消息的通告,比如新版本的發(fā)行??梢酝ㄟ^github issue tracker來報告缺陷。
歡迎通過pull requests來進行代碼分發(fā)。
如果你正從中獲取收益,特別是用于盈利目的,考慮為更多的開發(fā)提供資金,Marijn Haverbeke將會為你提供咨詢。
文檔
了解如何安裝Tern,閱讀參考手冊是你需要進行的第一步。
如果你對這個系統(tǒng)的內(nèi)容工作比較感興趣,可以查看下blog和一些會議上的視頻
Tern 使用手冊##
Tern又幾個組件組成,依賴你利用它來做什么,你將關(guān)注Tern的不同層次。Editor Plugins,它位于最高的層次。Tern server,它是在Server模塊(提供編程接口)的基礎(chǔ)上實現(xiàn),利用推斷引擎inference engine來做真正的類型推斷。
Tern server
bin/tern用來啟動Tern server,你會經(jīng)常使用一個Editor plugin來啟動它,但是也可以手動啟動它,這樣比較方便調(diào)試。(注意server的基礎(chǔ)是通過編程接口提供出來的,對于使用在瀏覽器中的場景,將直接使用編程接口而不是這里描述的http方式)。
Server啟動時將在當前文件夾或者其子文件夾下尋找.tern-project文件,讀取里面的內(nèi)容作為配置。如果沒有project文件,默認配置將創(chuàng)建失敗。你可以通過放置一個.tern-config文件來改變默認配置,該文件的配置格式和.tern-project文件一致,并將該文件放在你的HOME目錄下。
Server在啟動時將其監(jiān)聽的端口(默認隨機)寫入標準輸出,Server通過http方式和json格式數(shù)據(jù)進行交互,客戶端可以通過http上傳代碼并詢問一些關(guān)于代碼的問題。
以下命令行標識將得到支持:
--port <number>
指定監(jiān)聽端口,通過這種方式可以取代默認的隨機端口方式
--host <host>
指定監(jiān)聽的host,默認127.0.0.1
--persistent
默認情況下,Server將在五分鐘沒有交互的情況下自動關(guān)閉,通過該選項可以禁用自動關(guān)閉
--ignore-stdin
默認情況下,在標準輸入流關(guān)閉時Server將自動關(guān)閉,通過該選項可以禁用該行為
--verbose
Server將輸出請求和返回的信息,以及錯誤信息,這有助于調(diào)試
--no-port-file
Server將不會輸出.tern-port文件
JSON格式協(xié)議
向Tern發(fā)送查詢請求要通過POST方式發(fā)送,請求體以json格式傳送。請求提有三個可選字段:query,files,timeout。
query描述了你所請求的信息類型,如果請求只是為了推送新的代碼,那該字段可以忽略。files用于指定一組文件,如果請求所操作的代碼Server上已經(jīng)存在,并沒有添加新的文件,那么該字段將被忽略。timeout用于指定該請求的最大工作時長(cpu時間),毫秒。
query是一個對象,至少有一個type屬性,用以標識請求類型,其他屬性依賴于不同的類型而不同。
以下是Tern server所能理解的請求。(插件可能添加自定義的類型)
-
completions
在給定的位置,詢問代碼完成
字段:
-
file,end(required)
指定代碼完成的位置
-
types(optional,默認false)
是否在結(jié)果數(shù)據(jù)中包含代碼完成的類型
depths(optional,默認false)
docs,urls,origins(optional,默認false)
-
filter(optional,默認true)
是否只返回符合當前位置的詞語的完成列表,否則返回全部
-
caseInsensitive(optional,默認false)
當前位置的詞語和潛在完成列表是否采用大小寫敏感性比較
-
guess(optional,默認true)
當找不到匹配的完成結(jié)果時,是否返回啟發(fā)式的建議
-
sort(optional,默認true)
結(jié)果是否排序
-
expandWordForward(optional,默認true)
true,鼠標所在的整個變量名將被包含,false,只有指定位置前的文本內(nèi)容會被考慮
-
omitObjectPrototype(optional,默認true)
是否忽略O(shè)bject.prototype的屬性
-
includeKeywords(optional,默認false)
當代碼完成發(fā)生在一個屬性上,是否包含javascript的關(guān)鍵字
-
inLiteral(optional,默認true)
字面量上是否返回完成內(nèi)容
返回結(jié)果包含兩個屬性,start和end,表示完成的詞語的偏移量,isProperty是布爾類型,表示完成的是否為一個屬性或者一個變量,completions包含一組完成
-
-
define
詢問表達式的定義。
略。
-
documentation
略
-
refs
獲取一個變量或?qū)傩缘乃幸谩?/p>
file,end(required)
start(optional)
返回:一個對象,包含name屬性,變量或?qū)傩缘拿?,refs是一個數(shù)組,包含{file,start,end},如果是變量,將包含type:"global"或"local"
-
rename
重命名一個變量
file,end(required)
start(optional)
返回:一個對象,changes屬性是一個數(shù)組,該數(shù)組包含{file,start,end,text},客戶端需要根據(jù)這個結(jié)果做真正的修改。
-
properties
獲取一個對象的所有屬性名
略 -
files
獲取server當前持有的文件
編程接口
基礎(chǔ)Server是沒有http交互也沒有配置文件的,其實現(xiàn)在lib/tern.js中。
該包提供了一個Server構(gòu)造器,通過它我們可以創(chuàng)建一個server對象。它使用一個對象作為配置,該配置包含的選項如下(都有默認值):
-
defs(array of strings)
類型定義對象,加入到sever
-
plugins(object)
指定server需要加載的插件
-
ecmaVersion(number)
按ECMAScript哪個版本進行解析。應(yīng)該選擇5或6,默認6.
-
getFile(function)
為server提供一個獲取文件內(nèi)容的方式。如果async選項為false,該函數(shù)接收filename作為參數(shù),并返回一個字符串,或者接收一個filename參數(shù)和一個callback參數(shù),callback接收error信息作為第一個參數(shù),第二個參數(shù)為字符串類型的文件內(nèi)容。
-
async(bool)
指定getFile是否為異步,默認為false.
fetchTimeout(number)
指定異步getFile最大等待時間,單位為毫秒。默認1000。
Server對象擁有以下方法:
-
addFile(name:string,text?:string,parent?:string)
向server注冊一個文件。注意文件也可包含在請求中,如果需要通過這個方法加載一個依賴,就在第三個參數(shù)中指定文件名稱(如果Tern理解這個文件)。該文件將計入依賴預(yù)算。
-
delFile(name:string)
注銷一個文件。
-
request(doc:object,callback:fn(error,response))
執(zhí)行一個請求。doc是一個json文檔,其格式在JSON格式協(xié)議中有所描述。請求執(zhí)行完畢后,callback將得到執(zhí)行,如果有錯誤發(fā)生將在第一個參數(shù)中傳入,返回內(nèi)容將以第二個參數(shù)傳入。
當server并沒有配置為異步方式,callcack
-
flush(callback:fn())
強行讀取并解析所有文件,然后調(diào)用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會觸發(fā)以下類型的事件:
-
reset
當server拋棄已有的分析并開始新的運行狀態(tài)時
-
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處的類型后觸發(fā)
-
completion(file,query)
代碼完成開始時執(zhí)行,可以返回一個代碼完成結(jié)果來替換默認算法