diff --git a/Directory.Build.props b/Directory.Build.props index c0f8d87b..cf49a01c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ (c) $([System.DateTime]::Now.Year), Pawel Gerr. All rights reserved. - 8.0.1 + 8.0.2 Pawel Gerr true https://github.com/PawelGerr/Thinktecture.Runtime.Extensions diff --git a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/SmartEnums/SmartEnumCodeGenerator.cs b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/SmartEnums/SmartEnumCodeGenerator.cs index c2a1ac26..2a28e367 100644 --- a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/SmartEnums/SmartEnumCodeGenerator.cs +++ b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/SmartEnums/SmartEnumCodeGenerator.cs @@ -108,56 +108,14 @@ private void GenerateEnum(CancellationToken cancellationToken) { GenerateModuleInitializer(_state.KeyMember); - if (_state.KeyMember.IsString()) - { - _sb.Append(@" - -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<"); - - AppendLookupTypeTuple(_state.KeyMember); - _sb.Append(@"> _lookups - = new global::System.Lazy<"); - AppendLookupTypeTuple(_state.KeyMember); - _sb.Append(@">(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static "); - AppendLookupType(_state.KeyMember); - _sb.Append(@" _itemsLookup => _lookups.Value.Item1; -#else"); - } - else - { - _sb.Append(@" -"); - } - _sb.Append(@" - private static readonly global::System.Lazy<"); - AppendLookupType(_state.KeyMember); - _sb.Append(@"> _lookups - = new global::System.Lazy<"); - AppendLookupType(_state.KeyMember); - _sb.Append(@">(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - private static "); - AppendLookupType(_state.KeyMember); - _sb.Append(" _itemsLookup => _lookups.Value;"); - - if (_state.KeyMember.IsString()) - { - _sb.Append(@" -#endif"); - } - - _sb.Append(@" - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList<").AppendTypeFullyQualified(_state).Append("> Items => _items.Value;"); + public static global::System.Collections.Generic.IReadOnlyList<").AppendTypeFullyQualified(_state).Append("> Items => _lookups.Value.List;"); GenerateKeyMember(_sb, _state.KeyMember, true); } @@ -286,7 +244,7 @@ public override int GetHashCode() if (_state.KeyMember is not null) { - GenerateGetLookup(_state.KeyMember); + GenerateGetLookups(_state.KeyMember); } else { @@ -915,7 +873,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] ") if (_state.Settings.IsValidatable) { _sb.Append(@" - if(_itemsLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out item)) + if(_lookups.Value.Lookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out item)) return true; item = CreateAndCheckInvalidItem(").AppendEscaped(keyProperty.ArgumentName).Append(@"); @@ -924,7 +882,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] ") else { _sb.Append(@" - return _itemsLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(", out item);"); + return _lookups.Value.Lookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(", out item);"); } _sb.Append(@" @@ -948,7 +906,7 @@ public static bool TryGet(global::System.ReadOnlySpan ").AppendEscaped(key if (_state.Settings.IsValidatable) { _sb.Append(@" - if(_lookups.Value.Item2.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out item)) + if(_lookups.Value.AlternateLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out item)) return true; item = CreateAndCheckInvalidItem(").AppendEscaped(keyProperty.ArgumentName).Append(@".ToString()); @@ -957,7 +915,7 @@ public static bool TryGet(global::System.ReadOnlySpan ").AppendEscaped(key else { _sb.Append(@" - return _lookups.Value.Item2.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(", out item);"); + return _lookups.Value.AlternateLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(", out item);"); } _sb.Append(@" @@ -1153,35 +1111,13 @@ public bool Equals(").AppendTypeFullyQualifiedNullAnnotated(_state).Append(@" ot }"); } - private void GenerateGetLookup(KeyMemberState keyMember) + private void GenerateGetLookups(KeyMemberState keyMember) { var totalNumberOfItems = _state.Items.Count; _sb.Append(@" - private static"); - - if (keyMember.IsString()) - { - _sb.Append(@" -#if NET9_0_OR_GREATER - "); - AppendLookupTypeTuple(keyMember); - _sb.Append(@" -#else - "); - AppendLookupType(keyMember); - _sb.Append(@" -#endif - "); - } - else - { - _sb.Append(" "); - AppendLookupType(keyMember); - } - - _sb.Append(@" GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary<").AppendTypeFullyQualified(keyMember).Append(", ").AppendTypeFullyQualified(_state).Append(">(").Append(totalNumberOfItems); @@ -1194,7 +1130,8 @@ private void GenerateGetLookup(KeyMemberState keyMember) _sb.Append(", global::System.StringComparer.OrdinalIgnoreCase"); } - _sb.Append(");"); + _sb.Append(@"); + var list = new global::System.Collections.Generic.List<").AppendTypeFullyQualified(_state).Append(">(").Append(totalNumberOfItems).Append(");"); if (_state.Items.Count > 0) { @@ -1232,6 +1169,7 @@ void AddItem(").AppendTypeFullyQualified(_state).Append(@" item, string itemName throw new global::System.ArgumentException($""The type \""").AppendTypeMinimallyQualified(_state).Append(@"\"" has multiple items with the identifier \""{item.").Append(keyMember.Name).Append(@"}\"".""); lookup.Add(item.").Append(keyMember.Name).Append(@", item); + list.Add(item); } "); @@ -1264,32 +1202,36 @@ void AddItem(").AppendTypeFullyQualified(_state).Append(@" item, string itemName { _sb.Append(@" #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif"); } else { _sb.Append(@" - return frozenDictionary;"); + return new Lookups(frozenDictionary, list.AsReadOnly());"); } _sb.Append(@" #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif - }"); - } + } - private void AppendLookupType(KeyMemberState keyMember) - { - _sb.Append("global::System.Collections.Generic.IReadOnlyDictionary<").AppendTypeFullyQualified(keyMember).Append(", ").AppendTypeFullyQualified(_state).Append(">"); - } + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary<").AppendTypeFullyQualified(keyMember).Append(", ").AppendTypeFullyQualified(_state).Append("> Lookup,"); - private void AppendLookupTypeTuple(KeyMemberState keyMember) - { - _sb.Append("(global::System.Collections.Generic.IReadOnlyDictionary<").AppendTypeFullyQualified(keyMember).Append(", ").AppendTypeFullyQualified(_state).Append(">, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>").Append(")"); + if (keyMember.IsString()) + { + _sb.Append(@" +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>").Append(@" AlternateLookup, +#endif"); + } + + _sb.Append(@" + global::System.Collections.Generic.IReadOnlyList<").AppendTypeFullyQualified(_state).Append("> List);"); } private void GenerateGetItems() @@ -1396,7 +1338,7 @@ private void GenerateGet(IMemberState keyProperty) } _sb.Append(@" - if (!_itemsLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out var item)) + if (!_lookups.Value.Lookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out var item)) {"); if (_state.Settings.IsValidatable) @@ -1437,7 +1379,7 @@ private void GenerateGetForReadOnlySpanOfChar(IMemberState keyProperty) _sb.Append(@" public static ").AppendTypeFullyQualified(_state).Append(" ").Append(Constants.Methods.GET).Append("(global::System.ReadOnlySpan ").AppendEscaped(keyProperty.ArgumentName).Append(@") { - if (!_lookups.Value.Item2.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out var item)) {"); if (_state.Settings.IsValidatable) @@ -1495,7 +1437,7 @@ private void GenerateCreateAndCheckInvalidItem(IMemberState keyProperty, bool ne { _sb.Append(@" - if (_itemsLookup.ContainsKey(item.").Append(keyProperty.Name).Append(@")) + if (_lookups.Value.Lookup.ContainsKey(item.").Append(keyProperty.Name).Append(@")) throw new global::System.Exception(""The implementation of method '").Append(Constants.Methods.CREATE_INVALID_ITEM).Append("' must not return an instance with property '").Append(keyProperty.Name).Append(@"' equals to one of a valid item."");"); } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_advanced_string_based_validatable_class_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_advanced_string_based_validatable_class_0.verified.cs index 99432357..969672fd 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_advanced_string_based_validatable_class_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_advanced_string_based_validatable_class_0.verified.cs @@ -26,24 +26,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -152,7 +140,7 @@ static partial void ValidateConstructorArguments( if (@name is null) return default; - if (!_itemsLookup.TryGetValue(@name, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@name, out var item)) { item = CreateAndCheckInvalidItem(@name); } @@ -168,7 +156,7 @@ static partial void ValidateConstructorArguments( /// An instance of if is not null; otherwise null. public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @name) { - if (!_lookups.Value.Item2.TryGetValue(@name, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@name, out var item)) { item = CreateAndCheckInvalidItem(@name.ToString()); } @@ -187,7 +175,7 @@ static partial void ValidateConstructorArguments( if (item.IsValid) throw new global::System.Exception("The implementation of method 'CreateInvalidItem' must return an instance with property 'IsValid' equals to 'false'."); - if (_itemsLookup.ContainsKey(item.Name)) + if (_lookups.Value.Lookup.ContainsKey(item.Name)) throw new global::System.Exception("The implementation of method 'CreateInvalidItem' must not return an instance with property 'Name' equals to one of a valid item."); return item; @@ -207,7 +195,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - if(_itemsLookup.TryGetValue(@name, out item)) + if(_lookups.Value.Lookup.TryGetValue(@name, out item)) return true; item = CreateAndCheckInvalidItem(@name); @@ -223,7 +211,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @name, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - if(_lookups.Value.Item2.TryGetValue(@name, out item)) + if(_lookups.Value.AlternateLookup.TryGetValue(@name, out item)) return true; item = CreateAndCheckInvalidItem(@name.ToString()); @@ -712,15 +700,10 @@ public TResult MapPartially( return @default; } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::Thinktecture.ComparerAccessors.StringOrdinal.EqualityComparer); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -737,6 +720,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Name}\"."); lookup.Add(item.Name, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -745,13 +729,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::Thinktecture.ComparerAccessors.StringOrdinal.EqualityComparer); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_class_with_abstract_property_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_class_with_abstract_property_0.verified.cs index 46ac1423..3ef5c28b 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_class_with_abstract_property_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_class_with_abstract_property_0.verified.cs @@ -25,24 +25,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -99,7 +87,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -116,7 +104,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key.ToString()); } @@ -139,7 +127,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -151,7 +139,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -362,15 +350,10 @@ public TResult Map( } } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -384,6 +367,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -392,13 +376,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_0.verified.cs index 26313539..efe9d427 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_0.verified.cs @@ -22,17 +22,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -82,7 +77,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(int @key) { - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -98,7 +93,7 @@ static partial void ValidateConstructorArguments( /// true if a valid item with provided exists; false otherwise. public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] int @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } /// @@ -287,9 +282,10 @@ public TResult Map( } } - private static global::System.Collections.Generic.IReadOnlyDictionary GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -300,6 +296,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -307,10 +304,14 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup); - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ComparisonOperators_DefaultWithKeyTypeOverloads_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ComparisonOperators_DefaultWithKeyTypeOverloads_0.verified.cs index 26313539..efe9d427 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ComparisonOperators_DefaultWithKeyTypeOverloads_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ComparisonOperators_DefaultWithKeyTypeOverloads_0.verified.cs @@ -22,17 +22,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -82,7 +77,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(int @key) { - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -98,7 +93,7 @@ static partial void ValidateConstructorArguments( /// true if a valid item with provided exists; false otherwise. public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] int @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } /// @@ -287,9 +282,10 @@ public TResult Map( } } - private static global::System.Collections.Generic.IReadOnlyDictionary GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -300,6 +296,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -307,10 +304,14 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup); - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ValueObjectFactoryAttribute_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ValueObjectFactoryAttribute_0.verified.cs index 4b924895..a7fdd69e 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ValueObjectFactoryAttribute_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ValueObjectFactoryAttribute_0.verified.cs @@ -23,17 +23,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -83,7 +78,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(int @key) { - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -99,7 +94,7 @@ static partial void ValidateConstructorArguments( /// true if a valid item with provided exists; false otherwise. public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] int @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } /// @@ -459,9 +454,10 @@ public TResult MapPartially( return @default; } - private static global::System.Collections.Generic.IReadOnlyDictionary GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -472,6 +468,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -479,10 +476,14 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup); - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ValueObjectFactoryAttribute_and_UseForSerialization_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ValueObjectFactoryAttribute_and_UseForSerialization_0.verified.cs index 8622914a..32159429 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ValueObjectFactoryAttribute_and_UseForSerialization_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_int_based_class_with_ValueObjectFactoryAttribute_and_UseForSerialization_0.verified.cs @@ -24,17 +24,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -84,7 +79,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(int @key) { - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -100,7 +95,7 @@ static partial void ValidateConstructorArguments( /// true if a valid item with provided exists; false otherwise. public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] int @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } /// @@ -460,9 +455,10 @@ public TResult MapPartially( return @default; } - private static global::System.Collections.Generic.IReadOnlyDictionary GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -473,6 +469,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -480,10 +477,14 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup); - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_0.verified.cs index dfbfe101..92df35a5 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_0.verified.cs @@ -25,24 +25,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -99,7 +87,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -116,7 +104,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key.ToString()); } @@ -139,7 +127,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -151,7 +139,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -362,15 +350,10 @@ public TResult Map( } } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -384,6 +367,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -392,13 +376,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_having_ValueObjectValidationErrorAttribute_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_having_ValueObjectValidationErrorAttribute_0.verified.cs index ffb8dedf..49b634d7 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_having_ValueObjectValidationErrorAttribute_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_having_ValueObjectValidationErrorAttribute_0.verified.cs @@ -25,24 +25,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -99,7 +87,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -116,7 +104,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key.ToString()); } @@ -139,7 +127,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -151,7 +139,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -533,15 +521,10 @@ public TResult MapPartially( return @default; } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -555,6 +538,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -563,13 +547,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_with_base_class_and_non_default_constructors_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_with_base_class_and_non_default_constructors_0.verified.cs index cd28a81e..60575223 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_with_base_class_and_non_default_constructors_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_with_base_class_and_non_default_constructors_0.verified.cs @@ -25,24 +25,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -133,7 +121,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -150,7 +138,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key.ToString()); } @@ -173,7 +161,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -185,7 +173,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -567,15 +555,10 @@ public TResult MapPartially( return @default; } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -589,6 +572,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -597,13 +581,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_with_inner_derived_type_which_is_generic_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_with_inner_derived_type_which_is_generic_0.verified.cs index ff4feadf..b90ff283 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_with_inner_derived_type_which_is_generic_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_with_inner_derived_type_which_is_generic_0.verified.cs @@ -25,24 +25,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -99,7 +87,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -116,7 +104,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key.ToString()); } @@ -139,7 +127,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -151,7 +139,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -828,15 +816,10 @@ public TResult MapPartially( return @default; } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(7, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(7); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -850,6 +833,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item_1, nameof(@Item_1)); @@ -863,13 +847,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_Map_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_Map_0.verified.cs index 8e3f9c47..9103e556 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_Map_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_Map_0.verified.cs @@ -25,24 +25,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -99,7 +87,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -116,7 +104,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key.ToString()); } @@ -139,7 +127,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -151,7 +139,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -477,15 +465,10 @@ public TResult SwitchPartially( return @default(state, this); } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -499,6 +482,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -507,13 +491,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_Switch_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_Switch_0.verified.cs index cc1e2e3b..a09048a5 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_Switch_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_Switch_0.verified.cs @@ -25,24 +25,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -99,7 +87,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -116,7 +104,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key.ToString()); } @@ -139,7 +127,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -151,7 +139,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -297,15 +285,10 @@ public TResult MapPartially( return @default; } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -319,6 +302,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -327,13 +311,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_namespace_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_namespace_0.verified.cs index 2b877190..5cb65303 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_namespace_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_class_without_namespace_0.verified.cs @@ -23,24 +23,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -97,7 +85,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::TestEnum), @key); } @@ -114,7 +102,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::TestEnum), @key.ToString()); } @@ -137,7 +125,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -149,7 +137,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -531,15 +519,10 @@ public TResult MapPartially( return @default; } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::TestEnum item, string itemName) { @@ -553,6 +536,7 @@ void AddItem(global::TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -561,12 +545,19 @@ void AddItem(global::TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_validatable_class_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_validatable_class_0.verified.cs index 65fc4e2a..bcd2dec7 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_validatable_class_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_validatable_class_0.verified.cs @@ -26,24 +26,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -122,7 +110,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { item = CreateAndCheckInvalidItem(@key); } @@ -138,7 +126,7 @@ static partial void ValidateConstructorArguments( /// An instance of if is not null; otherwise null. public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { item = CreateAndCheckInvalidItem(@key.ToString()); } @@ -179,7 +167,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - if(_itemsLookup.TryGetValue(@key, out item)) + if(_lookups.Value.Lookup.TryGetValue(@key, out item)) return true; item = CreateAndCheckInvalidItem(@key); @@ -195,7 +183,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - if(_lookups.Value.Item2.TryGetValue(@key, out item)) + if(_lookups.Value.AlternateLookup.TryGetValue(@key, out item)) return true; item = CreateAndCheckInvalidItem(@key.ToString()); @@ -684,15 +672,10 @@ public TResult MapPartially( return @default; } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -709,6 +692,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -717,13 +701,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_validatable_struct_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_validatable_struct_0.verified.cs index 420982df..e464066e 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_validatable_struct_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_string_based_validatable_struct_0.verified.cs @@ -27,24 +27,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -122,7 +110,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { item = CreateAndCheckInvalidItem(@key); } @@ -138,7 +126,7 @@ static partial void ValidateConstructorArguments( /// An instance of if is not null; otherwise null. public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { item = CreateAndCheckInvalidItem(@key.ToString()); } @@ -176,7 +164,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - if(_itemsLookup.TryGetValue(@key, out item)) + if(_lookups.Value.Lookup.TryGetValue(@key, out item)) return true; item = CreateAndCheckInvalidItem(@key); @@ -192,7 +180,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - if(_lookups.Value.Item2.TryGetValue(@key, out item)) + if(_lookups.Value.AlternateLookup.TryGetValue(@key, out item)) return true; item = CreateAndCheckInvalidItem(@key.ToString()); @@ -672,15 +660,10 @@ public TResult MapPartially( return @default; } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -694,6 +677,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -702,13 +686,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } } diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_take_over_nullability_of_generic_members_0.verified.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_take_over_nullability_of_generic_members_0.verified.cs index 9cfbe22d..3dda3f4e 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_take_over_nullability_of_generic_members_0.verified.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_take_over_nullability_of_generic_members_0.verified.cs @@ -25,24 +25,12 @@ internal static void ModuleInit() global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata); } -#if NET9_0_OR_GREATER - private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)> _lookups - = new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value.Item1; -#else - private static readonly global::System.Lazy> _lookups - = new global::System.Lazy>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); - - private static global::System.Collections.Generic.IReadOnlyDictionary _itemsLookup => _lookups.Value; -#endif - private static readonly global::System.Lazy> _items - = new global::System.Lazy>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static readonly global::System.Lazy _lookups = new global::System.Lazy(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly); /// /// Gets all valid items. /// - public static global::System.Collections.Generic.IReadOnlyList Items => _items.Value; + public static global::System.Collections.Generic.IReadOnlyList Items => _lookups.Value.List; /// /// The identifier of this item. @@ -103,7 +91,7 @@ static partial void ValidateConstructorArguments( if (@key is null) return default; - if (!_itemsLookup.TryGetValue(@key, out var item)) + if (!_lookups.Value.Lookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key); } @@ -120,7 +108,7 @@ static partial void ValidateConstructorArguments( /// If there is no item with the provided . public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan @key) { - if (!_lookups.Value.Item2.TryGetValue(@key, out var item)) + if (!_lookups.Value.AlternateLookup.TryGetValue(@key, out var item)) { throw new global::Thinktecture.UnknownEnumIdentifierException(typeof(global::Thinktecture.Tests.TestEnum), @key.ToString()); } @@ -143,7 +131,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st return false; } - return _itemsLookup.TryGetValue(@key, out item); + return _lookups.Value.Lookup.TryGetValue(@key, out item); } #if NET9_0_OR_GREATER @@ -155,7 +143,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st /// true if a valid item with provided exists; false otherwise. public static bool TryGet(global::System.ReadOnlySpan @key, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item) { - return _lookups.Value.Item2.TryGetValue(@key, out item); + return _lookups.Value.AlternateLookup.TryGetValue(@key, out item); } #endif @@ -366,15 +354,10 @@ public TResult Map( } } - private static -#if NET9_0_OR_GREATER - (global::System.Collections.Generic.IReadOnlyDictionary, global::System.Collections.Frozen.FrozenDictionary.AlternateLookup>) -#else - global::System.Collections.Generic.IReadOnlyDictionary -#endif - GetLookup() + private static Lookups GetLookups() { var lookup = new global::System.Collections.Generic.Dictionary(2, global::System.StringComparer.OrdinalIgnoreCase); + var list = new global::System.Collections.Generic.List(2); void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) { @@ -388,6 +371,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Key}\"."); lookup.Add(item.Key, item); + list.Add(item); } AddItem(@Item1, nameof(@Item1)); @@ -396,13 +380,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName) #if NET8_0_OR_GREATER var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::System.StringComparer.OrdinalIgnoreCase); #if NET9_0_OR_GREATER - return (frozenDictionary, frozenDictionary.GetAlternateLookup>()); + return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup>(), list.AsReadOnly()); #else - return frozenDictionary; + return new Lookups(frozenDictionary, list.AsReadOnly()); #endif #else - return lookup; + return new Lookups(lookup, list.AsReadOnly()); #endif } + + private record struct Lookups( + global::System.Collections.Generic.IReadOnlyDictionary Lookup, +#if NET9_0_OR_GREATER + global::System.Collections.Frozen.FrozenDictionary.AlternateLookup> AlternateLookup, +#endif + global::System.Collections.Generic.IReadOnlyList List); } }