ionide-vscode-fsharp
ionide-vscode-fsharp copied to clipboard
Syntax highlighting and suggestions of import references do not sync upon file modification in multi-project solutions.
Describe the bug
When working with solutions with multiple projects, updating a file in one project will not update syntax highlighting and suggestions for imported modules in another project. As an example, one can add a module to a file in project 1, go to project 2, and that new module won't show up in suggestions and will show an error bar below if the module is typed in.
Steps to reproduce (on Linux with the dotnet CLI)
Set up the environment
- Start by making an entirely new solution folder with
dotnet new sln -o bugReport - cd to the new folder
cd bugReport - In the new bugReport folder make a new project with
dotnet new library -lang "F#" -o bugLib - Add the new project to the solution
dotnet sln add bugLib/bugLib.fsproj - Make a second new project
dotnet new console -lang "F#" -o bugHello - Add this second project to the solution
dotnet sln add bugHello/bugHello.fsproj - Add a reference to the library project to the console project
dotnet add bugHello/bugHello.fsproj reference bugLib/bugLib.fsproj
Our testing environment is set up now
Reproduce the bug
- Open our new solution folder in code
code . - Reference our library in our bugHello
program.fsfile
- Remove unnecessary boilerplate and call our pre-existing method in our bugLib.Say module. This module and the method
Sayexisted before we opened VS code, so syntax highlighting and suggestions should work for this module and method.
- If we run the project now with
dotnet run --project bugHello, our console should give us the iconic "Hello World!" message. This is all expected behavior. - Now, if we add another method to our library and save, suggestions and highlighting for that new method will not work in our
program.fsfile

- We can prove that this code still compiles and works by just running
dotnet run --project bugHelloagain. We should see two messages, confirming that our goodbye method is working. - If we close and re-open VS Code or reload the window with
Ctrl - Shift - P>>Developer: Reload Window, the highlighting and suggestions should be fixed. - Finally, if we remove these two methods (
helloandgoodbye) from ourSaymodule, the highlighting will not represent that these methods no longer exist when we look at ourprogram.fs
Link to sample reproduction
Here's the trivial solution we built above in repo form. Play around with it by adding and removing methods from bugLib.Say and verify that syntax highlighting and suggestions don't properly update when viewing program.fs.
https://github.com/zacharylott94/fsharp-ionide-bug
Expected behaviour
I would expect editing a file in a different project in the solution would update the syntax highlighting and suggestions in another project in the same opened solution.
Machine info
- OS: Linux Mint 19.3 (Tricia)
- .NET SDK version: 5.0.404
- Ionide version: 5.10.2
Additional context
A user on the F# Discord suggest that this is a bug in FsAutoComplete. Here's a screenshot.

I did some work in FSAC and found that we have three distinct scenarios that we need to handle:
- Script file direct dependencies (script A #loads script B)
- Dependent files in the same project (file B uses code from file B in the same project)
- Dependent files across projects (file B in project B uses code from file A in project A)
The first two are fairly straightforward to solve: after checking a file, trigger checking of dependent files. For scripts, this means finding other scripts where the OriginalLoadReferences include your newly-parsed file. For source files, this means taking the list of SourceFiles for the project and finding all other source files that are after this file in the array. Then, we call our Parse helper function which ensures notifications are up to date, which ends up with the user experience you want:
A:

B:

The third case is substantially harder. Here's my hypothesis: we can trigger re-checking of the files in other projects, but as part of checking the metadata of the earlier project is read from the dll on the disk, which in an editor scenario isn't always up to date (because this requires actually writing the bytes). We would need to implement our own version of the tryGetMetadataSnapshot lambda that can be passed into the Checker in order to have this kind of functionality, and that's a lot of work. The VS integration does just this, but it does so by leaning on a lot of VS services that we don't have in VS code, so we'd need to recreate a lot of infrastructure.
Ultimately, I want to land the changes for parts 1 and 2 in the very near term, and look into 3 as a longer term effort. There's too many unknowns for me personally to put a reasonable guess at the work there. Like maybe we'd get around that by triggering compilation to a temp location and then creating metadata readers for those locations? Who knows 🤷
Hello :smile_cat:
I found this issue while looking for existing issues for a scenario that I think is related. We have a project that uses a lot of #r farts_lib.dll type references in .fsx files. Where the referenced DLL is being built from an .fsproj in the same repo.
I'm not aware of the details of how all of this works, but this seems simpler than the hard 3rd scenario that @baronfel described above in that the language server doesn't need to do any compiling and caching on its own. Rather, the existing DLL just needs to be watched and re-scanned when it is over-written.
I also asked on slack here if there's a way to do this manually. This seems like a valid intermediate solution if there's a way to add a command to the VSCode command palette to "Regenerate Completions" or similar.
Currently, the only way that we have found to get the completions to be correct is to close and restart VSCode. Which is pretty annoying.
@tymokvo this kind of last-modified-based invalidation should be handled already by the compiler APIs we're using - part of my puzzlement here is that it doesn't seem to be taken into account.