@@ -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
2934type 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
188215module 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
0 commit comments