源生成器获取引用项目路径 - 从 IncrementalValueProvider 检索有用的值<string>

问题描述 投票:0回答:1

我正在发现源生成器的概念。

为了根据目标/引用项目的文件夹结构使用源生成器对某些文件(更准确地说是图像文件)执行某些逻辑,我需要:

  • 获取目标/引用项目的路径/目录。

第一种方法

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

c# msbuild roslyn sourcegenerators csharp-source-generator
1个回答
0
投票

第三种方法是关闭返回类型是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!});
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.