C# 源生成器不包括项目参考的结果

Sal*_*dor 8 c# roslyn roslyn-code-analysis sourcegenerators csharp-source-generator

Edit3:在某个时候,这才开始起作用。不知道为什么。也许是 VS 的一个 bug 被修复了?

Edit2:查看解决方案资源管理器中的分析器节点,我发现当我第一次打开程序时,源生成器成功运行,然后它停止,并且在对代码进行一些更改后,它生成的所有内容都会消失。

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.
Run Code Online (Sandbox Code Playgroud)

编辑:按照注释的建议进行调用后Debugger.Launch(),我可以确认生成器代码正在运行,并且源文本看起来与预期的完全一样。但 IDE 和编译器仍然会给出错误,就好像未包含结果一样。

我正在尝试设置一个源生成器以从本地项目引用运行,但无法让它实际运行。我的 NUnit 测试正在通过,所以我知道实际的生成逻辑很好,但是准系统测试项目既无法编译,又会在 Visual Studio 中报告错误。我正在使用 Visual Studio 2022 Preview 5.0,以防万一。

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.
Run Code Online (Sandbox Code Playgroud)
<--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>
Run Code Online (Sandbox Code Playgroud)
<--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>
Run Code Online (Sandbox Code Playgroud)
//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 */
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*n.K 1

源生成器目标netstandard2.0,您的项目目标net6.0。当您通过 . 使用源生成器时,这不是问题PackageReference

认为ProjectReference在这种情况下工作,您需要添加SetTargetFramework元数据。

  <ItemGroup>
    <ProjectReference Include="..\MySourceGenerators\MySourceGenerators.csproj" 
                      OutputItemType="Analyzer"
                      SetTargetFramework="netstandard2.0"
                      ReferenceOutputAssembly="false"/>
  </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

这可能有用,抱歉现在无法尝试。