|
| 1 | +# Code Fixes In F# |
| 2 | + |
| 3 | +Code fixes are suggestions provided by IDEs to automatically address coding issues. In Visual Studio, they fall under the category of [Quick Actions](https://learn.microsoft.com/visualstudio/ide/quick-actions) and are displayed within the light bulb icon menu. |
| 4 | + |
| 5 | +## Quick Facts |
| 6 | + |
| 7 | +1. Code fixes are triggered by one or more [diagnostics](https://github.com/dotnet/fsharp/blob/main/docs/diagnostics.md) (e.g., FS0039 and/or IDE0005). |
| 8 | +1. If there are multiple diagnostics, they are guaranteed to share the same _span_ (the red squiggly). |
| 9 | +1. Every code fix can produce: |
| 10 | + - No suggestions (got triggered but couldn't come up with a suitable suggestion for a fix). |
| 11 | + - One suggestion (e.g., "Discard unused value"). |
| 12 | + - Multiple suggestions (e.g., "Open namespace X" or "Fully qualify namespace X"). |
| 13 | + |
| 14 | + |
| 15 | + |
| 16 | +_Bulk code fixes_ perform the same actions for identical diagnostics across a document/project/solution: |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | +## Technical Implementation |
| 21 | + |
| 22 | +- Code fixes need to adhere to certain Visual Studio API requirements: |
| 23 | + - Have the `[<ExportCodeFixProvider>]` attribute. |
| 24 | + - Inherit from the `CodeFixProvider` class. |
| 25 | +- When inheriting `CodeFixProvider`, a few members should be overridden: |
| 26 | + - `FixableDiagnosticIds` - lists all diagnostics triggering the code fix. |
| 27 | + - `RegisterCodeFixesAsync` - has the primary code fix logic. |
| 28 | + - `GetFixAllProvider` - needed for those with bulk behavior. |
| 29 | +- On top of that, we have our own framework for F# code fixes, found in the `IFSharpCodeFix.fs` file. In that regard, code fixes should implement one of: |
| 30 | + - The `IFSharpCodeFixProvider` interface - for those generating at most one suggestion (the majority). |
| 31 | + - The `IFSharpMultiCodeFixProvider` interface - for those able to produce several suggestions. |
| 32 | +- Code fixes within the above framework can and should be unit tested. |
| 33 | + |
| 34 | +## Improving Existing Code Fixes |
| 35 | + |
| 36 | +1. Find the corresponding unit test suite. |
| 37 | +2. Introduce a test featuring the code with the diagnostic alongside the expected code fix behavior (0, 1, or multiple suggestions). |
| 38 | +3. Adopt a TDD approach and modify the code fix logic. Keep in mind that occasionally, issues might originate in the compiler layer. |
| 39 | + |
| 40 | +## Creating New Code Fixes |
| 41 | + |
| 42 | +1. Create a matching unit test suite with both positive and negative cases. |
| 43 | +2. Seek a similar code fix for inspiration. |
| 44 | +3. Craft your new code fix, ensuring compliance with the framework described above. |
| 45 | +4. Just before submitting the code fix, manually double-check that it works in VS - demo videos are welcome. |
| 46 | + |
| 47 | +## Useful Links: |
| 48 | + |
| 49 | +1. [Code fix tracking issue](https://github.com/dotnet/fsharp/issues/15408) - tracks bugs, enhancements, and suggestions for new code fixes. |
| 50 | +2. [A session from Amplifying F#](https://amplifying-fsharp.github.io/sessions/2023/06/16/) that largely focuses on crafting code fixes. |
0 commit comments