Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Give FCS open file contents per checker (DocumentSource) instead of the global FileSystem

Open
#1,555 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
12/100
Issue type
Refactor
Clarity
Mostly clear
Activity status
Active
Tech stack
fsharp

Research direction

Start with the global shim in src/FsAutoComplete.Core/FileSystem.fs and the SharedFileSystem registry in AdaptiveServerState.fs, then trace where FSAC hands open-file text to the FCS checker. The issue sets the goal: create checkers with DocumentSource.Custom, call NotifyFileChanged on did change, did save and close, and keep only the path helpers process-wide. Done means no static server state remains, two servers in one process cannot see each other's open files, and the LSP test groups can run in parallel on shared folders.

Written by the indexing model from the issue text.

Description

Summary

FSAC gives FCS the contents and timestamps of open files through the process-wide FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem. FCS also offers a per-checker way to do this, FSharpChecker.Create(documentSource = DocumentSource.Custom getSource). Moving to it would remove the last piece of shared, process-wide state between language servers in one process.

Today

Every AdaptiveState installs FSAC's FileSystem shim (src/FsAutoComplete.Core/FileSystem.fs) as the global FCS file system. The shim does three things:

  1. OpenFileForReadShim returns the in-memory text of open files.
  2. GetLastWriteTimeShim returns the time an open file was last changed, which is how FCS notices edits and rechecks.
  3. IsPathRootedShim, GetFullPathShim and NormalizePathShim handle paths in an OS-agnostic way.

Until #1554 each state wrapped the global file system around the previous one and never unwrapped it, so every state ever created stayed reachable. #1554 replaces that with a registry (SharedFileSystem in AdaptiveServerState.fs) that asks each live state for its open files, newest first, and lets a disposed state unregister. That fixes the leak, but the state is still shared: when two servers in one process have the same file open, FCS reads of one can see the text of the other. The test suite runs LSP test groups in parallel since #1554, and has to keep groups that use the same TestCases folder from overlapping for that reason. In the product there is one server per process, so it does not show there.

The alternative

DocumentSource.Custom gives each checker its own source of file text. Two things change with it (FCS main):

  • FCS stamps each source file once, when the incremental builder is created, instead of asking for its last write time (IncrementalBuild.fs#L1647-L1653).
  • A custom document source switches the checker to change notifications (service.fs#L215-L218), so FSAC has to call checker.NotifyFileChanged (service.fs#L376) when an open file changes. Today the shim's last write times do this implicitly.

So the work is roughly:

  • Create the checker with DocumentSource.Custom, answering from the state's open files and falling back to disk.
  • Call NotifyFileChanged where open files change (did change, did save, close), for the BackgroundCompiler. The TransparentCompiler already gets file versions through its snapshots; check whether it still reads through the global file system anywhere.
  • Keep only the path members (3.) in a process-wide shim, or drop the shim if FCS's defaults are fine there. They hold no per-server state.
  • Remove SharedFileSystem, and let the test suite run groups on the same folders in parallel.
Why
  • No server state reachable from a static; the per-server file view lives with the checker.
  • Servers in one process cannot read each other's open files.
  • Explicit invalidation instead of timestamp comparisons on every file read.
Dominant language
F#
Stars
489
Forks
173
Avg merge
2d 7h
Merged PRs (30d)
10

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ionide/FsAutoComplete

All issues in ionide/FsAutoComplete

Similar issues

More Compilers issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.