-
Notifications
You must be signed in to change notification settings - Fork 331
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: rewrite set_option style linter in lean (#12928)
Unlike the Python version, this script also supports set_option tactics and terms, and we add a couple of tests.
- Loading branch information
Showing
12 changed files
with
189 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/- | ||
Copyright (c) 2024 Michael Rothgang. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Michael Rothgang | ||
-/ | ||
|
||
import Lean.Elab.Command | ||
import Lean.Linter.Util | ||
|
||
/-! | ||
## Style linters | ||
This file contains (currently one, eventually more) linters about stylistic aspects: | ||
these are only about coding style, but do not affect correctness nor global coherence of mathlib. | ||
Historically, these were ported from the `lint-style.py` Python script. | ||
-/ | ||
|
||
open Lean Elab Command | ||
|
||
namespace Mathlib.Linter | ||
|
||
/-- The `setOption` linter emits a warning on a `set_option` command, term or tactic | ||
which sets a `pp`, `profiler` or `trace` option. -/ | ||
register_option linter.setOption : Bool := { | ||
defValue := true | ||
descr := "enable the `setOption` linter" | ||
} | ||
|
||
namespace Style.SetOption | ||
|
||
/-- Whether a syntax element is a `set_option` command, tactic or term: | ||
Return the name of the option being set, if any. -/ | ||
def parse_set_option : Syntax → Option (Ident) | ||
-- This handles all four possibilities of `_val`: a string, number, `true` and `false`. | ||
| `(command|set_option $name:ident $_val) => some name | ||
| `(set_option $name:ident $_val in $_x) => some name | ||
| `(tactic|set_option $name:ident $_val in $_x) => some name | ||
| _ => none | ||
|
||
/-- Whether a given piece of syntax is a `set_option` command, tactic or term. -/ | ||
def is_set_option : Syntax → Bool := | ||
fun stx ↦ parse_set_option stx matches some _name | ||
|
||
/-- Gets the value of the `linter.setOption` option. -/ | ||
def getLinterHash (o : Options) : Bool := Linter.getLinterValue linter.setOption o | ||
|
||
/-- The `setOption` linter: this lints any `set_option` command, term or tactic | ||
which sets a `pp`, `profiler` or `trace` option. | ||
**Why is this bad?** These options are good for debugging, but should not be | ||
used in production code. | ||
**How to fix this?** Remove these options: usually, they are not necessary for production code. | ||
(Some tests will intentionally use one of these options; in this case, simply allow the linter.) | ||
-/ | ||
def setOptionLinter : Linter where run := withSetOptionIn fun stx => do | ||
unless getLinterHash (← getOptions) do | ||
return | ||
if (← MonadState.get).messages.hasErrors then | ||
return | ||
if let some (head) := stx.find? is_set_option then | ||
if let some (name) := parse_set_option head then | ||
-- Drop a leading backtick. | ||
let name := (toString name).drop 1 | ||
if name.startsWith "pp." || name.startsWith "profiler." || name.startsWith "trace." then | ||
Linter.logLint linter.setOption head m!"Forbidden set_option `{name}`; please remove" | ||
|
||
initialize addLinter setOptionLinter | ||
|
||
end Style.SetOption | ||
|
||
end Mathlib.Linter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import Mathlib.Tactic.Linter.Style | ||
import Mathlib.Tactic.Common | ||
|
||
/-! Tests for all the style linters. -/ | ||
|
||
/-! Tests for the `setOption` linter -/ | ||
section setOption | ||
|
||
-- The warning generated by `linter.setOption` is not suppressed by `#guard_msgs`, | ||
-- because the linter is run on `#guard_msgs` itself. This is a known issue, see e.g. | ||
-- https://leanprover.zulipchat.com/#narrow/stream/348111-batteries/topic/unreachableTactic.20linter.20not.20suppressed.20by.20.60.23guard_msgs.60 | ||
-- We jump through an extra hoop here to silence the warning. | ||
|
||
-- All types of options are supported: boolean, numeric and string-valued. | ||
-- On the top level, i.e. as commands. | ||
|
||
set_option linter.setOption false in | ||
/-- | ||
warning: Forbidden set_option `pp.all`; please remove | ||
note: this linter can be disabled with `set_option linter.setOption false` | ||
-/ | ||
#guard_msgs in | ||
set_option linter.setOption true in | ||
set_option pp.all true | ||
|
||
set_option linter.setOption false in | ||
/-- | ||
warning: Forbidden set_option `pp.all`; please remove | ||
note: this linter can be disabled with `set_option linter.setOption false` | ||
-/ | ||
#guard_msgs in | ||
set_option linter.setOption true in | ||
set_option pp.all false | ||
|
||
set_option linter.setOption false in | ||
/-- | ||
warning: Forbidden set_option `pp.raw.maxDepth`; please remove | ||
note: this linter can be disabled with `set_option linter.setOption false` | ||
-/ | ||
#guard_msgs in | ||
set_option linter.setOption true in | ||
set_option pp.raw.maxDepth 32 | ||
|
||
set_option linter.setOption false in | ||
/-- | ||
warning: Forbidden set_option `trace.profiler.output`; please remove | ||
note: this linter can be disabled with `set_option linter.setOption false` | ||
-/ | ||
#guard_msgs in | ||
set_option linter.setOption true in | ||
set_option trace.profiler.output "foo" | ||
|
||
-- The lint does not fire on arbitrary options. | ||
set_option autoImplicit false | ||
|
||
-- We also cover set_option tactics. | ||
|
||
set_option linter.setOption false in | ||
/-- | ||
warning: Forbidden set_option `pp.all`; please remove | ||
note: this linter can be disabled with `set_option linter.setOption false` | ||
-/ | ||
#guard_msgs in | ||
set_option linter.setOption true in | ||
lemma tactic : True := by | ||
set_option pp.all true in | ||
trivial | ||
|
||
set_option linter.setOption false in | ||
/-- | ||
warning: Forbidden set_option `pp.raw.maxDepth`; please remove | ||
note: this linter can be disabled with `set_option linter.setOption false` | ||
-/ | ||
#guard_msgs in | ||
set_option linter.setOption true in | ||
lemma tactic2 : True := by | ||
set_option pp.raw.maxDepth 32 in | ||
trivial | ||
|
||
set_option linter.setOption false in | ||
/-- | ||
warning: Forbidden set_option `pp.all`; please remove | ||
note: this linter can be disabled with `set_option linter.setOption false` | ||
-/ | ||
#guard_msgs in | ||
set_option linter.setOption true in | ||
lemma tactic3 : True := by | ||
set_option pp.all false in | ||
trivial | ||
|
||
set_option linter.setOption false in | ||
/-- | ||
warning: Forbidden set_option `trace.profiler.output`; please remove | ||
note: this linter can be disabled with `set_option linter.setOption false` | ||
-/ | ||
#guard_msgs in | ||
set_option linter.setOption true in | ||
lemma tactic4 : True := by | ||
set_option trace.profiler.output "foo" in | ||
trivial | ||
|
||
-- This option is not affected, hence does not throw an error. | ||
set_option autoImplicit true in | ||
lemma foo' : True := trivial | ||
|
||
-- TODO: add terms for the term form | ||
|
||
end setOption |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters