我正在发现源生成器的概念。
为了根据目标/引用项目的文件夹结构使用源生成器对某些文件(更准确地说是图像文件)执行某些逻辑,我需要:
namespace SourceGen
{
[Generator]
public class Class1 : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var projDirectory = context.AnalyzerConfigOptionsProvider
.Select((x, _) => x.GlobalOptions
.TryGetValue("build_property.MSBuildProjectDirectory", out var projectDirectory) ? projectDirectory : null);
File.AppendAllText("\\" + "log.txt", projDirectory );
}
}
}
我正在记录到一个文件以进行调试(以检查在本例中我正在读取的属性值),因为我找不到另一种方法来调试此类项目。
在我得到的日志文件中,因为
IncrementalValueProvider<string>.ToString()
返回类型而不是其中的任何值:
Microsoft.CodeAnalysis.IncrementalValueProvider`1[System.string]。
以下https://stackoverflow.com/a/66548212:
var mainSyntaxTree = context.CompilationProvider.Select((x, _) => x.SyntaxTrees.First(x => x.HasCompilationUnitRoot));
var directory = Path.GetDirectoryName(mainSyntaxTree.Select((x, _) => x.FilePath);
同样的问题
Path.GetDirectoryName()
抱怨提供的参数是IncrementalValueProvider<string>
类型,而期望是string
。
不知道如何从 FilePath
类型中获取有用的字符串值 (IncrementalValueProvider<string>
)。
这次日志文件根本没有写入/创建:
var provider = context.AnalyzerConfigOptionsProvider.Select((x, _) =>
{
x.GlobalOptions.TryGetValue("build_property.MSBuildProjectDirectory", out var projectDirectory);
File.AppendAllText("\\" + "log.txt", "testing" + projectDirectory);
return projectDirectory;
});
文档:https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.cookbook.md
第三种方法是关闭返回类型是IncrementalValueProvider而不是值本身。然后您需要将此提供商与其他提供商结合起来。我就是这样做的
var someInfo = context.AnalyzerConfigOptionsProvider
.Select(static (ctx, _) => {
if(ctx.GlobalOptions.TryGetValue("build_property.someInfo", out var info))
{
return info;
}
return defaultInfo;
});
var dataFromAttribute = context.SyntaxProvider
.ForAttributeWithMetadataName(
"MyAttribute",
predicate: static (s, _) => s is ClassDeclarationSyntax { AttributeLists.Count: > 0 },
transform: static (ctx, _) => GetAttributeData(ctx.SemanticModel, ctx.TargetNode))
.Where(static m => m is not null);
var attributeDataEnhancedWithInfo = dataFromAttribute .Combine(someInfo ).Select((pair, _) => {
pair.Left!.Info = pair.Right;
return pair. Left!});