FsAutoComplete installs a process-wide FileSystemAutoOpens.FileSystem shim so FCS reads the in-memory text of open files. We would like to stop doing that and give each checker its own view of the files (ionide/FsAutoComplete#1555). With the TransparentCompiler, project files already come from snapshots we build ourselves. Scripts are the part that still goes through the global file system, and the per-checker alternative, DocumentSource.Custom, does not work well there yet.
Links are to main at 409c7a6.
1. GetProjectSnapshotFromScript ignores the checker's document source
FSharpChecker.GetProjectSnapshotFromScript falls back to DocumentSource.FileSystem when no documentSource is passed, also when the checker was created with DocumentSource.Custom (service.fs#L533). The TransparentCompiler's GetProjectOptionsFromScript always passes DocumentSource.FileSystem (TransparentCompiler.fs#L2377). So the files a script #loads are read through the global file system (FSharpProjectSnapshot.fs#L81-L89).
2. A custom document source gives every file snapshot a new version
FSharpFileSnapshot.CreateFromDocumentSource uses DateTime.Now.Ticks as the version (FSharpProjectSnapshot.fs#L95). Each call creates new versions for files that did not change, so the TransparentCompiler caches miss. This happens for:
3. None from a custom document source throws
When the function returns None, CreateFromDocumentSource fails with "Couldn't get source for file" (FSharpProjectSnapshot.fs#L104). The BackgroundCompiler reads the file from disk in that case (FSharpSource.fs#L69-L77). An editor only knows the text of its open files, so with the TransparentCompiler it has to read every other file itself.
Possible changes
- Use the checker's document source in
GetProjectSnapshotFromScript when none is passed.
- Let a custom source return a version with the text, or use a stable version, for example the last write time for files read from disk.
- Treat
None as "read from the file system", as the BackgroundCompiler does.
- Or, for the snapshot API: let the caller create the snapshots of the
#loaded files (a string -> Async<FSharpFileSnapshot> callback), as it already does for project files.
documentSource on FSharpChecker.Create is marked experimental and "likely to be removed in the future" (service.fsi#L53). If that is still the plan, which way should an editor give the TransparentCompiler the text of open files that a script #loads?
FsAutoComplete installs a process-wide
FileSystemAutoOpens.FileSystemshim so FCS reads the in-memory text of open files. We would like to stop doing that and give each checker its own view of the files (ionide/FsAutoComplete#1555). With the TransparentCompiler, project files already come from snapshots we build ourselves. Scripts are the part that still goes through the global file system, and the per-checker alternative,DocumentSource.Custom, does not work well there yet.Links are to
mainat 409c7a6.1.
GetProjectSnapshotFromScriptignores the checker's document sourceFSharpChecker.GetProjectSnapshotFromScriptfalls back toDocumentSource.FileSystemwhen nodocumentSourceis passed, also when the checker was created withDocumentSource.Custom(service.fs#L533). The TransparentCompiler'sGetProjectOptionsFromScriptalways passesDocumentSource.FileSystem(TransparentCompiler.fs#L2377). So the files a script#loads are read through the global file system (FSharpProjectSnapshot.fs#L81-L89).2. A custom document source gives every file snapshot a new version
FSharpFileSnapshot.CreateFromDocumentSourceusesDateTime.Now.Ticksas the version (FSharpProjectSnapshot.fs#L95). Each call creates new versions for files that did not change, so the TransparentCompiler caches miss. This happens for:#loaded files whenGetProjectSnapshotFromScriptis givenDocumentSource.Custom(TransparentCompiler.fs#L2483);FSharpProjectOptionsbased call on a TransparentCompiler created withDocumentSource.Custom, throughFSharpProjectSnapshot.FromOptions(FSharpProjectSnapshot.fs#L715-L738).3.
Nonefrom a custom document source throwsWhen the function returns
None,CreateFromDocumentSourcefails with "Couldn't get source for file" (FSharpProjectSnapshot.fs#L104). The BackgroundCompiler reads the file from disk in that case (FSharpSource.fs#L69-L77). An editor only knows the text of its open files, so with the TransparentCompiler it has to read every other file itself.Possible changes
GetProjectSnapshotFromScriptwhen none is passed.Noneas "read from the file system", as the BackgroundCompiler does.#loaded files (astring -> Async<FSharpFileSnapshot>callback), as it already does for project files.documentSourceonFSharpChecker.Createis marked experimental and "likely to be removed in the future" (service.fsi#L53). If that is still the plan, which way should an editor give the TransparentCompiler the text of open files that a script#loads?