Skip to content

Commit

Permalink
Merge pull request #2 from EngRajabi/cleanup
Browse files Browse the repository at this point in the history
add more methods
  • Loading branch information
EngRajabi authored May 28, 2022
2 parents 218cbc4 + 4f493b9 commit 2f6d9bb
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 80 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
## 1.0.11
- Add method GetValuesFast
- Add method GetNamesFast
- Add method GetLengthFast

## 1.0.10
- Add method ToDisplayFast
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/EngRajabi/Enum.Source.Generator/master/LICENSE)
[![Nuget](https://img.shields.io/nuget/dt/Supernova.Enum.Generators?label=Nuget.org%20Downloads&style=flat-square&color=blue)](https://www.nuget.org/packages/Supernova.Enum.Generators)
[![Nuget](https://img.shields.io/nuget/vpre/Supernova.Enum.Generators.svg?label=NuGet)](https://www.nuget.org/packages/Supernova.Enum.Generators)

# Supernova.Enum.Generators
# The best Source Generator for working with enums in C#
Expand Down Expand Up @@ -79,25 +80,54 @@ For example:
_ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
};
}
public static UnitTests.UserTypeTest[] GetValuesFast()
{
return new[]
{
UnitTests.UserTypeTest.Men,
UnitTests.UserTypeTest.Women,
UnitTests.UserTypeTest.None,
};
}
public static string[] GetNamesFast()
{
return new[]
{
nameof(UnitTests.UserTypeTest.Men),
nameof(UnitTests.UserTypeTest.Women),
nameof(UnitTests.UserTypeTest.None),
};
}
public static int GetLengthFast()
{
return 3;

}
}
```

You do not see this file inside the project. But you can use it.

Usage
```csharp
var stringEnum = UserType.Men.StringToFast(); //Men;
var stringEnum = UserTypeTest.Men.StringToFast(); //Men;
var isDefined = UserTypeTestEnumExtensions.IsDefinedFast(UserType.Men); //true;
var displayEnum = UserType.Men.ToDisplayFast(); //مرد
var displayEnum = UserTypeTest.Men.ToDisplayFast(); //مرد
var names = UserTypeTestEnumExtensions.GetNamesFast(); //string[]
var values = UserTypeTestEnumExtensions.GetValuesFast(); //UserType[]
var length = UserTypeTestEnumExtensions.GetLengthFast(); //3
```

If you had trouble using UserTypeTestEnumExtensions and the IDE did not recognize it. This is an IDE problem and you need to restart the IDE once.

Benchmark

![Benchmark](https://raw.githubusercontent.com/EngRajabi/Enum.Source.Generator/master/Supernova.Enum.Generators.png?v=1)
![Benchmark](https://raw.githubusercontent.com/EngRajabi/Enum.Source.Generator/master/Supernova.Enum.Generators.png?v=4)

## Contributing

Expand Down
Binary file modified Supernova.Enum.Generators.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
216 changes: 142 additions & 74 deletions Supernova.Enum.Generators/EnumSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ public void Initialize(GeneratorInitializationContext context)

public void Execute(GeneratorExecutionContext context)
{
//#if DEBUG
// if (!Debugger.IsAttached)
// {
// Debugger.Launch();
// }
//#endif
//#if DEBUG
// if (!Debugger.IsAttached)
// {
// Debugger.Launch();
// }
//#endif
context.AddSource($"{SourceGeneratorHelper.AttributeName}Attribute.g.cs", SourceText.From($@"using System;
namespace {SourceGeneratorHelper.NameSpace}
{{
Expand Down Expand Up @@ -69,113 +69,181 @@ public sealed class {SourceGeneratorHelper.AttributeName}Attribute : Attribute
// .DefaultIfEmpty(SourceGeneratorHelper.ExtensionMethodName).First()
// : SourceGeneratorHelper.ExtensionMethodName;


/**********************/
var memberAttribute = new Dictionary<string, string>();
foreach (var member in enumSymbol.GetMembers())
{
if (member is not IFieldSymbol field
|| field.ConstantValue is null)
continue;

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.Equals("Name", StringComparison.OrdinalIgnoreCase) &&
namedArgument.Value.Value?.ToString() is { } dn)
{
memberAttribute.Add(member.Name, dn);
break;
}
}
}

var sourceBuilder = new StringBuilder($@"using System;
namespace {SourceGeneratorHelper.NameSpace}
{{
public static class {symbol.Name}EnumExtensions
{{");

//ToStringFast
sourceBuilder.Append($@"
public static string {SourceGeneratorHelper.ExtensionMethodNameToString}(this {symbolName} states)
ToStringFast(sourceBuilder, symbolName, e);

//IsDefined enum
IsDefinedEnum(sourceBuilder, symbolName, e);

//IsDefined string
IsDefinedString(sourceBuilder, e, symbolName);

//ToDisplay string
ToDisplay(sourceBuilder, symbolName, e, memberAttribute);

//GetValues
GetValuesFast(sourceBuilder, symbolName, e);

//GetNames
GetNamesFast(sourceBuilder, symbolName, e);

//GetLength
GetLengthFast(sourceBuilder, symbolName, e);

sourceBuilder.Append(@"
}
}
");

context.AddSource($"{symbol.Name}_EnumGenerator.g.cs",
SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
}

private static void ToDisplay(StringBuilder sourceBuilder, string symbolName, EnumDeclarationSyntax e,
Dictionary<string, string> memberAttribute)
{
sourceBuilder.Append($@"
public static string {SourceGeneratorHelper.ExtensionMethodNameToDisplay}(this {symbolName} states)
{{
return states switch
{{
");
foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
sourceBuilder.AppendLine($@" {symbolName}.{member} => nameof({symbolName}.{member}),");
sourceBuilder.Append(
@" _ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
foreach (var member in e.Members)
{
var display = memberAttribute
.FirstOrDefault(r =>
r.Key.Equals(member.Identifier.ValueText, StringComparison.OrdinalIgnoreCase))
.Value
?? member.Identifier.ValueText;

sourceBuilder.AppendLine(
$@" {symbolName}.{member.Identifier.ValueText} => ""{display}"",");
}

sourceBuilder.Append(
@" _ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
};
}");
}

private static void IsDefinedString(StringBuilder sourceBuilder, EnumDeclarationSyntax e, string symbolName)
{
sourceBuilder.Append($@"
public static bool {SourceGeneratorHelper.ExtensionMethodNameIsDefined}(string states)
{{
return states switch
{{
");
foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
sourceBuilder.AppendLine($@" nameof({symbolName}.{member}) => true,");
sourceBuilder.Append(
@" _ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
};
}");
}

//IsDefined enum
sourceBuilder.Append($@"
private static void IsDefinedEnum(StringBuilder sourceBuilder, string symbolName, EnumDeclarationSyntax e)
{
sourceBuilder.Append($@"
public static bool {SourceGeneratorHelper.ExtensionMethodNameIsDefined}({symbolName} states)
{{
return states switch
{{
");
foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
sourceBuilder.AppendLine($@" {symbolName}.{member} => true,");
sourceBuilder.Append(
@" _ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
sourceBuilder.AppendLine($@" {symbolName}.{member} => true,");
sourceBuilder.Append(
@" _ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
};
}");
}


//IsDefined string
sourceBuilder.Append($@"
public static bool {SourceGeneratorHelper.ExtensionMethodNameIsDefined}(string states)
private static void ToStringFast(StringBuilder sourceBuilder, string symbolName, EnumDeclarationSyntax e)
{
sourceBuilder.Append($@"
public static string {SourceGeneratorHelper.ExtensionMethodNameToString}(this {symbolName} states)
{{
return states switch
{{
");
foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
sourceBuilder.AppendLine($@" nameof({symbolName}.{member}) => true,");
sourceBuilder.Append(
@" _ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
sourceBuilder.AppendLine($@" {symbolName}.{member} => nameof({symbolName}.{member}),");
sourceBuilder.Append(
@" _ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
};
}");
}

private static void GetValuesFast(StringBuilder sourceBuilder, string symbolName, EnumDeclarationSyntax e)
{
sourceBuilder.Append($@"
public static {symbolName}[] {SourceGeneratorHelper.ExtensionMethodNameGetValues}()
{{
return new[]
{{
");
foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
sourceBuilder.AppendLine($@" {symbolName}.{member},");

/**********************/
var memberAttribute = new Dictionary<string, string>();
foreach (var member in enumSymbol.GetMembers())
{
if (member is not IFieldSymbol field
|| field.ConstantValue is null)
continue;

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.Equals("Name", StringComparison.OrdinalIgnoreCase) &&
namedArgument.Value.Value?.ToString() is { } dn)
{
memberAttribute.Add(member.Name, dn);
break;
}
}
}

sourceBuilder.Append(@" };
}");
}

//ToDisplay string
sourceBuilder.Append($@"
public static string {SourceGeneratorHelper.ExtensionMethodNameToDisplay}(this {symbolName} states)
private static void GetNamesFast(StringBuilder sourceBuilder, string symbolName, EnumDeclarationSyntax e)
{
sourceBuilder.Append($@"
public static string[] {SourceGeneratorHelper.ExtensionMethodNameGetNames}()
{{
return states switch
return new[]
{{
");
//foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
foreach (var member in e.Members)
{
var display = memberAttribute
.FirstOrDefault(r =>
r.Key.Equals(member.Identifier.ValueText, StringComparison.OrdinalIgnoreCase))
.Value
?? member.Identifier.ValueText;

sourceBuilder.AppendLine(
$@" {symbolName}.{member.Identifier.ValueText} => ""{display}"",");
}
foreach (var member in e.Members.Select(x => x.Identifier.ValueText))
sourceBuilder.AppendLine($@" nameof({symbolName}.{member}),");

sourceBuilder.Append(
@" _ => throw new ArgumentOutOfRangeException(nameof(states), states, null)
};
sourceBuilder.Append(@" };
}");

sourceBuilder.Append(@"
}
}

private static void GetLengthFast(StringBuilder sourceBuilder, string symbolName, EnumDeclarationSyntax e)
{
sourceBuilder.Append($@"
public static int {SourceGeneratorHelper.ExtensionMethodNameGetLength}()
{{
return {e.Members.Count};
");

context.AddSource($"{symbol.Name}_EnumGenerator.g.cs",
SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
sourceBuilder.Append(@"
}");
}
}
3 changes: 3 additions & 0 deletions Supernova.Enum.Generators/SourceGeneratorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public static class SourceGeneratorHelper
public const string ExtensionMethodNameToString = "StringToFast";
public const string ExtensionMethodNameIsDefined = "IsDefinedFast";
public const string ExtensionMethodNameToDisplay = "ToDisplayFast";
public const string ExtensionMethodNameGetValues = "GetValuesFast";
public const string ExtensionMethodNameGetNames = "GetNamesFast";
public const string ExtensionMethodNameGetLength = "GetLengthFast";

public const string Attribute = Header + $@"
Expand Down
10 changes: 7 additions & 3 deletions Supernova.Enum.Generators/Supernova.Enum.Generators.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
<PackageId>Supernova.Enum.Generators</PackageId>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Version>1.0.10</Version>
<PackageVersion>1.0.10</PackageVersion>
<AssemblyVersion>1.0.10</AssemblyVersion>
<Version>1.0.11</Version>
<PackageVersion>1.0.11</PackageVersion>
<AssemblyVersion>1.0.11</AssemblyVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>icon.png</PackageIcon>
<PackageReleaseNotes>v1.0.11
- Add method GetValuesFast
- Add method GetNamesFast
- Add method GetLengthFast</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 2f6d9bb

Please sign in to comment.