File: .lake/packages/batteries/Batteries/Tactic/Lint/Frontend.lean

full_name: Std.Tactic.Lint.LintVerbosity.high
code: /-- Verbosity for the linter output. -/
inductive LintVerbosity
  /-- `low`: only print failing checks, print nothing on success. -/
  | low
  /-- `medium`: only print failing checks, print confirmation on success. -/
  | medium
  /-- `high`: print output of every check. -/
  | high
  deriving Inhabited, DecidableEq, Repr
goal: Std.Tactic.Lint.LintVerbosity

full_name: Std.Tactic.Lint.instReprLintVerbosity
code: /-- Verbosity for the linter output. -/
inductive LintVerbosity
  /-- `low`: only print failing checks, print nothing on success. -/
  | low
  /-- `medium`: only print failing checks, print confirmation on success. -/
  | medium
  /-- `high`: print output of every check. -/
  | high
  deriving Inhabited, DecidableEq, Repr
goal: Repr Std.Tactic.Lint.LintVerbosity

full_name: Std.Tactic.Lint.LintVerbosity.low
code: /-- Verbosity for the linter output. -/
inductive LintVerbosity
  /-- `low`: only print failing checks, print nothing on success. -/
  | low
  /-- `medium`: only print failing checks, print confirmation on success. -/
  | medium
  /-- `high`: print output of every check. -/
  | high
  deriving Inhabited, DecidableEq, Repr
goal: Std.Tactic.Lint.LintVerbosity

full_name: Std.Tactic.Lint.LintVerbosity
code: /-- Verbosity for the linter output. -/
inductive LintVerbosity
  /-- `low`: only print failing checks, print nothing on success. -/
  | low
  /-- `medium`: only print failing checks, print confirmation on success. -/
  | medium
  /-- `high`: print output of every check. -/
  | high
  deriving Inhabited, DecidableEq, Repr
goal: Type

full_name: Std.Tactic.Lint.instDecidableEqLintVerbosity
code: /-- Verbosity for the linter output. -/
inductive LintVerbosity
  /-- `low`: only print failing checks, print nothing on success. -/
  | low
  /-- `medium`: only print failing checks, print confirmation on success. -/
  | medium
  /-- `high`: print output of every check. -/
  | high
  deriving Inhabited, DecidableEq, Repr
goal: DecidableEq Std.Tactic.Lint.LintVerbosity

full_name: Std.Tactic.Lint.instInhabitedLintVerbosity
code: /-- Verbosity for the linter output. -/
inductive LintVerbosity
  /-- `low`: only print failing checks, print nothing on success. -/
  | low
  /-- `medium`: only print failing checks, print confirmation on success. -/
  | medium
  /-- `high`: print output of every check. -/
  | high
  deriving Inhabited, DecidableEq, Repr
goal: Inhabited Std.Tactic.Lint.LintVerbosity

full_name: Std.Tactic.Lint.LintVerbosity.medium
code: /-- Verbosity for the linter output. -/
inductive LintVerbosity
  /-- `low`: only print failing checks, print nothing on success. -/
  | low
  /-- `medium`: only print failing checks, print confirmation on success. -/
  | medium
  /-- `high`: print output of every check. -/
  | high
  deriving Inhabited, DecidableEq, Repr
goal: Std.Tactic.Lint.LintVerbosity

full_name: Std.Tactic.Lint.getChecks
code: /-- `getChecks slow runOnly runAlways` produces a list of linters.
`runOnly` is an optional list of names that should resolve to declarations with type `NamedLinter`.
If populated, only these linters are run (regardless of the default configuration).
`runAlways` is an optional list of names that should resolve to declarations with type
`NamedLinter`. If populated, these linters are always run (regardless of their configuration).
Specifying a linter in `runAlways` but not `runOnly` is an error.
Otherwise, it uses all enabled linters in the environment tagged with `@[env_linter]`.
If `slow` is false, it only uses the fast default tests. -/
def getChecks (slow : Bool) (runOnly : Option (List Name)) (runAlways : Option (List Name)) :
    CoreM (Array NamedLinter) 
goal: Lean.CoreM (Array Std.Tactic.Lint.NamedLinter)

full_name: Std.Tactic.Lint.lintCore
code: /--
Runs all the specified linters on all the specified declarations in parallel,
producing a list of results.
-/
def lintCore (decls : Array Name) (linters : Array NamedLinter) :
    CoreM (Array (NamedLinter × HashMap Name MessageData)) 
goal: Lean.CoreM (Array (Std.Tactic.Lint.NamedLinter × Lean.HashMap Lean.Name Lean.MessageData))

full_name: Std.Tactic.Lint.sortResults
code: /-- Sorts a map with declaration keys as names by line number. -/
def sortResults (results : HashMap Name α) : CoreM <| Array (Name × α) 
goal: Lean.CoreM (Array (Lean.Name × α))

full_name: Std.Tactic.Lint.printWarning
code: /-- Formats a linter warning as `#check` command with comment. -/
def printWarning (declName : Name) (warning : MessageData) (useErrorFormat : Bool := false)
  (filePath : System.FilePath := default) : CoreM MessageData 
goal: Lean.CoreM Lean.MessageData

full_name: Std.Tactic.Lint.printWarnings
code: /-- Formats a map of linter warnings using `print_warning`, sorted by line number. -/
def printWarnings (results : HashMap Name MessageData) (filePath : System.FilePath := default)
    (useErrorFormat : Bool := false) : CoreM MessageData 
goal: Lean.CoreM Lean.MessageData

full_name: Std.Tactic.Lint.groupedByFilename
code: /--
Formats a map of linter warnings grouped by filename with `-- filename` comments.
The first `drop_fn_chars` characters are stripped from the filename.
-/
def groupedByFilename (results : HashMap Name MessageData) (useErrorFormat : Bool := false) :
    CoreM MessageData 
goal: Lean.CoreM Lean.MessageData

full_name: Std.Tactic.Lint.formatLinterResults
code: /--
Formats the linter results as Lean code with comments and `#check` commands.
-/
def formatLinterResults
    (results : Array (NamedLinter × HashMap Name MessageData))
    (decls : Array Name)
    (groupByFilename : Bool)
    (whereDesc : String) (runSlowLinters : Bool)
    (verbose : LintVerbosity) (numLinters : Nat) (useErrorFormat : Bool := false) :
    CoreM MessageData 
goal: Lean.CoreM Lean.MessageData

full_name: Std.Tactic.Lint.getDeclsInCurrModule
code: /-- Get the list of declarations in the current module. -/
def getDeclsInCurrModule : CoreM (Array Name) 
goal: Lean.CoreM (Array Lean.Name)

full_name: Std.Tactic.Lint.getAllDecls
code: /-- Get the list of all declarations in the environment. -/
def getAllDecls : CoreM (Array Name) 
goal: Lean.CoreM (Array Lean.Name)

full_name: Std.Tactic.Lint.getDeclsInPackage
code: /-- Get the list of all declarations in the specified package. -/
def getDeclsInPackage (pkg : Name) : CoreM (Array Name) 
goal: Lean.CoreM (Array Lean.Name)

full_name: Std.Tactic.Lint.inProject
code: /-- The `in foo` config argument allows running the linter on a specified project. -/
syntax inProject := " in " ident
goal: Lean.ParserDescr

full_name: Std.Tactic.Lint.«command#lint+-*Only___»
code: /-- The command `#lint` runs the linters on the current file (by default).

`#lint only someLinter` can be used to run only a single linter. -/
elab tk:"#lint" verbosity:("+" <|> "-")? fast:"*"? only:(&" only")?
    linters:(ppSpace ident)* project:(inProject)? : command => do
  let (decls, whereDesc, groupByFilename) ← match project with
    | none => do pure (← liftCoreM getDeclsInCurrModule, "in the current file", false)
    | some cfg => match cfg with
      | `(inProject| in $id) =>
        let id := id.getId.eraseMacroScopes
        if id == `all then
          pure (← liftCoreM getAllDecls, "in all files", true)
        else
          pure (← liftCoreM (getDeclsInPackage id), s!"in {id}", true)
      | _ => throwUnsupportedSyntax
  let verbosity : LintVerbosity ← match verbosity with
    | none => pure .medium
    | some ⟨.node _ `token.«+» _⟩ => pure .high
    | some ⟨.node _ `token.«-» _⟩ => pure .low
    | _ => throwUnsupportedSyntax
  let fast := fast.isSome
  let onlyNames : Option (List Name) := match only.isSome with
    | true => some (linters.map fun l => l.getId).toList
    | false => none
  let linters ← liftCoreM do
    let mut result ← getChecks (slow := !fast) (runOnly := onlyNames) none
    let linterState := batteriesLinterExt.getState (← getEnv)
    for id in linters do
      let name := id.getId.eraseMacroScopes
      let some (declName, _) := linterState.find? name | throwErrorAt id "not a linter: {name}"
      Elab.addConstInfo id declName
      let linter ← getLinter name declName
      result := result.binInsert (·.name.lt ·.name) linter
    pure result
  let results ← liftCoreM <| lintCore decls linters
  let failed := results.any (!·.2.isEmpty)
  let mut fmtResults ← liftCoreM <|
    formatLinterResults results decls (groupByFilename := groupByFilename)
      whereDesc (runSlowLinters := !fast) verbosity linters.size
  if failed then
    logError fmtResults
  else if verbosity != LintVerbosity.low then
    logInfoAt tk m!"{fmtResults}\n-- All linting checks passed!"
goal: Lean.ParserDescr

full_name: Std.Tactic.Lint.«_aux_.lake_packages_batteries_Batteries_Tactic_Lint_Frontend___elabRules_Std_Tactic_Lint_command#lint+-*Only____1»
code: /-- The command `#lint` runs the linters on the current file (by default).

`#lint only someLinter` can be used to run only a single linter. -/
elab tk:"#lint" verbosity:("+" <|> "-")? fast:"*"? only:(&" only")?
    linters:(ppSpace ident)* project:(inProject)? : command => do
  let (decls, whereDesc, groupByFilename) ← match project with
    | none => do pure (← liftCoreM getDeclsInCurrModule, "in the current file", false)
    | some cfg => match cfg with
      | `(inProject| in $id) =>
        let id := id.getId.eraseMacroScopes
        if id == `all then
          pure (← liftCoreM getAllDecls, "in all files", true)
        else
          pure (← liftCoreM (getDeclsInPackage id), s!"in {id}", true)
      | _ => throwUnsupportedSyntax
  let verbosity : LintVerbosity ← match verbosity with
    | none => pure .medium
    | some ⟨.node _ `token.«+» _⟩ => pure .high
    | some ⟨.node _ `token.«-» _⟩ => pure .low
    | _ => throwUnsupportedSyntax
  let fast := fast.isSome
  let onlyNames : Option (List Name) := match only.isSome with
    | true => some (linters.map fun l => l.getId).toList
    | false => none
  let linters ← liftCoreM do
    let mut result ← getChecks (slow := !fast) (runOnly := onlyNames) none
    let linterState := batteriesLinterExt.getState (← getEnv)
    for id in linters do
      let name := id.getId.eraseMacroScopes
      let some (declName, _) := linterState.find? name | throwErrorAt id "not a linter: {name}"
      Elab.addConstInfo id declName
      let linter ← getLinter name declName
      result := result.binInsert (·.name.lt ·.name) linter
    pure result
  let results ← liftCoreM <| lintCore decls linters
  let failed := results.any (!·.2.isEmpty)
  let mut fmtResults ← liftCoreM <|
    formatLinterResults results decls (groupByFilename := groupByFilename)
      whereDesc (runSlowLinters := !fast) verbosity linters.size
  if failed then
    logError fmtResults
  else if verbosity != LintVerbosity.low then
    logInfoAt tk m!"{fmtResults}\n-- All linting checks passed!"
goal: Lean.Elab.Command.CommandElab

full_name: Std.Tactic.Lint.«command#list_linters»
code: /-- The command `#list_linters` prints a list of all available linters. -/
elab "#list_linters" : command => do
  let mut result := #[]
  for (name, _, dflt) in batteriesLinterExt.getState (← getEnv) do
    result := result.binInsert (·.1.lt ·.1) (name, dflt)
  let mut msg := m!"Available linters (linters marked with (*) are in the default lint set):"
  for (name, dflt) in result do
    msg := msg ++ m!"\n{name}{if dflt then " (*)" else ""}"
  logInfo msg
goal: Lean.ParserDescr

full_name: Std.Tactic.Lint.«_aux_.lake_packages_batteries_Batteries_Tactic_Lint_Frontend___elabRules_Std_Tactic_Lint_command#list_linters_1»
code: /-- The command `#list_linters` prints a list of all available linters. -/
elab "#list_linters" : command => do
  let mut result := #[]
  for (name, _, dflt) in batteriesLinterExt.getState (← getEnv) do
    result := result.binInsert (·.1.lt ·.1) (name, dflt)
  let mut msg := m!"Available linters (linters marked with (*) are in the default lint set):"
  for (name, dflt) in result do
    msg := msg ++ m!"\n{name}{if dflt then " (*)" else ""}"
  logInfo msg
goal: Lean.Elab.Command.CommandElab