From 06fb857b44d9fa988e377ae07b39641ec312101e Mon Sep 17 00:00:00 2001 From: webwarrior Date: Wed, 20 Dec 2023 13:36:53 +0100 Subject: [PATCH] UsedUnderscorePrefixedElements: fix rule Fix rule so that it identifies all usages of identifiers that start with `_`. --- .../UsedUnderscorePrefixedElements.fs | 70 +++++++++---------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/src/FSharpLint.Core/Rules/Conventions/UsedUnderscorePrefixedElements.fs b/src/FSharpLint.Core/Rules/Conventions/UsedUnderscorePrefixedElements.fs index e9f771829..6d6f1696e 100644 --- a/src/FSharpLint.Core/Rules/Conventions/UsedUnderscorePrefixedElements.fs +++ b/src/FSharpLint.Core/Rules/Conventions/UsedUnderscorePrefixedElements.fs @@ -5,51 +5,45 @@ open System open FSharpLint.Framework open FSharpLint.Framework.Suggestion open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.CodeAnalysis open FSharpLint.Framework.Ast open FSharpLint.Framework.Rules -let private checkUsedIdent (previousIdent: Ident) (body: SynExpr) = - match body with - | SynExpr.Sequential(_debugPointAtSequential, _isTrueSeq, synExpr, _expr2, _range) -> - match synExpr with - | SynExpr.App(_exprAtomicFlag, _isInfix, _funcExpr, argExpr, range) -> - match argExpr with - | SynExpr.Ident ident -> - if previousIdent.idText = ident.idText then - { - Range = range +let private checkUsedIdent (identifier: Ident) (usages: array) (scopeRange: Range) = + usages + |> Array.collect (fun usage -> + if not usage.IsFromDefinition && usage.Symbol.FullName = identifier.idText + && ExpressionUtilities.rangeContainsOtherRange scopeRange usage.Range then + { + Range = usage.Range + Message = String.Format(Resources.GetString ("RulesUsedUnderscorePrefixedElements")) + SuggestedFix = None + TypeChecks = List.Empty + } |> Array.singleton + else + Array.empty) + +let runner (args: AstNodeRuleParams) = + // hack to only run rule once + if args.NodeIndex = 0 then + match args.CheckInfo with + | Some checkResults -> + checkResults.GetAllUsesOfAllSymbolsInFile() + |> Seq.choose (fun usage -> + if not usage.IsFromDefinition && usage.Symbol.FullName.StartsWith "_" then + Some { + Range = usage.Range Message = String.Format(Resources.GetString ("RulesUsedUnderscorePrefixedElements")) SuggestedFix = None TypeChecks = List.Empty - } |> Array.singleton + } else - Array.empty - | _ -> - Array.empty - | _ -> - Array.empty - | _ -> - Array.empty - -let runner (args: AstNodeRuleParams) = - - let error = - match args.AstNode with - | AstNode.Expression (SynExpr.LetOrUse (_isRecursive, _isUse, bindings, body, _range)) -> - match List.tryHead bindings with - | Some(SynBinding(_synAccessOption, _synBindingKind, _mustInline, _isMutable, _synAttributeLists, _preXmlDoc, _synValData, headPat, _synBindingReturnInfoOption, _synExpr, _range, _debugPointAtBinding)) -> - match headPat with - | SynPat.Named(_synPat, ident, _isSelfIdentifier, _synAccessOption, _range) -> - if ident.idText.StartsWith "_" then - checkUsedIdent ident body - else - Array.empty - | _ -> - Array.empty - | _ -> Array.empty - | _ -> Array.empty - - error + None) + |> Seq.toArray + | None -> Array.empty + else + Array.empty let rule = { Name = "UsedUnderscorePrefixedElements"