0

I'm trying to learn and use source generator in C#, but I'm having few issues.

I want to make use of some C# new features, like generic attribute, and use it to generate custom code.

I have for example these attribute:

namespace StrongValues;

[AttributeUsage(AttributeTargets.Struct, Inherited = true, AllowMultiple = false)]
public class StrongValueAttribute<TValue> : StrongValueBaseAttribute
    where TValue : IEquatable<TValue>, IComparable<TValue>
    ;

[AttributeUsage(AttributeTargets.Struct, Inherited = true, AllowMultiple = false)]
public abstract class StrongValueBaseAttribute : Attribute
{
    public ConvertOperator ValueToStrongOperator { get; set; } = ConvertOperator.Implicit;
    public ConvertOperator StrongToValueOperator { get; set; } = ConvertOperator.Explicit;

    public bool UseJsonConverter { get; set; } = true;
    public bool UseTypeConverter { get; set; } = true;
}

public enum ConvertOperator
{
    _ = 0,
    None = _,
    Implicit,
    Explicit
}

What I want when I use the attribute, like here:

namespace NS

[StrongValue<string>]
public partial struct Email;

is to generate the following:

// Generated

namespace NS;

partial struct Email
{
  public string Value { get; init; }
}

I'm trying to make a stripped version from StronglyTypedId, but I don't know how to detect the attribute properly.

I'm trying first to detect struct types:

        var structsToGenerate = context.SyntaxProvider
                .ForAttributeWithMetadataName(
                    Parser.StrongValueAttributeDisplayName,
                    predicate: (node, _) => node is StructDeclarationSyntax,
                    transform: Parser.GetStructSemanticTarget)
                .Where(static m => m is not null)
                ;
    
// Not sure what should be the name here since it's generic.
public const string StrongValueAttributeDisplayName = "StrongValues.StrongValueAttribute`1";

Is this the right way to detect the attribute? How can I get the generic type?

string tValue = null!;

        foreach (AttributeData attribute in structSymbol.GetAttributes())
        {
            if (!(
                (attribute.AttributeClass?.Name == "StrongValueAttribute"
                || attribute.AttributeClass?.Name == "StrongValueAttribute`1"
                || attribute.AttributeClass?.Name == "StrongValue"
                || attribute.AttributeClass?.Name == "StrongValue`1")
                && attribute.AttributeClass.ToDisplayString() == StrongValueAttributeDisplayName))
            {
                // wrong attribute
                continue;
            }

            (var hasMisconfiguredInput, attrProps) = GetConstructorValues(attribute);

            if (hasMisconfiguredInput) return null;

            tValue = attribute.AttributeClass!.TypeArguments.First().ToDisplayString();

            if (tValue is null) return null;
        }
1
  • 1
    I found it very helpful to through the to-be detected code into sharplab.io and set it to "syntax tree" to see what to look for, exactly. Commented Jan 7 at 6:04

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.