Closed WebbertSolutions closed 6 months ago
Depending on the computer, you may or may not get constructors returned for private constructors.
Do these private
members exist in source or metadata?
Source. They exist before the generator runs.
The generator gets the information about the constructors and then generates code given what type of parameters and scope it has. The second picture above shows what it looks like.
Issue with generating code involving Private Constructors
Rather than sharing screenshots, it would be much more helpful if you could just share a dump of the process. You can save a dump from the Debug
menu when you're paused on a breakpoint. This will be very helpful as I've been unable to reproduce your failure condition locally.
Issue when running unit tests involving Private Constructors
I'm entirely unsure what you're saying with this part of the issue; why would the debugger have anything to do with the live IDE state? Are you simply running into the fact that VS cannot pick up changes to source generator project references without a restart (and restart of the build servers)? Either way, let's please keep separate issues in separate issues, rather than a single issue, so that we can properly track things.
Ok. Let's deal with the first: Issue with generating code involving Private Constructors
Here is the dump of the generation issue as requested, however the dump exceeded upload max of 25M.
Had to store on ondrive here: https://1drv.ms/f/c/1e01d4a72dbe2024/Emp2GT-VlG5AmpVE1xlGB8YBB3eNb6wSWh0ySpJRsfEMOQ?e=bt01uN
Alright, so your source generator is indeed getting PrivateWith
from a metadata reference, not from source. Specifically, it's coming from this assembly: D:\Coding\GitHub\SourceGenerators\Generators\GenerateObjectMother\GenerateObjectMotherTest.Models\obj\Debug\net6.0\ref\GenerateObjectMotherTest.Models.dll
. private
constructors are not put into the ref assemblies. It seems likely that your source generator will need to handle this case in general.
@chsienki, I would have somewhat expected IsRoslynComponent
to pass project references as project references, but it looks like that's not the case? Is that expected behavior?
@333fred IsRoslynComponent
just takes the command line of whatever would be passed to CSC and runs it as the debug target. It doesn't consider project/package references as they dont exist at that level, everything is just a regular reference to an assembly on disk.
Thanks Chris. Given that, I would call the behavior you're seeing here expected @WebbertSolutions.
Ok, I think I understand but for clarity...
1) Because I'm debugging, the process running is the generator. As such, it is then referencing back to the project/DLL where the class code exists, which is being done through metadata. Private constructors are not available in the metadata and that is why INamedTypeSymbol.Constructors is returning an empty list.
Is that correct?
2) Under normal circumstances where I'm adding the attribute to a class and the generator runs automatically, then I'm in the context of the source and therefore I do have access to the constructor information through INamedTypeSymbol.Constructors.
Is that correct?
Not quite correct, no. IsRoslynComponent is mimicking the exact semantics you will see with dotnet build
. The only time you will see project references as anything other than dll references is in the IDE.
hmm.... Not sure of the difference in how it runs then. Either way, I think I understand enough and have an idea how to work around the first issue and will see what I can do on the second.
Thanks for your assistance.
I should also mention, while frustrating at times, I've really enjoyed working with the Source Generator. It has allowed me to do somethings much easier than other ways in the past. Looking forward to seeing what other problems I can solve.
Thanks for the feedback! Feel free to come talk to us on discord as well: https://discord.gg/csharp, a number of us hang out in the roslyn channel and talk to a lot of people about source generators.
I've included 2 issues which are both related to INamedTypeSymbol.Constructors not returning information about a class.
The class in question has a private constructor with a public static Create() method to ensure that the private constructor doesn't get lost.
The issues are:
Version Used: Microsoft.CodeAnalysis.CSharp" Version="4.7.0
Issue with generating code involving Private Constructors
Steps to Reproduce: https://github.com/WebbertSolutions/SourceGenerators
Depending on the computer, you may or may not get constructors returned for private constructors. The public seems to work fine. Pictures are added to show when it is failing.
Issue when running unit tests involving Private Constructors
When unit tests are run, the generated code does not match what the debugger is running.
Steps to Reproduce: https://github.com/WebbertSolutions/SourceGenerators
Pictures are added to show the difference between the debugger code running and the go to implementation generated code.
This is the debugger
This is the Go To Implementation code