dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.88k stars 783 forks source link

IDE code analysis starts to freeze on large files affecting Intellisense, text coloring, tooltips and responsiveness #16050

Open edgarfgp opened 1 year ago

edgarfgp commented 1 year ago

While working in Fabulous.Avalonia, had my project in a refactoring "broken" state, and suddenly it went in a borked state . Had to manually remove parts of the code until the IDE was able to handle it again. Repro steps Provide the steps required to reproduce the problem:

If possible, attach a zip file with the repro case. This often makes it easier for others to reproduce. The zip file should ideally represent the situation just before the call/step that is problematic.

You can find the related IDE snapshot if that help diagnosing the issue https://github.com/fabulous-dev/Fabulous.Avalonia/tree/repro-code-analysis-freeze/idesnapshots

Expected behavior Regardless of the state of your project. the IDE should be able to analyze/report the state of your code.

Actual behavior IDE code analysis starts to freeze on large files affecting Intellisense, text coloring, tooltips and responsiveness

Known workarounds Start removing part of the code in State.fs until the IDE/Compiler is able to handle the solution Provide a description of any known workarounds.

Related information

Provide any related information (optional):

vzarytovskii commented 1 year ago

This needs an FCS or VS repro, since we're unable to debug rider, and I can't see it in latest VS.

vzarytovskii commented 1 year ago

@auduchinok how old is FCS fork in the affected version?

0101 commented 1 year ago

When opening the solution in VS I get: image

Output Window says: Some of the properties associated with the solution could not be read.

But Gallery/Root/State.fs seems to work fine, with coloring, tooltips, completions and hints.

edgarfgp commented 1 year ago

When opening the solution in VS I get: image

Output Window says: Some of the properties associated with the solution could not be read.

But Gallery/Root/State.fs seems to work fine, with coloring, tooltips, completions and hints.

Had the same issue and I think is because VS does not support “SingleProject” apart of the Maui one right ? It only works with Rider and that is why difficult for me to have a repro in VS

vzarytovskii commented 1 year ago

When opening the solution in VS I get: image

Output Window says: Some of the properties associated with the solution could not be read.

But Gallery/Root/State.fs seems to work fine, with coloring, tooltips, completions and hints.

Had the same issue and I think is because VS does not support “SingleProject” apart of the Maui one right ? It only works with Rider and that is why difficult for me to have a repro in VS

What is SingleProject? We don't explicitly support or restrict it in FSharp.Build.

edgarfgp commented 1 year ago

When opening the solution in VS I get: image

Output Window says: Some of the properties associated with the solution could not be read.

But Gallery/Root/State.fs seems to work fine, with coloring, tooltips, completions and hints.

Had the same issue and I think is because VS does not support “SingleProject” apart of the Maui one right ? It only works with Rider and that is why difficult for me to have a repro in VS

What is SingleProject? We don't explicitly support or restrict it in FSharp.Build.

Target multiple platforms from Avalonia single project . Similar to what Maui does it. More info https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/single-project

Update: Basically NET 7 single project with MsBuild custom targets for Mobile,Desktop

majocha commented 12 months ago

Yeah, I can repro. Eats up all memory and freezes VS. Similar effect with just running dotnet build on the solution, eats all RAM, seem to be stuck, never finishes.

Looks like the problem occurs earlier than State.fs, uncommenting code in NavigationState.fs revives the analysis.

vzarytovskii commented 12 months ago

Yeah, I can repro. Eats up all memory and freezes VS.

Similar effect with just running dotnet build on the solution, eats all RAM, seem to be stuck, never finishes.

Looks like the problem occurs earlier than State.fs, uncommenting code in NavigationState.fs revives the analysis.

What's the VS version?

majocha commented 12 months ago

Version is current preview, I can see it also in Rider EAP.

vzarytovskii commented 12 months ago

@0101 you weren't able to repro it on main, right?

majocha commented 12 months ago

@vzarytovskii It does repro on main (but make sure to be on the correct branch that Edgar provided: repro-code-analysis-freeze)

I did a snapshot and it seems that the compiler allocates quite a lot of these:

image
vzarytovskii commented 12 months ago

Ok, one difference I see with main is that it now uses CEs a lot more. It's a kind of known issue with them.

auduchinok commented 12 months ago

Ok, one difference I see with main is that it now uses CEs a lot more. It's a kind of known issue with them.

It's an interesting point, but both performance snapshots and memory snapshot screenshot above point to pattern match compilation, not computation expressions. Regardless, I think we should think how to make IDEs perform better in the face of such code.

vzarytovskii commented 12 months ago

Ok, one difference I see with main is that it now uses CEs a lot more. It's a kind of known issue with them.

It's an interesting point, but both performance snapshots and memory snapshot screenshot above point to pattern match compilation, not computation expressions. Regardless, I think we should think how to make IDEs perform better in the face of such code.

It is used in many places, in the codegen for comparers, for example as well. Wondering what are the roots for the allocations in the dump above, @majocha do you have the dump still?

majocha commented 12 months ago

@vzarytovskii, sorry I don't have it. But I extracted the problematic code for easier repro: https://gist.github.com/majocha/71a6a7f9ceed273fe1511faa7777c5ed

auduchinok commented 12 months ago

@majocha Could you try to extract that into a console app project, so dependencies and script-specific things couldn't influence the issues, please?

majocha commented 12 months ago

@auduchinok https://github.com/majocha/IdeFreeze should repro in Rider EAP as soon as you open Program.fs

vzarytovskii commented 12 months ago

@auduchinok majocha/IdeFreeze should repro in Rider EAP as soon as you open Program.fs

Even without the packages?

majocha commented 12 months ago

@vzarytovskii all I do is open the solution from https://github.com/majocha/IdeFreeze, open Program.fs in the editor and observe memory consumption go up and up. I guess IDE automatically restores FSharp Core on load: Packages when opened in VS:

image
vzarytovskii commented 12 months ago

Looks like a weird loop of rewriting/investigating pattern matching. Where TDSwitch is getting recreated for the whole decision tree.

auduchinok commented 12 months ago

Even without the packages?

This actually could be the reason for the analysis explosion if, for example, it builds a bigger decision tree on each unresolved name error like that.

Edit:

Looks like a weird loop of rewriting/investigating pattern matching. Where TDSwitch is getting recreated for the whole decision tree.

Yes, exactly, it's something like what I've had on my mind, I haven't seen your reply.

vzarytovskii commented 12 months ago

Probably related or the same issue as https://github.com/dotnet/fsharp/issues/15086

edgarfgp commented 11 months ago

Thanks @majocha for finding a minimal repro for this issue. I hope in the future we can make IDEs perform better in this cases like this, When using elmish model is really common to have long update function with a lot of DU cases and the IDE will explode in the middle of a refactoring phase :(

psfinaki commented 4 months ago

Hey @majocha can you check if this still reproduces in the latest VS? I tried your repro, both the script and the project, nothing terrible is happening on my machine.

I couldn't get to the original Fabulous repro, the branch doesn't exist anymore I think.

abelbraaksma commented 4 months ago

@edgarfgp, can you update the link in the original issue text? This gives a 404 (or instead, just paste whatever images are supposed to be there?): https://github.com/fabulous-dev/Fabulous.Avalonia/tree/repro-code-analysis-freeze/idesnapshots (edit: I think @psfinaki had the same issue with that repo, lol, maybe point to a specific commit in main?).

I just tried to understand what used to happen here as currently, I sometimes see only partial refresh of source code highlighting, leading to parts staying grey/white-ish.

smoothdeveloper commented 4 months ago

I just tried to understand what used to happen here as currently, I sometimes see only partial refresh of source code highlighting, leading to parts staying grey/white-ish.

Seeing this quite frequently in VS, I'm wondering if it wouldn't be helpful to have some kind of watchdog in VS / interaction with FCS: if a document is not semantically colorized / type checked after arbitrary time limit and nothing is in the queue for this document, maybe it should be attempted again?

edgarfgp commented 4 months ago

@edgarfgp, can you update the link in the original issue text? This gives a 404 (or instead, just paste whatever images are supposed to be there?): https://github.com/fabulous-dev/Fabulous.Avalonia/tree/repro-code-analysis-freeze/idesnapshots (edit: I think @psfinaki had the same issue with that repo, lol, maybe point to a specific commit in main?).

I just tried to understand what used to happen here as currently, I sometimes see only partial refresh of source code highlighting, leading to parts staying grey/white-ish.

Fortunately I had a copy in my local machine. It should work now @abelbraaksma @psfinaki.

Tried and in Rider and this branch still freezes and eats all my memory.

vzarytovskii commented 4 months ago

@edgarfgp, can you update the link in the original issue text? This gives a 404 (or instead, just paste whatever images are supposed to be there?): https://github.com/fabulous-dev/Fabulous.Avalonia/tree/repro-code-analysis-freeze/idesnapshots (edit: I think @psfinaki had the same issue with that repo, lol, maybe point to a specific commit in main?).

I just tried to understand what used to happen here as currently, I sometimes see only partial refresh of source code highlighting, leading to parts staying grey/white-ish.

Fortunately I had a copy in my local machine. It should work now @abelbraaksma @psfinaki.

Tried and in Rider and this branch still freezes and eats all my memory.

@psfinaki Rider is behind in the version of FCS it uses, it needs to be tested on the main with vsix deployed. There were a couple of changes in the CEs recently, but I wouldn't expect it to be fixed.

edgarfgp commented 4 months ago

There was attempt to improve this https://github.com/dotnet/fsharp/pull/16430 but got abandoned

abelbraaksma commented 4 months ago

Seeing this quite frequently in VS, I'm wondering if it wouldn't be helpful to have some kind of watchdog in VS / interaction with FCS: if a document is not semantically colorized

@smoothdeveloper yeah, same here, but it's not likely the same issue that plagues the freezing of IDE as mentioned here. Perhaps we should create a separate issue on the repaint/refresh problem?

I did notice something odd while testing, though. I changed all colors to one single color and tested that in VS. This worked initially, but after some time, it magically refreshed and showed the expected color encodings, though partially (it shouldn't have shown any coloring, as I hard-coded them. This seems to point to some caching and/or separate location in the code where coloring is done).

majocha commented 4 months ago

@psfinaki I tested on main and it still eats memory indefinitely.

vzarytovskii commented 4 months ago

@psfinaki I tested on main and it still eats memory indefinitely.

Yes, that what I would expect. Decision trees compilation is very heavy, and more issues you have in code, the worse it will be. Ideal solution would be to move TClause to typed tree and do most (if not all) checks in the post inference phase.

Additionally there can be a switch for tooling to skip tdswitch compilation as a whole. And only do it when compiling. Unsure about this one though.