Skip to content

Commit 08bfc89

Browse files
committed
ServiceParseTreeWalk is now required solely for SynMatchClauses
-> should be easier to adopt new version once available
1 parent 2024435 commit 08bfc89

File tree

3 files changed

+1016
-1004
lines changed

3 files changed

+1016
-1004
lines changed

src/FsAutoComplete.Core/InlayHints.fs

+43-43
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,45 @@ open FSharp.Compiler.CodeAnalysis
1313
open FSharp.Compiler.Text.Range
1414
open 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+
1655
type 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-
592592
let 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

Comments
 (0)