roslyn: Source Generators: design-time completion/intellisense is never fixed
Version Used:
I copied the global.json from the samples. I’m using Visual Studio Community 2019 - Version 16.6.0 Preview 6.0 (just installed).
Steps to Reproduce:
- Unzip the attached repro: generator.zip
- There are two sets of binlogs collected with the Project System Tools: after the first build of the solution, after restarting VS as indicated in the known issues in the announcement.
- After closing VS, deleting the
.vs
directory and cleaning all bin/obj folders and opening VS and doing another build.
Expected Behavior: At least after restarting, the completion is fixed. Worst case, it’s fixed after a restart.
Actual Behavior: Build works fine, but completion is never fixed, no matter how many times I restart VS 😦
Workaround:
Add the following to your project:
⚠ WARNING: using this workaround is likely to severely impair performance in ways that are very difficult to identify and correct later. It should not be used.
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(CompilerGeneratedFilesOutputPath)\**" />
</ItemGroup>
<Target Name="RemoveSourceGeneratedFiles" BeforeTargets="CoreCompile">
<ItemGroup>
<Compile Remove="$(CompilerGeneratedFilesOutputPath)\**" />
</ItemGroup>
</Target>
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 11
- Comments: 65 (28 by maintainers)
@kzu, in my generator, i workaround also by writting all the time generated files, but i skip them when building using an msbuild target run just before compilation :
my generated files are suffixed with
SourceGenerated.cs
Thus, i can navigate to generated code with VS, and have working intellisense and debugging experience…
NOTICE:
The workaround here is to fix
Rider 2021.1
ONLY If you are having issues with Visual Studio, update to 16.10+!Original Post:
I got building and intellisense working by doing the following:
If you want to have the generated folder cleaned during rebuild, add this:
Everything absolutely does not work for in-solution source generators. Without any workarounds, every time I open my solution it’s basically a random dice roll whether Intellisense (including error squiggles) actually works for things affected by the source generator. It fails more often than not.
If it wasn’t for my workaround, I would’ve had to move my source generator back to being a manually-run command line tool ages ago.
@Sergio0694 has a more recent repro here: https://github.com/dotnet/roslyn/issues/51810
While I agree with the premise, the conclusion here is flawed. The intent of
IIncrementalGenerator
is exactly to eliminate the need to re-run the full source generator when the output did not change. It does not need to save source files to disk in order to achieve this goal.To the contrary, it has proven extremely difficult to author customized build logic which successfully generates source on demand prior to the compilation step and then correctly ties into the many implementations of up-to-date checks.
I’m extremely concerned about the suggestions regarding
<EmitCompilerGeneratedFiles>
and<CompilerGeneratedFilesOutputPath>
. These properties are intended for the convenience of a project maintainer and must not be controlled by a source generator package. I’ve edited the comment to make it more difficult for someone to copy/paste this text and cause downstream bugs that we have to go back and work through.@CorrM keep in mind that is an unsupported scenario that is known to break. It might sometimes appear correct, but other work in progress directly conflicts with it we’ve seen it can be extremely difficult to understand which it suddenly stops working in strange ways.
This workaround will cause a severe productivity impairment (it breaks all of design time builds, incremental solution updates, and the fast up-to-date check). It is imperative that this workaround not be used. I updated the post to strongly discourage use of the workaround to help avoid an onslaught of performance-related feedback that doesn’t make sense in the context of these features.
Thanks for the feedback @kamronbatman it’s really appreciated. Ive had a dig through the issues and I think my problem is closer linked to #48083 where VS is caching the source generator and intellisense isn’t picking up changes to the source generator code (although the build does) until I restart visual studio.
Thanks again
I remember getting that when I forgot to use
partial
. Make sure both your user code, and generated code are usingpartial
classes. If you are still getting the error then it is possible you have duplicate code somewhere. This also happened to me in some cases. Cleaning the source generated folder and regenerating fixed it.To troubleshoot I would actually manually modify the generated code to look like how I want and eliminate the errors, then update the codegen to match.
(Anyone who decided to use my workaround above should definitely get the updated version that includes a check for
CompilerGeneratedFilesOutputPath
being defined. I forgot to check it and someone found out the hard way when they got into a situation where it wasn’t defined and MSBuild happily deleted every C# source file on their C: drive.)@u7pro your technique worked perfectly. Thanks
@b-straub ide support for source generators is a work in progress.
@jasonmalinowski to look into the underlying issue.
In terms of writing out to disk etc, its a scenario we’re actively working on: https://github.com/dotnet/roslyn/projects/54#card-34161504
There are still multiple issues pending to be resolved.
Even when I’ve made intellisense working, it was still slow if you have 30+ classes in solution. in .NET 6 there is incremental generator which should help with performance (https://andrewlock.net/exploring-dotnet-6-part-9-source-generator-updates-incremental-generators/) but for me even this didn’t work as I’m loading and parsing classes from another csproj. Reported issue: https://github.com/dotnet/runtime/issues/56702
Currently, my workaround is to get it working as I had behaviour with https://github.com/AArnott/CodeGeneration.Roslyn
So, package reference is excluded from design time:
<PackageReference Condition="'$(DesignTimeBuild)'!='true'" Include="X.Core.Generator" OutputItemType="Analyzer" Version="$(XCoreNugetVersion)" />
Then, for build I’m using:
this way, I have intellisense and performance is not impacted.
@sharwell @chsienki here we go #55199
Almost all cases have been fixed for the 16.10 release, and the remaining ones tend to be less severe than the problems introduced by workarounds. If you have a detailed repro case we can take a look (best to file a new issue and tag me and @chsienki).