vscode-csharp
vscode-csharp copied to clipboard
Support for source generators
Issue Type: Bug
.Net team introduced source generators and OmniSharp doesn't work correctly with them.
I enabled Analyzers in VS Code and this works well. After I added a source generator to a project Intellisense doesn't work in the source generator file and I see errors in log.
[warn]: OmniSharp.Roslyn.CSharp.Workers.Diagnostics.AnalyzerWorkQueue
Timeout before work got ready for foreground analysis queue. This is assertion to prevent complete api hang in case of error.
[fail]: OmniSharp.MSBuild.ProjectManager
Failure while loading the analyzer reference 'TypeCatalogGenenerator': Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
[warn]: OmniSharp.Roslyn.CSharp.Workers.Diagnostics.AnalyzerWorkQueue
Timeout before work got ready for foreground analysis queue. This is assertion to prevent complete api hang in case of error.
[warn]: OmniSharp.Roslyn.CSharp.Workers.Diagnostics.AnalyzerWorkQueue
Timeout before work got ready for foreground analysis queue. This is assertion to prevent complete api hang in case of error.
It seems OmniSharp run the source generator like an analyzer although it shouldn't have to.
Extension version: 1.23.6 VS Code version: Code 1.51.1 (e5a624b788d92b8d34d1392e4c4d9789406efe8f, 2020-11-10T23:34:32.027Z) OS version: Windows_NT x64 10.0.18363
System Info
| Item | Value |
|---|---|
| CPUs | Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz (4 x 2295) |
| GPU Status | 2d_canvas: enabled flash_3d: enabled flash_stage3d: enabled flash_stage3d_baseline: enabled gpu_compositing: enabled multiple_raster_threads: enabled_on oop_rasterization: unavailable_off opengl: enabled_on protected_video_decode: unavailable_off rasterization: unavailable_off skia_renderer: disabled_off_ok video_decode: enabled vulkan: disabled_off webgl: enabled webgl2: enabled |
| Load (avg) | undefined |
| Memory (System) | 3.91GB (0.53GB free) |
| Process Argv | --crash-reporter-id a4f7808b-f735-44a7-add9-c658fbcfd849 |
| Screen Reader | no |
| VM | 0% |
@iSazonov Sorry you are running into issues with Generators. Can you share your full OmniSharp log from the Output pane?
@JoeRobich I experimented with source generators in last days and they works very strange. I see .Net team intends to improve them in the next .Net 6.0 milestone and actively use them in the .Net Runtime. I guess they will have to make a lot of changes to how it works. I don't think there is anything that can be done in OmniSharp right now due to the limitations in their implementation. So let's treat my report as a tracking issue.
PS: after I disabled analyzers in OmniSharp config IntelliSense works in the source generator file.
@iSazonov shared the implementation in another issue as https://github.com/iSazonov/PowerShell/commit/80e5ba9b40654d67d0276a006d2572f78b932b46
I'm not sure if this is because of the System.Reflection.MetadataLoadContext reference there; the that's going to be bringing in other dependencies that aren't being packaged by the generator package.
@iSazonov was there a reason you're using MetadataLoadContext to access symbols as opposed to accessing them in via the Roslyn symbol models? That'll be a lot faster (you're not reloading symbols multiple times) and would also avoid your loading issue.
@jakubfijalkowski I used a code from TypeCatalogGen project from PowerShell repository (the tool is used today in design time.). Thanks for the idea to use Roslyn symbol models! I will try this after source generators become more available in .Net 6.0.
I got similar error:
[fail]: OmniSharp.MSBuild.ProjectManager
Failure while loading the analyzer reference 'PersistentJobs.Generator':
Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
or one of its dependencies. The system cannot find the file specified.
I was getting same error in Visual Studio 2022 and Omnisharp, however building and running tests work.
FIXED
Your Generator project must target netstandard2.0 instead of net6.0, not sure why it breaks the omnisharp and Visual Studio 2022, but dotnet cli tool works.
This is a CSProj that worked for the generator:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.0.0" PrivateAssets="all" />
</ItemGroup>
</Project>
(Note that main project can still target .net6.0)
Your Generator project must target netstandard2.0 instead of net6.0, not sure why it breaks the omnisharp and Visual Studio 2022, but dotnet cli tool works.
Omnisharp and Visual Studio 2022 aren't internally running on net6.0, so we can't run code targeting that. (It's still a mix of Mono and the traditional .NET Framework). That's why we have you target netstandard2.0, so stuff can run everywhere.
Unclear if this is related to #4550 - the inability to properly navigate generated source files - but that's the challenge I'm running into. More specifically, while you can access generated source, that generated source won't let you navigate back to the main project or to other symbol references/definitions.
Let's say you have a source generator project MyProj.CodeGen and in there you have a source generator MyProj.CodeGen.MyGenerator. Inside GeneratedClass1 you do something like this:
public namespace MyProj;
public class GeneratedClass1
{
public void DoWork()
{
throw new NotSupportedException();
}
}
If you hit F12 on a usage of GeneratedClass1.DoWork you can navigate to the generated source, but it looks like it's in an odd folder location - /MyProj.CodeGen/MyProj.CodeGen.MyGenerator/GeneratedClass1.g.cs
Here's where the problem comes in - because of that weird folder name. If you then click on NotSupportedException and hit F12 to navigate to the definition, you'll fail, because /MyProj.CodeGen/MyProj.CodeGen.MyGenerator/GeneratedClass1.g.cs isn't a real file:
[warn]: OmniSharp.Roslyn.CSharp.Services.Navigation.FindUsagesService
No document found. File: /MyProj.CodeGen/MyProj.CodeGen.MyGenerator/GeneratedClass1.g.cs.
[warn]: OmniSharp.Roslyn.CSharp.Services.InlayHints.InlayHintService
Inlay hints requested for document not in workspace Location { FileName = /MyProj.CodeGen/MyProj.CodeGen.MyGenerator/GeneratedClass1.g.cs, Range = Range { Start = Point { Line = 131, Column = 0 }, End = Point { Line = 246, Column = 36 } } }
I would expect to get the metadata for NotSupportedException. Or, if I'm referencing classes in my own project, I should be able to navigate back to those symbols. Unfortunately, that's not possible right now.
If you set <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> in your project, you'll start seeing the generated code show up in obj/Debug/netXXX/generated/MyProj.CodeGen/MyProj.CodeGen.MyGenerator so they're real files, but this doesn't change the navigation - you'll still navigate to /MyProj.CodeGen/MyProj.CodeGen.MyGenerator/GeneratedClass1.g.cs instead of obj/Debug/..... You'll also still not be able to navigate out of that generated code back to symbols in the project.
I did just discover that if I'm in the debugger in VS Code I can step into and out of generated code just fine, so it does appear to primarily be an issue with navigating and not with actually locating or stepping into/out of that code at runtime.
https://github.com/OmniSharp/omnisharp-vscode/pull/4581 added support go-to-definition on source generated files.
https://github.com/OmniSharp/omnisharp-vscode/pull/5338 will add support for workspace symbols when they are in source generated files (the experience today is that they appear, but selecting them results in an error page).
https://github.com/OmniSharp/omnisharp-vscode/pull/5339 will add support for find-references when the result exists in a generated file. Features in the generated files themselves (such as find references, outline viewer, etc) need work to be enabled.
@333fred Are these great additions already in public version we can use? And is there anything else that needs to be done to finally resolve this request?
They will be in the next release of the vscode extension, I believe.