Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
385 commits
Select commit Hold shift + click to select a range
1ff0fd4
fix(hot-reload): preserve unsigned AssemblyRef versions
NatElkins Jun 24, 2026
644e23c
fix(hot-reload): treat all metadata rows as payload
NatElkins Jun 24, 2026
02a2a98
fix(hot-reload): preserve deltas with added rows
NatElkins Jun 24, 2026
a7fabfa
fix(hot-reload): parse split long out option
NatElkins Jun 24, 2026
40ee38c
fix(hot-reload): compare output paths by platform
NatElkins Jun 24, 2026
232e82f
fix(hot-reload): preserve active statement ranges
NatElkins Jun 24, 2026
2648c92
fix(hot-reload): align delta PDB state machine headers
NatElkins Jun 24, 2026
659e852
fix(hot-reload): serialize PDB document names structurally
NatElkins Jun 24, 2026
33d5b2d
style(hot-reload): apply fantomas to review fixes
NatElkins Jun 24, 2026
5e27640
fix(hot-reload): fold unit return identity to void in signature diff
NatElkins Jun 25, 2026
0eebc87
fix(hot-reload): tolerate compiler-generated companions in fail-close…
NatElkins Jun 25, 2026
bdbd533
Fail closed on baseline-less compiler-generated types under external …
NatElkins Jul 1, 2026
6667cf1
Add flag-gated experimental in-process compile for hot reload
NatElkins Jul 2, 2026
8451a12
Consume the in-process compile's emitted module directly in the delta…
NatElkins Jul 2, 2026
afdf48c
Fix Release-build CLR access violation in baseline metadata reading
NatElkins Jul 2, 2026
81e128e
Skip typed-tree diffing for checked files reused from the compiler cache
NatElkins Jul 2, 2026
124791f
Scope per-edit EnC debug-info and closure-name refreshes to changed f…
NatElkins Jul 2, 2026
8812bf7
Cache per-file optimized trees for the in-process hot reload compile
NatElkins Jul 2, 2026
8523328
Reuse the in-process compile's emitted artifacts in the delta emitter
NatElkins Jul 2, 2026
6d1cb57
Add env-gated stage timing to hot reload delta emission
NatElkins Jul 2, 2026
998e429
Add delta dump diagnostic and user-string decode regression test
NatElkins Jul 2, 2026
22bf964
Replay session closure names in the in-process compile for stable-nam…
NatElkins Jul 2, 2026
bec584f
Align line-shifted synthesized closures by guarded positional pairing
NatElkins Jul 2, 2026
7a75891
Preserve generation-0 synthesized closure names across line shifts
NatElkins Jul 2, 2026
fec6f41
Install replay naming state when the snapshot itself shows mixed allo…
NatElkins Jul 2, 2026
c69cb2b
Record the allocation-ordered synthesized-name snapshot in the baseli…
NatElkins Jul 2, 2026
8b71035
Record the complete post-IlxGen name map in the baseline snapshot CDI
NatElkins Jul 2, 2026
3580a03
Merge main: reconcile parallel-codegen determinism (#19810) with hot …
NatElkins Jul 2, 2026
256bea5
Merge branch 'hot-reload-v2' into hot-reload-v2-merge
NatElkins Jul 2, 2026
865e3ab
Reconcile complete recorded snapshots with task helper-chain replay
NatElkins Jul 2, 2026
8350ab2
Fix CI compile breaks in hot reload test files
NatElkins Jul 3, 2026
7f00c56
Fix net472 and CI-image portability breaks in hot reload test files
NatElkins Jul 3, 2026
2f065f3
Gate the Roslyn baseline comparison tests to .NET Core
NatElkins Jul 3, 2026
2657562
Normalize fixture line endings before update-source splicing
NatElkins Jul 3, 2026
d8e685e
Remove the accidentally committed .dotnet symlink
NatElkins Jul 5, 2026
ca6fc6b
Merge main after deterministic codegen fix
NatElkins Jul 7, 2026
0689a74
Fix synthesized type alias reuse in in-process hot reload
NatElkins Jul 10, 2026
f6cad50
Add Roslyn-format EnC CustomDebugInformation codec and portable PDB m…
NatElkins Jul 1, 2026
0d02145
Use ProcessStartInfo.Arguments for net472 compatibility
NatElkins Jul 1, 2026
66a1412
Make the EnC CDI test module public for xunit v3 discovery
NatElkins Jul 2, 2026
c8639f3
Extract stable synthesized-name replay layer
NatElkins Jul 2, 2026
d6319c1
Add ECMA-335 EnC metadata delta writer
NatElkins Jul 1, 2026
b0a487f
Add typed-tree diff slice for hot reload
NatElkins Jul 2, 2026
d505ab9
Fix generated-name scope test in stable names slice
NatElkins Jul 8, 2026
7aaacc5
Fix EnC CDI cross-validation test process launch on Desktop and bare …
NatElkins Jul 3, 2026
c78b2f6
Remove extra EOF blank line in delta metadata tests
NatElkins Jul 8, 2026
2facaf2
Merge branch 'refresh/20260717/hotreload-typedtree-diff' into refresh…
NatElkins Jul 17, 2026
cd1339b
Merge branch 'refresh/20260717/hotreload-stable-names' into refresh/2…
NatElkins Jul 17, 2026
ba5bce9
Merge branch 'refresh/20260717/enc-metadata-delta-writer' into refres…
NatElkins Jul 17, 2026
c23986b
Add hot reload baseline reader state
NatElkins Jul 3, 2026
ac6a1ba
Extract hot reload delta emitter
NatElkins Jul 3, 2026
11e8fa0
Fix synthesized-name snapshot assertions to use the array equality ov…
NatElkins Jul 3, 2026
b228654
Align the signature-change diff test with the evolved differ classifi…
NatElkins Jul 3, 2026
02e55c3
Merge remote-tracking branch 'origin/main' into refresh/20260717/hot-…
NatElkins Jul 17, 2026
f8868e7
Remove trailing EOF whitespace in hot reload tests
NatElkins Jul 17, 2026
3e1678d
Validate hot reload baseline metadata inputs
NatElkins Jul 17, 2026
5fdf705
Enforce cumulative metadata delta invariants
NatElkins Jul 17, 2026
c584660
Validate hot reload generated names before classification
NatElkins Jul 17, 2026
9a9211e
Validate hot reload baseline metadata inputs
NatElkins Jul 17, 2026
be6df7b
Preserve reviewed lower-slice invariants in delta emitter
NatElkins Jul 17, 2026
8932904
Unify delta emission on the shared metadata writer
NatElkins Jul 17, 2026
d40f0bc
Fail closed on unresolved accessor metadata
NatElkins Jul 17, 2026
11b50cc
Extract hot reload session slice
NatElkins Jul 3, 2026
36ef5ba
Fix CI compile breaks and extraction debris in the session slice tests
NatElkins Jul 3, 2026
330761c
Fix net472 and CI-image portability breaks in session slice tests
NatElkins Jul 3, 2026
a886637
Drop the netcore-only Contains overload from delta builder tests
NatElkins Jul 3, 2026
9bb2547
Gate the Roslyn baseline comparison tests to .NET Core
NatElkins Jul 3, 2026
6420b62
Normalize fixture line endings before update-source splicing
NatElkins Jul 3, 2026
c67ec56
Update ilxgen name-path architecture guard
NatElkins Jul 8, 2026
a4b8616
Remove duplicate delta metadata test copies
NatElkins Jul 8, 2026
4a1efa4
Remove duplicate compiler global reset member
NatElkins Jul 8, 2026
7216294
Remove duplicate compiler global reset signature
NatElkins Jul 8, 2026
2b461a8
Repair session slice after metadata writer consolidation
NatElkins Jul 17, 2026
9bf2891
Make hot reload session updates transactional
NatElkins Jul 17, 2026
1f7fa5d
Extract the flag-gated in-process compile perf slice
NatElkins Jul 3, 2026
8554882
Apply post-main hot reload perf cleanup
NatElkins Jul 7, 2026
eb1e86d
Remove trailing EOF whitespace in hot reload tests
NatElkins Jul 8, 2026
9c2d4b6
Fix synthesized type alias reuse in in-process hot reload
NatElkins Jul 10, 2026
464ee2a
Preserve hot reload slice invariants in in-process compilation
NatElkins Jul 17, 2026
186205d
Fix EnC CDI cross-validation test process launch on Desktop and bare …
NatElkins Jul 3, 2026
39f95dd
Enforce cumulative metadata delta invariants
NatElkins Jul 17, 2026
5533758
Validate hot reload generated names before classification
NatElkins Jul 17, 2026
1c5d1df
Make umbrella typed-tree classification fail closed
NatElkins Jul 17, 2026
9f04319
Validate umbrella hot reload baseline artifacts
NatElkins Jul 17, 2026
56d6561
Unify umbrella delta emission on the shared writer
NatElkins Jul 17, 2026
b7f2bf6
Unify delta emission on the shared metadata writer
NatElkins Jul 17, 2026
e043158
Reconcile shared writer integration with umbrella streams
NatElkins Jul 17, 2026
3f430f0
Fail closed on unresolved accessor metadata
NatElkins Jul 17, 2026
f530ae7
Make hot reload session updates transactional
NatElkins Jul 17, 2026
6bc060b
Preserve hot reload slice invariants in in-process compilation
NatElkins Jul 17, 2026
8ea9e6b
Harden in-process hot reload compilation
NatElkins Jul 17, 2026
1592b53
Harden in-process hot reload compilation
NatElkins Jul 17, 2026
2d0ffd4
Align hot reload documentation with session entities
NatElkins Jul 17, 2026
63db0b3
Verify overlapping hot reload emits serialize
NatElkins Jul 17, 2026
ed2ea8b
Verify overlapping hot reload emits serialize
NatElkins Jul 17, 2026
00f11e6
Minimize in-process compiler surface drift
NatElkins Jul 17, 2026
11a4022
Minimize in-process compiler surface drift
NatElkins Jul 17, 2026
8630f80
Lock intentional hot reload interface drift
NatElkins Jul 17, 2026
461daf3
Verify refreshed F# hot reload stack
NatElkins Jul 17, 2026
9112dab
Report hot reload update capabilities
NatElkins Jul 17, 2026
21dbd06
Report hot reload update capabilities
NatElkins Jul 17, 2026
b26df0f
Expose required hot reload capabilities
NatElkins Jul 17, 2026
408de0c
Report hot reload update capabilities
NatElkins Jul 17, 2026
5fa9d32
Expose required hot reload capabilities
NatElkins Jul 17, 2026
e0d4b96
Report hot reload update capabilities
NatElkins Jul 17, 2026
cbb9c40
Expose required hot reload capabilities
NatElkins Jul 17, 2026
52540ff
Verify required capability propagation
NatElkins Jul 17, 2026
490f458
Document F# hot reload rude-edit diagnostics
NatElkins Jul 17, 2026
412edf5
Document F# hot reload rude-edit diagnostics
NatElkins Jul 17, 2026
504452a
Document F# hot reload rude-edit diagnostics
NatElkins Jul 17, 2026
16b0de1
Format delta metadata writer sources
NatElkins Jul 17, 2026
a402010
Format delta metadata writer sources
NatElkins Jul 17, 2026
c7aed88
Format delta metadata writer sources
NatElkins Jul 17, 2026
0447915
Format delta metadata writer sources
NatElkins Jul 17, 2026
24f4879
Format hot reload compiler sources
NatElkins Jul 17, 2026
34950ea
Format hot reload compiler sources
NatElkins Jul 17, 2026
733a531
Format hot reload compiler sources
NatElkins Jul 17, 2026
1248503
Format hot reload emitter sources
NatElkins Jul 17, 2026
254b36c
Format hot reload session sources
NatElkins Jul 17, 2026
7e8cf28
Format in-process hot reload sources
NatElkins Jul 17, 2026
1b74411
Format umbrella hot reload sources
NatElkins Jul 17, 2026
98f17e7
Verify formatted hot reload stack
NatElkins Jul 17, 2026
c1f2edf
Verify formatted emitted IL baselines
NatElkins Jul 17, 2026
4768d1b
Retry CI after Linux runner memory exhaustion
NatElkins Jul 18, 2026
9d2e6e3
Retry CI after external regression flake
NatElkins Jul 18, 2026
bdb1d28
Add typed-tree diff slice for hot reload
NatElkins Jul 2, 2026
1a5c97e
Make typed-tree diff classification fail closed
NatElkins Jul 17, 2026
f7dd5dd
Format hot reload compiler sources
NatElkins Jul 17, 2026
c2d4c86
Add ECMA-335 EnC metadata delta writer
NatElkins Jul 1, 2026
83696d2
Remove extra EOF blank line in delta metadata tests
NatElkins Jul 8, 2026
6cc71de
Enforce cumulative metadata delta invariants
NatElkins Jul 17, 2026
7e2770f
Format delta metadata writer sources
NatElkins Jul 17, 2026
078961d
Retry CI after regression job timeout
NatElkins Jul 18, 2026
33fceef
Share delta user string encoding and trace configuration
NatElkins Jul 22, 2026
0e55c15
Harden hot reload session capture and file handling
NatElkins Jul 22, 2026
ad6c411
Merge remote-tracking branch 'origin/main' into refresh/20260717/hotr…
NatElkins Jul 22, 2026
e981e30
Handle metadata-only methods in PDB ambiguity checks
NatElkins Jul 22, 2026
1f7a82b
Share delta user string encoding and trace configuration
NatElkins Jul 22, 2026
2be0bff
Merge remote-tracking branch 'origin/main' into refresh/20260717/hot-…
NatElkins Jul 22, 2026
a0573bc
Handle metadata-only methods in PDB ambiguity checks
NatElkins Jul 22, 2026
7f7366d
Share delta user string encoding and trace configuration
NatElkins Jul 22, 2026
e58fd0e
Harden hot reload session capture and file handling
NatElkins Jul 22, 2026
06378d5
Make synthesized name snapshots deterministic
NatElkins Jul 22, 2026
a7d885c
Make synthesized name snapshots deterministic
NatElkins Jul 22, 2026
6129dda
Harden typed-tree diff classification
NatElkins Jul 22, 2026
9b7afdc
Preserve threaded optimizer state in incremental emit cache
NatElkins Jul 22, 2026
2913faf
Merge remote-tracking branch 'origin/main' into refresh/20260717/hotr…
NatElkins Jul 22, 2026
5f85d70
Handle metadata-only methods in PDB ambiguity checks
NatElkins Jul 22, 2026
1463648
Share delta user string encoding and trace configuration
NatElkins Jul 22, 2026
b05b479
Make synthesized name snapshots deterministic
NatElkins Jul 22, 2026
1366c65
Harden hot reload session capture and file handling
NatElkins Jul 22, 2026
4ad2364
Harden baseline metadata parsing
NatElkins Jul 22, 2026
88c0c62
Merge remote-tracking branch 'origin/main' into refresh/20260717/hotr…
NatElkins Jul 22, 2026
9dad496
Handle metadata-only methods in PDB ambiguity checks
NatElkins Jul 22, 2026
e7531a7
Make synthesized name snapshots deterministic
NatElkins Jul 22, 2026
eaaf64e
Harden typed-tree diff classification
NatElkins Jul 22, 2026
2491370
Harden baseline metadata parsing
NatElkins Jul 22, 2026
03b7852
Harden typed-tree diff classification
NatElkins Jul 22, 2026
73e2687
Harden baseline metadata parsing
NatElkins Jul 22, 2026
6ace15d
Harden typed-tree diff classification
NatElkins Jul 22, 2026
ac42fbf
Harden delta metadata identity and cleanup
NatElkins Jul 22, 2026
2aefa5f
Merge remote-tracking branch 'origin/main' into refresh/20260717/hotr…
NatElkins Jul 22, 2026
17f464f
Handle metadata-only methods in PDB ambiguity checks
NatElkins Jul 22, 2026
25eca5c
Share delta user string encoding and trace configuration
NatElkins Jul 22, 2026
98aeadb
Make synthesized name snapshots deterministic
NatElkins Jul 22, 2026
e84c143
Harden typed-tree diff classification
NatElkins Jul 22, 2026
2a827b0
Harden baseline metadata parsing
NatElkins Jul 22, 2026
01d19b1
Harden delta metadata identity and cleanup
NatElkins Jul 22, 2026
6365078
Harden delta metadata identity and cleanup
NatElkins Jul 22, 2026
278deb0
Harden baseline metadata parsing
NatElkins Jul 22, 2026
0e6a58e
Harden delta metadata identity and cleanup
NatElkins Jul 22, 2026
cf1e85b
Preserve threaded optimizer state in incremental emit cache
NatElkins Jul 22, 2026
118edc8
Ignore transient provider scopes in body identity
NatElkins Jul 22, 2026
eb661b3
Ignore transient provider scopes in body identity
NatElkins Jul 22, 2026
20f67d8
Ignore transient provider scopes in body identity
NatElkins Jul 22, 2026
ecc4592
Ignore transient provider scopes in body identity
NatElkins Jul 22, 2026
54eba2f
Preserve recorded synthesized alias replay
NatElkins Jul 22, 2026
9949e24
Preserve recorded synthesized alias replay
NatElkins Jul 22, 2026
aaaf715
Refresh intentional service signature drift guard
NatElkins Jul 22, 2026
e3e089d
Bound decision-tree identity traversal
NatElkins Jul 23, 2026
7ffe458
Bound baseline string heap reads
NatElkins Jul 23, 2026
42d29eb
Bound decision-tree identity traversal
NatElkins Jul 23, 2026
0b44ec4
Fail closed on closure-name recapture mismatch
NatElkins Jul 23, 2026
7b00822
Bound baseline string heap reads
NatElkins Jul 23, 2026
ec0f30b
Bound decision-tree identity traversal
NatElkins Jul 23, 2026
f2d7c1e
Bound baseline string heap reads
NatElkins Jul 23, 2026
f2e3b13
Fail closed on closure-name recapture mismatch
NatElkins Jul 23, 2026
bee5347
Bound decision-tree identity traversal
NatElkins Jul 23, 2026
76c874c
Bound baseline string heap reads
NatElkins Jul 23, 2026
2bc2a0f
Fail closed on closure-name recapture mismatch
NatElkins Jul 23, 2026
f666ebb
Bound decision-tree identity traversal
NatElkins Jul 23, 2026
99d018d
Bound baseline string heap reads
NatElkins Jul 23, 2026
a052db3
Format bounded string heap reader
NatElkins Jul 23, 2026
474bbef
Format bounded string heap reader
NatElkins Jul 23, 2026
9f6a761
Make closure recapture test deterministic
NatElkins Jul 23, 2026
68d281d
Make closure recapture test deterministic
NatElkins Jul 23, 2026
203395e
Make closure recapture test deterministic
NatElkins Jul 23, 2026
e5d6392
Merge remote-tracking branch 'origin/main' into refresh/20260717/hotr…
NatElkins Jul 23, 2026
54cd67d
Merge branch 'main' into enc-metadata-delta-writer
T-Gro Jul 24, 2026
62df5dc
Merge branch 'main' into hotreload-typedtree-diff
T-Gro Jul 24, 2026
8d28083
Merge remote-tracking branch 'origin/main' into refresh/20260717/enc-…
NatElkins Jul 24, 2026
b492d58
Merge remote-tracking branch 'origin/main' into refresh/20260717/hotr…
NatElkins Jul 24, 2026
ead308d
Merge remote-tracking branch 'origin/main' into refresh/20260717/hotr…
NatElkins Jul 24, 2026
7622b7e
Merge remote-tracking branch 'origin/main' into refresh/20260717/hotr…
NatElkins Jul 24, 2026
c83b6ab
Complete hot reload merge integration
NatElkins Jul 24, 2026
6c7a61b
Fix compiled baseline metadata table parsing
NatElkins Jul 24, 2026
4386ab1
Update delta metadata test writer options
NatElkins Jul 24, 2026
e0a38af
Complete baseline reader merge integration
NatElkins Jul 24, 2026
e1d6a50
Merge branch 'refresh/20260717/enc-metadata-delta-writer' into refres…
NatElkins Jul 24, 2026
3ce3b14
Merge branch 'refresh/20260717/hotreload-typedtree-diff' into refresh…
NatElkins Jul 24, 2026
b994397
Merge branch 'refresh/20260717/hotreload-baseline-reader' into refres…
NatElkins Jul 24, 2026
cf0202c
Merge branch 'refresh/20260717/hotreload-delta-emitter' into refresh/…
NatElkins Jul 24, 2026
469a3b2
Complete session merge integration
NatElkins Jul 24, 2026
5b12365
Deduplicate merged compiler source entries
NatElkins Jul 24, 2026
4c0bba2
Merge branch 'refresh/20260717/hotreload-delta-emitter' into refresh/…
NatElkins Jul 24, 2026
c4005a9
Merge branch 'refresh/20260717/hotreload-session' into refresh/202607…
NatElkins Jul 24, 2026
09c6e34
Merge branch 'refresh/20260717/hotreload-inprocess-compile' into refr…
NatElkins Jul 24, 2026
000171d
Remove obsolete baseline reader copy
NatElkins Jul 24, 2026
e9b19d1
Merge branch 'refresh/20260717/hotreload-delta-emitter' into refresh/…
NatElkins Jul 24, 2026
cdbf303
Merge branch 'refresh/20260717/hotreload-session' into refresh/202607…
NatElkins Jul 24, 2026
559848c
Merge branch 'refresh/20260717/hotreload-inprocess-compile' into refr…
NatElkins Jul 24, 2026
2a149c0
Cover baseline metadata table parsing in umbrella
NatElkins Jul 24, 2026
a34afbc
Renumber hot reload driver diagnostics
NatElkins Jul 24, 2026
30b5e44
Merge branch 'refresh/20260717/hotreload-session' into refresh/202607…
NatElkins Jul 24, 2026
e4f27d6
Merge branch 'refresh/20260717/hotreload-inprocess-compile' into refr…
NatElkins Jul 24, 2026
42175e8
Complete umbrella merge integration
NatElkins Jul 24, 2026
24aa4a4
Preserve delta stream builder compatibility
NatElkins Jul 24, 2026
3c49b38
Refresh intentional interface drift guard
NatElkins Jul 24, 2026
0ad1dce
Place baseline reader release note in current FCS notes
NatElkins Jul 24, 2026
47e92ee
Merge refreshed baseline reader release note
NatElkins Jul 24, 2026
5bdb691
Deduplicate composite release notes
NatElkins Jul 24, 2026
88053ca
Merge refreshed delta emitter release notes
NatElkins Jul 24, 2026
1511b10
Give session slice a single current release note
NatElkins Jul 24, 2026
5e4a084
Merge refreshed session release notes
NatElkins Jul 24, 2026
efd961e
Give in-process slice a single current release note
NatElkins Jul 24, 2026
59d5f9b
Merge refreshed in-process release notes
NatElkins Jul 24, 2026
e3b7719
Consolidate umbrella release notes
NatElkins Jul 24, 2026
238ebb6
Keep hot reload diagnostics sorted
NatElkins Jul 24, 2026
12a64db
Merge sorted hot reload diagnostics
NatElkins Jul 24, 2026
a0e1012
Merge sorted hot reload diagnostics
NatElkins Jul 24, 2026
127317f
Format umbrella integration fixes
NatElkins Jul 24, 2026
06e0ad8
Merge current main
NatElkins Jul 24, 2026
e56776f
Merge current main
NatElkins Jul 24, 2026
6218916
Merge current main
NatElkins Jul 24, 2026
2ec1bd2
Merge refreshed enc-metadata-delta-writer
NatElkins Jul 24, 2026
5f359e8
Merge refreshed hotreload-typedtree-diff
NatElkins Jul 24, 2026
b2642b8
Merge refreshed hotreload-baseline-reader
NatElkins Jul 24, 2026
ea8c3d3
Merge refreshed delta emitter
NatElkins Jul 24, 2026
d2b2966
Merge refreshed hot reload session
NatElkins Jul 24, 2026
2c8d3a7
Merge refreshed in-process compiler
NatElkins Jul 24, 2026
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
4 changes: 4 additions & 0 deletions .fantomasignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ src/Compiler/Facilities/prim-parsing.fsi
src/Compiler/Utilities/TaggedCollections.fsi
src/Compiler/Service/ServiceDeclarationLists.fsi

# Fantomas limitation: reformatting produces invalid F# (script uses constructs fantomas mis-handles)

tools/hot-reload/compare_roslyn.fsx

# Fantomas limitations on signature files in FSharp.Core (to investigate)

src/FSharp.Core/fslib-extra-pervasives.fsi
Expand Down
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ mono/launcher text eol=lf
mono/config.make text eol=lf
targets.make text eol=lf

# Hot reload tests embed F# source snippets as string literals and run line-anchored
# string operations ('\n' Replace/Contains) on them; keep these files LF so the snippets
# behave identically on Windows checkouts.
tests/FSharp.Compiler.ComponentTests/HotReload/*.fs text eol=lf
tests/FSharp.Compiler.Service.Tests/HotReload/*.fs text eol=lf

*.sh text eol=lf

*.bsl linguist-vendored=true
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ BenchmarkDotNet.Artifacts/

/tests/scripts/current
.dotnet/
# Also ignore .dotnet as a symlink (the trailing-slash pattern above matches directories only,
# which once let a dev-machine symlink slip into a commit and break every CI checkout).
.dotnet
.packages/
.tools/

Expand Down
5 changes: 5 additions & 0 deletions FSharp.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<BuildType Solution="Proto|*" Project="Release" />
</Project>
</Folder>
<Folder Name="/Tests/HotReloadDemo/">
<Project Path="tests/projects/HotReloadDemo/HotReloadDemoApp/HotReloadDemoApp.fsproj">
<BuildType Solution="Proto|*" Project="Debug" />
</Project>
</Folder>
<Folder Name="/Tests/FSharp.Compiler.Service.Tests support/">
<Project Path="tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj">
<BuildType Solution="Proto|*" Project="Debug" />
Expand Down
23 changes: 20 additions & 3 deletions docs/debug-emit.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,28 @@ Debugging information affects numerous user experiences:
* **Profiling** results
* **Code coverage** results

Some experiences are un-implemented by F# including:
Some debugger experiences remain incomplete in F# including:

* **Autos** during debugging
* **Edit and Continue**
* **Hot reload**
* Full IDE/debugger-host integration for **Edit and Continue** and **Hot Reload**. The compiler
has experimental metadata/IL/PDB delta support and a session API, but Visual Studio/vsdbg
active-statement plumbing is still separate host work.

## Hot reload heap tracing

The hot-reload metadata writer exposes a lightweight tracing hook for capturing heap sizes while iterating on delta emission. Set the environment variable `FSHARP_HOTRELOAD_TRACE_HEAPS=1` before running a targeted test, for example:

```
FSHARP_HOTRELOAD_TRACE_HEAPS=1 ./.dotnet/dotnet test --project tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj -c Debug --no-build -- --filter-class "*FSharpDeltaMetadataWriterTests*"
```

Each delta emitted during the run prints a summary such as:

```
[fsharp-hotreload][heap-summary] baseline:string=1234 blob=2048 guid=256 | delta:string=64 blob=32 guid=0
```

The new service-level regressions (`property/event/async delta reports baseline heap offsets`) validate that `MetadataDelta.HeapOffsets` mirror the baseline reader before any heap reuse changes are made. Combine those tests with the trace output above to document the current string/blob footprint before adjusting the builders.

## Emitted information

Expand Down
192 changes: 192 additions & 0 deletions docs/hot-reload-active-statements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# F# Hot Reload: Active Statements & Sequence Point Updates

This document covers the model types, per-edit sequence-point/line-update computation,
active-statement remapping, and the delta-surface exposure a debugger host consumes.
Source research: Roslyn main @ June 2026 (`src/Features/Core/Portable/Contracts/EditAndContinue/*`,
`ActiveStatement.cs`, `ActiveStatementsMap.cs`, `EditSession.cs`,
`AbstractEditAndContinueAnalyzer.cs` `GetLineEdits`/`AnalyzeUnchangedActiveMemberBodies`).

## Scope

This is the COMPILER-side active-statement machinery: what Roslyn's
`WatchHotReloadService`/`EmitSolutionUpdate` carries on every update even in watch mode. Full
debugger-host integration (VS/vsdbg wire-up, `IManagedHotReloadService` plumbing) is out of local
scope; see "Host integration notes" at the end for what a host has to do.

## Model: Roslyn contract mapping

Public types in `src/Compiler/HotReload/ActiveStatements.fs` (namespace
`FSharp.Compiler.CodeAnalysis`), mirroring `Microsoft.CodeAnalysis.Contracts.EditAndContinue`
field-for-field where semantics match:

| F# type | Roslyn contract type | Notes |
|---|---|---|
| `FSharpSourceSpan` | `SourceSpan` | Zero-based lines AND columns (one less than the 1-based Portable-PDB sequence-point coordinates). F# PDBs always carry columns, so the `-1 = missing column` convention is not modeled. |
| `FSharpManagedModuleMethodId` | `ManagedModuleMethodId` + enclosing `ManagedMethodId` | Module MVID + token + 1-based version. Keeping the MVID in the F# record makes MethodDef-token collisions unambiguous across a multi-project session. |
| `FSharpManagedInstructionId` | `ManagedInstructionId` | Method id + IL offset. |
| `FSharpActiveStatementFlags` + `FSharpActiveStatementFrameKind` | `ActiveStatementFlags` | The `LeafFrame`/`NonLeafFrame` bits become a closed union (`Leaf \| NonLeaf \| LeafAndNonLeaf`) so "neither leaf nor non-leaf" is unrepresentable; `MethodUpToDate`, `PartiallyExecuted`, `NonUserCode`, `Stale` map to independent booleans (they are genuinely independent). |
| `FSharpManagedActiveStatementDebugInfo` | `ManagedActiveStatementDebugInfo` | Instruction + PDB document name (option) + span + flags. |
| `FSharpSourceLineUpdate` | `SourceLineUpdate` | Zero-based old line -> new line. |
| `FSharpSequencePointUpdates` | `SequencePointUpdates` | Per-PDB-document line updates, sorted by old line; zero-delta entries terminate shifted ranges exactly like Roslyn's. |
| `FSharpManagedActiveStatementUpdate` | `ManagedActiveStatementUpdate` | Method id BEFORE the change (echoed from the debugger), old IL offset, new span. |
| `FSharpActiveStatementRemapResult` | — (F#-shaped) | Roslyn's `ManagedHotReloadUpdate.ActiveStatements` carries only remapped statements; F# also reports `MethodUpToDate of FSharpManagedInstructionId` explicitly so hosts/tests can assert untouched methods. |

Delta surface (`FSharpHotReloadDelta`, service.fsi):

- `SequencePointUpdates: FSharpSequencePointUpdates list` — mirrors
`ManagedHotReloadUpdate.SequencePoints`.
- `ActiveStatementUpdates: FSharpActiveStatementRemapResult list` — mirrors
`ManagedHotReloadUpdate.ActiveStatements` (plus the explicit `MethodUpToDate` entries).
- `ManagedHotReloadUpdate.ExceptionRegions` has NO F# counterpart yet (see "Deferred").

## Supplying active statements (API shape)

`FSharpHotReloadSession.SetActiveStatements: FSharpManagedActiveStatementDebugInfo seq -> unit`
(session-scoped setter; REPLACES the whole set; empty clears).

Rationale: Roslyn's `EmitSolutionUpdate(solution, activeStatementSpanProvider)` PULLS the debugger's
break state per edit session (`DebuggingSession` queries
`IManagedHotReloadService.GetActiveStatementsAsync` lazily). FCS has no callback seam into the
host, so the fetch inverts to a push: the host reports the break state whenever the debugger stops,
and the next `FSharpHotReloadSession.EmitDelta` consumes it. A session setter (rather than an
`EmitDelta` parameter) matches the session-scoped lifetime of the break state. The session stores
the debugger batch once and filters it by module MVID for each project emit.

## Sequence-point updates (line shifts)

The typed-tree diff's hashes are deliberately range-independent (in the lambda occurrence model,
ranges are diagnostics-only, never identity), so an edit that only MOVES code produces no semantic edits. Confirmed and wired:
the line updates come from sequence-point comparison alone.

Pipeline (all inside `IlxDeltaEmitter.emitDeltaWithDebugData` + `ActiveStatementAnalysis`):

1. **Committed view** — `FSharpEmitBaseline.SequencePointSnapshots: Map<MethodDef token,
MethodSequencePoints>` is the debugger's current view of each method's lines. Seeded from the
baseline portable PDB at session start (sibling-read from disk in the checker flow, because
`readIlModule` attaches no debug points) and REPLACED wholesale with the fresh compile's points
after every committed update. This matches Roslyn diffing line edits against the
`CommittedSolution`: each generation's updates are relative to what the debugger last applied,
and they compose across generations.
2. **Fresh view** — decoded from the fresh compile's on-disk PDB (passed down from
`FSharpHotReloadSession.EmitDelta` through `EmitDeltaForCompilation`/`EmitDelta`), falling back to the
emitter's in-memory PDB for callers that construct modules with debug points. The same bytes
feed the emitted PDB delta, which therefore carries real sequence points in the checker flow.
3. **Per-method classification** (`compareMethodSequencePoints`, every baseline-matched method not
already recompiled by the request):
- `Identical` — nothing to do (still contributes a zero-delta segment for overlap detection,
Roslyn parity).
- `UniformLineShift d` — same IL offsets, columns and line extents, every visible point moved
by `d` lines: a line-edit segment.
- `Different` — anything else (a line split inside a body, column changes, document changes):
the method body is RECOMPILED in the delta so its debug information stays accurate. This is
the analog of Roslyn's trivia edits forcing a member body update
(`AbstractEditAndContinueAnalyzer` reports `requiresUpdate` and converts the member to a
semantic edit).
4. **Segment merge** (`mergeLineShiftSegments`) — verbatim port of Roslyn `GetLineEdits`: sort by
(document, old start line); zero-delta reset entries terminate shifted ranges; consecutive
equal deltas collapse; segments overlapping a previous segment with a DIFFERENT delta cannot be
expressed as line updates and fall back to recompilation of that method ("the debugger does not
apply line deltas to recompiled methods").

### Line-shift-only deltas

Previously a line-shift edit emitted `NoChanges` (the debugger's lines went silently stale).
Now `EmitDeltaForCompilation` always runs the emitter and decides from the artifacts:

- semantic/trivia changes -> normal delta (line updates ride along for the methods that only moved);
- ONLY line shifts -> a delta carrying ONLY `SequencePointUpdates`: `Metadata`/`IL` empty,
`UpdatedMethods` empty, `GenerationId = Guid.Empty`, NO generation consumed. The updated
sequence-point view and implementation files are staged as one pending line-only update;
`Commit` advances them and `Discard` leaves the committed view unchanged.
- nothing at all -> `NoChanges`, as before.

**Documented deviation**: Roslyn emits a Module-row-only EnC generation for line-only updates (its
`EmitDifference` always runs); the F# emitter deliberately skips the no-op `ApplyUpdate` — there is
nothing for the runtime to apply, hosts just rebind the debugger's lines. If byte-parity with
Roslyn's generation chain ever matters here, the empty-update emit path is the place to add the
Module-row-only delta.

Also note: emits with NO semantic edits no longer register unmatched fresh definitions as
additions — regeneration noise (e.g. a generative type provider re-emitting its members under a
changed static argument with unchanged consumed IL) previously hid behind the `NoChanges`
short-circuit and would otherwise materialize into spurious delta rows.

## Active statement remapping

`ActiveStatementAnalysis.remapActiveStatement(s)`, invoked by
`FSharpEditAndContinueLanguageService.EmitDelta` after the emitter returns and BEFORE any session
state is staged (a rude outcome blocks the whole update and leaves the session at the previous
generation, surfacing as `FSharpHotReloadError.UnsupportedEdit`).

Per supplied statement:

- containing method NOT recompiled by the delta -> `MethodUpToDate` (line shifts, if any, are
covered by `SequencePointUpdates`; Roslyn likewise leaves these to the line deltas).
- containing method recompiled -> resolve the statement's IL offset to the last visible committed
sequence point at or before it, and map BY ORDINAL to the fresh visible points when both sides
have the same visible-point count; the result is
`Remapped { Method = (echoed debugger id); ILOffset = (old offset); NewSpan = (fresh span) }`.

Conservative-but-honest rude fallbacks (F# has no Roslyn syntax map — the diff is typed-tree
based — so ambiguous sequence-point alignment fails TOWARD rude, Roslyn parity for the
statement-destroying classes `ActiveStatementUpdate`/`DeleteActiveStatement`):

| Condition | Outcome |
|---|---|
| visible-point counts differ (statement added/deleted at or around the active statement) | rude |
| NON-LEAF frame and the aligned span changed by anything other than a pure line shift (same columns + line extent) | rude (the runtime cannot remap a non-topmost frame; LEAF frames may move freely — the debugger remaps them) |
| statement is `Stale` or not `MethodUpToDate` and its method is updated again | rude (the executing version is older than the committed view; alignment would be a guess) |
| `PartiallyExecuted` statement in an updated method | rude (Roslyn: partially executed statements can't be edited) |
| no committed or no fresh sequence points for an updated method (no PDB, lost debug info) | rude |
| IL offset resolves into a hidden region or before the first sequence point | rude |

Note the ordinal alignment is stricter than Roslyn: adding a statement anywhere in a method with an
active statement is rude in F# (Roslyn tracks the statement through the syntax map and allows it).
Loosening this requires source-span tracking of the supplied statement spans against the typed
tree — see "Deferred".

## Where things live

- `src/Compiler/HotReload/ActiveStatements.fs` — public model + `ActiveStatementAnalysis`
(decode/classify/merge/remap).
- `src/Compiler/CodeGen/HotReloadBaseline.fs` — `FSharpEmitBaseline.SequencePointSnapshots`.
- `src/Compiler/CodeGen/IlxDeltaEmitter.fs` — `emitDeltaWithDebugData`, in-emitter analysis,
trivia-recompile injection, committed-view chaining, `IlxDelta.SequencePointUpdates` /
`ChainedSequencePoints` / `ActiveStatementUpdates`.
- `src/Compiler/HotReload/EditAndContinueLanguageService.fs` — emit-or-NoChanges decision,
line-only commit, remap + rude gating.
- `src/Compiler/HotReload/HotReloadState.fs` — session `ActiveStatements`,
`UpdateActiveStatements`, `UpdateCommittedSequencePoints`.
- `src/Compiler/Service/service.fs(i)` — `FSharpHotReloadDelta.SequencePointUpdates` /
`ActiveStatementUpdates`, `FSharpHotReloadSession.SetActiveStatements`, on-disk PDB plumbing.
- `tests/FSharp.Compiler.Service.Tests/HotReload/ActiveStatementTests.fs` — line-shift (incl.
disk-restarted session), remap-to-new-span cross-checked against the delta PDB's sequence-point
table, MethodUpToDate, delete-statement rude, non-leaf-edit rude.

## Host integration notes (future watch/debugger wiring)

- **dotnet-watch (no debugger)**: leave the session's active-statement set empty; consume
`SequencePointUpdates` to decide that a line-only change needs NO restart and NO `ApplyUpdate`
(`Metadata` empty). Watch's `HotReloadService` forwards the updates to the agent unchanged.
- **Debugger host**: on break, translate the debugger's active statement info
(`ICorDebugFunction` token/version + IL offset + PDB span) into
`FSharpManagedActiveStatementDebugInfo` and push it; after a successful emit, apply
`SequencePointUpdates` (rebind sequence points/breakpoints) and feed
`ActiveStatementUpdates`' `Remapped` entries to the debugger's IP remapper; on
`UnsupportedEdit` mentioning active statements, surface Roslyn's "restart required" UX.
- Line updates compose: each delta's `OldLine` refers to the lines as of the PREVIOUS applied
update (Roslyn `CommittedSolution` semantics), not to generation 0.
- The committed view survives process restarts only at generation 0 (decoded from the on-disk
PDB); mid-session restore inherits the existing limitation that delta PDBs are not re-read on restore
of a mid-chain session.

## Deferred

- `ManagedExceptionRegionUpdate` (exception-region tracking and non-remappable regions) — Roslyn
computes these from syntax; F# would derive them from the IL exception-region tables of old vs
new bodies.
- Span-based statement tracking to relax the ordinal-alignment rude edits (statement insertion in
a method with an active statement).
- Module-row-only EnC generation for line-only updates (Roslyn byte-parity).
- VS/vsdbg `IManagedHotReloadLanguageService` adapter exposing these payloads over the contract
types.
Loading
Loading