This PR adds a `register_linter_set` command for declaring linter sets. The `getLinterValue` function now checks if the present linter is contained in a set that has been enabled (using the `set_option` command or on the command line). The implementation stores linter set membership in an environment extension. As a consequence, we need to pass more data to `getLinterValue`: the argument of ype `Options` has been replaced with a `LinterOptions`, which you can access by writing `getLinterOptions` instead of `getOptions`. (The alternative I considered is to modify the `Options` structure. The current approach seems a bit higher-level and lower-impact.) The logic for checking whether a linter should be enabled now goes in four steps: 1. If the linter has been explicitly en/disabled, return that. 2. If `linter.all` has been explicitly set, return that. 3. If the linter is in any set that has been enabled, return true. 4. Return the default setting for the linter. Reasoning: * The linter's explicit setting should take precedence. * We want to be able to disable all but the explicitly enabled linters with `linter.all`, so it should take precedence over linter sets. * We want to progressively enable more linters as they become available, so the check over sets should be *any*. * Falling back to the default value last, ensures compatibility with the current way we define linters. The public-facing API currently does not allow modifying sets: all linters have to be added when the set is declared. This way, there is one place where all the contents of the set are listed. Linter sets can be declared to contain linters that have not been declared (yet): this allows declaring linter sets low down in the import hierarchy when not all the requested linters are defined yet. --------- Co-authored-by: grunweg <rothgami@math.hu-berlin.de>
93 lines
2.5 KiB
Text
93 lines
2.5 KiB
Text
import LinterSet.Def
|
|
|
|
open Lean Linter
|
|
|
|
def fooInitially : MetaM Unit := do
|
|
-- linter.foo1 and linter.foo2 are declared to be false by default
|
|
assert! !(getLinterValue linter.foo1 (← getLinterOptions))
|
|
assert! !(getLinterValue linter.foo2 (← getLinterOptions))
|
|
-- linter.foo_true is declared to be true by default
|
|
assert! (getLinterValue linter.foo_true (← getLinterOptions))
|
|
pure ()
|
|
|
|
#eval fooInitially
|
|
|
|
set_option linter.set.foo true
|
|
|
|
def fooSetTrue : MetaM Unit := do
|
|
-- All linters in the `foo` set should now be true
|
|
assert! (getLinterValue linter.foo1 (← getLinterOptions))
|
|
assert! (getLinterValue linter.foo2 (← getLinterOptions))
|
|
assert! (getLinterValue linter.foo_true (← getLinterOptions))
|
|
pure ()
|
|
|
|
#eval fooSetTrue
|
|
|
|
section OverrideFalse
|
|
|
|
set_option linter.foo2 false
|
|
|
|
def overrideFalse : MetaM Unit := do
|
|
-- The overridden linter should now be false.
|
|
assert! (getLinterValue linter.foo1 (← getLinterOptions))
|
|
assert! !(getLinterValue linter.foo2 (← getLinterOptions))
|
|
assert! (getLinterValue linter.foo_true (← getLinterOptions))
|
|
pure ()
|
|
|
|
#eval overrideFalse
|
|
|
|
end OverrideFalse
|
|
|
|
section AllFalse
|
|
|
|
set_option linter.all false
|
|
|
|
def allSetFalse : MetaM Unit := do
|
|
-- All linters, including those in the `foo` set, should now be false
|
|
assert! !(getLinterValue linter.foo1 (← getLinterOptions))
|
|
assert! !(getLinterValue linter.foo2 (← getLinterOptions))
|
|
assert! !(getLinterValue linter.foo_true (← getLinterOptions))
|
|
pure ()
|
|
|
|
#eval allSetFalse
|
|
|
|
end AllFalse
|
|
|
|
set_option linter.set.foo false
|
|
|
|
def fooSetFalse : MetaM Unit := do
|
|
-- All linters in the `foo` set should now be back to default.
|
|
assert! !(getLinterValue linter.foo1 (← getLinterOptions))
|
|
assert! !(getLinterValue linter.foo2 (← getLinterOptions))
|
|
assert! (getLinterValue linter.foo_true (← getLinterOptions))
|
|
pure ()
|
|
|
|
#eval fooSetFalse
|
|
|
|
section AllTrue
|
|
|
|
set_option linter.all true
|
|
|
|
/-- Running this code will check that all linters in the `foo` set are true.
|
|
|
|
This docstring is required due to `linter.all` being true(!). -/
|
|
def allSetTrue : MetaM Unit := do
|
|
-- All linters, including those in the `foo` set, should now be true
|
|
assert! (getLinterValue linter.foo1 (← getLinterOptions))
|
|
assert! (getLinterValue linter.foo2 (← getLinterOptions))
|
|
assert! (getLinterValue linter.foo_true (← getLinterOptions))
|
|
pure ()
|
|
|
|
#eval allSetTrue
|
|
|
|
end AllTrue
|
|
|
|
/-! Test setting user options from lakefile. -/
|
|
|
|
open Lean
|
|
|
|
def barFromLakefile : MetaM Unit := do
|
|
assert! (getLinterValue linter.bar (← getLinterOptions))
|
|
|
|
#eval barFromLakefile
|
|
|