@@ -13,6 +13,45 @@ open FSharp.Compiler.CodeAnalysis
1313open FSharp.Compiler .Text .Range
1414open FsAutoComplete.Core .Workaround .ServiceParseTreeWalk
1515
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+
1655type HintKind =
1756 | Parameter
1857 | Type
@@ -79,10 +118,10 @@ type private FSharp.Compiler.CodeAnalysis.FSharpParseFileResults with
79118
80119 pats |> List.tryPick exprFunc
81120
82- override _ .VisitPat( _path , defaultTraverse , pat ) =
121+ override visitor .VisitPat( path , defaultTraverse , pat ) =
83122 match pat with
84123 | SynPat.Typed (_ pat, _ targetType, range) when Position.posEq range.Start pos -> Some range
85- | _ -> defaultTraverse pat
124+ | _ -> defaultTraversePat visitor path pat
86125
87126 override _.VisitBinding ( _path , defaultTraverse , binding ) =
88127 match binding with
@@ -550,45 +589,6 @@ let rec private getParensForIdentPat (text: NamedText) (pat: SynPat) (path: Synt
550589 getParsenForPatternWithIdent patternRange identStart path
551590 | _ -> failwith " Pattern must be Named or OptionalVal!"
552591
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-
592592let tryGetExplicitTypeInfo ( text : NamedText , ast : ParsedInput ) ( pos : Position ) : ExplicitType option =
593593 SyntaxTraversal.Traverse(
594594 pos,
@@ -628,7 +628,7 @@ let tryGetExplicitTypeInfo (text: NamedText, ast: ParsedInput) (pos: Position) :
628628 None
629629 | _ -> defaultTraverse expr
630630
631- member _ . VisitPat( path, defaultTraverse, pat) =
631+ member visitor .VisitPat( path, defaultTraverse, pat) =
632632 let invalidPositionForTypeAnnotation ( pos : Position ) ( path : SyntaxNode list ) =
633633 match path with
634634 | SyntaxNode.SynExpr ( SynExpr.LetOrUseBang( isUse = true )) :: _ ->
@@ -684,7 +684,7 @@ let tryGetExplicitTypeInfo (text: NamedText, ast: ParsedInput) (pos: Position) :
684684 // `?v: int`, NOT `?v: int option`
685685 }
686686 |> Some
687- | _ -> defaultTraverse pat //todo: custom traverse? -> doesn't require FCS to handle `SynPat.Record`
687+ | _ -> defaultTraversePat visitor path pat
688688
689689 member _. VisitSimplePats( path, pats) =
690690 // SynSimplePats at:
0 commit comments