dotnet icon indicating copy to clipboard operation
dotnet copied to clipboard

[MVVM] Don't add default parameter in attribute constructor

Open hellow554 opened this issue 1 year ago • 1 comments

Describe the bug

I have an Attribute, which constructor looks like this:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class CrossValidateAttribute : ValidationAttribute {
    public CrossValidateAttribute([CallerMemberName] string? member = null) { }
}

The idea is to get the properties name when this gets constructed. If I put this on a normal Property, e.g.

[CrossValidate]
public string Foo { ... }

it will work and I get Foo as content of member.

But, if I put this on an [ObservableProperty] the generator will output this:

[ObservableProperty]
[CrossValidate]
private string? bar;
/// <inheritdoc cref="bar"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::XXX.CrossValidateAttribute(null)]
public string? Bar { ... }

Here you can see the XXX.CrossValidateAttribute(null) call, which is not want I want.

Can this be done the way I want it, e.g. XXX.CrossValidateAttribute()?

IDE and version

VS 2022

IDE version

Version 17.7.6

Nuget packages

  • [ ] CommunityToolkit.Common
  • [ ] CommunityToolkit.Diagnostics
  • [ ] CommunityToolkit.HighPerformance
  • [X] CommunityToolkit.Mvvm (aka MVVM Toolkit)

Nuget package version(s)

8.2.2

Additional context

No response

Help us help you

Yes, I'd like to be assigned to work on this item

hellow554 avatar Oct 27 '23 14:10 hellow554

Hi there

I did some research on this one and found following:

In ../src/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/Models/AttributeInfo.cs:41

        // Get the constructor arguments
        foreach (TypedConstant typedConstant in attributeData.ConstructorArguments)
        {
            constructorArguments.Add(TypedConstantInfo.Create(typedConstant));
        }

For testing purposed I replaced this part with:

        // Get the constructor arguments
        for (int i = 0; i < attributeData.AttributeConstructor.Parameters.Count(); i++)
        {
            if (attributeData.AttributeConstructor.Parameters[i].HasExplicitDefaultValue) break;

            var typedConstant = attributeData.ConstructorArguments[i];
            var info = TypedConstantInfo.Create(typedConstant);
            constructorArguments.Add(info);
        }

Parameters with default value are skipped.

Maybe this (or somehow better) can be discussed as a solution.

best regards

JochenMader avatar Nov 03 '23 11:11 JochenMader