Skip to content

Commit eb67825

Browse files
committed
Core/PreferStringInterpolationWithSprintf: fix SelfCheck
1 parent 33caf5d commit eb67825

File tree

1 file changed

+33
-35
lines changed

1 file changed

+33
-35
lines changed

src/FSharpLint.Core/Rules/Conventions/PreferStringInterpolationWithSprintf.fs

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,54 +10,52 @@ open FSharpLint.Framework.Rules
1010
let mutable moduleIdentifiers = Set.empty
1111
let mutable letIdentifiers = Set.empty
1212

13-
let private isStringFormat (identifiers: List<Ident>) =
14-
"String" = identifiers.[0].idText && "Format" = identifiers.[1].idText
13+
[<TailCall>]
14+
let rec isVisible (id: Ident) asts =
15+
let isNamedBinding binding =
16+
match binding with
17+
| SynBinding(_, _, _, _, _, _, _, SynPat.Named(SynIdent.SynIdent(ident, _), _, _, _), _, _, _, _, _) ->
18+
id.idText = ident.idText
19+
| _ -> false
1520

16-
let private genereateErrorMessage range =
17-
{ Range = range
18-
Message = Resources.GetString "RulesPreferStringInterpolationWithSprintf"
19-
SuggestedFix = None
20-
TypeChecks = List.empty }
21-
|> Array.singleton
21+
match asts with
22+
| AstNode.Expression (SynExpr.LetOrUse (_, _, [binding], _, _, _)) :: rest ->
23+
isNamedBinding binding || isVisible id rest
24+
| _ :: rest -> isVisible id rest
25+
| [] -> false
26+
27+
[<TailCall>]
28+
let rec getTopLevelParent args index =
29+
let parents = List.rev (args.GetParents index)
30+
match parents with
31+
| AstNode.ModuleDeclaration (SynModuleDecl.Let _) :: rest -> rest
32+
| _ -> getTopLevelParent args (index + 1)
2233

2334
let runner args =
35+
let isStringFormat (identifiers: List<Ident>) =
36+
"String" = identifiers.[0].idText && "Format" = identifiers.[1].idText
37+
38+
let emitViolation range =
39+
{ Range = range
40+
Message = Resources.GetString "RulesPreferStringInterpolationWithSprintf"
41+
SuggestedFix = None
42+
TypeChecks = List.empty }
43+
|> Array.singleton
44+
2445
match args.AstNode with
2546
| AstNode.Expression(SynExpr.App(_, _, SynExpr.LongIdent(_, SynLongIdent(ids, _, _), _, _), paren, range)) when ids.Length = 2 && isStringFormat ids ->
2647
let isTopMember (text: string) =
2748
moduleIdentifiers.Contains text
2849
match paren with
2950
| SynExpr.Paren(SynExpr.Tuple(_, [SynExpr.Const(SynConst.String(_), _); _], _, _), _, _, _) ->
30-
genereateErrorMessage range
51+
emitViolation range
3152
| SynExpr.Paren(SynExpr.Tuple(_, [SynExpr.Ident identifier; _], _, _), _, _, range) ->
3253

3354
if isTopMember identifier.idText then
34-
genereateErrorMessage range
55+
emitViolation range
3556
else
36-
let isNamedBinding binding =
37-
match binding with
38-
| SynBinding(_, _, _, _, _, _, _, SynPat.Named(SynIdent.SynIdent(ident, _), _, _, _), _, _, _, _, _) ->
39-
identifier.idText = ident.idText
40-
| _ -> false
41-
42-
let isVisible asts =
43-
let rec loop asts =
44-
match asts with
45-
| AstNode.Expression (SynExpr.LetOrUse (_, _, [binding], _, _, _)) :: rest ->
46-
isNamedBinding binding || loop rest
47-
| _ :: rest -> loop rest
48-
| [] -> false
49-
loop asts
50-
51-
let getTopLevelParent index =
52-
let rec loop index =
53-
let parents = List.rev (args.GetParents index)
54-
match parents with
55-
| AstNode.ModuleDeclaration (SynModuleDecl.Let _) :: rest -> rest
56-
| _ -> loop (index + 1)
57-
loop index
58-
59-
if letIdentifiers.Contains identifier.idText && isVisible (getTopLevelParent 2) then
60-
genereateErrorMessage range
57+
if letIdentifiers.Contains identifier.idText && isVisible identifier (getTopLevelParent args 2) then
58+
emitViolation range
6159
else
6260
Array.empty
6361
| _ -> Array.empty

0 commit comments

Comments
 (0)