roslyn: Visual Studio does not reload source generator assemblies when they change on disk

I’m just started writing a source generator, and I’m finding that Visual Studio is caching source generators aggressively, and it’s making it very hard to do iterative development.

This is what I’m having to do to make even small changes.

  • Close Visual Studio (devenv.exe) instance in which the source generator project and its consumer (i.e., the project that ProjectReference’s the source generator)
  • pskill /t servicehub.roslyncodeanalysisservice
  • del $env:TEMP\VS\AnalyzerAssemblyLoader -Recurse -Force <- This is where the source generator binaries seem to get cached. Both devenv and servicehub.roslyncodeanalysisservice seems to hold handles to files under this location

Am I missing something simple to get the development process working more seamlessly ?

I’m on 5.0.100-rc.2.20473.20 + Visual Studio 2019 Enterprise 16.8.0 Preview 4.0 [30517.14.main

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 55
  • Comments: 141 (74 by maintainers)

Most upvoted comments

@palpha I completely forgot that i had already released this extension which makes writing source generators with vs and not needing to restart VS all the time a blast: https://marketplace.visualstudio.com/items?itemName=AlexanderGayko.AutoUpdateAssemblyName

well, the problem usually can be solved nicely. but writing the correct source generator in the first place is a pain. i honestly wonder how the good people at MS doing that can stand all the waiting all the time. (or you have magic instantly-loading VS versions? if so, can we please have them, too? 😃

I’m not sure I agree with your characterization of generators: they may be hard to implement (your side, or at least implement so they run efficiently) but they’re not that hard to use. v1 generators were particularly easy (walking through syntax trees, for example). v2, incremental generators (which I’m now using) are a little more complex (a slightly steeper learning curve) but once you get the hang of it, they’re also pretty straightforward (as evidenced by a generator I’m working on now).

What I was referring to is the DOCUMENTATION. And, to answer your question, for the very (very very) many (many many) pages I had to read to understand (in this case) incremental generators, the one that FINALLY did the trick, buried somewhere inside those inter-tubes was this one: https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.md

This single page should be splashed ANYWHERE someone searches code generators. And the rest of the docs should be written with that level of explanation. That page is a great start (not perfect, but it got me going, and i’m pretty dense).

And as for improving generators, maybe start by making easy stuff easy!!!

A trivial task (for example) is customizing the generator’s code generation (e.g. changing method names, adding/removing logging). And the most obvious, easiest way to do this is simply let users/consumers define custom props in their .csproj files (as propertygroup) that can then be read by the generator on execution. Wow, that’s NOT happening. Not only are you making us go through hoops just to read this (via, e.g., context.AnalyzerConfigOptionsProvider.Select(…)) but then you won’t even let us read our actual values UNLESS they’re also SPECIFICALLY identified in that same file (using <ItemGroup><CompilerVisibleProperty…/>) WHY so difficult? And, more importantly, WHERE ARE THE DOCS for this??? Had to stumble on multiple posts to finally figure it out, and still had difficulties with whether to put these directives in the generator project or the user project (it’s the user project, btw 😃).

My point is, this has nothing to do with the implementation of generators. It’s simply about the documentation of them. And making some better(?) choices about how to implement some of these features (e.g. why not simply a context.ProjectProps.Get() or something).

Or another one is how to attach a 3rdparty lib to the generator without it being then packaged to the consuming project’s output. Again, ridiculously hard (I actually gave up on that one, even though I got 99% there, couldn’t resolve the “lib not found” errors, or lib conflicts errors, even though it listed (both?) libs as exactly the same versions). Hmmm…

I think generators are an incredible addition to a dev’s toolkit and I just get a little frustrated with using them. Sorry.

Freddy. ps: thanks for taking the time to reply!

On Sat, Jan 28, 2023 at 11:00 AM CyrusNajmabadi @.***> wrote:

You don’t realize how incredibly obtuse [complex, difficult, disorganized] the docs are

PRs welcome 😃

Or if the tool is so difficult to use

Generators are hard. But their very nature. They’re letting you plug into the core of the compiler. But that must be done with extreme care as this impacts literally everything what in the system.

The fish of generators was to make this possible. But make no mistake, it’s not simple precisely because this domain is itself enormously complex and hard to do right.

If you have ideas on how to make it simple, def feel free to open prs on that. We’d absolutely look.

— Reply to this email directly, view it on GitHub https://github.com/dotnet/roslyn/issues/48083#issuecomment-1407428047, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJLIRLOFBQNYZSKK5DVYJTWUU7BVANCNFSM4R3DC3DA . You are receiving this because you commented.Message ID: @.***>

– Frederic Rudman, CTO Enervision Media Inc. http://www.EnervisionMedia.com 877.330.3077 ext 21

I think a core problem is that when users are experimenting with a new technology, they tend to skip unit tests to get a feel for it (if they ever write unit tests at all). They quickly experience issues with IntelliSense or whatever and end up here. If we’re lucky, they actually read this thread. Otherwise, they leave their 2 cents and wait for VS to be “fixed”.

What would help?

  1. A source generator project template (like the analyzer and code fix templates) with example unit tests. And within that a README that makes the importance of unit testing very clear and the potential consequences (and a link to the cookbook).
  2. All other documentation should likewise stress the importance and consequences. That would include the cookbook, MS Learn, videos, etc.

The entire premise of this issue and everyone reporting the same kind of troubles is, as far as I can tell, this type of scenario: source generators as supporting actors for some sort of larger project. Most of us, I suspect, are not in the business of developing source generators. We’re in the business of developing various kinds of larger systems, using many different tools and techniques, one of which could be source generators.

If what you’re saying is correct and the official Microsoft stance in the matter, I suggest making the expected kinds of use cases more clear in the documentation, so that we as developers know to look elsewhere for problems where a source generator would have to be continuously developed as part of the project.

In other words, this behaviour may be by design, but the design does not meet the needs of many people. This issue is a request that the design be changed and the limitations removed.

image At last some solution

Not from Microsoft…

image At last some solution

Ha - I got it working!

so after a little bit of research and looking into the roslyn sources, i found that the actual file name is being used as the key to check whether a cached assembly is to be used… so i just needed to create a dynamic <AssemblyName> - which is surprisingly hard. i found no consistent way of incrementing something by build using MSBuild Tasks and Targets…

I solved this problem by building a VS extension that just increments a number at the <AssemblyName> in the .csproj and then reloads the dependent packages - i can now rebuild the code generator project and see the updated generated code in its consumer projects. The disadvantage obviously is that at some point, lots of unneeded old assemblies are in some cache… but who cares.

is anyone interested?

I recommend getting everything working with ISourceGenerator first

I highly recommend not starting with ISourceGenerator. In my experience with creating many new source generators and porting existing source generators from ISourceGenerator to IIncrementalGenerator, I’ve found it much more difficult to port existing ones (so much so that it often means starting over).

It’s much easier to port IIncrementalGenerator back to ISourceGenerator than it is to port ISourceGenerator to IIncrementalGenerator.

Yeah, I hadn’t installed the May feature update required for the tool, so I’m currently waiting for that update and hoping it doesn’t overwrite the deleted data in the file system.

Any important files should have been in a repository and any changes should have been committed, and I should have checked the fix more carefully – it’s definitely my fault if I lose anything of value.

Hopefully the end result is just a bit of tedious work and yet another war story of how I’ve failed, with which I can bore my niece and nephews when I retire.

Is there a way to view the generated sources except through VS/intellisense ?

As of yesterday, you can now emit generated files to disk so you can inspect them: https://github.com/dotnet/roslyn/pull/47047

  • For other cases (which should be the majority of your time), you are not actively working on the source generator implementation. In this case, the source generator behavior is stable inside Visual Studio and unexpected errors will not be occurring.

@sharwell The issue my team runs into is:

  1. I make changes to our source generator and merge them into our main branch.
  2. My coworkers pull main and then their code won’t compile (because Visual Studio is still using the old version of the source generator).

This means that whenever I change our code generator, I need to ping everyone to let them know that after they pull the latest changes, they need to restart Visual Studio 😆

This also happens when switching branches, if one branch is based on newer code and the other is based on older code, so we end up needing to rebase our branches more than we normally would 🙂

I remember two times where I wanted to implement a source generator, that I stopped, because VS/Roslyn denied to accept code changes towards my source generator and had therefore always to restart VS. Thanks @palpha for the extension, it works, but I am just curious: why your names from your VS extension page and your GitHub page differ when you claim that it is your extension? Maybe out of scope of this issue.

EDIT: @palpha any vision to make the source code openly available? Because on the extension page it says that there some features worked on that I would like to help out with.

And as for improving generators, maybe start by making easy stuff easy!!!

There are no easy cases here. That’s my point. 😃

and I just get a little frustrated with using them. Sorry.

This is all open source. If you want your scenarios to improve, the best thing would be to invest in the improvements there. That said, as mentioned before, these are expert, extremely complex systems (think double black diamond level) intended for niche scenarios where no other mechanics are viable. They are not a catch all system to do basic code gen.

You are literally hooking the compiler at the deepest level. You get to run prior to us even getting the compilation value that powers literally everything higher up. With that great power comes great responsibility. It’s difficult by it’s very nature, and will continue to be that way.

I fully accept that limitations exist and that a certain kind of usage might be unsupported. It’s just nice to have that information up-front, so energy can be saved and frustration avoided. When source generators were introduced, I saw it as a potential technique for metaprogramming in C#. If it by design is not, that’s fine, but it needs to be communicated more clearly.

Afaict, what you are describing then sounds very much by design for the entirety of both the Roslyn and VS plugin extension extensibility systems.

The entire premise of this issue and everyone reporting the same kind of troubles is, as far as I can tell, this type of scenario: source generators as supporting actors for some sort of larger project. Most of us, I suspect, are not in the business of developing source generators. We’re in the business of developing various kinds of larger systems, using many different tools and techniques, one of which could be source generators.

If what you’re saying is correct and the official Microsoft stance in the matter, I suggest making the expected kinds of use cases more clear in the documentation, so that we as developers know to look elsewhere for problems where a source generator would have to be continuously developed as part of the project.

A simple declaration like “If a source generator is used on a project within Visual Studio, the IDE must be restarted for every change of the source generator’s code – this is by design” would help people decide whether their problem can be effectively solved using source generators.

If you rebuild the generator, it should be picked up the next time the host launches. Is that not happening?

Round and round we go. When a source generator is part of a larger code base (perhaps in the same solution as the projects using it), it is expected that it can be changed as any other piece of code without having to restart the IDE for it to take effect. Whether the changes are driven by unit tests is irrelevant – you might still need to change it frequently as part of the development of the larger code base.

@palpha 😱 That’s horrifying! Sorry you’re having to deal with that, glad to hear you have backups at least. I added a gate to skip that target if CompilerGeneratedFilesOutputPath is missing for whatever reason.

@PathogenDavid Using hash for version is not viable since it’s not monotonic and versions are expected to be.

I’d suggest that instead of running source generator in VS when developing it it’s better to run it in a unit test. Write a unit test that runs the generator and produces output. In that setting you can iterate fast - even using Edit and Continue to modify the generator code as you are debugging it. There is no need to mess with versions/reloading/VS complexity etc.

Can’t we just have a button in visual studio that restarts roslyn / refresh intellisense?

What would restarting/refreshing mean? Note that we’re already in a corrupt state at that point. So restarting will likely just lead to more corruption.

So many intellisense bugs over the years.

Please file issues on any bugs you run into.

Why do we always have to restart visual studio?

Because currently roslyn runs a lot of code in-process in VS, and there’s no clean way to restart components like that given that everything is in teh same address space, and object graphs are intertwined. Efforts to move roslyn to be independent and exist isolated from VS exist and can help here as we do more work in this area.

Until i realized that even adding a property to a class requires me to restart visual studio before intellisense picks it up.

This should not be the case, and i cannot repro this. If you have a repro for this, please file issue with the repro case, it would be very helpful. Thanks!

@teneko, The author is @AdmiralSnyder 🙂 He was replying to @palpha, which is why his name is in that quote 🙂

For everyone saying that the docs need improving: I’ve just filed https://github.com/dotnet/docs/issues/33936 , which asks that part of the Source Generators Cookbook be migrated to official documentation at https://learn.microsoft.com/

If you feel the same, please upvote that suggestion! 🙂

but they’re not that hard to use. v1 generators were particularly easy (walking through syntax trees, for example)

That’s a good example of their difficulty. Doing things this way was so detrimental that we’re now deprecating the v1 API since it’s core design is effectively unsalvageable.

As I stated before. This stuff is fundamentally hard. And apis that attempt to mask that are a strict mistake since you get the worst if all worlds.

This single page should be splashed ANYWHERE someone searches code generators.

Honestly, we should plaster a page first that takes every effort to convince people to buy use generators and to explain why they’re a poor choice for most use cases. We should then be clear about the narrow set of cases it is good for, and implore users to not use them unless they fall into that narrow slice of things.

I remember a Roslyn dev commenting in another issue that directly depending on a source generator project only works by accident, and shouldn’t be considered supported.

The recommended development path from Microsoft seems to be:

  1. Develop source generators via unit test
  2. Ship and consume source generators as NuGet packages.
    • Don’t directly link to a source generator project, even though this is possible.

If the above recommendations are followed, then VS never needs to be restarted.

That being said, I hope that taking a direct dependency on a source generator project is supported in the future! 🙂 For internal projects, having to package the source generator as a NuGet should be unnecessary 🙂

If I understand the issue correctly the problem is rooted in difficulties unloading an assembly once it’s loaded. If we accept this as our technical premise we might still be able to improve the user experience with some tricks.

  • Once there is a newer analyzer assembly, stop using the old one to not confuse the developer. Or maybe ask to stop in the toolbar like when extensions crash.
  • Even if the old assembly can’t be unloaded, couldn’t a new one be loaded if the assembly version increased? Could there be a an auto-increment for assembly version (build revision?) based on source changes? Some memory footprint would eventually develop but this seems like a reasonable tradeoff.
  • If none of the above works out perhaps VS could at least provide a project template for analyzer development that “automatically” feeds project source to the generator? Perhaps even emitting the generated files to the local projects for easy preview?

but this caching issue is ridiculous.

Can you clarify what issue you’re referring to?

Could you not make it so if a source generator project is built, it causes a regeneration of all of its generated code?

If you rebuild the generator, it should be picked up the next time the host launches. Is that not happening?

  1. The issue I am referring to is iterative development. The fact that you have to close and open visual studio in order to see the changes you have made to your source generator. Tonight it decided that closing and opening visual studio wasn’t good enough and it took me an hour to figure out that I had to clean the solution…
  2. Please clarify what you mean by “host launches”, do you mean closing and opening vs? Why can’t it be what I suggested, you build the source generator, it erases the cache and replaces it with a regenerated version?

Source generators are amazing, but this caching issue is ridiculous. Its been 2 years and 2 new versions of .net and we are still talking about the same issue…

Could you not make it so if a source generator project is built, it causes a regeneration of all of its generated code? Wouldn’t that solve the caching issues?

@vplusplus

Combination of the above two makes it impractical to target Incremental code generation for VS2022. * We can’t depend on IntelliSense as IntelliSense is lagging. * We can’t see the correct generated signature since IDE Editor is lagging.

I know this is not really the correct issue/thread but I eventually solved both of the above problems using the incremental generator. Although it feels like a million puzzle pieces have to be aligned just right, the deciding factor in my case was indeed the Roslyn pipeline cache. If you don’t treat the Roslyn cache like a queen it will either ignore caching altogether, thus defeating the purpose of the incremental generator, or it will cache too aggressively and starve the IDE + Intellisense from updates… Note that it will still build the project just fine, probably because the build runs as a separate process.

Make sure your IEquitable<MyGenerateInfo> is properly implemented and comparing not only the name but also relevant content, e.g.:

public bool Equals(MyGenerateInfo other) => other.SomeData == this.SomeData && other.SyntaxTree.IsEquivalentTo(this.SyntaxTree);

If anyone wants to point me to a better suited issue/thread I’d be happy to move my comment there.

@randrewy

At some point I add new controller and hit rebuild. What I expect is to see new member autogenerated to my ClientApi. But I can’t use it in Program without manual cleaning and restoring projects, because of the same issue with caching DLL.

This issue covers caching of the generator, not caching of what is generated.

My guess is that you are using incremental source generators and one of the caching steps is wrong.

If you can’t figure it out, I’d recommend opening a new issue.

This seems to workaround well for me. This deletes the Generated/ directory before every build so the source-generator will regenerate. Place this in the project that references the source generator.

<Target Name="CleanGenerated" BeforeTargets="BeforeBuild">
  <ItemGroup>
    <Compile Remove="$(GeneratedFolder)/**" />
  </ItemGroup>
  <RemoveDir Directories="$(GeneratedFolder)" />
  <ItemGroup>
    <Compile Include="$(GeneratedFolder)/**" />
  </ItemGroup>
</Target>

<PropertyGroup>
  <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
  <GeneratedFolder>Generated</GeneratedFolder>
  <CompilerGeneratedFilesOutputPath>$(GeneratedFolder)\$(TargetFramework)</CompilerGeneratedFilesOutputPath>
</PropertyGroup>

Well, I probably would take @sharwell’s advice over mine 😄

File.WriteAllText($“{pathToCodeBase }//{fullName}.g.cs”, source);

Note: this is explicitly not supported, and may break in teh future.

This already does not work for a bunch of features. It also bypasses all the incremental generator performance improvements related to avoiding syntax parsing.

Source generators must not read data directly from disk, and must not write data directly to disk.

The best part about being a lead, maybe the only good part, is the ability to delegate … @chsienki

😉

So the one problem @vatsan-madhavan you’re probably running into is once we’ve loaded your assembly…the CLR doesn’t give us sane ways to unload it or load a different version if the assembly version hasn’t changed. @chsienki or @cartermp any chance somebody already has some MSBuild magic to work around this in some way?

@vatsan-madhavan

For the purpose of testing/debugging, I was viewing them with a simple hack (which isn’t good, but did the purpose for me).

https://github.com/Youssef1313/PrintMembersGenerator/commit/31e31ce65803f3aa6055aa4f621216931f66c911

Then after things got stable with me, I moved to unit testing to confirm the correctness of the generated sources.

https://github.com/Youssef1313/PrintMembersGenerator/blob/master/src/PrintMembersGeneratorTests/PrintMembersGeneratorTest.cs

VS support for source-generators is pre-alpha. I would not expect a good VS experience here for a while. Certainly not prior to the 16.9 timeframe.

Am I missing something simple to get the development process working more seamlessly ?

Nope, you’re not missing anything. It will just be a while until SGs are really supported in VS.

What works for me is setting up an internal nuget repo (can be as simple as a network share folder where the packages go) and put versioned packages with the analyzer/codegen there. Thats the only reliable way I found to get things working in a team.

Writing unit tests to check whether members or methods exists sounds a little bit crazy.

Not in the slightest. Unit tests are written for static scenarios. Roslyn itself contains hundreds of thousands of them. And every generator we produce is heavily tested.

I’m not really happy the way this source gen works at the moment.

Source generators are an extremely advanced system that ties literally into the lowest level of the compiler possible. They are intended to be used only when that’s the way needed to solve challenging problems with no other existing solutions. I’d recommend strongly looking into whether you actually need a generator or not. And, of you do, following the best practices listed here.

One path is fast and supported, the other is not supported and fundamentally limited by the .net framework. The best we can do is advise you which path to take. What you end up choosing is ultimately up to you.

Can’t we just have a button in visual studio that restarts roslyn / refresh intellisense? So many intellisense bugs over the years. Why do we always have to restart visual studio?

I had a horrible first experience trying to use the new source generators. Until i realized that even adding a property to a class requires me to restart visual studio before intellisense picks it up. How does something like this get released and goes by unnoticed?

I can’t understand, is Microsoft going to add reloading of analyzers that were generated by Source generators?

hey, yeah, open-sourcing it would be possible, but i have still not decided whether i want at some point make a living by building extensions commercially, and in that case, it wouldn’t be that wise to open source it - so i think providing the extensions for free for now is the best i can do 😃

@sharwell i didn’t look at the state of generators for a while, so if there’s better approaches, that’s great, thank you.

@TWhidden thank you so much

@teneko i decided to go with my real name for my extensions (i.e. my vsix marketplace profile) because: see above 😃 but, for help with features, just ping me over on the c# discord server (I’m AdmSnyder there)

when you claim that it is your extension

I have never claimed this, @teneko. Read again and you’ll find the author.

Open-sourcing seems like a reasonable suggestion.

If i’d be using the unit test based approach for writing those source generators … i’d also have to modify those test cases whenever our codebase changes …

This isn’t necessarily the case. Here’s a source generator test suite that fully automates the creation and maintenance of expected outputs (via the WRITE_EXPECTED directive in one of the source files): https://github.com/microsoft/vs-extension-testing/tree/main/src/Microsoft.VisualStudio.Extensibility.Testing.SourceGenerator.UnitTests

Hey @CyrusNajmabadi - sorry for the delay, Uni had prio.

Unless your actual solution is the environment you’d need to build unit test abstractions for - which would mean having to duplicate everything 😛

Sorry… not exactly sure what you mean by this. (i tried reading it a few times, but i think it’s not clicking). Can you clarify? Thanks!

in my case i build source generators that auto-generate lots of boiler plate stuff for our codebase - stuff for our ORM, mixin stuff for my imports, different places, different needs. and the usecases for these code generations are not giving my generators to others so they can do that, too, but helping our codebase - which changes, naturally, over time. so when my codebase changes, obviously, my generators will have to change, too. If i’d be using the unit test based approach for writing those source generators, i’d not only have to abstract my codebase into test cases, i’d also have to modify those test cases whenever our codebase changes, too. which is just hard, unnecessary work that i want to avoid 😃

You don’t realize how incredibly obtuse [complex, difficult, disorganized] the docs are

PRs welcome 😃

Or if the tool is so difficult to use

Generators are hard. But their very nature. They’re letting you plug into the core of the compiler. But that must be done with extreme care as this impacts literally everything what in the system.

The fish of generators was to make this possible. But make no mistake, it’s not simple precisely because this domain is itself enormously complex and hard to do right.

If you have ideas on how to make it simple, def feel free to open prs on that. We’d absolutely look.

I believe we cover this in the docs

Guess that’s the problem! You don’t realize how incredibly obtuse [complex, difficult, disorganized] the docs are!!! Sure, they may be “complete” (in someone’s mind) but they sure don’t make for easy reading. Just to reiterate what’s been said before (by others) some of us (many?) are not in the (your?) business of creating generators. We’re merely using them as tools to solve a larger problem. If the tool becomes a barrier, then it’s a useless tool (for us). Or if the tool is so difficult to use (because of, say, poor docs) then that’s the same result.

I believe we cover this in the docs, which mention how to unit test these.

Where? I see one GitHub issue there, but no official documentation.

This is the third-party documentation that finally made be understand (and love) unit testing source generators.

Not sure I recall the discussion. Now i’m sad - i thought we were friends 😛

Seriously, though, yep, you didn’t feel differently. and since i ended up coming up with a working workaround, i didn’t feel the need to steal more of your time.

All benefits, no drawbacks afaict. Unless your actual solution is the environment you’d need to build unit test abstractions for - which would mean having to duplicate everything 😛

@CyrusNajmabadi

I don’t find myself ever waiting. I literally just right click the appropriate test folder in Test Explorer and say “run these tests”. I pay the cost of the build, but then get results back in ms after that.

yeah, when you have a testing-based approach, sure. but if you’re building a source generator as a tool for your application (as it is argued in this thread that people want to do it), that’s not feasible… we discussed that over on the discord sufficiently, though.

There was a mention of “not enough documentation” earlier in this thread. Everything we need to know is represented well here: https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.md

I had caching issues too. And solution to my issues were there in the document. It’s a dense document; Consider every line is important.

Using Microsoft Visual Studio Community 2022 (64-bit) - Current - Version 17.4.1

Incremental generator works just fine under the covers. Two issues (already discussed well above) still exist:

Issue 1: IDE editor doesn’t reflect the changes. Having VSCode open in parallel on same folder, and I can see changes immediately. Can live with this, as in our use-case, viewing generated code is optional and nice-to-have.

Issue 2: Intelisence doesn’t catch-up with the changes. The compiler is happy, generated changes are immediate and the project compiles and runs with no errors. So, there is no caching issue on the compiler path. IntelliSense doesn’t understand the changes, generated properties/methods doesn’t show-up and red squiggly lines stays.

Combination of the above two makes it impractical to target Incremental code generation for VS2022.

  • We can’t depend on IntelliSense as IntelliSense is lagging.
  • We can’t see the correct generated signature since IDE Editor is lagging.

So, we have to guess generated code, type, compile and see it runs.

Interesting enough .NET Razor is using IIncrementalGenerator REF: https://github.com/dotnet/razor/tree/main/src/Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators

If developer experience works for ASP.Net, it should work for us as well. Spent lot of time studying dotnet/razor/compiler implementation, if they are playing nice with caching. Could not find any specific trick/approach I am using differently.

What are we missing? Thanks in advance

This problem is a real pain))

@AdmiralSnyder

by building a VS extension … is anyone interested?

I am interested! It would be cool to have such extension with some additional care like first time preparation for the generator project for version incrementing. Looks like this Vsix will live for few years, which is fine I think! As an alternative, may be Roslyn team will just unlock dlls in $env:TEMP\VS\AnalyzerAssemblyLoader between its “usage events”? If so, a simplest Vsix will delete such dlls and this will be a nice workaround. is this difficult to implement? @CyrusNajmabadi ? @chsienki ?

File.WriteAllText($“{pathToCodeBase }//{fullName}.g.cs”, source);

Note: this is explicitly not supported, and may break in teh future.

maybe there is even a way to generate only code for the files IntelliSense just compiled

There is no such concept. Any change anywhere could have an impact on any generator. So all need to be run on any change to see their impact.

There is an incremental-generator API that is now available where you can set up pipelines stating what information your generator needs, and we will then run the pipeline, terminating further downstream steps when we can see they’re receiving the same inputs as before.

HOwever, this requires rewriting the generator to use this new API to get the perf benefit.

Yeah, the compilation is generated on every (or almost every?) change. That’s how intellisense can suggest things based on code you’ve written but not compiled.

@Phylum123 We are working on source generators constantly. However, they are extremely complex with many parts of their design requiring an enormous amount of effort across our entire stack. Performance alone has occupied many devs worth of time for years at this point.

Source Generators and IDEs will likely continue to take many more releases to get around to everything that people want.

I’ve filed a Visual Studio bug for this, since I suppose that this is technically a VS issue 🙂 Feel free to upvote! https://developercommunity.visualstudio.com/t/changes-to-source-generator-arent-applied-without/1698836

Hi @KhaledSamir , I recommend to use Unit Tests to build the generator. You find an example in this project: https://github.com/thomasclaudiushuber/mvvmgen

Using hash for version is not viable since it’s not monotonic and versions are expected to be.

Fair enough for making that the default behavior of *, but for the purposes of this discussion the version number being monotonic doesn’t matter.

I’d suggest that instead of running source generator in VS when developing it it’s better to run it in a unit test.

This is essentially what I’ve been doing. (Except running dotnet build outside of Visual Studio with EmitCompilerGeneratedFiles enabled.)

The main frustration for me has been that once I have finished working on my source generator, convincing Visual Studio to relinquish whatever hidden cached source generator it is seemingly impossible to do reliably. At the very least I’d expect restarting Visual Studio to fix things, but even stopping all instances of Visual Studio, killing any lingering service hubs, deleting the cache folder named in the main issue, deleting all folders starting with vs in my temp folder, making a blood sacrifice, deleting my .vs folder, and finally restarting Visual Studio: My old generator still sometimes (somehow) sticks around. (But only sometimes.)

Is the Roslyn team not going through the same pains as us?

Curious: if the generators in this case are strong name signed could we potentially manipulate the version here and load the new copy?