@@ -13,6 +13,13 @@ open FSharpLint.Framework.ExpressionUtilities
13
13
open FSharpLint.Framework .HintParser
14
14
open FSharpLint.Framework .Rules
15
15
16
+ type ToStringConfig = { Replace: bool
17
+ ParentAstNode: AstNode option
18
+ Args: AstNodeRuleParams
19
+ MatchedVariables: Dictionary < char , SynExpr >
20
+ ParentHintNode: option < HintNode >
21
+ HintNode: HintNode }
22
+
16
23
type Config =
17
24
{ HintTrie: MergeSyntaxTrees .Edges }
18
25
@@ -503,15 +510,20 @@ module private FormatHint =
503
510
Debug.Assert( false , " Expected operator to be an expression identifier, but was " + expression.ToString())
504
511
String.Empty
505
512
506
- let rec toString replace parentAstNode ( args : AstNodeRuleParams ) ( matchedVariables : Dictionary < _ , SynExpr >) parentHintNode hintNode =
507
- let toString = toString replace parentAstNode args matchedVariables ( Some hintNode)
513
+ let rec toString ( config : ToStringConfig ) =
514
+ let toString hintNode = toString { Replace = config.Replace
515
+ ParentAstNode = config.ParentAstNode
516
+ Args = config.Args
517
+ MatchedVariables = config.MatchedVariables
518
+ ParentHintNode = ( Some config.HintNode)
519
+ HintNode = hintNode}
508
520
509
521
let str =
510
- match hintNode with
511
- | HintExpr( Expression.Variable( varChar)) when replace ->
512
- match matchedVariables .TryGetValue varChar with
522
+ match config.HintNode with
523
+ | HintExpr( Expression.Variable( varChar)) when config.Replace ->
524
+ match config.MatchedVariables .TryGetValue varChar with
513
525
| true , expr ->
514
- match ExpressionUtilities.tryFindTextOfRange expr.Range args .FileContent with
526
+ match ExpressionUtilities.tryFindTextOfRange expr.Range config.Args .FileContent with
515
527
| Some( replacement) -> replacement
516
528
| _ -> varChar.ToString()
517
529
| _ -> varChar.ToString()
@@ -543,7 +555,7 @@ module private FormatHint =
543
555
| HintPat( Pattern.Parentheses( hint)) -> " (" + toString ( HintPat hint) + " )"
544
556
| HintExpr( Expression.Lambda( arguments, LambdaBody( body))) ->
545
557
" fun "
546
- + lambdaArgumentsToString replace parentAstNode args matchedVariables arguments
558
+ + lambdaArgumentsToString config.Replace config.ParentAstNode config.Args config.MatchedVariables arguments
547
559
+ " -> " + toString ( HintExpr body)
548
560
| HintExpr( Expression.LambdaArg( argument)) ->
549
561
toString ( HintExpr argument)
@@ -569,33 +581,53 @@ module private FormatHint =
569
581
" else " + toString ( HintExpr expr)
570
582
| HintExpr( Expression.Null)
571
583
| HintPat( Pattern.Null) -> " null"
572
- if replace && Precedence.requiresParenthesis matchedVariables hintNode parentAstNode parentHintNode then " (" + str + " )"
584
+ if config.Replace && Precedence.requiresParenthesis config.MatchedVariables config.HintNode config.ParentAstNode config.ParentHintNode then " (" + str + " )"
573
585
else str
574
586
and private lambdaArgumentsToString replace parentAstNode args matchedVariables ( arguments : LambdaArg list ) =
575
587
arguments
576
- |> List.map ( fun ( LambdaArg expr ) -> toString replace parentAstNode args matchedVariables None ( HintExpr expr))
588
+ |> List.map ( fun ( LambdaArg expr ) -> toString { Replace = replace
589
+ ParentAstNode = parentAstNode
590
+ Args = args
591
+ MatchedVariables = matchedVariables
592
+ ParentHintNode = None
593
+ HintNode = ( HintExpr expr) } )
577
594
|> String.concat " "
578
595
579
- let private hintError typeChecks hint ( args : AstNodeRuleParams ) range matchedVariables parentAstNode =
580
- let matched = FormatHint.toString false None args matchedVariables None hint.MatchedNode
581
-
582
- match hint.Suggestion with
596
+ type HintErrorConfig = { TypeChecks: ( unit -> bool ) list
597
+ Hint: Hint
598
+ Args: AstNodeRuleParams
599
+ Range: FSharp .Compiler .Text .Range
600
+ MatchedVariables: Dictionary < char , SynExpr >
601
+ ParentAstNode: AstNode option }
602
+ let private hintError ( config : HintErrorConfig ) =
603
+ let toStringConfig = { ToStringConfig.Replace = false
604
+ ToStringConfig.ParentAstNode = None
605
+ ToStringConfig.Args = config.Args
606
+ ToStringConfig.MatchedVariables = config.MatchedVariables
607
+ ToStringConfig.ParentHintNode = None
608
+ ToStringConfig.HintNode = config.Hint.MatchedNode }
609
+ let matched = FormatHint.toString toStringConfig
610
+
611
+ match config.Hint.Suggestion with
583
612
| Suggestion.Expr( expr) ->
584
- let suggestion = FormatHint.toString false None args matchedVariables None ( HintExpr expr)
613
+ let suggestion = FormatHint.toString { toStringConfig with HintNode = ( HintExpr expr) }
585
614
let errorFormatString = Resources.GetString( " RulesHintRefactor" )
586
615
let error = System.String.Format( errorFormatString, matched, suggestion)
587
616
588
- let toText = FormatHint.toString true parentAstNode args matchedVariables None ( HintExpr expr)
617
+ let toText = FormatHint.toString { toStringConfig with
618
+ Replace = true
619
+ ParentAstNode = config.ParentAstNode
620
+ HintNode = ( HintExpr expr) }
589
621
590
622
let suggestedFix = lazy (
591
- ExpressionUtilities.tryFindTextOfRange range args .FileContent
592
- |> Option.map ( fun fromText -> { FromText = fromText; FromRange = range ; ToText = toText }))
623
+ ExpressionUtilities.tryFindTextOfRange config.Range config.Args .FileContent
624
+ |> Option.map ( fun fromText -> { FromText = fromText; FromRange = config.Range ; ToText = toText }))
593
625
594
- { Range = range ; Message = error; SuggestedFix = Some suggestedFix; TypeChecks = typeChecks }
626
+ { Range = config.Range ; Message = error; SuggestedFix = Some suggestedFix; TypeChecks = config.TypeChecks }
595
627
| Suggestion.Message( message) ->
596
628
let errorFormatString = Resources.GetString( " RulesHintSuggestion" )
597
629
let error = System.String.Format( errorFormatString, matched, message)
598
- { Range = range ; Message = error; SuggestedFix = None; TypeChecks = typeChecks }
630
+ { Range = config.Range ; Message = error; SuggestedFix = None; TypeChecks = config.TypeChecks }
599
631
600
632
let private getMethodParameters ( checkFile : FSharpCheckFileResults ) ( methodIdent : LongIdentWithDots ) =
601
633
let symbol =
@@ -651,7 +683,12 @@ let private confirmFuzzyMatch (args:AstNodeRuleParams) (hint:HintParser.Hint) =
651
683
| AstNode.Expression( SynExpr.Paren(_)), HintExpr(_)
652
684
| AstNode.Pattern( SynPat.Paren(_)), HintPat(_) -> ()
653
685
| AstNode.Pattern( pattern), HintPat( hintPattern) when MatchPattern.matchHintPattern ( pattern, hintPattern) ->
654
- hintError List.Empty hint args pattern.Range ( Dictionary<_, _>()) None
686
+ hintError { TypeChecks = List.Empty
687
+ Hint = hint
688
+ Args = args
689
+ Range = pattern.Range
690
+ MatchedVariables = ( Dictionary<_, _>())
691
+ ParentAstNode = None }
655
692
|> suggestions.Add
656
693
| AstNode.Expression( expr), HintExpr( hintExpr) ->
657
694
let arguments =
@@ -665,7 +702,12 @@ let private confirmFuzzyMatch (args:AstNodeRuleParams) (hint:HintParser.Hint) =
665
702
match MatchExpression.matchHintExpr arguments with
666
703
| MatchExpression.Match( typeChecks) ->
667
704
let suggest checks =
668
- hintError checks hint args expr.Range arguments.MatchedVariables ( List.tryHead breadcrumbs)
705
+ hintError { TypeChecks = checks
706
+ Hint = hint
707
+ Args = args
708
+ Range = expr.Range
709
+ MatchedVariables = arguments.MatchedVariables
710
+ ParentAstNode = ( List.tryHead breadcrumbs) }
669
711
|> suggestions.Add
670
712
671
713
match ( hint.MatchedNode, hint.Suggestion) with
0 commit comments