Skip to content

Commit

Permalink
Handle DisplayAttribute. (#13)
Browse files Browse the repository at this point in the history
* Handle DisplayAttribute.

* Fix indentation.

* Add comment.

* Update the test.

* Update naming.

* Add System.ComponentModel.Annotations package.

* Add Integration test

* Fix CS8604 warning.

* Fix: Warning CS8600  Converting null literal or possible null value to non - nullable type.

* Remove the need of Linq

* Add conditions to System.ComponentModel.Annotations

* Update tests/NetEscapades.EnumGenerators.IntegrationTests/ExtensionTests.cs

value.GetType() -> typeof(value)

Co-authored-by: Andrew Lock <[email protected]>

* Fix: typeof(value) -> typeof(T)

* Remove unnecessary package.

* Add allowMatchingDisplayAttribute to IsDefined.
Simplify TryParse.

* Add allowMatchingDisplayAttribute optsion to TryParse

* Add SameDisplayName tests.

* Add benchmarks.

* Fix naming.

* Update IsDefinedNameBenchmark

* Update TryParseBenchmark

* Switch from optional parameter to overload in case of IsDefined and TryParse.

* Update tests

* Update tests.

* TryParse ignore case optimization

* Update IsDefined

* Update naming.

Co-authored-by: Ádám Radócz <[email protected]>
Co-authored-by: Andrew Lock <[email protected]>
  • Loading branch information
3 people authored Apr 18, 2022
1 parent 7907e7c commit f97ecf5
Show file tree
Hide file tree
Showing 33 changed files with 1,501 additions and 428 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ To use the generator, add the `[EnumExtensions]` attribute to an enum. For examp
public enum MyEnum
{
First,

[Display(Name = "2nd")]
Second,
}
```
Expand All @@ -56,7 +58,7 @@ public static partial class MyEnumExtensions
=> value switch
{
MyEnum.First => nameof(MyEnum.First),
MyEnum.Second => nameof(MyEnum.Second),
MyEnum.Second => "2nd",
_ => value.ToString(),
};

Expand Down
28 changes: 25 additions & 3 deletions src/NetEscapades.EnumGenerators/EnumGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ static List<EnumToGenerate> GetTypesToGenerate(Compilation compilation, IEnumera
string underlyingType = enumSymbol.EnumUnderlyingType?.ToString() ?? "int";

var enumMembers = enumSymbol.GetMembers();
var members = new List<KeyValuePair<string, object>>(enumMembers.Length);
var members = new List<KeyValuePair<string, EnumValueOption>>(enumMembers.Length);
var displayNames = new HashSet<string>();
var isDisplayNameTheFirstPresence = false;

foreach (var member in enumMembers)
{
Expand All @@ -159,7 +161,26 @@ static List<EnumToGenerate> GetTypesToGenerate(Compilation compilation, IEnumera
continue;
}

members.Add(new KeyValuePair<string, object>(member.Name, field.ConstantValue));
string? displayName = null;
foreach (var attribute in member.GetAttributes())
{
if (attribute.AttributeClass is null || attribute.AttributeClass.Name != "DisplayAttribute")
{
continue;
}

foreach (var namedArgument in attribute.NamedArguments)
{
if (namedArgument.Key == "Name" && namedArgument.Value.Value?.ToString() is { } dn)
{
displayName = dn;
isDisplayNameTheFirstPresence = displayNames.Add(displayName);
break;
}
}
}

members.Add(new KeyValuePair<string, EnumValueOption>(member.Name, new EnumValueOption(displayName, isDisplayNameTheFirstPresence)));
}

enumsToGenerate.Add(new EnumToGenerate(
Expand All @@ -169,7 +190,8 @@ static List<EnumToGenerate> GetTypesToGenerate(Compilation compilation, IEnumera
underlyingType: underlyingType,
isPublic: enumSymbol.DeclaredAccessibility == Accessibility.Public,
hasFlags: hasFlags,
values: members));
names: members,
isDisplaAttributeUsed: displayNames.Count > 0));
}

return enumsToGenerate;
Expand Down
16 changes: 12 additions & 4 deletions src/NetEscapades.EnumGenerators/EnumToGenerate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,31 @@ public readonly struct EnumToGenerate
public readonly bool IsPublic;
public readonly bool HasFlags;
public readonly string UnderlyingType;
public readonly List<KeyValuePair<string, object>> Values;

/// <summary>
/// Key is the enum name.
/// </summary>
public readonly List<KeyValuePair<string, EnumValueOption>> Names;

public readonly bool IsDisplaAttributeUsed;

public EnumToGenerate(
string name,
string ns,
string fullyQualifiedName,
string underlyingType,
bool isPublic,
List<KeyValuePair<string, object>> values,
bool hasFlags)
List<KeyValuePair<string, EnumValueOption>> names,
bool hasFlags,
bool isDisplaAttributeUsed)
{
Name = name;
Namespace = ns;
UnderlyingType = underlyingType;
Values = values;
Names = names;
HasFlags = hasFlags;
IsPublic = isPublic;
FullyQualifiedName = fullyQualifiedName;
IsDisplaAttributeUsed = isDisplaAttributeUsed;
}
}
16 changes: 16 additions & 0 deletions src/NetEscapades.EnumGenerators/EnumValueOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace NetEscapades.EnumGenerators;

public readonly struct EnumValueOption
{
/// <summary>
/// Custom name setted by the <c>[Display(Name)]</c> attribute.
/// </summary>
public string? DisplayName { get; }
public bool IsDisplayNameTheFirstPresence { get; }

public EnumValueOption(string? displayName, bool isDisplayNameTheFirstPresence)
{
DisplayName = displayName;
IsDisplayNameTheFirstPresence = isDisplayNameTheFirstPresence;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</ItemGroup>

<ItemGroup>
<None Include="../../README.md" Pack="true" PackagePath="\"/>
<None Include="../../README.md" Pack="true" PackagePath="\" />
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
<None Include="$(OutputPath)\NetEscapades.EnumGenerators.Attributes.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
<None Include="$(OutputPath)\NetEscapades.EnumGenerators.Attributes.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true" />
Expand Down
Loading

0 comments on commit f97ecf5

Please sign in to comment.