Skip to content

Commit a21d5ee

Browse files
committed
Support .fsi files (for now without the knowledge of the fs-fsi relationships)
1 parent 7ce5d00 commit a21d5ee

2 files changed

Lines changed: 81 additions & 7 deletions

File tree

tests/FSharp.Compiler.Service.Tests2/DepResolving.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,13 @@ let detectFileDependencies (nodes : FileAST[]) : Graph =
239239
[<Test>]
240240
let TestDepsResolver() =
241241

242+
let A_fsi =
243+
"""
244+
module A
245+
val a : int
246+
type X = int
247+
"""
248+
242249
let A =
243250
"""
244251
module A
@@ -285,6 +292,7 @@ type B = int
285292
"""
286293

287294
let files = [
295+
"A.fsi", A_fsi
288296
"A.fs", A
289297
"B.fs", B
290298
"C.fs", C

tests/FSharp.Compiler.Service.Tests2/TypeTests.fs

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ let rec visitSynModuleDecl (decl : SynModuleDecl) : Stuff =
4343
// module B = A
4444
// let x = B.A1.x
4545
failwith "Module abbreviations are not currently supported"
46-
//visitLongIdent longId
4746
| SynModuleDecl.NamespaceFragment synModuleOrNamespace ->
4847
visitSynModuleOrNamespace synModuleOrNamespace
4948
| SynModuleDecl.NestedModule(synComponentInfo, isRecursive, synModuleDecls, isContinuing, range, synModuleDeclNestedModuleTrivia) ->
@@ -1025,10 +1024,67 @@ and visitSynModuleOrNamespace (x : SynModuleOrNamespace) : Stuff =
10251024
yield! synModuleDecls |> Seq.collect visitSynModuleDecl
10261025
yield! visitSynAttributeLists synAttributeLists
10271026
}
1027+
1028+
// Sigs
1029+
1030+
and visitSynMemberSigs = visitMulti visitSynMemberSig
1031+
1032+
and visitSynExceptionSig (x : SynExceptionSig) : Stuff =
1033+
match x with
1034+
| SynExceptionSig(synExceptionDefnRepr, withKeyword, synMemberSigs, range) ->
1035+
seq {
1036+
yield! visitSynExceptionDefnRepr synExceptionDefnRepr
1037+
yield! visitSynMemberSigs synMemberSigs
1038+
}
1039+
1040+
and visitSynTypeDefnSigs = visitMulti visitSynTypeDefnSign
1041+
1042+
and visitSynModuleSigDecl (x : SynModuleSigDecl) : Stuff =
1043+
match x with
1044+
| SynModuleSigDecl.Exception(synExceptionSig, range) ->
1045+
visitSynExceptionSig synExceptionSig
1046+
| SynModuleSigDecl.Open(synOpenDeclTarget, range) ->
1047+
visitSynOpenDeclTarget synOpenDeclTarget
1048+
| SynModuleSigDecl.Types(synTypeDefnSigs, range) ->
1049+
visitSynTypeDefnSigs synTypeDefnSigs
1050+
| SynModuleSigDecl.Val(synValSig, range) ->
1051+
visitSynValSig synValSig
1052+
| SynModuleSigDecl.HashDirective(parsedHashDirective, range) ->
1053+
[]
1054+
| SynModuleSigDecl.ModuleAbbrev(ident, longId, range) ->
1055+
// TODO Module abbrevation can break the algorithm.
1056+
// We need to either give up when seeing this or handle it properly.
1057+
//
1058+
// Consider the following:
1059+
// module A = module A1 = let x = 1
1060+
// module B = A
1061+
// let x = B.A1.x
1062+
failwith "Module abbreviations are not currently supported"
1063+
| SynModuleSigDecl.NamespaceFragment synModuleOrNamespaceSig ->
1064+
visitSynModuleOrNamespaceSig synModuleOrNamespaceSig
1065+
| SynModuleSigDecl.NestedModule(synComponentInfo, isRecursive, synModuleSigDecls, range, synModuleSigDeclNestedModuleTrivia) ->
1066+
seq {
1067+
yield! visitSynComponentInfo synComponentInfo
1068+
yield! visitSynModuleSigDecls synModuleSigDecls
1069+
}
1070+
1071+
and visitSynModuleSigDecls = visitMulti visitSynModuleSigDecl
1072+
1073+
and visitSynModuleOrNamespaceSig (x : SynModuleOrNamespaceSig) : Stuff =
1074+
match x with
1075+
| SynModuleOrNamespaceSig.SynModuleOrNamespaceSig(longId, isRecursive, synModuleOrNamespaceKind, synModuleDecls, preXmlDoc, synAttributeLists, synAccessOption, range, synModuleOrNamespaceTrivia) ->
1076+
seq {
1077+
// Don't include 'longId' as that's module definition rather than reference
1078+
yield! synModuleDecls |> Seq.collect visitSynModuleSigDecl
1079+
yield! visitSynAttributeLists synAttributeLists
1080+
}
10281081

10291082
and visit (input : ParsedInput) =
10301083
match input with
1031-
| ParsedInput.SigFile _ -> failwith "Signature files are not currently supported"
1084+
| ParsedInput.SigFile(ParsedSigFileInput(fileName, qualifiedNameOfFile, scopedPragmas, parsedHashDirectives, synModuleOrNamespaceSigs, parsedSigFileInputTrivia)) ->
1085+
synModuleOrNamespaceSigs
1086+
|> Seq.collect visitSynModuleOrNamespaceSig
1087+
|> Seq.toArray
10321088
| ParsedInput.ImplFile(ParsedImplFileInput(fileName, isScript, qualifiedNameOfFile, scopedPragmas, parsedHashDirectives, synModuleOrNamespaces, flags, parsedImplFileInputTrivia)) ->
10331089
synModuleOrNamespaces
10341090
|> Seq.collect visitSynModuleOrNamespace
@@ -1058,8 +1114,18 @@ let topModuleOrNamespace (input : ParsedInput) =
10581114
LongIdent.Empty
10591115
else
10601116
longId
1061-
| ParsedInput.SigFile _ ->
1062-
failwith "Sig files not supported atm"
1117+
| ParsedInput.SigFile f ->
1118+
match f.Contents with
1119+
| [] -> failwith "No modules or namespaces"
1120+
| first :: rest ->
1121+
match first with
1122+
| SynModuleOrNamespaceSig(longId, isRecursive, synModuleOrNamespaceKind, synModuleDecls, preXmlDoc, synAttributeLists, synAccessOption, range, synModuleOrNamespaceTrivia) ->
1123+
if mightHaveAutoOpen synAttributeLists then
1124+
// Contents of a module that's potentially AutoOpen are available everywhere, so treat it as if it had no name ('root' module).
1125+
// This makes the dependency tracking algorithm detect it as a dependency for all further files.
1126+
LongIdent.Empty
1127+
else
1128+
longId
10631129

10641130
[<Test>]
10651131
let ``Single SynEnumCase contains range of constant`` () =
@@ -1126,10 +1192,10 @@ module B
11261192
let x = 3
11271193
"""
11281194

1129-
let parsedA = getParseResults A
1195+
let parsedA = parseSourceCode("A.fs", A)
11301196
let visitedA = visit parsedA
1131-
let parsedB = getParseResults B
1132-
let topB = topModuleOrNamespace parsedB
1197+
let parsedB = parseSourceCode("B.fs", B)
1198+
let topB = topModuleOrNamespace parsedB
11331199
printfn $"Top B: %+A{topB}"
11341200
printfn $"A refs: %+A{visitedA}"
11351201
()

0 commit comments

Comments
 (0)