I'm not sure if this is the correct place to create issues with regards to C# source generators.
I'm using dotnet version: 3.1.402
I'm trying out source generators and if I reference System.CodeDom and use it in the code generator it fails.
Normally I can attach a debugger to the code generator by Debugger.Launch(), but if I'm using System.CodeDom the Debugger.Launch() wont be execute either so I really dont know whats happening there.
I've create a simple solution with 2 projects, which one is a source generator(Test.SourceGenerator).
In Test.SourceGenerator project if you remove line
var codeCompileUnit = new CodeCompileUnit();
the source generator works fine and the Test.Consumer project builds.
Does source generators have restrictions on using nuget packages?
You can find the solution in the Test.zip file
Test.zip
Words cannot describe how sad I will be if we create Source Generators only to find they are used to resurrect CodeDom. 馃槶
@Vake93 The likely cause is that you're missing some dependency for CodeDom. When the compiler tries to load your generator, it will load CodeDom, which fails, and the generator won't get loaded (hence why nothing executes when you reference it).
You can obviously try and figure out the correct dependency chain for CodeDom, but I would question the need for it. Is there something specific you're trying to achieve through its use (porting an existing codebase?) or just familiarity with the API?
@Vake93 The likely cause is that you're missing some dependency for CodeDom. When the compiler tries to load your generator, it will load CodeDom, which fails, and the generator won't get loaded (hence why nothing executes when you reference it).
You can obviously try and figure out the correct dependency chain for CodeDom, but I would question the need for it. Is there something specific you're trying to achieve through its use (porting an existing codebase?) or just familiarity with the API?
Thanks for the explanation I'll try to resolve the dependencies. But shouldn't that be done when the source generator project builds?
As for why I'm using CodeDom; If I'm not using CodeDom, the 2 other alternatives is to use string builder or syntax trees to build the new generated code. If I use string builder maintaining and changers down the line would be difficult. Using syntax tree api is too low level and a lot more work. So CodeDom (at least for me) strikes a middle ground where it's fairly easy to write and change down the line.
Currently I'm trying out the API to migrate some reflection workloads on my projects at work to use source generators.
For example currently we are using reflection to setup the DI container on a ASP.NET core project based on a class attribute. This can be done at the compile time by source generators. (I've actually tried this and got it to work by using string builder to build the source code string 馃コ)
Words cannot describe how sad I will be if we create Source Generators only to find they are used to resurrect CodeDom. 馃槶
That wasn't my intention, sorry. 馃槄
Source generators are awesome new tool but I think there has to be a better way to build the generated source other than using string builder and string concatenation.
Adding @cartermp to this, as "I wish I had a saner generation API" is something we've heard from other places too.
hey @chsienki when I looked at the dependencies for CodeDom there isnt any. (See: nuget)
Any idea what else might be the issue here causing generator to not load?
@jasonmalinowski Wouldn't SyntaxGenerator be one of those 'saner apis'? Can we not make that type available to be used?
Ah @Vake93 I didn't realize you provided a test solution, I just took a look. It is a dependency flow problem, but not directly because of System.CodeDom.
When you reference an analyzer via ProjectReference
the dependencies from the analyzer project do not flow automatically. The generator is loaded into the test project, but it fails to load System.CodeDom. The solution is to pass System.CodeDom as an explicit analyzer reference (via /analyzer:...
on the command line or <Analyzer Include="..." />
in the project file) to the consuming project.
This step happens automatically for PackageReference
, but not via ProjectReference
. We're aware of the experience gap, and are actively working to improve it in a future release. Also be aware that _consuming_ the package reference will add the dependencies, but during _authoring_ you will need to explicitly add them. More info is available in the cookbook here: https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.cookbook.md#use-functionality-from-nuget-packages
@chsienki Yes that worked! Thanks. 馃槑
@canton7 in your issue you have said that you need to get a user interface (or a class) from a referrance assembly. I too had the same problem and solved it creating a SymbolVisitor and overiding the VisitNamedType method to collect the types from referrance assemblies.
```C#
public class NamedTypeSymbolVisitor : SymbolVisitor
{
private readonly List
public NamedTypeSymbolVisitor()
{
_symbols = new List<INamedTypeSymbol>();
}
public IReadOnlyCollection<INamedTypeSymbol> NamedTypeSymbols => _symbols;
public override void VisitNamespace(INamespaceSymbol symbol)
{
var members = symbol.GetMembers();
foreach (var member in members)
{
member.Accept(this);
}
}
public override void VisitNamedType(INamedTypeSymbol symbol)
{
_symbols.Add(symbol);
}
}
```
```C#
// in the source generator
var visitor = new NamedTypeSymbolVisitor();
var externalReferences = context.Compilation.ExternalReferences;
foreach (var reference in externalReferences)
{
var symbol = context.Compilation.GetAssemblyOrModuleSymbol(reference);
if (symbol is IAssemblySymbol assemblySymbol)
{
visitor.Visit(assemblySymbol.GlobalNamespace);
}
}
// visitor.NamedTypeSymbols should contain the types from the referrance assemblies.
```
Most helpful comment
Words cannot describe how sad I will be if we create Source Generators only to find they are used to resurrect CodeDom. 馃槶