@@ -2,11 +2,11 @@ module FSharpLint.Rules.UsedUnderscorePrefixedElements
22
33open System
44
5+ open FSharp.Compiler .Symbols
6+ open FSharp.Compiler .CodeAnalysis
7+
58open FSharpLint.Framework
69open FSharpLint.Framework .Suggestion
7- open FSharp.Compiler .Syntax
8- open FSharp.Compiler .Text
9- open FSharp.Compiler .CodeAnalysis
1010open FSharpLint.Framework .Ast
1111open FSharpLint.Framework .Rules
1212
@@ -15,21 +15,42 @@ let runner (args: AstNodeRuleParams) =
1515 if args.NodeIndex = 0 then
1616 match args.CheckInfo with
1717 | Some checkResults ->
18- checkResults.GetAllUsesOfAllSymbolsInFile()
19- |> Seq.choose ( fun usage ->
20- match usage.Symbol with
21- | :? FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue as symbol ->
22- if not usage.IsFromDefinition && symbol.FullName.StartsWith " _"
23- && symbol.FullName <> " _" && not symbol.IsCompilerGenerated then
24- Some {
25- Range = usage.Range
26- Message = String.Format( Resources.GetString ( " RulesUsedUnderscorePrefixedElements" ))
27- SuggestedFix = None
28- TypeChecks = List.Empty
29- }
30- else
31- None
32- | _ -> None )
18+ let allUsages = checkResults.GetAllUsesOfAllSymbolsInFile() |> Seq.toArray
19+ seq {
20+ for usage in allUsages do
21+ match usage.Symbol with
22+ | : ? FSharpMemberOrFunctionOrValue as symbol ->
23+ if not usage.IsFromDefinition && symbol.DisplayName.StartsWith " _"
24+ && symbol.DisplayName <> " _" && not symbol.IsCompilerGenerated && not symbol.IsMember then
25+ let nameWithoutUnderscore = symbol.DisplayName.[ 1 ..]
26+ let clashesWithOtherDefinitions =
27+ allUsages
28+ |> Array.exists
29+ ( fun each -> each.Symbol.DisplayName = nameWithoutUnderscore && each.IsFromDefinition)
30+
31+ if clashesWithOtherDefinitions then
32+ yield {
33+ Range = usage.Range
34+ Message = Resources.GetString ( " RulesUsedUnderscorePrefixedElements" )
35+ SuggestedFix = None
36+ TypeChecks = List.Empty
37+ }
38+ else
39+ for range in [ usage.Range; symbol.DeclarationLocation] do
40+ let warningDetrails =
41+ lazy (
42+ let fromText = symbol.DisplayName
43+ Some { FromRange = range; FromText = fromText; ToText = nameWithoutUnderscore })
44+ yield {
45+ Range = range
46+ Message = Resources.GetString ( " RulesUsedUnderscorePrefixedElements" )
47+ SuggestedFix = Some warningDetrails
48+ TypeChecks = List.Empty
49+ }
50+ else
51+ ()
52+ | _ -> () }
53+ |> Seq.distinctBy ( fun wargningDetails -> wargningDetails.Range)
3354 |> Seq.toArray
3455 | None -> Array.empty
3556 else
0 commit comments