C#增量源代码生成器在修改生成的文件时不触发构建
C# Incremental Source Generator Not Triggering build when generated files are modified
我有 2 个项目,IE:projX.csproj 和 projY.csproj。
我的src生成器被projX引用了,但是生成的代码是基于projY上的类。
当 projY 类 发生变化时,生成的文件应该会发生变化(它们确实会发生变化),但是因为 projX 上没有发生变化,所以不会拾取这些变化,projX 上也没有构建。
我正在考虑但找不到答案的路线:
- 如何让 projX 识别生成的文件已更改?
- 否则,如何在 projY 更改时强制构建 projX?
谢谢。
评论太长了。
我认为此时可能的一件事是您以错误的方式获取类型,我使用它从传递给属性的 Expression
中获取值。目前它实际上不适用于 DefaultExpressionSyntax
,这就是为什么我在属性中使用 NamedParameters
来避免它:
public record ValueSymbolInfo(object? Value, TypeInfo? Type);
private ValueSymbolInfo GetValue(SemanticModel semanticModel, ExpressionSyntax expression)
{
var constantType = semanticModel.GetTypeInfo(expression);
if (expression is TypeOfExpressionSyntax typeOfExpressionSyntax)
return new(GetValue(semanticModel, typeOfExpressionSyntax.Type).Type, constantType);
if (expression is DefaultExpressionSyntax defaultExpressionSyntax)
return new(null, GetValue(semanticModel, defaultExpressionSyntax.Type).Type);
if (expression is ArrayCreationExpressionSyntax arrayCreationExpressionSyntax)
{
var initializer = arrayCreationExpressionSyntax.Initializer;
var type = semanticModel.GetTypeInfo(arrayCreationExpressionSyntax.Type);
if (initializer is null)
{
return new(null, type);
}
else
{
var expressions = initializer.Expressions;
var value = expressions.Select(syntax => GetValue(semanticModel, syntax)).Select(info => info?.Value).ToArray();
return new(value, type);
}
}
var constantValue = semanticModel.GetConstantValue(expression);
return new(constantValue.HasValue ? constantValue.Value : default, constantType);
}
如果在 typeof(ProjYType)
上使用,它应该 return 引用类型的 TypeInfo
作为值,System.Type
的 TypeInfo
作为 Type
否则我只能想象你的项目文件有问题。
我发现针对此特定情况的最佳解决方法是添加:
<ItemGroup>
<Compile Include="../YourProjectName/*/*.cs"/>
</ItemGroup>
include 中传递的内容视情况而定,但最好尽可能具体。
这也会将语法树添加到编译中。
我有 2 个项目,IE:projX.csproj 和 projY.csproj。
我的src生成器被projX引用了,但是生成的代码是基于projY上的类。
当 projY 类 发生变化时,生成的文件应该会发生变化(它们确实会发生变化),但是因为 projX 上没有发生变化,所以不会拾取这些变化,projX 上也没有构建。 我正在考虑但找不到答案的路线:
- 如何让 projX 识别生成的文件已更改?
- 否则,如何在 projY 更改时强制构建 projX?
谢谢。
评论太长了。
我认为此时可能的一件事是您以错误的方式获取类型,我使用它从传递给属性的 Expression
中获取值。目前它实际上不适用于 DefaultExpressionSyntax
,这就是为什么我在属性中使用 NamedParameters
来避免它:
public record ValueSymbolInfo(object? Value, TypeInfo? Type);
private ValueSymbolInfo GetValue(SemanticModel semanticModel, ExpressionSyntax expression)
{
var constantType = semanticModel.GetTypeInfo(expression);
if (expression is TypeOfExpressionSyntax typeOfExpressionSyntax)
return new(GetValue(semanticModel, typeOfExpressionSyntax.Type).Type, constantType);
if (expression is DefaultExpressionSyntax defaultExpressionSyntax)
return new(null, GetValue(semanticModel, defaultExpressionSyntax.Type).Type);
if (expression is ArrayCreationExpressionSyntax arrayCreationExpressionSyntax)
{
var initializer = arrayCreationExpressionSyntax.Initializer;
var type = semanticModel.GetTypeInfo(arrayCreationExpressionSyntax.Type);
if (initializer is null)
{
return new(null, type);
}
else
{
var expressions = initializer.Expressions;
var value = expressions.Select(syntax => GetValue(semanticModel, syntax)).Select(info => info?.Value).ToArray();
return new(value, type);
}
}
var constantValue = semanticModel.GetConstantValue(expression);
return new(constantValue.HasValue ? constantValue.Value : default, constantType);
}
如果在 typeof(ProjYType)
上使用,它应该 return 引用类型的 TypeInfo
作为值,System.Type
的 TypeInfo
作为 Type
否则我只能想象你的项目文件有问题。
我发现针对此特定情况的最佳解决方法是添加:
<ItemGroup>
<Compile Include="../YourProjectName/*/*.cs"/>
</ItemGroup>
include 中传递的内容视情况而定,但最好尽可能具体。 这也会将语法树添加到编译中。