Moonpick 是 Moonscript 的替代 linter。雖然 Moonscript 附帶了內建的 linter,但目前它可以偵測到的內容有限。例如,內建 linter 將檢測未使用的變量,但僅針對所有可能未使用的聲明的子集。它不會檢測未使用的導入變數、分解變數、未使用的函數等。
Moonpick 可以透過 Luarocks 安裝:
$ luarocks install moonpick
然後可以從命令列運行它:
$ moonpick < path-to-file >
輸出非常模仿 Moonscript 內建 linter 的輸出。
它也可以輕鬆地捆綁到獨立應用程式中,因為它唯一的依賴項是 Moonscript。有關如何以程式設計方式運行它的更多信息,請參閱 API 部分。
Moonpick 檢測所有形式的未使用變量,無論它們是透過分配明確用作變量還是作為import
語句、表分解語句等的一部分隱式創建。
Moonpick 還可以偵測並抱怨已聲明但未使用的函數參數。預設不啟用此功能,因為有未使用的參數是很常見的。例如,一個函數可能遵循外部 API,並且仍然想要指示可用的參數,即使並非所有參數都被使用。若要啟用此功能,請將report_params
設定選項設為true
。
Moonpick 附帶了一個預設配置,該配置會將任何以「_」開頭的參數列入白名單,從而提供了一種保留函數的文件方面並仍然滿足 linter 要求的方法。
偵測到未使用的循環變數。可以在配置中完全停用此功能,或僅為循環變數提供明確白名單。 Moonpick 附帶一個預設配置,該配置將參數「i」和「j」或任何以「_」開頭的變數列入白名單。
與內建 linter Moonpick 類似,它會偵測未定義的引用。
每當一個聲明遮蔽了較早的同名聲明時,就會發生聲明遮蔽。考慮以下程式碼:
my_mod = require ' my_mod '
-- [.. more code in between.. ]
for my_mod in get_modules ( ' foo ' )
my_mod . bar!
雖然在上面的範例中很清楚,循環中聲明的my_mod
與頂層my_mod
不同,但如果在 for 聲明和以後的使用之間插入更多程式碼,這一點很快就會變得不太清楚。到那時,程式碼就變得不明確了。聲明遮蔽透過確保每個變數最多以明確的方式定義一次,從而有助於解決此問題。
透過將report_shadowing
配置變數設為false可以完全關閉偵測,並且可以透過指定whitelist_shadowing
配置清單來配置白名單。
請注意,對於早於 0.5 的 Moonscript 版本,此類陰影實際上只會重複使用先前的聲明,從而導致容易被忽視和混淆的錯誤。
很少需要重新分配先前定義的保存函數值的變量,並且通常是由於忘記先前的聲明而導致的。
-- with the following declaration and usage
done = ( x ) -> x . foo and x . bar
done ( {} )
-- one might mistakenly reuse the name further down
i = 1
-- [..]
done = i == 10
這可能會導致難以偵錯的問題,特別是如果重新分配僅在不總是執行的程式碼路徑中完成的話。
可以透過將report_fndef_reassignments
配置變數設為false來完全關閉偵測,並且可以透過指定whitelist_fndef_reassignments
配置清單來配置白名單。
從函數或方法內重新分配頂級變數有時可能會導致不明顯和難以捉摸的錯誤,例如:
module = require ' lib.module '
-- [..] much further down
get_foo = ( y ) ->
module = y match ( ' %w+ ' ) lower! -- mistakenly reusing the `module` var
return " #{module}_bar "
如果上面的get_foo
僅被有條件地調用,這可能會導致嚴重的錯誤被忽略。
與其他檢測相比,預設情況下不啟用此檢測。可以透過將report_top_level_reassignments
配置變數設為true來開啟偵測,並且可以透過指定whitelist_top_level_reassignments
配置清單來配置白名單。不過,強烈建議啟用此功能。
預設未啟用此功能的原因是,從子函數或方法中操作頂級變數的合法程式碼並不罕見。為了避免 linter 的投訴,要么必須配置白名單,要么需要採用不同的編碼風格,其中不重新分配頂級變數(例如,使用表來保存模組狀態)。
Moonpick 支援一組與內建 linter 相同的設定檔和格式。
它透過添加對配置函數參數和循環變數的 linting 的支援來提供額外的配置選項,並且還允許所有白名單中的 Lua 模式。 Linter 設定檔可以用 Lua 或 Moonscript 寫(分別為lint_config.lua
和lint_config.moon
)。
請參閱以下範例(lint_config.moon,使用 Moonscript 語法):
{
whitelist_globals : {
-- whitelist for all files
[ " . " ] : { ' always_ignore ' } ,
-- whitelist for files matching 'spec'
spec : { ' test_helper ' } ,
}
whitelist_params : {
-- whitelist params for all files
[ " . " ] : { ' my_param ' } ,
-- ignore unused param for files in api
api : { ' extra_info ' } ,
}
whitelist_loop_variables : {
-- always allow loop variables 'i', 'j', 'k', as well as any
-- variable starting with '_' (using a Lua pattern)
[ " . " ] : { ' i ' , ' j ' , ' k ' , ' ^_ ' } ,
}
-- general whitelist for unused variables if desired for
-- some reason
whitelist_unused : {
[ " . " ] : {} ,
}
-- below you'll see the boolean switches controlling the
-- linting, shown with the default value
-- report_loop_variables: true
-- report_params: true
-- report_shadowing: true
-- report_fndef_reassignments: true
-- report_top_level_reassignments: false
}
如果白名單項目包含字母數字字元以外的任何內容,則將其視為模式。
local moonpick = require ( ' moonpick ' )
對code
中的給定程式碼進行 Lint 處理,傳回 linting 檢查表。 config
是用於檔案的 linting 配置,可以包含通常在設定檔中找到的元素的平面版本( whitelist_globals
、 whitelist_params
、 whitelist_loop_variables
、 whitelist_unused
、 report_params
、 report_loop_variables
)。
配置表示例(Lua語法):
local moonpick = require ( ' moonpick ' )
local code = ' a = 2 '
moonpick . lint ( code , {
whitelist_globals = { ' foo ' , ' bar ' , }
whitelist_params = { ' ^_+ ' , ' other_+ ' }
})
對於上面的範例,傳回的檢查表如下所示:
{
{
line = 1 ,
pos = 1 ,
msg = ' declared but unused - `a` ' ,
code = ' a = 2 '
}
}
對給定file
進行 Lint 處理,傳回 linting 檢查表。 opts
目前可以包含一個值lint_config
,它指定要從中載入設定的設定檔。
local moonpick_config = require ( ' moonpick.config ' )
傳回path
相關設定檔的路徑,如果沒有找到則傳回nil
。
從config_path
給定的設定檔載入檔案file
的 linting 設定。傳回的配置將是file
的扁平化配置選項表。
傳回給定 linting 選項的評估器實例(例如由load_config_from
傳回)。求值器實例提供以下函數(請注意,這些是函數,要使用普通的點運算子.
來呼叫):
allow_global_access
, allow_unused_param
, allow_unused_loop_variable
, allow_unused
, allow_fndef_reassignment
, allow_top_level_reassignment
頂層_級別_重新分配。
所有這些都將符號(作為字串)作為其第一個參數,並根據符號是否透過 linting 來傳回true
或false
。
請注意,Moonpick 在這個階段還很年輕,雖然它已經在更大的程式碼庫上成功運行,但它很可能會產生誤報和不正確的報告。如果您遇到這種情況,請使用說明錯誤行為的程式碼範例提出問題。
版權所有 2016-2017 尼爾斯諾德曼
Moonpick 在 MIT 許可證下發布(有關完整詳細信息,請參閱許可證文件)。
測試需要busted
才能運行,以及pl
模組(Penlight - luarock install penlight
)。只需在專案的根目錄中busted
即可。
使用指向本地src
目錄的指定 LUA_PATH 執行。假設結帳位置為~/code/moonpick
:
LUA_PATH= " $HOME /code/moonpick/src/?.lua; $HOME /code/moonpick/src/?/init.lua; $( lua -e ' print(package.path) ' ) " ~ /code/moonpick/bin/moonpick * .moon