-
Notifications
You must be signed in to change notification settings - Fork 48
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
Handle DisplayAttribute. #13
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good work, thanks! Before we merge it, I think we should do 2 things:
- Add an integration test for the behaviour
- Figure out why it doesn't work in .NET Framework
Definitely happy to merge it once we have those, thanks again!
Edit:
internal class TestHelpers
{
public static (ImmutableArray<Diagnostic> Diagnostics, string Output) GetGeneratedOutput<T>(string source)
where T : IIncrementalGenerator, new()
{
var syntaxTree = CSharpSyntaxTree.ParseText(source);
var references = AppDomain.CurrentDomain.GetAssemblies()
.Where(_ => !_.IsDynamic && !string.IsNullOrWhiteSpace(_.Location))
.Select(_ => MetadataReference.CreateFromFile(_.Location))
.Concat(new[]
{
MetadataReference.CreateFromFile(typeof(T).Assembly.Location),
MetadataReference.CreateFromFile(typeof(EnumExtensionsAttribute).Assembly.Location),
+ MetadataReference.CreateFromFile(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute).Assembly.Location)
});
var compilation = CSharpCompilation.Create(
"generator",
new[] { syntaxTree },
references,
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
var originalTreeCount = compilation.SyntaxTrees.Length;
var generator = new T();
var driver = CSharpGeneratorDriver.Create(generator);
driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics);
var trees = outputCompilation.SyntaxTrees.ToList();
return (diagnostics, trees.Count != originalTreeCount ? trees[trees.Count - 1].ToString() : string.Empty);
}
} end of edit If you add a reference to the correct NuGet package and load the corresponding library "it just works". Following steps I did:
Before.Net 4.8 without PackageReference (also notice the different attributeName) After.Net 4.8 with PackageReference some code[Fact]
public Task CanGenerateEnumExtensionsWithDisplayName()
{
var x = new System.ComponentModel.DataAnnotations.DisplayAttribute();
//const string input = ...
//...
} |
@FroggieFrog Thanks, made the changes. |
Done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @adamradocz, this is looking really good! 😃 Just a couple of nits, but I'm wondering if we should include the [Display]
name in the TryParse()
etc methods too 🤔 I'm undecided, what do you think? Also wondering if we should make this attribute functionality optional, but we could always add that later if needs be!
tests/NetEscapades.EnumGenerators.IntegrationTests/ExtensionTests.cs
Outdated
Show resolved
Hide resolved
src/NetEscapades.EnumGenerators/NetEscapades.EnumGenerators.csproj
Outdated
Show resolved
Hide resolved
...etEscapades.EnumGenerators.IntegrationTests/EnumWithDisplayNameInNamespaceExtensionsTests.cs
Outdated
Show resolved
Hide resolved
…sts.cs value.GetType() -> typeof(value) Co-authored-by: Andrew Lock <[email protected]>
Simplify TryParse.
|
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
11th Gen Intel Core i7-11800H 2.30GHz, 1 CPU, 16 logical and 8 physical cores
[Host] : .NET Framework 4.8 (4.8.4470.0), X64 RyuJIT [AttachedDebugger]
DefaultJob : .NET Framework 4.8 (4.8.4470.0), X64 RyuJIT
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
11th Gen Intel Core i7-11800H 2.30GHz, 1 CPU, 16 logical and 8 physical cores
[Host] : .NET Framework 4.8 (4.8.4470.0), X64 RyuJIT [AttachedDebugger]
DefaultJob : .NET Framework 4.8 (4.8.4470.0), X64 RyuJIT
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
11th Gen Intel Core i7-11800H 2.30GHz, 1 CPU, 16 logical and 8 physical cores
[Host] : .NET Framework 4.8 (4.8.4470.0), X64 RyuJIT [AttachedDebugger]
DefaultJob : .NET Framework 4.8 (4.8.4470.0), X64 RyuJIT
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is looking really good @adamradocz, thanks 🙂 Just a couple of final questions/suggestions!
...ors.Tests/Snapshots/EnumGeneratorTests.CanGenerateEnumExtensionsWithDisplayName.verified.txt
Outdated
Show resolved
Hide resolved
...napshots/EnumGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName.verified.txt
Outdated
Show resolved
Hide resolved
The optimized TryParse is a little bit faster.
|
@andrewlock I think, the |
I agree. It would be annoying (for example) if I had a Just a thought - I think we should support the |
How would you differentiate the two attributes then, when parsing? What if I set the Edit: |
The only questioning thing is the |
How about adding an additional property to the attribute and respect the defined order? public class EnumExtensionsAttribute : System.Attribute
{
//...
public Type[]? AdditionalMetaData { get; set; }
}
[EnumExtensions(AdditionalMetaData = new[] { typeof(DisplayAttribute), typeof(DescriptionAttribute) })]
public enum MyEnum
{
[Display(Name ="1st")]
First = 0,
[Description("2nd")]
Second = 1,
[Description("3rd")]
[Display(Name = "the third")]
Third = 2,
} So |
I'm undecided. Personally, I don't think it's worth fighting with this edge case too much. I would probably just use whichever is defined first. I can't imagine anyone is adding both the |
It's okay with me. I'll update the naming soon. |
I renamed the variable. I think this PR is complete. |
Sorry for the delay on merging this @adamradocz, and thanks for all your hard work! It's much appreciated 🙂 |
Closes #11
Handles the
[Display(Name = "Customer name")]
attribute. It works on .NET Core 3.1+, but unfortunately, I couldn't figure out why doesn't it work on .NET Framework 4.8.