JetBrains / JetBrains/resharper-fsharp

Too many parsing requests for the active file on every edit/focus.

Open
#492 6 comments 0 reactions 0 assignees View on GitHub
Dominant language
F#
Stars
351
Forks
55
Avg merge
9h 38m
Merged PRs (30d)
16

Description

Parsing can take ~10-20% of time to check files/projects. I think some of the requests are not necessary.
This compounded by [lack of parsing caching in FCS](https://github.com/dotnet/fsharp/issues/14848) means there is a lot of unnecessary work happening all the time in the IDE.

I'm running Rider with a locally built FCS.
I added a breakpoint here: https://github.com/JetBrains/fsharp/blob/35e742b334353de45b11d1d5c4cfecb02e6e58fe/src/Compiler/Driver/ParseAndCheckInputs.fs#L428
and can see that the parsing happens more often than I would expect when editing/focusing on files.

Some extract showing the parsing events.
Every `ParseInput(fileName)` means a single call to the above method.
The other lines reflect user actions:
```
1. Change cursor position in the editor
ParseInput(Sandbox.fs)
ParseInput(Sandbox.fs)
2. Change cursor position again
ParseInput(Sandbox.fs)
ParseInput(Sandbox.fs)
3. Type a single character
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(Sandbox.fs)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(Sandbox.fs)
4. Click outside the Rider window
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
5. Click again inside the editor
ParseInput(Sandbox.fs)
ParseInput(Sandbox.fs)
6. Type a single character
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
```

The following is a result of these 3 steps:
1. focus on editor
2. type `let x = 1`
3. leave focus
```
ParseInput(Sandbox.fs)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(Sandbox.fs)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(Sandbox.fs)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(Sandbox.fs)
ParseInput(Sandbox.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
ParseInput(C:\projekty\fantomas\src\Fantomas\AssemblyInfo.fsi)
```

It does feel like there are a few too many calls to parse a file. In particular I can see the following issues:
1. Cursor position change triggers two parsing requests.
2. Typing a single character causes four parsing requests.
3. Clicking outside the window triggers a parsing request.
4. There are separate requests for `Sandbox.fs` and `AssemblyInfo.fsi`.
5. Subsequent calls for `AssemblyInfo.fsi` do not hit the parsing cache. I can see the right entry in the cache, but parsing still occurs - see the screenshot below. This one is probably to be fixed in FCS, but still relevant:
image

More context for 5.:
I found that one of the reasons caching doesn't work is that the two caching keys, while otherwise identical, have a different set of `FSharpParsingOptions.ConditionalDefines`. One of them has these two extra defines: `EDITING ; COMPILED` at the top (note that `COMPILED` also appears at the end of the list in both.
image
image
Is this set of defines controlled by Rider? If so, could the sets in both calls be aligned?

Contributor guide

No contributing guide indexed for this repository

Research direction

Reproduce the listed editor focus, cursor, and typing actions while tracing ParseInput calls at ParseAndCheckInputs.fs line 428. Compare the requests for Sandbox.fs and AssemblyInfo.fsi, including their FSharpParsingOptions.ConditionalDefines and cache entries; done means the redundant parsing behavior and cache-key mismatch are explained and addressed.

Written by the indexing model from the issue text.

Assessment

Tech stack
fsharp
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.