fix: short-circuit ignore functions in unused variables linter

This commit is contained in:
larsk21 2022-07-06 17:58:06 +02:00 committed by Sebastian Ullrich
parent 9fcae6ffe9
commit 70aff92f8f

View file

@ -25,12 +25,12 @@ def getLinterUnusedVariables (o : Options) : Bool := o.get linter.unusedVariable
def getLinterUnusedVariablesFunArgs (o : Options) : Bool := o.get linter.unusedVariables.funArgs.name (getLinterUnusedVariables o)
def getLinterUnusedVariablesPatternVars (o : Options) : Bool := o.get linter.unusedVariables.patternVars.name (getLinterUnusedVariables o)
def unusedVariables : Linter := fun stx => do
def unusedVariables : Linter := fun cmdStx => do
-- NOTE: `messages` is local to the current command
if (← get).messages.hasErrors then
return
let some stxRange := stx.getRange?
let some cmdStxRange := cmdStx.getRange?
| pure ()
let infoTrees := (← get).infoState.trees.toArray
@ -83,7 +83,7 @@ def unusedVariables : Linter := fun stx => do
| continue
let some localDecl := decl.info.lctx.find? id
| continue
if !stxRange.contains range.start || localDecl.userName.hasMacroScopes then
if !cmdStxRange.contains range.start || localDecl.userName.hasMacroScopes then
continue
-- check linter options
@ -92,7 +92,7 @@ def unusedVariables : Linter := fun stx => do
continue
-- collect ignore functions
let mut ignoredPatternFns := #[
let mut ignoreFns := #[
isTopLevelDecl constDecls,
matchesUnusedPattern,
isVariable,
@ -104,36 +104,34 @@ def unusedVariables : Linter := fun stx => do
isInDepArrow
]
if !getLinterUnusedVariablesFunArgs opts then
ignoredPatternFns := ignoredPatternFns.append #[
ignoreFns := ignoreFns.append #[
isInLetDeclaration,
isInDeclarationSignature,
isInFun
]
if !getLinterUnusedVariablesPatternVars opts then
ignoredPatternFns := ignoredPatternFns.append #[
ignoreFns := ignoreFns.append #[
isPatternVar
]
-- collect syntax versions from macro expansions
let mut stxVersions := #[stx]
for tree in infoTrees do
-- evaluate ignore functions on original syntax
if let some stack := findSyntaxStack? cmdStx declStx then
if ignoreFns.any (· declStx stack) then
continue
else
continue
-- evaluate ignore functions on macro expansion outputs
if ← infoTrees.anyM fun tree => do
if let some macroExpansions ← collectMacroExpansions? range tree then
for exp in macroExpansions do
stxVersions := stxVersions.push exp.output
-- apply ignore functions to syntax stacks
let continue? ← stxVersions.foldlM (init := none) (fun (result : Option Bool ) stx => do
if result matches some true then
return true
let some stack := findSyntaxStack? stx declStx
| return result
if ignoredPatternFns.any (· declStx stack) then
return true
return macroExpansions.reverse.any fun expansion =>
if let some stack := findSyntaxStack? expansion.output declStx then
ignoreFns.any (· declStx stack)
else
false
else
return false)
if continue? matches some true || continue? matches none then
return false
then
continue
-- publish warning if variable is unused