@@ -1037,6 +1037,53 @@ let private getAllLocalReferences (ctx: #IContext<#IOptions>) (sourceFiles: Ts.S
1037
1037
1038
1038
sourceFilesMap.Values |> Seq.toArray |> Array.map ( fun v -> v.fileName, v) |> Array.unzip
1039
1039
1040
+ open DataTypes
1041
+
1042
+ let createDependencyGraph ( sourceFiles : Ts.SourceFile seq ) =
1043
+ let sourceFiles = Array.ofSeq sourceFiles
1044
+ let files = sourceFiles |> Array.map ( fun sf -> sf.fileName, sf) |> Map.ofArray
1045
+ let mutable graph = Graph.empty
1046
+
1047
+ let tryFindDefinitionFile ( sourceFile : Ts.SourceFile ) relativePath =
1048
+ let tryGet name =
1049
+ files |> Map.tryFind ( Path.join [ Path.dirname sourceFile.fileName; name])
1050
+ tryGet $" {relativePath}.d.ts"
1051
+ |> Option.orElseWith ( fun () -> tryGet ( Path.join [ relativePath; " index.d.ts" ]))
1052
+
1053
+ let handleModuleSpecifier ( sourceFile : Ts.SourceFile ) ( e : Ts.Expression ) =
1054
+ if e.kind = Ts.SyntaxKind.StringLiteral then
1055
+ let specifier = (!! e : Ts.StringLiteral) .text
1056
+ if specifier.StartsWith( " ." ) then
1057
+ tryFindDefinitionFile sourceFile specifier
1058
+ |> Option.map ( fun target ->
1059
+ graph <- graph |> Graph.add sourceFile.fileName target.fileName
1060
+ target)
1061
+ else None
1062
+ else None
1063
+
1064
+ let rec go ( sourceFile : Ts.SourceFile ) ( n : Ts.Node ) : unit option =
1065
+ match n.kind with
1066
+ | Ts.SyntaxKind.ImportEqualsDeclaration ->
1067
+ let n = n :?> Ts.ImportEqualsDeclaration
1068
+ if (!! n.moduleReference : Ts.Node) .kind = Ts.SyntaxKind.ExternalModuleReference then
1069
+ (!! n.moduleReference : Ts.ExternalModuleReference) .expression
1070
+ |> handleModuleSpecifier sourceFile
1071
+ |> Option.iter goSourceFile
1072
+ | Ts.SyntaxKind.ImportDeclaration ->
1073
+ let n = n :?> Ts.ImportDeclaration
1074
+ n.moduleSpecifier
1075
+ |> handleModuleSpecifier sourceFile
1076
+ |> Option.iter goSourceFile
1077
+ | _ -> ()
1078
+ n.forEachChild( go sourceFile)
1079
+
1080
+ and goSourceFile ( sourceFile : Ts.SourceFile ) =
1081
+ for statement in sourceFile.statements do
1082
+ go sourceFile statement |> ignore
1083
+
1084
+ for sourceFile in sourceFiles do goSourceFile sourceFile
1085
+ graph
1086
+
1040
1087
let createContextFromFiles ( ctx : #IContext< #IOptions> ) compilerOptions ( fileNames : string []) : ParserContext =
1041
1088
let fileNames , program =
1042
1089
let fileNames =
@@ -1108,4 +1155,13 @@ let parse (ctx: ParserContext) : Input =
1108
1155
| example :: _ -> JsHelper.getPackageInfo example.fileName
1109
1156
| [] -> None
1110
1157
1111
- { sources = sources; info = info }
1158
+ let dependencyGraph =
1159
+ let g = createDependencyGraph srcs
1160
+ Graph.stronglyConnectedComponents g ( List.ofArray ctx.fileNames)
1161
+
1162
+ for group in dependencyGraph do
1163
+ match group with
1164
+ | [] | [_] -> ()
1165
+ | _ -> ctx.logger.warnf " there are mutually-referencing source files: %s " ( group |> String.concat " , " )
1166
+
1167
+ { sources = sources; info = info; dependencyGraph = dependencyGraph }
0 commit comments