Skip to content

Commit a278964

Browse files
committed
[WIP] Migrate to core library (4)
1 parent 84932ea commit a278964

File tree

6 files changed

+545
-380
lines changed

6 files changed

+545
-380
lines changed

lib/DataTypes/Graph.fs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@ namespace DataTypes
33
type Graph<'node when 'node: comparison> = Map<'node, 'node list>
44

55
module Graph =
6+
let empty : Graph<_> = Map.empty
7+
8+
let add origin target (graph: Graph<_>) : Graph<_> =
9+
match graph |> Map.tryFind origin with
10+
| None -> graph |> Map.add origin [target]
11+
| Some targets -> graph |> Map.add origin (target :: targets |> List.distinct)
12+
13+
let addEdge (origin, target) (graph: Graph<_>) : Graph<_> = add origin target graph
14+
15+
let remove origin target (graph: Graph<_>) : Graph<_> =
16+
match graph |> Map.tryFind origin with
17+
| Some targets -> graph |> Map.add origin (targets |> List.except [target])
18+
| None -> graph
19+
20+
let removeEdge (origin, target) (graph: Graph<_>) : Graph<_> = remove origin target graph
21+
622
let rec private dfsImpl' g (used, ordRev) v =
723
let used = used |> Set.add v
824
let used, ordRev =
@@ -19,11 +35,13 @@ module Graph =
1935

2036
let ofEdges (edges: ('a * 'a) list) : Graph<_> =
2137
edges
38+
|> List.distinct
2239
|> List.groupBy fst
2340
|> List.fold (fun state (k, xs) -> state |> Map.add k (xs |> List.map snd)) Map.empty
2441

2542
let ofEdgesRev (edges: ('a * 'a) list) : Graph<_> =
2643
edges
44+
|> List.distinct
2745
|> List.groupBy snd
2846
|> List.fold (fun state (k, xs) -> state |> Map.add k (xs |> List.map fst)) Map.empty
2947

lib/Parser.fs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,53 @@ let private getAllLocalReferences (ctx: #IContext<#IOptions>) (sourceFiles: Ts.S
10371037

10381038
sourceFilesMap.Values |> Seq.toArray |> Array.map (fun v -> v.fileName, v) |> Array.unzip
10391039

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+
10401087
let createContextFromFiles (ctx: #IContext<#IOptions>) compilerOptions (fileNames: string[]) : ParserContext =
10411088
let fileNames, program =
10421089
let fileNames =
@@ -1108,4 +1155,13 @@ let parse (ctx: ParserContext) : Input =
11081155
| example :: _ -> JsHelper.getPackageInfo example.fileName
11091156
| [] -> None
11101157

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 }

lib/Syntax.fs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,16 @@ and Module = {
488488
member this.getComments() = this.comments
489489
member this.mapComments f = { this with comments = f this.comments }
490490

491+
and Export = {
492+
comments: Comment list
493+
clauses: ExportClause list
494+
loc: Location
495+
origText: string
496+
} with
497+
interface ICommented<Export> with
498+
member this.getComments() = this.comments
499+
member this.mapComments f = { this with comments = f this.comments }
500+
491501
and ExportClause =
492502
/// ```ts
493503
/// export = ident;
@@ -553,16 +563,6 @@ and ExportClause =
553563
/// ```
554564
| NamespaceExport of ns:string
555565

556-
and Export = {
557-
comments: Comment list
558-
clauses: ExportClause list
559-
loc: Location
560-
origText: string
561-
} with
562-
interface ICommented<Export> with
563-
member this.getComments() = this.comments
564-
member this.mapComments f = { this with comments = f this.comments }
565-
566566
and [<RequireQualifiedAccess>] Exported =
567567
| No
568568
/// ```ts
@@ -688,6 +688,12 @@ type PackageInfo = {
688688
type Input = {
689689
sources: SourceFile list
690690
info: PackageInfo option
691+
/// a list of groups of filenames.
692+
///
693+
/// if a group has more than one filenames, the files are mutually-referencing.
694+
///
695+
/// the files in later groups reference the files in former groups.
696+
dependencyGraph: Path.Absolute list list
691697
}
692698

693699
module Literal =

0 commit comments

Comments
 (0)