File: .lake/packages/batteries/Batteries/Linter/UnnecessarySeqFocus.lean

full_name: Batteries.Linter.linter.unnecessarySeqFocus
code: /--
Enables the 'unnecessary `<;>`' linter. This will warn whenever the `<;>` tactic combinator
is used when `;` would work.

```
example : True := by apply id <;> trivial
```
The `<;>` is unnecessary here because `apply id` only makes one subgoal.
Prefer `apply id; trivial` instead.

In some cases, the `<;>` is syntactically necessary because a single tactic is expected:
```
example : True := by
  cases () with apply id <;> apply id
  | unit => trivial
```
In this case, you should use parentheses, as in `(apply id; apply id)`:
```
example : True := by
  cases () with (apply id; apply id)
  | unit => trivial
```
-/
register_option linter.unnecessarySeqFocus : Bool := {
  defValue := true
  descr := "enable the 'unnecessary <;>' linter"
}
goal: Lean.Option Bool

full_name: Batteries.Linter.initFn._@..lake.packages.batteries.Batteries.Linter.UnnecessarySeqFocus._hyg.7
code: /--
Enables the 'unnecessary `<;>`' linter. This will warn whenever the `<;>` tactic combinator
is used when `;` would work.

```
example : True := by apply id <;> trivial
```
The `<;>` is unnecessary here because `apply id` only makes one subgoal.
Prefer `apply id; trivial` instead.

In some cases, the `<;>` is syntactically necessary because a single tactic is expected:
```
example : True := by
  cases () with apply id <;> apply id
  | unit => trivial
```
In this case, you should use parentheses, as in `(apply id; apply id)`:
```
example : True := by
  cases () with (apply id; apply id)
  | unit => trivial
```
-/
register_option linter.unnecessarySeqFocus : Bool := {
  defValue := true
  descr := "enable the 'unnecessary <;>' linter"
}
goal: IO (Lean.Option Bool)

full_name: Batteries.Linter.UnnecessarySeqFocus.getLinterUnnecessarySeqFocus
code: /-- Gets the value of the `linter.unnecessarySeqFocus` option. -/
def getLinterUnnecessarySeqFocus (o : Options) : Bool 
goal: Bool

full_name: Batteries.Linter.UnnecessarySeqFocus.multigoalAttr
code: /--
The `multigoal` attribute keeps track of tactics that operate on multiple goals,
meaning that `tac` acts differently from `focus tac`. This is used by the
'unnecessary `<;>`' linter to prevent false positives where `tac <;> tac'` cannot
be replaced by `(tac; tac')` because the latter would expose `tac` to a different set of goals.
-/
initialize multigoalAttr : TagAttributeExtra ←
  registerTagAttributeExtra `multigoal "this tactic acts on multiple goals" [
    ``Parser.Tactic.«tacticNext_=>_»,
    ``Parser.Tactic.allGoals,
    ``Parser.Tactic.anyGoals,
    ``Parser.Tactic.case,
    ``Parser.Tactic.case',
    ``Parser.Tactic.Conv.«convNext__=>_»,
    ``Parser.Tactic.Conv.allGoals,
    ``Parser.Tactic.Conv.anyGoals,
    ``Parser.Tactic.Conv.case,
    ``Parser.Tactic.Conv.case',
    ``Parser.Tactic.rotateLeft,
    ``Parser.Tactic.rotateRight,
    ``Parser.Tactic.tacticShow_,
    ``Parser.Tactic.tacticStop_
  ]
goal: Lean.TagAttributeExtra

full_name: Batteries.Linter.UnnecessarySeqFocus.initFn._@..lake.packages.batteries.Batteries.Linter.UnnecessarySeqFocus._hyg.87
code: /--
The `multigoal` attribute keeps track of tactics that operate on multiple goals,
meaning that `tac` acts differently from `focus tac`. This is used by the
'unnecessary `<;>`' linter to prevent false positives where `tac <;> tac'` cannot
be replaced by `(tac; tac')` because the latter would expose `tac` to a different set of goals.
-/
initialize multigoalAttr : TagAttributeExtra ←
  registerTagAttributeExtra `multigoal "this tactic acts on multiple goals" [
    ``Parser.Tactic.«tacticNext_=>_»,
    ``Parser.Tactic.allGoals,
    ``Parser.Tactic.anyGoals,
    ``Parser.Tactic.case,
    ``Parser.Tactic.case',
    ``Parser.Tactic.Conv.«convNext__=>_»,
    ``Parser.Tactic.Conv.allGoals,
    ``Parser.Tactic.Conv.anyGoals,
    ``Parser.Tactic.Conv.case,
    ``Parser.Tactic.Conv.case',
    ``Parser.Tactic.rotateLeft,
    ``Parser.Tactic.rotateRight,
    ``Parser.Tactic.tacticShow_,
    ``Parser.Tactic.tacticStop_
  ]
goal: IO Lean.TagAttributeExtra

full_name: Batteries.Linter.UnnecessarySeqFocus.Entry
code: /-- The information we record for each `<;>` node appearing in the syntax. -/
structure Entry where
  /-- The `<;>` node itself. -/
  stx : Syntax
  /--
  * `true`: this `<;>` has been used unnecessarily at least once
  * `false`: it has never been executed
  * If it has been used properly at least once, the entry is removed from the table.
  -/
  used : Bool
goal: Type

full_name: Batteries.Linter.UnnecessarySeqFocus.Entry.used
code: /-- The information we record for each `<;>` node appearing in the syntax. -/
structure Entry where
  /-- The `<;>` node itself. -/
  stx : Syntax
  /--
  * `true`: this `<;>` has been used unnecessarily at least once
  * `false`: it has never been executed
  * If it has been used properly at least once, the entry is removed from the table.
  -/
  used : Bool
goal: Bool

full_name: Batteries.Linter.UnnecessarySeqFocus.Entry.stx
code: /-- The information we record for each `<;>` node appearing in the syntax. -/
structure Entry where
  /-- The `<;>` node itself. -/
  stx : Syntax
  /--
  * `true`: this `<;>` has been used unnecessarily at least once
  * `false`: it has never been executed
  * If it has been used properly at least once, the entry is removed from the table.
  -/
  used : Bool
goal: Lean.Syntax

full_name: Batteries.Linter.UnnecessarySeqFocus.M
code: /-- The monad for collecting used tactic syntaxes. -/
abbrev M (ω) 
goal: Type

full_name: Batteries.Linter.UnnecessarySeqFocus.isSeqFocus
code: /-- True if this is a `<;>` node in either `tactic` or `conv` classes. -/
@[inline] def isSeqFocus (k : SyntaxNodeKind) : Bool 
goal: Bool

full_name: Batteries.Linter.UnnecessarySeqFocus.getTactics
code: /-- Accumulates the set of tactic syntaxes that should be evaluated at least once. -/
@[specialize] partial def getTactics {ω} (stx : Syntax) : M ω Unit 
goal: Batteries.Linter.UnnecessarySeqFocus.M ω Unit

full_name: Batteries.Linter.UnnecessarySeqFocus.getPath
code: /--
Traverse the info tree down a given path.
Each `(n, i)` means that the array must have length `n` and we will descend into the `i`'th child.
-/
def getPath : Info → PersistentArray InfoTree → List ((n : Nat) × Fin n) → Option Info
  
goal: Lean.Elab.Info → Lean.PersistentArray Lean.Elab.InfoTree → List ((n : Nat) × Fin n) → Option Lean.Elab.Info

full_name: Batteries.Linter.UnnecessarySeqFocus.unnecessarySeqFocusLinter
code: @[inherit_doc Batteries.Linter.linter.unnecessarySeqFocus]
def unnecessarySeqFocusLinter : Linter 
goal: Lean.Linter

full_name: Batteries.Linter.UnnecessarySeqFocus.initFn._@..lake.packages.batteries.Batteries.Linter.UnnecessarySeqFocus._hyg.1977
code: initialize addLinter unnecessarySeqFocusLinter
goal: IO Unit