Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experimental] [WIP] Transparent Compiler #15179

Merged
merged 326 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
326 commits
Select commit Hold shift + click to select a range
df659bf
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 7, 2023
9d46422
fix cache agent loop
0101 Jun 8, 2023
c934399
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 8, 2023
46973be
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 9, 2023
8dc87ee
Merge branch 'main' into experiments
0101 Jun 9, 2023
d6b2444
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 9, 2023
302c8cc
wip
0101 Jun 12, 2023
31206be
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 12, 2023
41ce83f
ParseAndCheckProject
0101 Jun 12, 2023
b0507df
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 12, 2023
fa99d61
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 14, 2023
a7e1e96
Fix dependency manager
0101 Jun 14, 2023
0f22216
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 15, 2023
f16c9f0
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 16, 2023
6f703c8
Giraffe benchmark
0101 Jun 16, 2023
23cda12
Merge branch 'main' into experiments
0101 Jun 16, 2023
585e6bd
Merge branch 'experiments' of github.com:0101/fsharp into experiments
0101 Jun 19, 2023
78a91dc
Merge branch 'main' into experiments
0101 Jun 20, 2023
1bcd323
Merge branch 'experiments' of github.com:0101/fsharp into experiments
0101 Jun 20, 2023
4964043
wip
0101 Jun 20, 2023
3a3e91d
f
0101 Jun 20, 2023
037e053
f
0101 Jun 20, 2023
eba5dde
wip
0101 Jun 20, 2023
ec9b025
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 20, 2023
dea9f0e
CancellableTask updates
0101 Jun 20, 2023
63c83cd
wip
0101 Jun 21, 2023
8f7e306
wip
0101 Jun 21, 2023
b35e9ec
test
0101 Jun 21, 2023
695be31
Merge branch 'main' into experiments
0101 Jun 21, 2023
d7d9a76
test
0101 Jun 21, 2023
f036b81
Merge branch 'main' into experiments
0101 Jun 22, 2023
5a7b68f
wip
0101 Jun 22, 2023
e7f9930
WIP
nojaf Jun 23, 2023
f0cc8ea
reuse TcIntermediate for ParseAndCheckFile
0101 Jun 23, 2023
1d8aa13
Sort resultsToAdd when folding the firstState.
nojaf Jun 26, 2023
0203625
Undo temporary changes.
nojaf Jun 26, 2023
12fdbdd
Use NodeToTypeCheck instead of idx.
nojaf Jun 26, 2023
8616d7f
Undo spaces
nojaf Jun 26, 2023
dbc0988
Merge branch 'main' into continuation
nojaf Jun 26, 2023
1cde07c
Merge branch 'continuation' into experiments
0101 Jun 26, 2023
b6addc1
wip
0101 Jun 26, 2023
d9c8524
wip
0101 Jun 27, 2023
84fbaaf
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jun 28, 2023
ce3464d
wip
0101 Jun 29, 2023
a94d7b5
wip
0101 Jun 29, 2023
d86ef65
reuse fsc graph processing
0101 Jun 29, 2023
edaed6e
Merge branch 'main' into experiments
0101 Jun 29, 2023
48db165
Merge branch 'main' into experiments
0101 Jul 3, 2023
cb737b3
wip
0101 Jul 12, 2023
07ea682
Merge branch 'main' into experiments
0101 Jul 12, 2023
ee0b60b
Symbols in project results, plug in some tests
0101 Jul 14, 2023
32ddc2f
f
0101 Jul 14, 2023
36ea340
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jul 18, 2023
ad35bc5
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jul 20, 2023
5e1318a
Merge remote-tracking branch 'upstream/main' into experiments
0101 Aug 1, 2023
0a99f43
Merge remote-tracking branch 'upstream/main' into experiments
0101 Aug 4, 2023
d0ed695
wip
vzarytovskii Aug 30, 2023
f92609d
Merge remote-tracking branch 'upstream/main' into experiments
0101 Aug 31, 2023
81421fe
Experiments 6 (#2)
0101 Sep 4, 2023
7612843
cleanup
0101 Sep 4, 2023
ee7d940
more experiments
0101 Sep 5, 2023
af3272c
Merge branch 'main' into experiments
0101 Sep 5, 2023
d0bbd78
more experiments
0101 Sep 5, 2023
df20016
Merge branch 'experiments-7' of https://github.com/0101/fsharp into e…
0101 Sep 5, 2023
113d8db
debug output update
0101 Sep 5, 2023
be97731
Merge remote-tracking branch 'upstream/main' into experiments
0101 Sep 6, 2023
ff1d790
Merge branch 'experiments' into experiments-7
0101 Sep 6, 2023
8b56248
fix merge
0101 Sep 6, 2023
21020d9
more experiments
0101 Sep 5, 2023
9ed6b12
more experiments
0101 Sep 5, 2023
8511a6f
debug output update
0101 Sep 5, 2023
a61da67
Merge branch 'experiments-7' of github.com:0101/fsharp into experimen…
0101 Sep 6, 2023
1db5b38
more debug info
0101 Sep 7, 2023
f1778eb
wip
vzarytovskii Sep 8, 2023
a94bb5f
wip
vzarytovskii Sep 8, 2023
c24a1a3
wip
vzarytovskii Sep 8, 2023
cc5f92b
wip
vzarytovskii Sep 11, 2023
38ea540
Fantomas
vzarytovskii Sep 11, 2023
709d6d5
more wip
vzarytovskii Sep 11, 2023
18b07a5
wip: cache semantic highlightings for opened docs
vzarytovskii Sep 11, 2023
98c2a5a
more wip
vzarytovskii Sep 11, 2023
73877dc
wip
vzarytovskii Sep 12, 2023
524c12c
wip
vzarytovskii Sep 12, 2023
a6a1664
fantomas
vzarytovskii Sep 12, 2023
de10ca0
debug info
0101 Sep 13, 2023
9a8d303
Merge branch 'experiments' of https://github.com/0101/fsharp into exp…
0101 Sep 13, 2023
56c92b8
Merge branch 'experiments' into experiments-7
0101 Sep 13, 2023
6c4f126
debug cache version
0101 Sep 14, 2023
9116623
fix external navigation
vzarytovskii Sep 14, 2023
be1f966
SnapshotWithSources wip
0101 Sep 14, 2023
a3b0233
SnapshotWithSources
0101 Sep 15, 2023
a5ac09d
wip
vzarytovskii Sep 18, 2023
2951339
Merge remote-tracking branch 'upstream/main' into experiments
0101 Sep 18, 2023
27cb2f3
wip
vzarytovskii Sep 18, 2023
6419d39
Merge
vzarytovskii Sep 18, 2023
227c6e2
Merge remote-tracking branch 'upstream/main' into more-cancellable-ta…
vzarytovskii Sep 18, 2023
6da2790
wip
0101 Sep 18, 2023
4901a68
wip
vzarytovskii Sep 20, 2023
bd4baba
Automated command ran: fantomas
github-actions[bot] Sep 20, 2023
21898a1
clear caches on solution unload
0101 Sep 21, 2023
d3d1d87
wip
0101 Sep 21, 2023
1521851
Checking referenced projects not needed for parsing
0101 Sep 22, 2023
a0ce1d8
cancel running jobs with the same key
0101 Sep 25, 2023
ce9715a
wip
0101 Sep 25, 2023
c1025c1
wip
0101 Sep 26, 2023
efa0a3f
wip
0101 Sep 26, 2023
d4ce1da
wip
0101 Sep 29, 2023
6758b9a
wip
0101 Sep 29, 2023
ff94633
wip
0101 Sep 29, 2023
c64a9ff
Project key depends on output/target
0101 Oct 2, 2023
4c2846a
wip
0101 Oct 2, 2023
cbe52f2
Merge branch 'main' into more-cancellable-tasks3
0101 Oct 2, 2023
fefdadf
Merge remote-tracking branch 'upstream/main' into experiments
0101 Oct 2, 2023
2fbb523
Merge branch 'experiments' into experiments-8
0101 Oct 2, 2023
21e890f
Merge remote-tracking branch 'vlad/more-cancellable-tasks3' into expe…
0101 Oct 2, 2023
029f060
wip
0101 Oct 2, 2023
08072a7
reuse snapshots for finding references
0101 Oct 3, 2023
4ff503e
Merge remote-tracking branch 'upstream/main' into experiments
0101 Oct 5, 2023
258e5cb
Merge branch 'experiments' into experiments-9
0101 Oct 5, 2023
6c47396
Configurable cache size factor
0101 Oct 5, 2023
5905122
snapshot cache cleanup
0101 Oct 6, 2023
297da99
don't store all cache durations
0101 Oct 6, 2023
29b7c4b
wip
vzarytovskii Oct 9, 2023
a40c0e2
Merge branch 'more-cancellable-tasks3' of https://github.com/vzarytov…
vzarytovskii Oct 9, 2023
ce87dce
Merge remote-tracking branch 'vlad/more-cancellable-tasks3' into expe…
0101 Oct 9, 2023
d9e92a6
Merge remote-tracking branch 'upstream/main' into experiments
0101 Oct 9, 2023
732d43a
fix
0101 Oct 9, 2023
a87b217
f
0101 Oct 9, 2023
1a39923
move LruCache to separate file
0101 Oct 9, 2023
0958b35
re-enable hashed versions
0101 Oct 9, 2023
991f33b
Merge remote-tracking branch 'upstream/main' into experiments
0101 Oct 10, 2023
34721a8
Merge remote-tracking branch 'upstream/main' into experiments
0101 Nov 2, 2023
dfec9ac
Merge branch 'main' into experiments
0101 Nov 13, 2023
5da210c
Fixed cache bug
0101 Nov 13, 2023
8772573
Fix finding references testing
0101 Nov 15, 2023
708e679
added cache hit ratio, symbol env for diagnostics
0101 Nov 15, 2023
0b2897d
test todos
0101 Nov 15, 2023
a2c14b8
enabling some tests
0101 Nov 15, 2023
e64ea32
Merge branch 'main' into experiments
0101 Nov 15, 2023
4ec6ce3
enable some more tests
0101 Nov 16, 2023
4dbd767
fixed proj file
0101 Nov 16, 2023
e921357
tests
0101 Nov 16, 2023
fe607f2
reduce surface area changes
0101 Nov 16, 2023
f70d88b
fix tests
0101 Nov 16, 2023
15049b0
cache update
0101 Nov 16, 2023
cf0c1ac
more tests, include implFiles in project check result
0101 Nov 16, 2023
ff87032
fix
0101 Nov 16, 2023
9a5a714
fix more tests
0101 Nov 16, 2023
d2119f8
implement backgroundcompiler events to enable more tests
0101 Nov 16, 2023
0387fca
reduce api surface
0101 Nov 20, 2023
3222104
Fixed snapshot version
0101 Nov 20, 2023
b874823
cache fix
0101 Nov 20, 2023
f09b1e7
Merge branch 'main' into experiments
0101 Nov 20, 2023
020c2f1
this is actually faster, oops
0101 Nov 22, 2023
9587e06
f
0101 Nov 22, 2023
cdc6c0a
back to node
0101 Nov 22, 2023
16427ac
fix
0101 Nov 23, 2023
71d9407
Merge remote-tracking branch 'upstream/main' into experiments
0101 Nov 23, 2023
8622d85
F
0101 Nov 23, 2023
d99b13d
BackgorundCompiler sync
0101 Nov 23, 2023
8e8f3f2
Merge branch 'experiments' into experiments-10
0101 Nov 23, 2023
069ab14
fix
0101 Nov 23, 2023
ad0af09
BDN update
0101 Nov 23, 2023
da8c1f6
BDN update
0101 Nov 23, 2023
0a70004
Replay diagnostics for cached computations
0101 Nov 23, 2023
c10f216
Merge branch 'experiments-10' into experiments
0101 Nov 23, 2023
6577566
F
0101 Nov 23, 2023
7c52422
Fixed fsproj
0101 Nov 23, 2023
ecf201d
test fixes
0101 Nov 24, 2023
0b207e6
F
0101 Nov 24, 2023
0e31a5c
test fixes
0101 Nov 24, 2023
fe1d32e
serialize snapshot to json
0101 Nov 27, 2023
9b01f9c
Fix DiagnosticExtendedData
0101 Nov 27, 2023
5ee6b37
Merge remote-tracking branch 'upstream/main' into experiments
0101 Nov 29, 2023
9952028
Move Project Snapshot to class
0101 Nov 30, 2023
0b132b1
FSharpProjectSnapshotBase<_>
0101 Dec 5, 2023
618fbf6
repro
0101 Dec 6, 2023
bfadbd6
Moved stuff around
0101 Dec 6, 2023
2bf0ea7
remove parallelism limit
0101 Dec 7, 2023
17316fc
Merge remote-tracking branch 'upstream/main' into experiments
0101 Dec 7, 2023
6f3d604
Add Cancellable.UsingToken
0101 Dec 7, 2023
4b94a0e
wip
0101 Dec 7, 2023
8eb24e5
this might work
0101 Dec 8, 2023
4b40008
ISourceTextNew to keep backwards compatibility
0101 Dec 12, 2023
086d807
Merge remote-tracking branch 'upstream/main' into experiments
0101 Dec 18, 2023
e8fe90e
f
0101 Dec 18, 2023
29a840f
Cancellation tracking and improvements
0101 Dec 19, 2023
89b9b58
Merge branch 'experiments' into experiments-snapshot-reuse
0101 Dec 19, 2023
6447b39
fix fsproj
0101 Dec 19, 2023
f02c7a4
BootrstrapInfoId
0101 Dec 20, 2023
1bdf2ea
Yaml experiment
0101 Dec 20, 2023
4c1a1f4
Pipeline experiment
0101 Dec 20, 2023
a5c6205
Skip Giraffe tests if there's no Giraffe
0101 Dec 20, 2023
a786ef1
Choose to use transparent compiler in tests based on experimental env…
0101 Dec 20, 2023
32a5e82
Merge branch 'experiments' into experiments-snapshot-reuse
0101 Dec 20, 2023
d41b064
pipeline experiment
0101 Dec 20, 2023
cad39a6
BackgroundCompiler ParseFile from snapshot
0101 Dec 21, 2023
4f87494
another yaml experiment
0101 Dec 21, 2023
22ddc6f
Proper diagnostics handler for type checks
0101 Dec 21, 2023
5672520
f
0101 Dec 21, 2023
ab888db
Merge remote-tracking branch 'origin/experiments' into experiments-sn…
0101 Dec 21, 2023
1119434
remove failwith
0101 Dec 21, 2023
b0afc6e
fix test
0101 Dec 21, 2023
a21cf8a
apply nowarns
0101 Dec 22, 2023
7e46a23
disable experimental build
0101 Dec 22, 2023
6cf896e
Merge remote-tracking branch 'upstream/main' into experiments
0101 Dec 22, 2023
b02eadd
fix test
0101 Dec 22, 2023
60eb8f0
fix test
0101 Dec 22, 2023
9239b64
fix
0101 Dec 22, 2023
c1c5be2
fix tests
0101 Dec 27, 2023
a78a4d6
update debug surface area
0101 Dec 27, 2023
2d0e052
add experimental attributes
0101 Dec 27, 2023
badc267
public facing snapshot class
0101 Dec 27, 2023
e917342
Merge branch 'experiments' into experiments-snapshot-reuse
0101 Dec 27, 2023
ec76906
Merge branch 'experiments-snapshot-api' into experiments-snapshot-reuse
0101 Dec 27, 2023
bf7e7de
update
0101 Dec 27, 2023
fc1e45f
nowarn
0101 Dec 27, 2023
d66b48d
api
0101 Dec 27, 2023
bedc8dd
add references stamp to hash
0101 Dec 27, 2023
41d4942
f
0101 Dec 27, 2023
cb0374a
Merge remote-tracking branch 'origin/experiments' into experiments-sn…
0101 Dec 27, 2023
9c23b51
invalidate snapshot when references on disk change
0101 Dec 27, 2023
c008444
Merge branch 'experiments' of github.com:0101/fsharp into experiments
0101 Jan 3, 2024
3c3befc
reusable snapshot menu option
0101 Jan 8, 2024
e777c67
Merge branch 'experiments' into experiments-snapshot-reuse
0101 Jan 8, 2024
8f454c1
api
0101 Jan 8, 2024
b2ac722
make FSharpProjectSnapshot public
0101 Jan 8, 2024
9533d5e
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jan 8, 2024
338043f
f
0101 Jan 8, 2024
4575389
API, use DLL from disk if fresh
0101 Jan 9, 2024
1c72172
f
0101 Jan 10, 2024
3c97e89
Removed TaskAgent
0101 Jan 10, 2024
0e4643f
cleanup
0101 Jan 10, 2024
a70f4ab
Merge branch 'main' into experiments
0101 Jan 10, 2024
cee7b90
Merge branch 'experiments' of https://github.com/0101/fsharp into exp…
0101 Jan 10, 2024
271ff38
doc
0101 Jan 10, 2024
ba71759
signatures
0101 Jan 10, 2024
3e9d961
cleanup
0101 Jan 10, 2024
183f1d0
settings disclaimer
0101 Jan 10, 2024
de0364b
Merge branch 'main' into experiments
0101 Jan 11, 2024
71ec4e0
auto opt in for telemetry
0101 Jan 11, 2024
090c9f8
option to clear cache for a given project
0101 Jan 12, 2024
59992f9
f
0101 Jan 12, 2024
ce270e4
disable snapshot reuse by default
0101 Jan 12, 2024
5e40460
Merge remote-tracking branch 'upstream/main' into experiments
0101 Jan 15, 2024
ad0fa6a
revert pipeline
0101 Jan 15, 2024
6b86bb4
revert pipeline
0101 Jan 15, 2024
4b099a1
Try to fix flakiness in async tests
0101 Jan 15, 2024
0493b32
Merge branch 'main' into experiments
0101 Jan 15, 2024
4985d77
Merge branch 'main' into experiments
0101 Jan 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 75 additions & 15 deletions src/Compiler/Driver/GraphChecking/Graph.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,42 @@ module internal Graph =
|> Array.map (fun (KeyValue (k, v)) -> k, v)
|> readOnlyDict

let transitive<'Node when 'Node: equality> (graph: Graph<'Node>) : Graph<'Node> =
/// Find transitive dependencies of a single node.
let transitiveDeps (node: 'Node) =
let visited = HashSet<'Node>()
let nodes (graph: Graph<'Node>) : Set<'Node> =
graph.Values |> Seq.collect id |> Seq.append graph.Keys |> Seq.distinct |> Set
vzarytovskii marked this conversation as resolved.
Show resolved Hide resolved

/// Find transitive dependencies of a single node.
let transitiveDeps (node: 'Node) (graph: Graph<'Node>) =
let visited = HashSet<'Node>()

let rec dfs (node: 'Node) =
graph[node]
// Add direct dependencies.
// Use HashSet.Add return value semantics to filter out those that were added previously.
|> Array.filter visited.Add
|> Array.iter dfs
let rec dfs (node: 'Node) =
graph[node]
// Add direct dependencies.
// Use HashSet.Add return value semantics to filter out those that were added previously.
|> Array.filter visited.Add
|> Array.iter dfs

dfs node
visited |> Seq.toArray
dfs node
visited |> Seq.toArray

let transitive<'Node when 'Node: equality> (graph: Graph<'Node>) : Graph<'Node> =
0101 marked this conversation as resolved.
Show resolved Hide resolved
graph.Keys
|> Seq.toArray
|> Array.Parallel.map (fun node -> node, transitiveDeps node)
|> Array.Parallel.map (fun node -> node, graph |> transitiveDeps node)
|> readOnlyDict

/// Get subgraph of the given graph that contains only nodes that are reachable from the given node.
let subGraphFor node graph =
let allDeps = graph |> transitiveDeps node
let relevant n = n = node || allDeps |> Array.contains n
0101 marked this conversation as resolved.
Show resolved Hide resolved

graph
|> Seq.choose (fun (KeyValue (src, deps)) ->
if relevant src then
Some(src, deps |> Array.filter relevant)
else
None)
|> make

/// Create a reverse of the graph
let reverse (originalGraph: Graph<'Node>) : Graph<'Node> =
originalGraph
Expand All @@ -59,6 +75,48 @@ module internal Graph =
|> readOnlyDict
|> addIfMissing originalGraph.Keys

/// Returns leaves of the graph and the remaining graph without the leaves.
vzarytovskii marked this conversation as resolved.
Show resolved Hide resolved
let cutLeaves (graph: Graph<'Node>) =
let notLeaves =
set
[
for (KeyValue (node, deps)) in graph do
if deps.Length > 0 then
node
]

let leaves =
set
[
for (KeyValue (node, deps)) in graph do
if deps.Length = 0 then
node

yield! deps |> Array.filter (notLeaves.Contains >> not)
]

leaves,
seq {
for (KeyValue (node, deps)) in graph do
if deps.Length > 0 then
node, deps |> Array.filter (leaves.Contains >> not)
}
|> make

/// Returns layers of leaves repeatedly removed from the graph until there's nothing left
let leafSequence (graph: Graph<'Node>) =
let rec loop (graph: Graph<'Node>) acc =
match graph |> cutLeaves with
| leaves, _ when leaves.IsEmpty -> acc
| leaves, graph ->
seq {
yield! acc
leaves
}
|> loop graph

loop graph Seq.empty

let printCustom (graph: Graph<'Node>) (nodePrinter: 'Node -> string) : unit =
printfn "Graph:"
let join (xs: string[]) = System.String.Join(", ", xs)
Expand All @@ -69,7 +127,7 @@ module internal Graph =
let print (graph: Graph<'Node>) : unit =
printCustom graph (fun node -> node.ToString())

let serialiseToMermaid path (graph: Graph<FileIndex * string>) =
let serialiseToMermaid (graph: Graph<FileIndex * string>) =
let sb = StringBuilder()
let appendLine (line: string) = sb.AppendLine(line) |> ignore

Expand All @@ -84,8 +142,10 @@ module internal Graph =
appendLine $" %i{idx} --> %i{depIdx}"

appendLine "```"
sb.ToString()

let writeMermaidToFile path (graph: Graph<FileIndex * string>) =
use out =
FileSystem.OpenFileForWriteShim(path, fileMode = System.IO.FileMode.Create)

out.WriteAllText(sb.ToString())
graph |> serialiseToMermaid |> out.WriteAllText
10 changes: 9 additions & 1 deletion src/Compiler/Driver/GraphChecking/Graph.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@ module internal Graph =
/// Build the graph.
val make: nodeDeps: seq<'Node * 'Node array> -> Graph<'Node> when 'Node: equality
val map<'T, 'U when 'U: equality> : f: ('T -> 'U) -> graph: Graph<'T> -> Graph<'U>
/// Get all nodes of the graph.
val nodes: graph: Graph<'Node> -> Set<'Node>
/// Create a transitive closure of the graph in O(n^2) time (but parallelize it).
/// The resulting graph contains edge A -> C iff the input graph contains a (directed) non-zero length path from A to C.
val transitive<'Node when 'Node: equality> : graph: Graph<'Node> -> Graph<'Node>
/// Get a sub-graph of the graph containing only the nodes reachable from the given node.
val subGraphFor: node: 'Node -> graph: Graph<'Node> -> Graph<'Node> when 'Node: equality
/// Create a reverse of the graph.
val reverse<'Node when 'Node: equality> : originalGraph: Graph<'Node> -> Graph<'Node>
/// Returns layers of leaves repeatedly removed from the graph until there's nothing left
val leafSequence: graph: Graph<'Node> -> Set<'Node> seq
/// Print the contents of the graph to the standard output.
val print: graph: Graph<'Node> -> unit
/// Create a simple Mermaid graph
val serialiseToMermaid: graph: Graph<FileIndex * string> -> string
/// Create a simple Mermaid graph and save it under the path specified.
val serialiseToMermaid: path: string -> graph: Graph<FileIndex * string> -> unit
val writeMermaidToFile: path: string -> graph: Graph<FileIndex * string> -> unit
82 changes: 42 additions & 40 deletions src/Compiler/Driver/ParseAndCheckInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1467,14 +1467,14 @@ let CheckOneInputWithCallback
prefixPathOpt,
tcSink,
tcState: TcState,
inp: ParsedInput,
input: ParsedInput,
_skipImplIfSigExists: bool): (unit -> bool) * TcConfig * TcImports * TcGlobals * LongIdent option * TcResultsSink * TcState * ParsedInput * bool)
: Cancellable<Finisher<TcState, PartialResult>> =
cancellable {
try
CheckSimulateException tcConfig

let m = inp.Range
let m = input.Range
let amap = tcImports.GetImportMap()

let conditionalDefines =
Expand All @@ -1483,7 +1483,7 @@ let CheckOneInputWithCallback
else
Some tcConfig.conditionalDefines

match inp with
match input with
| ParsedInput.SigFile file ->
let qualNameOfFile = file.QualifiedName

Expand Down Expand Up @@ -1609,6 +1609,43 @@ let AddSignatureResultToTcImplEnv (tcImports: TcImports, tcGlobals, prefixPathOp

partialResult, tcState

let TransformDependencyGraph (graph: Graph<FileIndex>, filePairs: FilePairMap) =
let mkArtificialImplFile n = NodeToTypeCheck.ArtificialImplFile n
let mkPhysicalFile n = NodeToTypeCheck.PhysicalFile n

/// Map any signature dependencies to the ArtificialImplFile counterparts,
/// unless the signature dependency is the backing file of the current (implementation) file.
let mapDependencies idx deps =
Array.map
(fun dep ->
if filePairs.IsSignature dep then
let implIdx = filePairs.GetImplementationIndex dep

if implIdx = idx then
// This is the matching signature for the implementation.
// Retain the direct dependency onto the signature file.
mkPhysicalFile dep
else
mkArtificialImplFile dep
else
mkPhysicalFile dep)
deps

// Transform the graph to include ArtificialImplFile nodes when necessary.
graph
|> Seq.collect (fun (KeyValue (fileIdx, deps)) ->
if filePairs.IsSignature fileIdx then
// Add an additional ArtificialImplFile node for the signature file.
[|
// Mark the current file as physical and map the dependencies.
mkPhysicalFile fileIdx, mapDependencies fileIdx deps
// Introduce a new node that depends on the signature.
mkArtificialImplFile fileIdx, [| mkPhysicalFile fileIdx |]
|]
else
[| mkPhysicalFile fileIdx, mapDependencies fileIdx deps |])
|> Graph.make

/// Constructs a file dependency graph and type-checks the files in parallel where possible.
let CheckMultipleInputsUsingGraphMode
((ctok, checkForErrors, tcConfig: TcConfig, tcImports: TcImports, tcGlobals, prefixPathOpt, tcState, eagerFormat, inputs): 'a * (unit -> bool) * TcConfig * TcImports * TcGlobals * LongIdent option * TcState * (PhasedDiagnostic -> PhasedDiagnostic) * ParsedInput list)
Expand All @@ -1630,42 +1667,7 @@ let CheckMultipleInputsUsingGraphMode
let graph, trie =
DependencyResolution.mkGraph tcConfig.compilingFSharpCore filePairs sourceFiles

let nodeGraph =
let mkArtificialImplFile n = NodeToTypeCheck.ArtificialImplFile n
let mkPhysicalFile n = NodeToTypeCheck.PhysicalFile n

/// Map any signature dependencies to the ArtificialImplFile counterparts,
/// unless the signature dependency is the backing file of the current (implementation) file.
let mapDependencies idx deps =
Array.map
(fun dep ->
if filePairs.IsSignature dep then
let implIdx = filePairs.GetImplementationIndex dep

if implIdx = idx then
// This is the matching signature for the implementation.
// Retain the direct dependency onto the signature file.
mkPhysicalFile dep
else
mkArtificialImplFile dep
else
mkPhysicalFile dep)
deps

// Transform the graph to include ArtificialImplFile nodes when necessary.
graph
|> Seq.collect (fun (KeyValue (fileIdx, deps)) ->
if filePairs.IsSignature fileIdx then
// Add an additional ArtificialImplFile node for the signature file.
[|
// Mark the current file as physical and map the dependencies.
mkPhysicalFile fileIdx, mapDependencies fileIdx deps
// Introduce a new node that depends on the signature.
mkArtificialImplFile fileIdx, [| mkPhysicalFile fileIdx |]
|]
else
[| mkPhysicalFile fileIdx, mapDependencies fileIdx deps |])
|> Graph.make
let nodeGraph = TransformDependencyGraph(graph, filePairs)

// Persist the graph to a Mermaid diagram if specified.
if tcConfig.typeCheckingConfig.DumpGraph then
Expand All @@ -1685,7 +1687,7 @@ let CheckMultipleInputsUsingGraphMode
.TrimStart([| '\\'; '/' |])

(idx, friendlyFileName))
|> Graph.serialiseToMermaid graphFile)
|> Graph.writeMermaidToFile graphFile)

let _ = ctok // TODO Use it
let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger
Expand Down
69 changes: 69 additions & 0 deletions src/Compiler/Driver/ParseAndCheckInputs.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,44 @@ open FSharp.Compiler.CompilerImports
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.DependencyManager
open FSharp.Compiler.DiagnosticsLogger
open FSharp.Compiler.GraphChecking
open FSharp.Compiler.NameResolution
open FSharp.Compiler.Syntax
open FSharp.Compiler.TcGlobals
open FSharp.Compiler.Text
open FSharp.Compiler.TypedTree
open FSharp.Compiler.UnicodeLexing

/// Auxiliary type for re-using signature information in TcEnvFromImpls.
///
/// TcState has two typing environments: TcEnvFromSignatures && TcEnvFromImpls
/// When type checking a file, depending on the type (implementation or signature), it will use one of these typing environments (TcEnv).
/// Checking a file will populate the respective TcEnv.
///
/// When a file has a dependencies, the information of the signature file in case a pair (implementation file backed by a signature) will suffice to type-check that file.
/// Example: if `B.fs` has a dependency on `A`, the information of `A.fsi` is enough for `B.fs` to type-check, on condition that information is available in the TcEnvFromImpls.
/// We introduce a special ArtificialImplFile node in the graph to satisfy this. `B.fs -> [ A.fsi ]` becomes `B.fs -> [ ArtificialImplFile A ].
/// The `ArtificialImplFile A` node will duplicate the signature information which A.fsi provided earlier.
/// Processing a `ArtificialImplFile` node will add the information from the TcEnvFromSignatures to the TcEnvFromImpls.
/// This means `A` will be known in both TcEnvs and therefor `B.fs` can be type-checked.
/// By doing this, we can speed up the graph processing as type checking a signature file is less expensive than its implementation counterpart.
///
/// When we need to actually type-check an implementation file backed by a signature, we cannot have the duplicate information of the signature file present in TcEnvFromImpls.
/// Example `A.fs -> [ A.fsi ]`. An implementation file always depends on its signature.
/// Type-checking `A.fs` will add the actual information to TcEnvFromImpls and we do not depend on the `ArtificialImplFile A` for `A.fs`.
///
/// In order to deal correctly with the `ArtificialImplFile` logic, we need to transform the resolved graph to contain the additional pair nodes.
/// After we have type-checked the graph, we exclude the ArtificialImplFile nodes as they are not actual physical files in our project.
[<RequireQualifiedAccess>]
type NodeToTypeCheck =
/// A real physical file in the current project.
/// This can be either an implementation or a signature file.
| PhysicalFile of fileIndex: FileIndex
/// An artificial node that will add the earlier processed signature information to the TcEnvFromImpls.
/// Dependants on this type of node will perceive that a file is known in both TcEnvFromSignatures and TcEnvFromImpls.
/// Even though the actual implementation file was not type-checked.
| ArtificialImplFile of signatureFileIndex: FileIndex

val IsScript: string -> bool

val ComputeQualifiedNameOfFileFromUniquePath: range * string list -> QualifiedNameOfFile
Expand Down Expand Up @@ -131,6 +163,8 @@ type TcState =

member CreatesGeneratedProvidedTypes: bool

type PartialResult = TcEnv * TopAttribs * CheckedImplFile option * ModuleOrNamespaceType

/// Get the initial type checking state for a set of inputs
val GetInitialTcState: range * string * TcConfig * TcGlobals * TcImports * TcEnv * OpenDeclaration list -> TcState

Expand All @@ -151,6 +185,41 @@ val CheckOneInput:
input: ParsedInput ->
Cancellable<(TcEnv * TopAttribs * CheckedImplFile option * ModuleOrNamespaceType) * TcState>

val CheckOneInputWithCallback:
checkForErrors: (unit -> bool) *
tcConfig: TcConfig *
tcImports: TcImports *
tcGlobals: TcGlobals *
prefixPathOpt: LongIdent option *
tcSink: TcResultsSink *
tcState: TcState *
input: ParsedInput *
_skipImplIfSigExists: bool ->
Cancellable<Finisher<TcState, PartialResult>>

val AddCheckResultsToTcState:
tcGlobals: TcGlobals *
amap: Import.ImportMap *
hadSig: bool *
prefixPathOpt: LongIdent option *
tcSink: TcResultsSink *
tcImplEnv: TcEnv *
qualNameOfFile: QualifiedNameOfFile *
implFileSigType: ModuleOrNamespaceType ->
tcState: TcState ->
ModuleOrNamespaceType * TcState

val AddSignatureResultToTcImplEnv:
tcImports: TcImports *
tcGlobals: TcGlobals *
prefixPathOpt: LongIdent option *
tcSink: TcResultsSink *
tcState: TcState *
input: ParsedInput ->
(TcState -> PartialResult * TcState)

val TransformDependencyGraph: graph: Graph<FileIndex> * filePairs: FilePairMap -> Graph<NodeToTypeCheck>

/// Finish the checking of multiple inputs
val CheckMultipleInputsFinish:
(TcEnv * TopAttribs * 'T option * 'U) list * TcState -> (TcEnv * TopAttribs * 'T list * 'U list) * TcState
Expand Down
5 changes: 4 additions & 1 deletion src/Compiler/FSharp.Compiler.Service.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
<Compile Include="Facilities\CompilerLocation.fs" />
<Compile Include="Facilities\BuildGraph.fsi" />
<Compile Include="Facilities\BuildGraph.fs" />
<Compile Include="Facilities\AsyncMemoize.fs" />
<FsLex Include="AbstractIL\illex.fsl">
<OtherFlags>--module FSharp.Compiler.AbstractIL.AsciiLexer --internal --open Internal.Utilities.Text.Lexing --open FSharp.Compiler.AbstractIL.AsciiParser --unicode --lexlib Internal.Utilities.Text.Lexing</OtherFlags>
<Link>AbstractIL\illex.fsl</Link>
Expand Down Expand Up @@ -486,7 +487,9 @@
<Compile Include="Service\QuickParse.fsi" />
<Compile Include="Service\QuickParse.fs" />
<Compile Include="Service\FSharpCheckerResults.fsi" />
<Compile Include="Service\FSharpCheckerResults.fs" />
<Compile Include="Service\FSharpCheckerResults.fs" />
<Compile Include="Service\BackgroundCompiler.fs" />
<Compile Include="Service\TransparentCompiler.fs" />
<Compile Include="Service\service.fsi" />
<Compile Include="Service\service.fs" />
<Compile Include="Service\ServiceInterfaceStubGenerator.fsi" />
Expand Down
Loading