Skip to content

Commit 41b6ed7

Browse files
authored
Add VisitValSig to SyntaxVisitorBase. (#15930)
* Add VisitValSig to SyntaxVisitorBase.
1 parent 4185ee3 commit 41b6ed7

File tree

5 files changed

+327
-1
lines changed

5 files changed

+327
-1
lines changed

src/Compiler/Service/ServiceParseTreeWalk.fs

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ type SyntaxNode =
2525
| SynMemberDefn of SynMemberDefn
2626
| SynMatchClause of SynMatchClause
2727
| SynBinding of SynBinding
28+
| SynModuleOrNamespaceSig of SynModuleOrNamespaceSig
29+
| SynModuleSigDecl of SynModuleSigDecl
30+
| SynValSig of SynValSig
31+
| SynTypeDefnSig of SynTypeDefnSig
32+
| SynMemberSig of SynMemberSig
2833

2934
type SyntaxVisitorPath = SyntaxNode list
3035

@@ -184,6 +189,28 @@ type SyntaxVisitorBase<'T>() =
184189
ignore (path, attributes)
185190
None
186191

192+
/// VisitModuleOrNamespaceSig allows overriding behavior when visiting module or namespaces
193+
abstract VisitModuleOrNamespaceSig: path: SyntaxVisitorPath * synModuleOrNamespaceSig: SynModuleOrNamespaceSig -> 'T option
194+
195+
default _.VisitModuleOrNamespaceSig(path, synModuleOrNamespaceSig) =
196+
ignore (path, synModuleOrNamespaceSig)
197+
None
198+
199+
/// VisitModuleDecl allows overriding signature module declaration behavior
200+
abstract VisitModuleSigDecl:
201+
path: SyntaxVisitorPath * defaultTraverse: (SynModuleSigDecl -> 'T option) * synModuleSigDecl: SynModuleSigDecl -> 'T option
202+
203+
default _.VisitModuleSigDecl(path, defaultTraverse, synModuleSigDecl) =
204+
ignore path
205+
defaultTraverse synModuleSigDecl
206+
207+
/// VisitValSig allows overriding SynValSig behavior
208+
abstract VisitValSig: path: SyntaxVisitorPath * defaultTraverse: (SynValSig -> 'T option) * valSig: SynValSig -> 'T option
209+
210+
default _.VisitValSig(path, defaultTraverse, valSig) =
211+
ignore path
212+
defaultTraverse valSig
213+
187214
/// A range of utility functions to assist with traversing an AST
188215
module SyntaxTraversal =
189216
// treat ranges as though they are half-open: [,)
@@ -926,6 +953,101 @@ module SyntaxTraversal =
926953
attributes
927954
|> List.map (fun attributes -> dive () attributes.Range (fun () -> visitor.VisitAttributeApplication(origPath, attributes)))
928955

956+
and traverseSynModuleOrNamespaceSig origPath (SynModuleOrNamespaceSig (decls = synModuleSigDecls; range = range) as mors) =
957+
match visitor.VisitModuleOrNamespaceSig(origPath, mors) with
958+
| Some x -> Some x
959+
| None ->
960+
let path = SyntaxNode.SynModuleOrNamespaceSig mors :: origPath
961+
962+
synModuleSigDecls
963+
|> List.map (fun x -> dive x x.Range (traverseSynModuleSigDecl path))
964+
|> pick range mors
965+
966+
and traverseSynModuleSigDecl origPath (decl: SynModuleSigDecl) =
967+
let pick = pick decl.Range
968+
969+
let defaultTraverse m =
970+
let path = SyntaxNode.SynModuleSigDecl m :: origPath
971+
972+
match m with
973+
| SynModuleSigDecl.ModuleAbbrev (_ident, _longIdent, _range) -> None
974+
| SynModuleSigDecl.NestedModule (moduleDecls = synModuleDecls; moduleInfo = SynComponentInfo (attributes = attributes)) ->
975+
synModuleDecls
976+
|> List.map (fun x -> dive x x.Range (traverseSynModuleSigDecl path))
977+
|> List.append (attributeApplicationDives path attributes)
978+
|> pick decl
979+
| SynModuleSigDecl.Val (synValSig, range) -> [ dive synValSig range (traverseSynValSig path) ] |> pick decl
980+
| SynModuleSigDecl.Types (types = types; range = range) ->
981+
types
982+
|> List.map (fun t -> dive t range (traverseSynTypeDefnSig path))
983+
|> pick decl
984+
| SynModuleSigDecl.Exception (_synExceptionDefn, _range) -> None
985+
| SynModuleSigDecl.Open (_target, _range) -> None
986+
| SynModuleSigDecl.HashDirective (parsedHashDirective, range) ->
987+
visitor.VisitHashDirective(path, parsedHashDirective, range)
988+
| SynModuleSigDecl.NamespaceFragment synModuleOrNamespaceSig -> traverseSynModuleOrNamespaceSig path synModuleOrNamespaceSig
989+
990+
visitor.VisitModuleSigDecl(origPath, defaultTraverse, decl)
991+
992+
and traverseSynValSig origPath (valSig: SynValSig) =
993+
let defaultTraverse (SynValSig (synType = t; attributes = attributes; synExpr = expr; range = m)) =
994+
let path = SyntaxNode.SynValSig valSig :: origPath
995+
996+
[
997+
yield! attributeApplicationDives path attributes
998+
yield dive t t.Range (traverseSynType path)
999+
match expr with
1000+
| Some expr -> yield dive expr expr.Range (traverseSynExpr path)
1001+
| None -> ()
1002+
]
1003+
|> pick m valSig
1004+
1005+
visitor.VisitValSig(origPath, defaultTraverse, valSig)
1006+
1007+
and traverseSynTypeDefnSig origPath (SynTypeDefnSig (synComponentInfo, typeRepr, members, tRange, _) as tydef) =
1008+
let path = SyntaxNode.SynTypeDefnSig tydef :: origPath
1009+
1010+
match visitor.VisitComponentInfo(origPath, synComponentInfo) with
1011+
| Some x -> Some x
1012+
| None ->
1013+
match synComponentInfo with
1014+
| SynComponentInfo (attributes = attributes) ->
1015+
[
1016+
yield! attributeApplicationDives path attributes
1017+
1018+
match typeRepr with
1019+
| SynTypeDefnSigRepr.Exception _ ->
1020+
// This node is generated in CheckExpressions.fs, not in the AST.
1021+
// But note exception declarations are missing from this tree walk.
1022+
()
1023+
| SynTypeDefnSigRepr.ObjectModel (memberSigs = memberSigs) ->
1024+
yield! memberSigs |> List.map (fun ms -> dive ms ms.Range (traverseSynMemberSig path))
1025+
| SynTypeDefnSigRepr.Simple (synTypeDefnSimpleRepr, _range) ->
1026+
match synTypeDefnSimpleRepr with
1027+
| SynTypeDefnSimpleRepr.Record (_synAccessOption, fields, m) ->
1028+
yield dive () typeRepr.Range (fun () -> traverseRecordDefn path fields m)
1029+
| SynTypeDefnSimpleRepr.Union (_synAccessOption, cases, m) ->
1030+
yield dive () typeRepr.Range (fun () -> traverseUnionDefn path cases m)
1031+
| SynTypeDefnSimpleRepr.Enum (cases, m) ->
1032+
yield dive () typeRepr.Range (fun () -> traverseEnumDefn path cases m)
1033+
| SynTypeDefnSimpleRepr.TypeAbbrev (_, synType, m) ->
1034+
yield dive typeRepr typeRepr.Range (fun _ -> visitor.VisitTypeAbbrev(path, synType, m))
1035+
| _ -> ()
1036+
yield! members |> List.map (fun ms -> dive ms ms.Range (traverseSynMemberSig path))
1037+
]
1038+
|> pick tRange tydef
1039+
1040+
and traverseSynMemberSig path (m: SynMemberSig) =
1041+
let path = SyntaxNode.SynMemberSig m :: path
1042+
1043+
match m with
1044+
| SynMemberSig.Member (memberSig = memberSig) -> traverseSynValSig path memberSig
1045+
| SynMemberSig.Interface (interfaceType = synType) -> traverseSynType path synType
1046+
| SynMemberSig.Inherit (inheritedType = synType) -> traverseSynType path synType
1047+
| SynMemberSig.ValField(field = SynField (attributes = attributes)) ->
1048+
attributeApplicationDives path attributes |> pick m.Range attributes
1049+
| SynMemberSig.NestedType (nestedType = nestedType) -> traverseSynTypeDefnSig path nestedType
1050+
9291051
match parseTree with
9301052
| ParsedInput.ImplFile file ->
9311053
let l = file.Contents
@@ -941,4 +1063,17 @@ module SyntaxTraversal =
9411063
l
9421064
|> List.map (fun x -> dive x x.Range (traverseSynModuleOrNamespace []))
9431065
|> pick fileRange l
944-
| ParsedInput.SigFile _sigFile -> None
1066+
| ParsedInput.SigFile sigFile ->
1067+
let l = sigFile.Contents
1068+
1069+
let fileRange =
1070+
#if DEBUG
1071+
match l with
1072+
| [] -> range0
1073+
| _ -> l |> List.map (fun x -> x.Range) |> List.reduce unionRanges
1074+
#else
1075+
range0 // only used for asserting, does not matter in non-debug
1076+
#endif
1077+
l
1078+
|> List.map (fun x -> dive x x.Range (traverseSynModuleOrNamespaceSig []))
1079+
|> pick fileRange l

src/Compiler/Service/ServiceParseTreeWalk.fsi

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ type SyntaxNode =
1717
| SynMemberDefn of SynMemberDefn
1818
| SynMatchClause of SynMatchClause
1919
| SynBinding of SynBinding
20+
| SynModuleOrNamespaceSig of SynModuleOrNamespaceSig
21+
| SynModuleSigDecl of SynModuleSigDecl
22+
| SynValSig of SynValSig
23+
| SynTypeDefnSig of SynTypeDefnSig
24+
| SynMemberSig of SynMemberSig
2025

2126
type SyntaxVisitorPath = SyntaxNode list
2227

@@ -151,6 +156,24 @@ type SyntaxVisitorBase<'T> =
151156
abstract VisitAttributeApplication: path: SyntaxVisitorPath * attributes: SynAttributeList -> 'T option
152157
default VisitAttributeApplication: path: SyntaxVisitorPath * attributes: SynAttributeList -> 'T option
153158

159+
abstract VisitModuleOrNamespaceSig:
160+
path: SyntaxVisitorPath * synModuleOrNamespaceSig: SynModuleOrNamespaceSig -> 'T option
161+
default VisitModuleOrNamespaceSig:
162+
path: SyntaxVisitorPath * synModuleOrNamespaceSig: SynModuleOrNamespaceSig -> 'T option
163+
164+
abstract VisitModuleSigDecl:
165+
path: SyntaxVisitorPath * defaultTraverse: (SynModuleSigDecl -> 'T option) * synModuleSigDecl: SynModuleSigDecl ->
166+
'T option
167+
default VisitModuleSigDecl:
168+
path: SyntaxVisitorPath * defaultTraverse: (SynModuleSigDecl -> 'T option) * synModuleSigDecl: SynModuleSigDecl ->
169+
'T option
170+
171+
abstract VisitValSig:
172+
path: SyntaxVisitorPath * defaultTraverse: (SynValSig -> 'T option) * valSig: SynValSig -> 'T option
173+
174+
default VisitValSig:
175+
path: SyntaxVisitorPath * defaultTraverse: (SynValSig -> 'T option) * valSig: SynValSig -> 'T option
176+
154177
module public SyntaxTraversal =
155178

156179
val internal rangeContainsPosLeftEdgeInclusive: m1: range -> p: pos -> bool

0 commit comments

Comments
 (0)