Edit3: At some point this just started working. No clue why. Maybe it was a VS bug that got fixed?
Edit2: Looking into the Analyzers node in solution explorer, I've discovered the source generator runs successfully when I first open the program, and then it stops and everything it generated goes away after only a few changes to my code.
immediately after opening solution:
> Analyzers
>> MySourceGenerators
>>> MySourceGenerators.NotifyPropertyChangesGenerator
>>>> _NotifyChangedClass_Notify.cs
after making any edits
> Analyzers
>> MySourceGenerators
>>> MySourceGenerators.NotifyPropertyChangesGenerator
>>>> This generator is not generating files.
Edit: After calling Debugger.Launch()
as suggested by comments, I can confirm that the generator code is running, and the source text looks exactly like it's supposed to. But both the IDE and compiler still give errors as if the results aren't being included.
I'm trying to setup a source generator to be run from a local project reference but can't get it to actually run. My NUnit tests are passing, so I know the actual generation logic is fine, but a barebones test project both fails to compile and reports errors in Visual Studio. I'm using Visual Studio 2022 Preview 5.0, in case that matters.
<--generator.csproj-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IncludeBuildOutpout>false</IncludeBuildOutpout>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" PrivateAssets="all" />
</ItemGroup>
</Project>
<--testproject.csproj-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MySourceGenerators\MySourceGenerators.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"/>
</ItemGroup>
</Project>
//generator.cs
[Generator]
public class NotifyPropertyChangesGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
var receiver = (NotifySyntaxReceiver)context.SyntaxReceiver!;
if (receiver.Classes.Count > 0)
{
foreach (var c in receiver.Classes)
{
/* Generate the source */
var source = SyntaxFactory.ParseCompilationUnit(builder.ToString())
.NormalizeWhitespace()
.GetText(Encoding.UTF8, Microsoft.CodeAnalysis.Text.SourceHashAlgorithm.Sha256);
context.AddSource($"_{c.ClassDeclaration.Identifier.ValueText}_Notify", source);
}
}
}
public void Initialize(GeneratorInitializationContext context)
{
context.RegisterForSyntaxNotifications(() => new NotifySyntaxReceiver());
}
}
class NotifySyntaxReceiver : ISyntaxReceiver
{
public List<NotifyClass> Classes { get; } = new();
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
if (syntaxNode is ClassDeclarationSyntax cds)
{
/* Identify classes that need generation */
}
}
}
//testproject.cs
internal class NotifyChangedClass : INotifyPropertyChanged
{
string n_Property;
}
CSharpGeneratorDriver
would be the usual approach to debug and develop source generators. If you need AdditionalText you can get implementations likeInMemoryAdditionalText
from here: UnitTests SourceGeneration – Cas