Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Emitted Attribute Order Deterministic in Options Source Generator #93260

Merged
merged 2 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,13 +540,13 @@ private string GenerateStronglyTypedCodeForCompareAttribute(HashSet<object>? dat

private void GenValidationAttributesClasses()
{
var attributesData = _optionsSourceGenContext.AttributesToGenerate;

if (attributesData.Count == 0)
if (_optionsSourceGenContext.AttributesToGenerate.Count == 0)
{
return;
}

var attributesData = _optionsSourceGenContext.AttributesToGenerate.OrderBy(static kvp => kvp.Key).ToArray();

OutLn($"namespace {StaticGeneratedValidationAttributesClassesNamespace}");
OutOpenBrace();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,41 @@ internal static class __Validators_2C497155
}
namespace __OptionValidationGeneratedAttributes
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")]
[global::System.AttributeUsage(global::System.AttributeTargets.Property, AllowMultiple = false)]
internal class __SourceGen__2C497155_CompareAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute
{
private static string DefaultErrorMessageString => "'{0}' and '{1}' do not match.";
public __SourceGen__2C497155_CompareAttribute(string otherProperty) : base(() => DefaultErrorMessageString)
{
if (otherProperty == null)
{
throw new global::System.ArgumentNullException(nameof(otherProperty));
}
OtherProperty = otherProperty;
}
public string OtherProperty { get; }
public override bool RequiresValidationContext => true;

protected override global::System.ComponentModel.DataAnnotations.ValidationResult? IsValid(object? value, global::System.ComponentModel.DataAnnotations.ValidationContext validationContext)
{
bool result = true;

if (validationContext.ObjectInstance is global::ValidationTest.OptionsUsingGeneratedAttributes && OtherProperty == "P5")
{
result = Equals(value, ((global::ValidationTest.OptionsUsingGeneratedAttributes)validationContext.ObjectInstance).P5);
}

if (!result)
{
string[]? memberNames = validationContext.MemberName is null ? null : new string[] { validationContext.MemberName };
return new global::System.ComponentModel.DataAnnotations.ValidationResult(FormatErrorMessage(validationContext.DisplayName), memberNames);
}

return null;
}
public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty);
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")]
[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)]
internal class __SourceGen__2C497155_LengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute
Expand Down Expand Up @@ -237,6 +272,97 @@ public override bool IsValid(object? value)
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")]
[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)]
internal class __SourceGen__2C497155_MaxLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute
{
private const int MaxAllowableLength = -1;
private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'.";
public __SourceGen__2C497155_MaxLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; }
public __SourceGen__2C497155_MaxLengthAttribute(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; }
public int Length { get; }
public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length);
public override bool IsValid(object? value)
{
if (Length == 0 || Length < -1)
{
throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length.");
}
if (value == null || MaxAllowableLength == Length)
{
return true;
}

int length;
if (value is string stringValue)
{
length = stringValue.Length;
}
else if (value is System.Collections.ICollection collectionValue)
{
length = collectionValue.Count;
}
else if (value is global::ValidationTest.FakeCount)
{
length = ((global::ValidationTest.FakeCount)value).Count;
}
else if (value is global::ValidationTest.FakeCountChild)
{
length = ((global::ValidationTest.FakeCountChild)value).Count;
}
else
{
throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type.");
}

return length <= Length;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")]
[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)]
internal class __SourceGen__2C497155_MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute
{
private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'.";

public __SourceGen__2C497155_MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; }
public int Length { get; }
public override bool IsValid(object? value)
{
if (Length < -1)
{
throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater.");
}
if (value == null)
{
return true;
}

int length;
if (value is string stringValue)
{
length = stringValue.Length;
}
else if (value is System.Collections.ICollection collectionValue)
{
length = collectionValue.Count;
}
else if (value is global::ValidationTest.FakeCount)
{
length = ((global::ValidationTest.FakeCount)value).Count;
}
else if (value is global::ValidationTest.FakeCountChild)
{
length = ((global::ValidationTest.FakeCountChild)value).Count;
}
else
{
throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type.");
}

return length >= Length;
}
public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length);
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")]
[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)]
internal class __SourceGen__2C497155_RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute
{
public __SourceGen__2C497155_RangeAttribute(int minimum, int maximum) : base()
Expand Down Expand Up @@ -342,130 +468,4 @@ private string GetValidationErrorMessage()
return value;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")]
[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)]
internal class __SourceGen__2C497155_MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute
{
private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'.";

public __SourceGen__2C497155_MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; }
public int Length { get; }
public override bool IsValid(object? value)
{
if (Length < -1)
{
throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater.");
}
if (value == null)
{
return true;
}

int length;
if (value is string stringValue)
{
length = stringValue.Length;
}
else if (value is System.Collections.ICollection collectionValue)
{
length = collectionValue.Count;
}
else if (value is global::ValidationTest.FakeCount)
{
length = ((global::ValidationTest.FakeCount)value).Count;
}
else if (value is global::ValidationTest.FakeCountChild)
{
length = ((global::ValidationTest.FakeCountChild)value).Count;
}
else
{
throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type.");
}

return length >= Length;
}
public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length);
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")]
[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)]
internal class __SourceGen__2C497155_MaxLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute
{
private const int MaxAllowableLength = -1;
private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'.";
public __SourceGen__2C497155_MaxLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; }
public __SourceGen__2C497155_MaxLengthAttribute(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; }
public int Length { get; }
public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length);
public override bool IsValid(object? value)
{
if (Length == 0 || Length < -1)
{
throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length.");
}
if (value == null || MaxAllowableLength == Length)
{
return true;
}

int length;
if (value is string stringValue)
{
length = stringValue.Length;
}
else if (value is System.Collections.ICollection collectionValue)
{
length = collectionValue.Count;
}
else if (value is global::ValidationTest.FakeCount)
{
length = ((global::ValidationTest.FakeCount)value).Count;
}
else if (value is global::ValidationTest.FakeCountChild)
{
length = ((global::ValidationTest.FakeCountChild)value).Count;
}
else
{
throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type.");
}

return length <= Length;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")]
[global::System.AttributeUsage(global::System.AttributeTargets.Property, AllowMultiple = false)]
internal class __SourceGen__2C497155_CompareAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute
{
private static string DefaultErrorMessageString => "'{0}' and '{1}' do not match.";
public __SourceGen__2C497155_CompareAttribute(string otherProperty) : base(() => DefaultErrorMessageString)
{
if (otherProperty == null)
{
throw new global::System.ArgumentNullException(nameof(otherProperty));
}
OtherProperty = otherProperty;
}
public string OtherProperty { get; }
public override bool RequiresValidationContext => true;

protected override global::System.ComponentModel.DataAnnotations.ValidationResult? IsValid(object? value, global::System.ComponentModel.DataAnnotations.ValidationContext validationContext)
{
bool result = true;

if (validationContext.ObjectInstance is global::ValidationTest.OptionsUsingGeneratedAttributes && OtherProperty == "P5")
{
result = Equals(value, ((global::ValidationTest.OptionsUsingGeneratedAttributes)validationContext.ObjectInstance).P5);
}

if (!result)
{
string[]? memberNames = validationContext.MemberName is null ? null : new string[] { validationContext.MemberName };
return new global::System.ComponentModel.DataAnnotations.ValidationResult(FormatErrorMessage(validationContext.DisplayName), memberNames);
}

return null;
}
public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty);
}
}
Loading
Loading