Skip to content

Commit

Permalink
Add support for duplicate values in flag enums
Browse files Browse the repository at this point in the history
  • Loading branch information
iqv-csis committed Mar 5, 2024
1 parent 5e169d2 commit cd3e0e6
Show file tree
Hide file tree
Showing 21 changed files with 493 additions and 239 deletions.
22 changes: 10 additions & 12 deletions Src/EnumSourceGen.Tests.CodeGen/Resources/DifferentNamespace.output
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,11 @@ namespace Some.Namespace.Here1;

public static partial class MyEnumExtensions
{
public static string GetString(this Some.Namespace.Here1.MyEnum value)
=> value switch
{
Some.Namespace.Here1.MyEnum.Value => "Value",
_ => value.ToString()
};
public static string GetString(this Some.Namespace.Here1.MyEnum value) => value switch
{
Some.Namespace.Here1.MyEnum.Value => "Value",
_ => value.ToString()
};

public static bool TryGetUnderlyingValue(this Some.Namespace.Here1.MyEnum value, out Int32 underlyingValue)
{
Expand Down Expand Up @@ -283,12 +282,11 @@ namespace Some.Namespace.Here2;

public static partial class MyEnumExtensions
{
public static string GetString(this Some.Namespace.Here2.MyEnum value)
=> value switch
{
Some.Namespace.Here2.MyEnum.Value => "Value",
_ => value.ToString()
};
public static string GetString(this Some.Namespace.Here2.MyEnum value) => value switch
{
Some.Namespace.Here2.MyEnum.Value => "Value",
_ => value.ToString()
};

public static bool TryGetUnderlyingValue(this Some.Namespace.Here2.MyEnum value, out Int32 underlyingValue)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,11 @@ namespace Some.Namespace.Here;

public static partial class MyEnumExtensions
{
public static string GetString(this Some.Namespace.Here.MyEnum value)
=> value switch
{
Some.Namespace.Here.MyEnum.Value => "Value",
_ => value.ToString()
};
public static string GetString(this Some.Namespace.Here.MyEnum value) => value switch
{
Some.Namespace.Here.MyEnum.Value => "Value",
_ => value.ToString()
};

public static bool TryGetUnderlyingValue(this Some.Namespace.Here.MyEnum value, out Byte underlyingValue)
{
Expand Down Expand Up @@ -283,12 +282,11 @@ namespace Some.Namespace.Here;

public static partial class MyEnum2Extensions
{
public static string GetString(this Some.Namespace.Here.MyEnum2 value)
=> value switch
{
Some.Namespace.Here.MyEnum2.Value => "Value",
_ => value.ToString()
};
public static string GetString(this Some.Namespace.Here.MyEnum2 value) => value switch
{
Some.Namespace.Here.MyEnum2.Value => "Value",
_ => value.ToString()
};

public static bool TryGetUnderlyingValue(this Some.Namespace.Here.MyEnum2 value, out UInt64 underlyingValue)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,11 @@ using System.Diagnostics.CodeAnalysis;

public static partial class MyEnumExtensions
{
public static string GetString(this global::MyEnum value)
=> value switch
{
global::MyEnum.Value => "Value",
_ => value.ToString()
};
public static string GetString(this global::MyEnum value) => value switch
{
global::MyEnum.Value => "Value",
_ => value.ToString()
};

public static bool TryGetUnderlyingValue(this global::MyEnum value, out Int32 underlyingValue)
{
Expand Down
15 changes: 7 additions & 8 deletions Src/EnumSourceGen.Tests.CodeGen/Resources/DisplayName.output
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,13 @@ namespace Some.Namespace.Here;

public static partial class MyEnumExtensions
{
public static string GetString(this Some.Namespace.Here.MyEnum value)
=> value switch
{
Some.Namespace.Here.MyEnum.Value1 => "Value1",
Some.Namespace.Here.MyEnum.Value2 => "Value2",
Some.Namespace.Here.MyEnum.Value3 => "Value3",
_ => value.ToString()
};
public static string GetString(this Some.Namespace.Here.MyEnum value) => value switch
{
Some.Namespace.Here.MyEnum.Value1 => "Value1",
Some.Namespace.Here.MyEnum.Value2 => "Value2",
Some.Namespace.Here.MyEnum.Value3 => "Value3",
_ => value.ToString()
};

public static bool TryGetUnderlyingValue(this Some.Namespace.Here.MyEnum value, out Int32 underlyingValue)
{
Expand Down
13 changes: 13 additions & 0 deletions Src/EnumSourceGen.Tests.CodeGen/Resources/DuplicateValues.input
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//This test is checks if we support duplicate values for flag enums

namespace Some.Namespace.Here;

[Flags]
[EnumSourceGen]
public enum Profile
{
Unknown = 0,
WindowsLegacy = 1 << 0,
WindowsServer2022 = 1 << 8,
NewestServer = WindowsServer2022,
}
235 changes: 235 additions & 0 deletions Src/EnumSourceGen.Tests.CodeGen/Resources/DuplicateValues.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
// <auto-generated />
#nullable enable
using System;

namespace Some.Namespace.Here;

[Flags]
public enum ProfileFormat : byte
{
None = 0,
Name = 1,
Value = 2,
Default = Name | Value
}
// <auto-generated />
#nullable enable
using System;

namespace Some.Namespace.Here;

public static partial class Enums
{
public static partial class Profile
{
public const int MemberCount = 4;
public const bool IsFlagEnum = true;

public static string[] GetMemberNames() => _names ??= new string[] {
"Unknown",
"WindowsLegacy",
"WindowsServer2022",
"NewestServer"
};

public static Some.Namespace.Here.Profile[] GetMemberValues() => _values ??= new Some.Namespace.Here.Profile[] {
Some.Namespace.Here.Profile.Unknown,
Some.Namespace.Here.Profile.WindowsLegacy,
Some.Namespace.Here.Profile.WindowsServer2022,
Some.Namespace.Here.Profile.NewestServer
};

public static Int32[] GetUnderlyingValues() => _underlyingValues ??= new Int32[] {
0,
1,
256,
256
};

public static bool TryParse(string value, out Some.Namespace.Here.Profile result, Some.Namespace.Here.ProfileFormat format = Some.Namespace.Here.ProfileFormat.Default, StringComparison comparison = StringComparison.Ordinal)
{
if (format.HasFlag(Some.Namespace.Here.ProfileFormat.Name))
{
if (value.Equals("Unknown", comparison))
{
result = Some.Namespace.Here.Profile.Unknown;
return true;
}

if (value.Equals("WindowsLegacy", comparison))
{
result = Some.Namespace.Here.Profile.WindowsLegacy;
return true;
}

if (value.Equals("WindowsServer2022", comparison))
{
result = Some.Namespace.Here.Profile.WindowsServer2022;
return true;
}

if (value.Equals("NewestServer", comparison))
{
result = Some.Namespace.Here.Profile.NewestServer;
return true;
}
}
if (format.HasFlag(Some.Namespace.Here.ProfileFormat.Value))
{
if (value.Equals("0", comparison))
{
result = Some.Namespace.Here.Profile.Unknown;
return true;
}

if (value.Equals("1", comparison))
{
result = Some.Namespace.Here.Profile.WindowsLegacy;
return true;
}

if (value.Equals("256", comparison))
{
result = Some.Namespace.Here.Profile.WindowsServer2022;
return true;
}

if (value.Equals("256", comparison))
{
result = Some.Namespace.Here.Profile.NewestServer;
return true;
}
}
result = default;
return false;
}

#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
public static bool TryParse(ReadOnlySpan<char> value, out Some.Namespace.Here.Profile result, Some.Namespace.Here.ProfileFormat format = Some.Namespace.Here.ProfileFormat.Default, StringComparison comparison = StringComparison.Ordinal)
{
if (format.HasFlag(Some.Namespace.Here.ProfileFormat.Name))
{
if (value.Equals("Unknown", comparison))
{
result = Some.Namespace.Here.Profile.Unknown;
return true;
}

if (value.Equals("WindowsLegacy", comparison))
{
result = Some.Namespace.Here.Profile.WindowsLegacy;
return true;
}

if (value.Equals("WindowsServer2022", comparison))
{
result = Some.Namespace.Here.Profile.WindowsServer2022;
return true;
}

if (value.Equals("NewestServer", comparison))
{
result = Some.Namespace.Here.Profile.NewestServer;
return true;
}
}
if (format.HasFlag(Some.Namespace.Here.ProfileFormat.Value))
{
if (value.Equals("0", comparison))
{
result = Some.Namespace.Here.Profile.Unknown;
return true;
}

if (value.Equals("1", comparison))
{
result = Some.Namespace.Here.Profile.WindowsLegacy;
return true;
}

if (value.Equals("256", comparison))
{
result = Some.Namespace.Here.Profile.WindowsServer2022;
return true;
}

if (value.Equals("256", comparison))
{
result = Some.Namespace.Here.Profile.NewestServer;
return true;
}
}
result = default;
return false;
}

public static Some.Namespace.Here.Profile Parse(ReadOnlySpan<char> value, Some.Namespace.Here.ProfileFormat format = Some.Namespace.Here.ProfileFormat.Default, StringComparison comparison = StringComparison.Ordinal)
{
if (!TryParse(value, out Some.Namespace.Here.Profile result, format, comparison))
throw new ArgumentOutOfRangeException($"Invalid value: {value.ToString()}");

return result;
}
#endif

public static Some.Namespace.Here.Profile Parse(string value, Some.Namespace.Here.ProfileFormat format = Some.Namespace.Here.ProfileFormat.Default, StringComparison comparison = StringComparison.Ordinal)
{
if (!TryParse(value, out Some.Namespace.Here.Profile result, format, comparison))
throw new ArgumentOutOfRangeException($"Invalid value: {value}");

return result;
}

public static bool IsDefined(Some.Namespace.Here.Profile input)
{
return unchecked(((Int32)257UL & (Int32)input) == (Int32)input);
}

private static string[]? _names;
private static Some.Namespace.Here.Profile[]? _values;
private static Int32[]? _underlyingValues;

}
}
// <auto-generated />
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;

namespace Some.Namespace.Here;

public static partial class ProfileExtensions
{
public static string GetString(this Some.Namespace.Here.Profile value) => value.ToString();

public static bool TryGetUnderlyingValue(this Some.Namespace.Here.Profile value, out Int32 underlyingValue)
{
switch (value.ToString())
{
case "Unknown":
underlyingValue = 0;
return true;
case "WindowsLegacy":
underlyingValue = 1;
return true;
case "WindowsServer2022":
underlyingValue = 256;
return true;
case "NewestServer":
underlyingValue = 256;
return true;
}
underlyingValue = default;
return false;
}

public static Int32 GetUnderlyingValue(this Some.Namespace.Here.Profile value)
{
if (!TryGetUnderlyingValue(value, out Int32 underlyingValue))
throw new ArgumentOutOfRangeException($"Invalid value: {value}");

return underlyingValue;
}

public static bool IsFlagSet(this Some.Namespace.Here.Profile value, Some.Namespace.Here.Profile flag) => ((Int32)value & (Int32)flag) == (Int32)flag;
}
11 changes: 5 additions & 6 deletions Src/EnumSourceGen.Tests.CodeGen/Resources/EnumClassName.output
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,11 @@ namespace Some.Namespace.Here;

public static partial class MyEnumExtensions
{
public static string GetString(this Some.Namespace.Here.MyEnum value)
=> value switch
{
Some.Namespace.Here.MyEnum.Value => "Value",
_ => value.ToString()
};
public static string GetString(this Some.Namespace.Here.MyEnum value) => value switch
{
Some.Namespace.Here.MyEnum.Value => "Value",
_ => value.ToString()
};

public static bool TryGetUnderlyingValue(this Some.Namespace.Here.MyEnum value, out Int32 underlyingValue)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,11 @@ namespace Some.Namespace.Here;

public static partial class MyEnumExtensions
{
public static string GetString(this Some.Namespace.Here.MyEnum value)
=> value switch
{
Some.Namespace.Here.MyEnum.Value => "Value",
_ => value.ToString()
};
public static string GetString(this Some.Namespace.Here.MyEnum value) => value switch
{
Some.Namespace.Here.MyEnum.Value => "Value",
_ => value.ToString()
};

public static bool TryGetUnderlyingValue(this Some.Namespace.Here.MyEnum value, out Int32 underlyingValue)
{
Expand Down
Loading

0 comments on commit cd3e0e6

Please sign in to comment.