Moonpick es un linter alternativo para Moonscript. Si bien moonscript se envía con un linter incorporado, actualmente está limitado en lo que puede detectar. El linter incorporado detectará, por ejemplo, variables no utilizadas, pero sólo para un subconjunto de todas las posibles declaraciones no utilizadas. No detectará variables de importación no utilizadas, variables de descomposición, funciones no utilizadas, etc. Moonpick nació en un intento de detectar lo anterior y más.
Moonpick se puede instalar a través de Luarocks:
$ luarocks install moonpick
Luego se puede ejecutar desde la línea de comando:
$ moonpick < path-to-file >
La salida imita fielmente la salida del linter incorporado de Moonscript.
También se incluye fácilmente en una aplicación independiente, ya que su única dependencia es moonscript. Consulte la sección API para obtener más información sobre cómo ejecutarla mediante programación.
Moonpick detecta variables no utilizadas en todas sus formas, ya sea que se usen explícitamente como variables mediante asignaciones o se creen implícitamente como parte de una declaración import
, una declaración de descomposición de tablas, etc.
Moonpick también puede detectar y quejarse de parámetros de funciones declarados pero no utilizados. Esto no está habilitado de forma predeterminada, ya que es muy común tener parámetros no utilizados. Por ejemplo, una función puede seguir una API externa y aún desea indicar los parámetros disponibles aunque no se utilicen todos. Para habilitar esto, establezca la opción de configuración report_params
en true
.
Moonpick se envía con una configuración predeterminada que incluye en la lista blanca cualquier parámetro que comience con '_', lo que proporciona una forma de mantener los aspectos documentales de una función y seguir complaciendo al linter.
Se detectan variables de bucle no utilizadas. Es posible deshabilitar esto completamente en la configuración o proporcionar una lista blanca explícita solo para las variables de bucle. Moonpick se envía con una configuración predeterminada que incluye en la lista blanca los argumentos 'i' y 'j', o cualquier variable que comience con '_'.
Similar al linter incorporado, Moonpick detecta referencias indefinidas.
El sombreado de declaraciones ocurre siempre que una declaración oculta una declaración anterior con el mismo nombre. Considere el siguiente código:
my_mod = require ' my_mod '
-- [.. more code in between.. ]
for my_mod in get_modules ( ' foo ' )
my_mod . bar!
Si bien en el ejemplo anterior queda bastante claro que my_mod
declarado en el bucle es diferente del my_mod
de nivel superior, esto puede volverse menos claro rápidamente si se inserta más código entre la declaración for y el uso posterior. En ese punto el código se vuelve ambiguo. El seguimiento de declaraciones ayuda con esto al garantizar que cada variable se defina como máximo una vez, de manera inequívoca.
La detección se puede desactivar por completo estableciendo la variable de configuración report_shadowing
en falso, y la lista blanca se puede configurar especificando una lista de configuración whitelist_shadowing
.
Tenga en cuenta que para versiones de Moonscript anteriores a la 0.5, este tipo de sombreados en realidad simplemente reutilizarían la declaración anterior, lo que generaría errores fácilmente pasados por alto y confusos.
Rara vez se desea reasignar una variable previamente definida que contiene un valor de función y, a menudo, es el resultado de olvidar una declaración anterior.
-- 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
Esto puede causar problemas difíciles de depurar, especialmente si la reasignación solo se realiza en una ruta de código que no siempre se utiliza.
La detección se puede desactivar por completo estableciendo la variable de configuración report_fndef_reassignments
en falso, y la lista blanca se puede configurar especificando una lista de configuración whitelist_fndef_reassignments
.
La reasignación de una variable de nivel superior desde una función o método a veces puede ser la causa de errores no obvios y esquivos, por ejemplo:
module = require ' lib.module '
-- [..] much further down
get_foo = ( y ) ->
module = y match ( ' %w+ ' ) lower! -- mistakenly reusing the `module` var
return " #{module}_bar "
Si get_foo
arriba solo se llama condicionalmente, esto podría provocar que errores graves pasen desapercibidos.
A diferencia de otras detecciones, esta detección no está habilitada de forma predeterminada. La detección se puede activar estableciendo la variable de configuración report_top_level_reassignments
en verdadero, y la lista blanca se puede configurar especificando una lista de configuración whitelist_top_level_reassignments
. Sin embargo, es muy recomendable habilitar esto.
La razón por la que esto no está habilitado de forma predeterminada es que no es raro tener código legítimo que manipule variables de nivel superior desde subfunciones o métodos. Para evitar quejas del linter, uno tendría que configurar la lista blanca o adoptar un estilo diferente de codificación donde las variables de nivel superior no se reasignen (por ejemplo, usando una tabla para mantener el estado del módulo).
Moonpick admite un súper conjunto del mismo archivo de configuración y formato que el linter integrado.
Proporciona opciones de configuración adicionales al agregar soporte para configurar el linting de parámetros de función y variables de bucle, y también permite patrones Lua en todas las listas blancas. Los archivos de configuración de Linter se pueden escribir en Lua o Moonscript ( lint_config.lua
y lint_config.moon
respectivamente).
Vea el siguiente ejemplo (lint_config.moon, usando la sintaxis de 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
}
Un elemento de la lista blanca se trata como un patrón si consta de algo que no sean caracteres alfanuméricos.
local moonpick = require ( ' moonpick ' )
Deshace el código dado en code
y devuelve una tabla de inspecciones de linting. config
es la configuración de linting que se utilizará para el archivo y puede contener versiones planas de los elementos que normalmente se encuentran en un archivo de configuración ( whitelist_globals
, whitelist_params
, whitelist_loop_variables
, whitelist_unused
, report_params
, report_loop_variables
).
Ejemplo de una tabla de configuración (sintaxis Lua):
local moonpick = require ( ' moonpick ' )
local code = ' a = 2 '
moonpick . lint ( code , {
whitelist_globals = { ' foo ' , ' bar ' , }
whitelist_params = { ' ^_+ ' , ' other_+ ' }
})
La tabla de inspecciones devueltas se vería así para el ejemplo anterior:
{
{
line = 1 ,
pos = 1 ,
msg = ' declared but unused - `a` ' ,
code = ' a = 2 '
}
}
Limpia el file
dado y devuelve una tabla de inspecciones de pelusa. opts
actualmente puede contener un valor, lint_config
, que especifica el archivo de configuración desde el que cargar la configuración.
local moonpick_config = require ( ' moonpick.config ' )
Devuelve la ruta del archivo de configuración relevante para path
, o nil
si no se encontró ninguno.
Carga la configuración de linting para el file
desde el archivo de configuración proporcionado por config_path
. La configuración devuelta será una tabla de opciones de configuración aplanadas para file
.
Devuelve una instancia de evaluador para las opciones de linting dadas (por ejemplo, según lo devuelto por load_config_from
). La instancia del evaluador proporciona las siguientes funciones (tenga en cuenta que son funciones que se invocarán utilizando el operador de punto ordinario .
:
allow_global_access
, allow_unused_param
, allow_unused_loop_variable
, allow_unused
, allow_fndef_reassignment
, allow_top_level_reassignment
.
Todos estos toman como primer argumento un símbolo (como una cadena) y devuelven true
o false
dependiendo de si el símbolo pasa linting o no.
Tenga en cuenta que Moonpick es bastante joven en esta etapa y, si bien se ha ejecutado con éxito en bases de código más grandes, es muy posible que produzca falsos positivos e informes incorrectos. Si encuentra esto, abra un problema con un código de muestra que ilustre el comportamiento incorrecto.
Copyright 2016-2017 Nils Nordman
Moonpick se publica bajo la licencia MIT (consulte el archivo LICENCIA para obtener todos los detalles).
Las pruebas requieren que busted
ejecuten, así como el módulo pl
(Penlight - luarock install penlight
). Simplemente ejecute busted
en el directorio raíz del proyecto.
Ejecute con un LUA_PATH especificado que apunte al directorio src
local. Suponiendo una ubicación de pago de ~/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