@@ -7,7 +7,15 @@ open FSharp.Compiler.SyntaxTrivia
77open NUnit.Framework
88
99let unsupported = " unsupported"
10- type Stuff = SynLongIdent seq
10+ type Kind =
11+ | Type
12+ | ModuleOrNamespace
13+ type Item =
14+ {
15+ Ident : LongIdent
16+ Kind : Kind
17+ }
18+ type Stuff = Item seq
1119
1220let rec visitSynModuleDecl ( decl : SynModuleDecl ) : Stuff =
1321 // TODO
@@ -27,7 +35,15 @@ let rec visitSynModuleDecl (decl : SynModuleDecl) : Stuff =
2735 | SynModuleDecl.Types( synTypeDefns, range) ->
2836 visitSynTypeDefns synTypeDefns
2937 | SynModuleDecl.ModuleAbbrev( ident, longId, range) ->
30- visitLongIdent longId
38+ // TODO Module abbrevation can break the algorithm.
39+ // We need to either give up when seeing this or handle it properly.
40+ //
41+ // Consider the following:
42+ // module A = module A1 = let x = 1
43+ // module B = A
44+ // let x = B.A1.x
45+ failwith " Module abbreviations are not currently supported"
46+ //visitLongIdent longId
3147 | SynModuleDecl.NamespaceFragment synModuleOrNamespace ->
3248 visitSynModuleOrNamespace synModuleOrNamespace
3349 | SynModuleDecl.NestedModule( synComponentInfo, isRecursive, synModuleDecls, isContinuing, range, synModuleDeclNestedModuleTrivia) ->
@@ -651,23 +667,25 @@ and visitSynOpenDeclTarget (target : SynOpenDeclTarget) : Stuff =
651667 visitType typeName
652668 | SynOpenDeclTarget.ModuleOrNamespace( synLongIdent, range) ->
653669 visitSynLongIdent synLongIdent
670+ |> Seq.map ( fun s -> { s with Kind = Kind.ModuleOrNamespace})
654671
655672and visitSynComponentInfo ( info : SynComponentInfo ) : Stuff =
656673 match info with
657674 | SynComponentInfo( synAttributeLists, synTyparDeclsOption, synTypeConstraints, longId, preXmlDoc, preferPostfix, synAccessOption, range) ->
658675 seq {
659676 yield ! visitSynAttributeLists synAttributeLists
660677 match synTyparDeclsOption with | Some decls -> yield ! visitSynTyparDecls decls | None -> ()
661- yield ! visitLongIdent longId
678+ // Don't include this as it's a module definition rather than reference
679+ // yield! visitLongIdent longId
662680 yield ! visitPreXmlDoc preXmlDoc
663681 match synAccessOption with | Some access -> yield ! visitSynAccess access | None -> ()
664682 }
665683
666684and visitLongIdent ( ident : LongIdent ) : Stuff =
667- [] // TODO Check - probably wrong. LongIdents *might* be used for the same purpose as SynLongIdent
685+ [{ Ident = ident ; Kind = Kind.Type }]
668686
669687and visitSynLongIdent ( ident : SynLongIdent ) : Stuff =
670- [ ident]
688+ [{ Ident = ident.LongIdent ; Kind = Kind.Type } ]
671689
672690and visitSynMatchClause ( x : SynMatchClause ) : Stuff =
673691 match x with
@@ -727,7 +745,7 @@ and visitSynMemberSig (x : SynMemberSig) : Stuff =
727745 visitSynField synField
728746
729747and visitExpr ( expr : SynExpr ) =
730- let l = System.Collections.Generic.List< SynLongIdent >()
748+ let l = System.Collections.Generic.List< Item >()
731749 let go ( items : Stuff ) =
732750 l.AddRange( items)
733751
@@ -995,17 +1013,30 @@ and visitSynModuleOrNamespace (x : SynModuleOrNamespace) : Stuff =
9951013 match x with
9961014 | SynModuleOrNamespace.SynModuleOrNamespace( longId, isRecursive, synModuleOrNamespaceKind, synModuleDecls, preXmlDoc, synAttributeLists, synAccessOption, range, synModuleOrNamespaceTrivia) ->
9971015 seq {
1016+ // Don't include 'longId' as that's module definition rather than reference
9981017 yield ! synModuleDecls |> Seq.collect visitSynModuleDecl
9991018 yield ! visitSynAttributeLists synAttributeLists
10001019 }
10011020
10021021and visit ( input : ParsedInput ) : Stuff =
10031022 match input with
1004- | ParsedInput.SigFile _ -> failwith unsupported
1023+ | ParsedInput.SigFile _ -> failwith " Signature files are not currently supported "
10051024 | ParsedInput.ImplFile( ParsedImplFileInput( fileName, isScript, qualifiedNameOfFile, scopedPragmas, parsedHashDirectives, synModuleOrNamespaces, flags, parsedImplFileInputTrivia)) ->
10061025 synModuleOrNamespaces
10071026 |> Seq.collect visitSynModuleOrNamespace
10081027
1028+ let topModuleOrNamespace ( input : ParsedInput ) =
1029+ match input with
1030+ | ParsedInput.ImplFile f ->
1031+ match f.Contents with
1032+ | [] -> failwith " No modules or namespaces"
1033+ | first :: rest ->
1034+ match first with
1035+ | SynModuleOrNamespace( longId, isRecursive, synModuleOrNamespaceKind, synModuleDecls, preXmlDoc, synAttributeLists, synAccessOption, range, synModuleOrNamespaceTrivia) ->
1036+ longId
1037+ | ParsedInput.SigFile _ ->
1038+ failwith " Sig files not supported atm"
1039+
10091040[<Test>]
10101041let ``Single SynEnumCase contains range of constant`` () =
10111042 let parseResults =
@@ -1048,15 +1079,39 @@ open A4
10481079let e = A1.a
10491080open A1
10501081let f = a
1051-
1052- module X = B
10531082"""
10541083
1055- printfn $" %+A {parseResults}"
10561084 let stuff = visit parseResults
1085+ let top = topModuleOrNamespace parseResults
1086+ printfn $" %+A {top}"
10571087 printfn $" %+A {stuff}"
10581088 ()
10591089
1090+ let depends ()
1091+
1092+ [<Test>]
1093+ let ``Test two`` () =
1094+
1095+ let A =
1096+ """
1097+ module A
1098+ open B
1099+ let x = B.x
1100+ """
1101+ let B =
1102+ """
1103+ module B
1104+ let x = 3
1105+ """
1106+
1107+ let parsedA = getParseResults A
1108+ let visitedA = visit parsedA
1109+ let parsedB = getParseResults B
1110+ let topB = topModuleOrNamespace parsedB
1111+ printfn $" Top B: %+A {topB}"
1112+ printfn $" A refs: %+A {visitedA}"
1113+ ()
1114+
10601115module A1 = let a = 3
10611116module A2 = let a = 3
10621117module A3 = let a = 3
0 commit comments