Skip to content

Commit

Permalink
Make Emitted Attribute Order Deterministic in Options Source Generator (
Browse files Browse the repository at this point in the history
#93260)

* Make Emitted Attribute Order Deterministic in Options Source Generator

* Use ordinal comparison when ordering the list
  • Loading branch information
tarekgh committed Oct 10, 2023
1 parent e47e120 commit 51ae59b
Show file tree
Hide file tree
Showing 5 changed files with 507 additions and 507 deletions.
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, StringComparer.Ordinal).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

0 comments on commit 51ae59b

Please sign in to comment.