Moonpick ist ein alternativer Linter für Moonscript. Während Moonscript mit einem eingebauten Linter ausgeliefert wird, ist dessen Erkennung derzeit begrenzt. Der integrierte Linter erkennt beispielsweise nicht verwendete Variablen, jedoch nur für eine Teilmenge aller möglichen nicht verwendeten Deklarationen. Nicht verwendete Importvariablen, Zerlegungsvariablen, nicht verwendete Funktionen usw. werden nicht erkannt. Moonpick wurde in dem Versuch geboren, das oben Genannte und mehr zu erkennen.
Moonpick kann über Luarocks installiert werden:
$ luarocks install moonpick
Es kann dann über die Befehlszeile ausgeführt werden:
$ moonpick < path-to-file >
Die Ausgabe ist der Ausgabe des integrierten Linter von Moonscript sehr ähnlich.
Es lässt sich auch problemlos in einer eigenständigen Anwendung bündeln, da seine einzige Abhängigkeit Moonscript ist. Weitere Informationen zur programmgesteuerten Ausführung finden Sie im Abschnitt API.
Moonpick erkennt nicht verwendete Variablen in all ihren Formen, unabhängig davon, ob sie explizit über Zuweisungen als Variablen verwendet oder implizit als Teil einer import
, Tabellenzerlegungsanweisung usw. erstellt werden.
Moonpick kann auch deklarierte, aber nicht verwendete Funktionsparameter erkennen und beanstanden. Dies ist standardmäßig nicht aktiviert, da es sehr häufig vorkommt, dass ungenutzte Parameter vorhanden sind. Beispielsweise folgt eine Funktion möglicherweise einer externen API und möchte dennoch die verfügbaren Parameter anzeigen, obwohl nicht alle verwendet werden. Um dies zu aktivieren, setzen Sie die Konfigurationsoption report_params
auf true
.
Moonpick wird mit einer Standardkonfiguration ausgeliefert, die alle Parameter, die mit einem „_“ beginnen, auf die Whitelist setzt. Dies bietet eine Möglichkeit, die Dokumentationsaspekte einer Funktion beizubehalten und dennoch den Linter zufrieden zu stellen.
Nicht verwendete Schleifenvariablen werden erkannt. Es ist möglich, dies in der Konfiguration vollständig zu deaktivieren oder eine explizite Whitelist nur für Schleifenvariablen bereitzustellen. Moonpick wird mit einer Standardkonfiguration geliefert, die die Argumente „i“ und „j“ oder jede Variable, die mit einem „_“ beginnt, auf die Whitelist setzt.
Ähnlich wie der eingebaute Linter erkennt Moonpick undefinierte Referenzen.
Das Deklarations-Shadowing tritt immer dann auf, wenn eine Deklaration eine frühere Deklaration mit demselben Namen überschattet. Betrachten Sie den folgenden Code:
my_mod = require ' my_mod '
-- [.. more code in between.. ]
for my_mod in get_modules ( ' foo ' )
my_mod . bar!
Während im obigen Beispiel ziemlich klar ist, dass sich der in der Schleife deklarierte my_mod
vom my_mod
der obersten Ebene unterscheidet, kann dies schnell weniger klar werden, wenn mehr Code zwischen der for-Deklaration und der späteren Verwendung eingefügt wird. An diesem Punkt wird der Code mehrdeutig. Deklarationsschatten helfen dabei, indem sie sicherstellen, dass jede Variable höchstens einmal und auf eindeutige Weise definiert wird.
Die Erkennung kann vollständig ausgeschaltet werden, indem die Konfigurationsvariable „ report_shadowing
“ auf „false“ gesetzt wird, und das Whitelisting kann durch Angabe einer Konfigurationsliste whitelist_shadowing
konfiguriert werden.
Beachten Sie, dass bei Versionen von Moonscript vor 0.5 diese Art von Shadowing tatsächlich nur die vorherige Deklaration wiederverwenden würde, was zu leicht übersehenen und verwirrenden Fehlern führen würde.
Die Neuzuweisung einer zuvor definierten Variablen, die einen Funktionswert enthält, ist selten erwünscht und ist häufig das Ergebnis des Vergessens einer früheren Deklaration.
-- 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
Dies kann zu schwer zu debuggenden Problemen führen, insbesondere wenn die Neuzuweisung nur in einem Codepfad erfolgt, der nicht immer genutzt wird.
Die Erkennung kann vollständig deaktiviert werden, indem die Konfigurationsvariable „ report_fndef_reassignments
“ auf „false“ gesetzt wird, und das Whitelisting kann durch Angabe einer Konfigurationsliste whitelist_fndef_reassignments
konfiguriert werden.
Die Neuzuweisung einer Variablen der obersten Ebene innerhalb einer Funktion oder Methode kann manchmal die Ursache für nicht offensichtliche und schwer fassbare Fehler sein, z. B.:
module = require ' lib.module '
-- [..] much further down
get_foo = ( y ) ->
module = y match ( ' %w+ ' ) lower! -- mistakenly reusing the `module` var
return " #{module}_bar "
Sollte get_foo
oben nur bedingt aufgerufen werden, könnte dies dazu führen, dass schwerwiegende Fehler unbemerkt bleiben.
Im Gegensatz zu den anderen Erkennungen ist diese Erkennung standardmäßig nicht aktiviert. Die Erkennung kann aktiviert werden, indem die Konfigurationsvariable „ report_top_level_reassignments
“ auf „true“ gesetzt wird, und das Whitelisting kann durch Angabe einer Konfigurationsliste whitelist_top_level_reassignments
konfiguriert werden. Es wird jedoch dringend empfohlen, dies zu aktivieren.
Der Grund dafür, dass dies nicht standardmäßig aktiviert ist, liegt darin, dass es nicht ungewöhnlich ist, legitimen Code zu haben, der Top-Level-Variablen innerhalb von Unterfunktionen oder Methoden manipuliert. Um Beschwerden seitens des Linter zu vermeiden, müsste man dann entweder die Whitelist konfigurieren oder einen anderen Codierungsstil übernehmen, bei dem Variablen der obersten Ebene nicht neu zugewiesen werden (z. B. indem man stattdessen eine Tabelle verwendet, um den Modulstatus zu speichern).
Moonpick unterstützt einen Supersatz derselben Konfigurationsdatei und desselben Formats wie der integrierte Linter.
Es bietet zusätzliche Konfigurationsoptionen, indem es Unterstützung für die Konfiguration des Lintings von Funktionsparametern und Schleifenvariablen hinzufügt, und ermöglicht außerdem Lua-Muster in allen Whitelists. Linter-Konfigurationsdateien können entweder in Lua oder Moonscript geschrieben werden ( lint_config.lua
bzw. lint_config.moon
).
Sehen Sie sich das folgende Beispiel an (lint_config.moon, mit Moonscript-Syntax):
{
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
}
Ein Whitelist-Element wird als Muster behandelt, wenn es aus anderen als alphanumerischen Zeichen besteht.
local moonpick = require ( ' moonpick ' )
Lint den angegebenen Code in code
und gibt eine Tabelle mit Linting-Inspektionen zurück. config
ist die Linting-Konfiguration, die für die Datei verwendet werden soll, und kann flache Versionen der Elemente enthalten, die normalerweise in einer Konfigurationsdatei zu finden sind ( whitelist_globals
, whitelist_params
, whitelist_loop_variables
, whitelist_unused
, report_params
, report_loop_variables
).
Beispiel einer Konfigurationstabelle (Lua-Syntax):
local moonpick = require ( ' moonpick ' )
local code = ' a = 2 '
moonpick . lint ( code , {
whitelist_globals = { ' foo ' , ' bar ' , }
whitelist_params = { ' ^_+ ' , ' other_+ ' }
})
Die Tabelle der zurückgegebenen Inspektionen würde für das obige Beispiel wie folgt aussehen:
{
{
line = 1 ,
pos = 1 ,
msg = ' declared but unused - `a` ' ,
code = ' a = 2 '
}
}
Lint die angegebene file
und gibt eine Tabelle mit Linting-Inspektionen zurück. opts
kann derzeit einen Wert enthalten, lint_config
, der die Konfigurationsdatei angibt, aus der die Konfiguration geladen werden soll.
local moonpick_config = require ( ' moonpick.config ' )
Gibt den Pfad der relevanten Konfigurationsdatei für path
zurück oder nil
, wenn keine gefunden wurde.
Lädt die Linting-Konfiguration für die Datei file
aus der durch config_path
angegebenen Konfigurationsdatei. Die zurückgegebene Konfiguration ist eine Tabelle mit abgeflachten Konfigurationsoptionen für file
.
Gibt eine Evaluator-Instanz für die angegebenen Linting-Optionen zurück (z. B. wie von load_config_from
zurückgegeben). Die Evaluator-Instanz stellt die folgenden Funktionen bereit (beachten Sie, dass es sich hierbei um Funktionen handelt, die mit dem gewöhnlichen Punktoperator aufgerufen werden können .
):
allow_global_access
, allow_unused_param
, allow_unused_loop_variable
, allow_unused
, allow_fndef_reassignment
, allow_top_level_reassignment
.
Alle davon nehmen als erstes Argument ein Symbol (als String) und geben true
oder false
zurück, je nachdem, ob das Symbol Linting besteht oder nicht.
Beachten Sie, dass Moonpick zu diesem Zeitpunkt noch recht jung ist und obwohl es erfolgreich auf größeren Codebasen ausgeführt wurde, kann es durchaus zu Fehlalarmen und falschen Berichten kommen. Sollten Sie auf dieses Problem stoßen, öffnen Sie bitte ein Problem mit einem Codebeispiel, das das fehlerhafte Verhalten veranschaulicht.
Copyright 2016-2017 Nils Nordman
Moonpick wird unter der MIT-Lizenz veröffentlicht (ausführliche Informationen finden Sie in der LIZENZ-Datei).
Für die Ausführung von Tests ist busted
sowie das pl
Modul (Penlight – luarock install penlight
) erforderlich. Führen Sie einfach busted
im Stammverzeichnis des Projekts aus.
Mit einem angegebenen LUA_PATH ausführen, der auf das lokale src
Verzeichnis verweist. Vorausgesetzt, es handelt sich um einen Checkout-Standort von ~/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