@@ -13,6 +13,45 @@ open FSharp.Compiler.CodeAnalysis
13
13
open FSharp.Compiler .Text .Range
14
14
open FsAutoComplete.Core .Workaround .ServiceParseTreeWalk
15
15
16
+ /// `traversePat`from `SyntaxTraversal.Traverse`
17
+ ///
18
+ /// Reason for extra function:
19
+ /// * can be used to traverse when traversal isn't available via `defaultTraverse` (for example: in `VisitExpr`, and want traverse a `SynPat`)
20
+ /// * visits `SynPat.Record(fieldPats)`
21
+ ///
22
+ /// Note: doesn't visit `SynPat.Typed(targetType)`: requires traversal into `SynType` (`SynPat.Typed(pat)` gets visited!)
23
+ let rec private traversePat ( visitor : SyntaxVisitorBase < _ >) origPath pat =
24
+ let defaultTraverse = defaultTraversePat visitor origPath
25
+ visitor.VisitPat( origPath, defaultTraverse, pat)
26
+ and private defaultTraversePat visitor origPath pat =
27
+ let path = SyntaxNode.SynPat pat :: origPath
28
+
29
+ match pat with
30
+ | SynPat.Paren ( p, _) -> traversePat visitor path p
31
+ | SynPat.As ( p1, p2, _)
32
+ | SynPat.Or ( p1, p2, _, _) ->
33
+ [ p1; p2 ]
34
+ |> List.tryPick ( traversePat visitor path)
35
+ | SynPat.Ands ( ps, _)
36
+ | SynPat.Tuple (_, ps, _)
37
+ | SynPat.ArrayOrList (_, ps, _) -> ps |> List.tryPick ( traversePat visitor path)
38
+ | SynPat.Attrib ( p, _, _) -> traversePat visitor path p
39
+ | SynPat.LongIdent ( argPats = args) ->
40
+ match args with
41
+ | SynArgPats.Pats ps -> ps |> List.tryPick ( traversePat visitor path)
42
+ | SynArgPats.NamePatPairs ( ps, _) ->
43
+ ps
44
+ |> List.map ( fun ( _ , _ , pat ) -> pat)
45
+ |> List.tryPick ( traversePat visitor path)
46
+ | SynPat.Typed ( p, _ ty, _) ->
47
+ traversePat visitor path p
48
+ // no access to `traverseSynType` -> no traversing into `ty`
49
+ | SynPat.Record ( fieldPats = fieldPats) ->
50
+ fieldPats
51
+ |> List.map ( fun ( _ , _ , pat ) -> pat)
52
+ |> List.tryPick ( traversePat visitor path)
53
+ | _ -> None
54
+
16
55
type HintKind =
17
56
| Parameter
18
57
| Type
@@ -79,10 +118,10 @@ type private FSharp.Compiler.CodeAnalysis.FSharpParseFileResults with
79
118
80
119
pats |> List.tryPick exprFunc
81
120
82
- override _ .VisitPat( _path , defaultTraverse , pat ) =
121
+ override visitor .VisitPat( path , defaultTraverse , pat ) =
83
122
match pat with
84
123
| SynPat.Typed (_ pat, _ targetType, range) when Position.posEq range.Start pos -> Some range
85
- | _ -> defaultTraverse pat
124
+ | _ -> defaultTraversePat visitor path pat
86
125
87
126
override _.VisitBinding ( _path , defaultTraverse , binding ) =
88
127
match binding with
@@ -550,45 +589,6 @@ let rec private getParensForIdentPat (text: NamedText) (pat: SynPat) (path: Synt
550
589
getParsenForPatternWithIdent patternRange identStart path
551
590
| _ -> failwith " Pattern must be Named or OptionalVal!"
552
591
553
- /// `traversePat`from `SyntaxTraversal.Traverse`
554
- ///
555
- /// Reason for extra function:
556
- /// * can be used to traverse when traversal isn't available via `defaultTraverse` (for example: in `VisitExpr`, and want traverse a `SynPat`)
557
- /// * visits `SynPat.As(lhsPat, rhsPat)` & `SynPat.Record(fieldPats)`
558
- ///
559
- /// Note: doesn't visit `SynPat.Typed(targetType)`: requires traversal into `SynType` (`SynPat.Typed(pat)` gets visited!)
560
- let rec private traversePat ( visitor : SyntaxVisitorBase < _ >) origPath pat =
561
- let defaultTraverse p =
562
- let path = SyntaxNode.SynPat p :: origPath
563
-
564
- match p with
565
- | SynPat.Paren ( p, _) -> traversePat visitor path p
566
- | SynPat.Or ( p1, p2, _, _) ->
567
- [ p1; p2 ]
568
- |> List.tryPick ( traversePat visitor path)
569
- | SynPat.Ands ( ps, _)
570
- | SynPat.Tuple (_, ps, _)
571
- | SynPat.ArrayOrList (_, ps, _) -> ps |> List.tryPick ( traversePat visitor path)
572
- | SynPat.Attrib ( p, _, _) -> traversePat visitor path p
573
- | SynPat.LongIdent ( argPats = args) ->
574
- match args with
575
- | SynArgPats.Pats ps -> ps |> List.tryPick ( traversePat visitor path)
576
- | SynArgPats.NamePatPairs ( ps, _) ->
577
- ps
578
- |> List.map ( fun ( _ , _ , pat ) -> pat)
579
- |> List.tryPick ( traversePat visitor path)
580
- | SynPat.Typed ( p, _, _) -> traversePat visitor path p
581
- | SynPat.As ( lhsPat = lhs; rhsPat = rhs) ->
582
- [ lhs; rhs ]
583
- |> List.tryPick ( traversePat visitor path)
584
- | SynPat.Record ( fieldPats = fieldPats) ->
585
- fieldPats
586
- |> List.map ( fun ( _ , _ , pat ) -> pat)
587
- |> List.tryPick ( traversePat visitor path)
588
- | _ -> None
589
-
590
- visitor.VisitPat( origPath, defaultTraverse, pat)
591
-
592
592
let tryGetExplicitTypeInfo ( text : NamedText , ast : ParsedInput ) ( pos : Position ) : ExplicitType option =
593
593
SyntaxTraversal.Traverse(
594
594
pos,
@@ -628,7 +628,7 @@ let tryGetExplicitTypeInfo (text: NamedText, ast: ParsedInput) (pos: Position) :
628
628
None
629
629
| _ -> defaultTraverse expr
630
630
631
- member _ . VisitPat( path, defaultTraverse, pat) =
631
+ member visitor .VisitPat( path, defaultTraverse, pat) =
632
632
let invalidPositionForTypeAnnotation ( pos : Position ) ( path : SyntaxNode list ) =
633
633
match path with
634
634
| SyntaxNode.SynExpr ( SynExpr.LetOrUseBang( isUse = true )) :: _ ->
@@ -684,7 +684,7 @@ let tryGetExplicitTypeInfo (text: NamedText, ast: ParsedInput) (pos: Position) :
684
684
// `?v: int`, NOT `?v: int option`
685
685
}
686
686
|> Some
687
- | _ -> defaultTraverse pat //todo: custom traverse? -> doesn't require FCS to handle `SynPat.Record`
687
+ | _ -> defaultTraversePat visitor path pat
688
688
689
689
member _. VisitSimplePats( path, pats) =
690
690
// SynSimplePats at:
0 commit comments