读取源生成器创建的属性的参数

huangapple go评论70阅读模式
英文:

Read parameters of attribute created by source generator

问题

我有以下的源代码生成器

[Generator]
public class Generator : ISourceGenerator
{
    public void Execute(GeneratorExecutionContext context)
    {
        var output = @"using System;
namespace SourceGeneratorAttributes;
[AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
class GlobalAttribute : Attribute
{
    public int OptionalNumber { get; set; } = 10;
    public string OptionalString { get; set; } = ""test"";
    public GlobalAttribute(string requiredString, int requiredNumber) {}
}
";
        context.AddSource("GlobalAttribute.cs", SourceText.From(output, Encoding.UTF8));

        var attributes = context.Compilation.Assembly.GetAttributes();
        foreach (var attribute in attributes)
        {
            Console.WriteLine(attribute);
        }
    }
    public void Initialize(GeneratorInitializationContext context)
    {
    }
}

然后在我使用源代码生成器的项目中,我有以下内容

[assembly:Global("text", 20, OptionalNumber = 33, OptionalString = "random")]

但是如果我在Console.WriteLine(attribute);上打断点并检查attribute,我会得到以下结果:
读取源生成器创建的属性的参数
我如何找到错误是什么?为什么所有参数都消失了?

如果我使用不同的属性如AssemblyFileVersion,那么我可以按预期读取参数。

完整的代码可以在这里找到: https://github.com/AnderssonPeter/SourceGeneratorAttributes

英文:

I have the following source code generator

[Generator]
public class Generator : ISourceGenerator
{
    public void Execute(GeneratorExecutionContext context)
    {
        var output = @"using System;
namespace SourceGeneratorAttributes;
[AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
class GlobalAttribute : Attribute
{
    public int OptionalNumber { get; set; } = 10;
    public string OptionalString { get; set; } = ""test"";
    public GlobalAttribute(string requiredString, int requiredNumber) {}
}
";
        context.AddSource("GlobalAttribute.cs", SourceText.From(output, Encoding.UTF8));

        var attributes = context.Compilation.Assembly.GetAttributes();
        foreach (var attribute in attributes)
        {
            Console.WriteLine(attribute);
        }
    }
    public void Initialize(GeneratorInitializationContext context)
    {
    }
}

Then in the project where I use the source generator I have the following

[assembly:Global("text", 20, OptionalNumber = 33, OptionalString = "random")]

But if I break on Console.WriteLine(attribute); and inspect the attribute I get the following:
读取源生成器创建的属性的参数
How do I find what the error is? and why are all arguments gone?

If I use a different attribute like AssemblyFileVersion then I can read the arguments as expected.

Full code can be found here: https://github.com/AnderssonPeter/SourceGeneratorAttributes

答案1

得分: 0

你需要创建一个单独的类,该类具有实现IIncrementalGenerator接口并使用RegisterPostInitializationOutput方法添加Generator属性。

示例:

[Generator]
public class AttributeGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        context.RegisterPostInitializationOutput(i =>
        {
            i.AddSource("GlobalParameterAttribute.g.cs", @"
using System;
namespace SourceGeneratorAttributes;
[AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
public sealed class GlobalParameterAttribute : Attribute
{
    public int OptionalNumber { get; set; } = 10;
    public string OptionalString { get; set; } = ""test"";
    public GlobalParameterAttribute(string requiredString, int requiredNumber) {}
}");
        });
    }
}

然后,你可以在正常的生成器中使用它,如下所示:

[Generator]
public class Generator : ISourceGenerator
{
    public void Execute(GeneratorExecutionContext context)
    {
        var attributes = context.Compilation.Assembly.GetAttributes();
        foreach (var attribute in attributes)
        {
            Console.WriteLine(attribute);
        }
    }

    public void Initialize(GeneratorInitializationContext context)
    {
    }
}
英文:

You have to create a separate class that has the Generator attribute that implements the IIncrementalGenerator and uses RegisterPostInitializationOutput to add the attribute

Example:

[Generator]
public class AttributeGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        context.RegisterPostInitializationOutput(i =>
        {
            i.AddSource("GlobalParameterAttribute.g.cs", @"using System;
namespace SourceGeneratorAttributes;
[AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
public sealed class GlobalParameterAttribute : Attribute
{
    public int OptionalNumber { get; set; } = 10;
    public string OptionalString { get; set; } = ""test"";
    public GlobalParameterAttribute(string requiredString, int requiredNumber) {}
}");
        });

    }
}

Then you can use it in your normal generator like so

[Generator]
public class Generator : ISourceGenerator
{
    public void Execute(GeneratorExecutionContext context)
    {
        var attributes = context.Compilation.Assembly.GetAttributes();
        foreach (var attribute in attributes)
        {
            Console.WriteLine(attribute);
        }
    }
    public void Initialize(GeneratorInitializationContext context)
    {
    }
}

huangapple
  • 本文由 发表于 2023年1月9日 06:23:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75051678.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定