为什么在没有任何变化的情况下调用增量源生成器?



下面的源生成器在初始化时创建一个新的记录类型。然后在另一个步骤中选择该类型的符号,并生成一个带有时间戳的虚拟文件。

由于底层记录类型仅在初始化时生成一次,并且此后不再更改,因此我希望下一个转换步骤仅被调用一次。然而,每次我在IDE (Rider 2022.3.1)中输入任何东西时,它似乎都会更新,即每次使用更新的时间戳重新生成test2.g.cs。

为什么会发生这种情况-我如何防止这些不必要的更新?

public class TestGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
// Create test1.g.cs on initialization
context.RegisterPostInitializationOutput(context => context.AddSource("test1.g.cs", "public record TestRecord();"));
// Find the type symbol for the previously generated record, and generate test2.g.cs based on this
context.RegisterSourceOutput(
context.SyntaxProvider.CreateSyntaxProvider(
static (context, _) => context is RecordDeclarationSyntax s && s.Identifier.Text.Equals("TestRecord"),
static (context, _) => context.SemanticModel.GetDeclaredSymbol(context.Node) as INamedTypeSymbol
).Where(x => x is not null),
(context, symbol) => context.AddSource("test2.g.gs", $"// Found: {symbol is not null} at {DateTime.UtcNow}")
);
}
}

不要在管道中包含符号。它们在内存中根编译,并且不会在不同的编译之间进行相等比较。

相反,您应该创建一个数据模型(使用适当的相等语义—最好使用记录)。数据模型应该只有包括生成时真正需要的东西,不包括符号、语法节点、编译。

原来这是由于直接引用分析器项目造成的。

当将它打包到NuGet包中并引用它时,缓存会按预期工作。

相关内容

最新更新