Skip to content

Commit 8f4e6d7

Browse files
committed
Fixed Switch/Map
1 parent b65d089 commit 8f4e6d7

File tree

18 files changed

+314
-476
lines changed

18 files changed

+314
-476
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<Copyright>(c) $([System.DateTime]::Now.Year), Pawel Gerr. All rights reserved.</Copyright>
5-
<VersionPrefix>8.0.1</VersionPrefix>
5+
<VersionPrefix>8.0.2</VersionPrefix>
66
<Authors>Pawel Gerr</Authors>
77
<GenerateDocumentationFile>true</GenerateDocumentationFile>
88
<PackageProjectUrl>https://github.com/PawelGerr/Thinktecture.Runtime.Extensions</PackageProjectUrl>

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/SmartEnums/SmartEnumCodeGenerator.cs

Lines changed: 32 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -108,56 +108,14 @@ private void GenerateEnum(CancellationToken cancellationToken)
108108
{
109109
GenerateModuleInitializer(_state.KeyMember);
110110

111-
if (_state.KeyMember.IsString())
112-
{
113-
_sb.Append(@"
114-
115-
#if NET9_0_OR_GREATER
116-
private static readonly global::System.Lazy<");
117-
118-
AppendLookupTypeTuple(_state.KeyMember);
119-
_sb.Append(@"> _lookups
120-
= new global::System.Lazy<");
121-
AppendLookupTypeTuple(_state.KeyMember);
122-
_sb.Append(@">(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly);
123-
124-
private static ");
125-
AppendLookupType(_state.KeyMember);
126-
_sb.Append(@" _itemsLookup => _lookups.Value.Item1;
127-
#else");
128-
}
129-
else
130-
{
131-
_sb.Append(@"
132-
");
133-
}
134-
135111
_sb.Append(@"
136-
private static readonly global::System.Lazy<");
137-
AppendLookupType(_state.KeyMember);
138-
_sb.Append(@"> _lookups
139-
= new global::System.Lazy<");
140-
AppendLookupType(_state.KeyMember);
141-
_sb.Append(@">(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly);
142112
143-
private static ");
144-
AppendLookupType(_state.KeyMember);
145-
_sb.Append(" _itemsLookup => _lookups.Value;");
146-
147-
if (_state.KeyMember.IsString())
148-
{
149-
_sb.Append(@"
150-
#endif");
151-
}
152-
153-
_sb.Append(@"
154-
private static readonly global::System.Lazy<global::System.Collections.Generic.IReadOnlyList<").AppendTypeFullyQualified(_state).Append(@">> _items
155-
= new global::System.Lazy<global::System.Collections.Generic.IReadOnlyList<").AppendTypeFullyQualified(_state).Append(@">>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly);
113+
private static readonly global::System.Lazy<Lookups> _lookups = new global::System.Lazy<Lookups>(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly);
156114
157115
/// <summary>
158116
/// Gets all valid items.
159117
/// </summary>
160-
public static global::System.Collections.Generic.IReadOnlyList<").AppendTypeFullyQualified(_state).Append("> Items => _items.Value;");
118+
public static global::System.Collections.Generic.IReadOnlyList<").AppendTypeFullyQualified(_state).Append("> Items => _lookups.Value.List;");
161119

162120
GenerateKeyMember(_sb, _state.KeyMember, true);
163121
}
@@ -286,7 +244,7 @@ public override int GetHashCode()
286244

287245
if (_state.KeyMember is not null)
288246
{
289-
GenerateGetLookup(_state.KeyMember);
247+
GenerateGetLookups(_state.KeyMember);
290248
}
291249
else
292250
{
@@ -915,7 +873,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] ")
915873
if (_state.Settings.IsValidatable)
916874
{
917875
_sb.Append(@"
918-
if(_itemsLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out item))
876+
if(_lookups.Value.Lookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out item))
919877
return true;
920878
921879
item = CreateAndCheckInvalidItem(").AppendEscaped(keyProperty.ArgumentName).Append(@");
@@ -924,7 +882,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] ")
924882
else
925883
{
926884
_sb.Append(@"
927-
return _itemsLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(", out item);");
885+
return _lookups.Value.Lookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(", out item);");
928886
}
929887

930888
_sb.Append(@"
@@ -948,7 +906,7 @@ public static bool TryGet(global::System.ReadOnlySpan<char> ").AppendEscaped(key
948906
if (_state.Settings.IsValidatable)
949907
{
950908
_sb.Append(@"
951-
if(_lookups.Value.Item2.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out item))
909+
if(_lookups.Value.AlternateLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out item))
952910
return true;
953911
954912
item = CreateAndCheckInvalidItem(").AppendEscaped(keyProperty.ArgumentName).Append(@".ToString());
@@ -957,7 +915,7 @@ public static bool TryGet(global::System.ReadOnlySpan<char> ").AppendEscaped(key
957915
else
958916
{
959917
_sb.Append(@"
960-
return _lookups.Value.Item2.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(", out item);");
918+
return _lookups.Value.AlternateLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(", out item);");
961919
}
962920

963921
_sb.Append(@"
@@ -1153,35 +1111,13 @@ public bool Equals(").AppendTypeFullyQualifiedNullAnnotated(_state).Append(@" ot
11531111
}");
11541112
}
11551113

1156-
private void GenerateGetLookup(KeyMemberState keyMember)
1114+
private void GenerateGetLookups(KeyMemberState keyMember)
11571115
{
11581116
var totalNumberOfItems = _state.Items.Count;
11591117

11601118
_sb.Append(@"
11611119
1162-
private static");
1163-
1164-
if (keyMember.IsString())
1165-
{
1166-
_sb.Append(@"
1167-
#if NET9_0_OR_GREATER
1168-
");
1169-
AppendLookupTypeTuple(keyMember);
1170-
_sb.Append(@"
1171-
#else
1172-
");
1173-
AppendLookupType(keyMember);
1174-
_sb.Append(@"
1175-
#endif
1176-
");
1177-
}
1178-
else
1179-
{
1180-
_sb.Append(" ");
1181-
AppendLookupType(keyMember);
1182-
}
1183-
1184-
_sb.Append(@" GetLookup()
1120+
private static Lookups GetLookups()
11851121
{
11861122
var lookup = new global::System.Collections.Generic.Dictionary<").AppendTypeFullyQualified(keyMember).Append(", ").AppendTypeFullyQualified(_state).Append(">(").Append(totalNumberOfItems);
11871123

@@ -1194,7 +1130,8 @@ private void GenerateGetLookup(KeyMemberState keyMember)
11941130
_sb.Append(", global::System.StringComparer.OrdinalIgnoreCase");
11951131
}
11961132

1197-
_sb.Append(");");
1133+
_sb.Append(@");
1134+
var list = new global::System.Collections.Generic.List<").AppendTypeFullyQualified(_state).Append(">(").Append(totalNumberOfItems).Append(");");
11981135

11991136
if (_state.Items.Count > 0)
12001137
{
@@ -1232,6 +1169,7 @@ void AddItem(").AppendTypeFullyQualified(_state).Append(@" item, string itemName
12321169
throw new global::System.ArgumentException($""The type \""").AppendTypeMinimallyQualified(_state).Append(@"\"" has multiple items with the identifier \""{item.").Append(keyMember.Name).Append(@"}\""."");
12331170
12341171
lookup.Add(item.").Append(keyMember.Name).Append(@", item);
1172+
list.Add(item);
12351173
}
12361174
");
12371175

@@ -1264,32 +1202,36 @@ void AddItem(").AppendTypeFullyQualified(_state).Append(@" item, string itemName
12641202
{
12651203
_sb.Append(@"
12661204
#if NET9_0_OR_GREATER
1267-
return (frozenDictionary, frozenDictionary.GetAlternateLookup<global::System.ReadOnlySpan<char>>());
1205+
return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup<global::System.ReadOnlySpan<char>>(), list.AsReadOnly());
12681206
#else
1269-
return frozenDictionary;
1207+
return new Lookups(frozenDictionary, list.AsReadOnly());
12701208
#endif");
12711209
}
12721210
else
12731211
{
12741212
_sb.Append(@"
1275-
return frozenDictionary;");
1213+
return new Lookups(frozenDictionary, list.AsReadOnly());");
12761214
}
12771215

12781216
_sb.Append(@"
12791217
#else
1280-
return lookup;
1218+
return new Lookups(lookup, list.AsReadOnly());
12811219
#endif
1282-
}");
1283-
}
1220+
}
12841221
1285-
private void AppendLookupType(KeyMemberState keyMember)
1286-
{
1287-
_sb.Append("global::System.Collections.Generic.IReadOnlyDictionary<").AppendTypeFullyQualified(keyMember).Append(", ").AppendTypeFullyQualified(_state).Append(">");
1288-
}
1222+
private record struct Lookups(
1223+
global::System.Collections.Generic.IReadOnlyDictionary<").AppendTypeFullyQualified(keyMember).Append(", ").AppendTypeFullyQualified(_state).Append("> Lookup,");
12891224

1290-
private void AppendLookupTypeTuple(KeyMemberState keyMember)
1291-
{
1292-
_sb.Append("(global::System.Collections.Generic.IReadOnlyDictionary<").AppendTypeFullyQualified(keyMember).Append(", ").AppendTypeFullyQualified(_state).Append(">, global::System.Collections.Frozen.FrozenDictionary<string, ").AppendTypeFullyQualified(_state).Append(">.AlternateLookup<global::System.ReadOnlySpan<char>>").Append(")");
1225+
if (keyMember.IsString())
1226+
{
1227+
_sb.Append(@"
1228+
#if NET9_0_OR_GREATER
1229+
global::System.Collections.Frozen.FrozenDictionary<string, ").AppendTypeFullyQualified(_state).Append(">.AlternateLookup<global::System.ReadOnlySpan<char>>").Append(@" AlternateLookup,
1230+
#endif");
1231+
}
1232+
1233+
_sb.Append(@"
1234+
global::System.Collections.Generic.IReadOnlyList<").AppendTypeFullyQualified(_state).Append("> List);");
12931235
}
12941236

12951237
private void GenerateGetItems()
@@ -1396,7 +1338,7 @@ private void GenerateGet(IMemberState keyProperty)
13961338
}
13971339

13981340
_sb.Append(@"
1399-
if (!_itemsLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out var item))
1341+
if (!_lookups.Value.Lookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out var item))
14001342
{");
14011343

14021344
if (_state.Settings.IsValidatable)
@@ -1437,7 +1379,7 @@ private void GenerateGetForReadOnlySpanOfChar(IMemberState keyProperty)
14371379
_sb.Append(@"
14381380
public static ").AppendTypeFullyQualified(_state).Append(" ").Append(Constants.Methods.GET).Append("(global::System.ReadOnlySpan<char> ").AppendEscaped(keyProperty.ArgumentName).Append(@")
14391381
{
1440-
if (!_lookups.Value.Item2.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out var item))
1382+
if (!_lookups.Value.AlternateLookup.TryGetValue(").AppendEscaped(keyProperty.ArgumentName).Append(@", out var item))
14411383
{");
14421384

14431385
if (_state.Settings.IsValidatable)
@@ -1495,7 +1437,7 @@ private void GenerateCreateAndCheckInvalidItem(IMemberState keyProperty, bool ne
14951437
{
14961438
_sb.Append(@"
14971439
1498-
if (_itemsLookup.ContainsKey(item.").Append(keyProperty.Name).Append(@"))
1440+
if (_lookups.Value.Lookup.ContainsKey(item.").Append(keyProperty.Name).Append(@"))
14991441
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."");");
15001442
}
15011443

test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/Snapshots/EnumSourceGeneratorTests.Should_generate_advanced_string_based_validatable_class_0.verified.cs

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,12 @@ internal static void ModuleInit()
2626
global::Thinktecture.Internal.KeyedValueObjectMetadataLookup.AddMetadata(enumType, metadata);
2727
}
2828

29-
#if NET9_0_OR_GREATER
30-
private static readonly global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum>, global::System.Collections.Frozen.FrozenDictionary<string, global::Thinktecture.Tests.TestEnum>.AlternateLookup<global::System.ReadOnlySpan<char>>)> _lookups
31-
= new global::System.Lazy<(global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum>, global::System.Collections.Frozen.FrozenDictionary<string, global::Thinktecture.Tests.TestEnum>.AlternateLookup<global::System.ReadOnlySpan<char>>)>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly);
32-
33-
private static global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum> _itemsLookup => _lookups.Value.Item1;
34-
#else
35-
private static readonly global::System.Lazy<global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum>> _lookups
36-
= new global::System.Lazy<global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum>>(GetLookup, global::System.Threading.LazyThreadSafetyMode.PublicationOnly);
37-
38-
private static global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum> _itemsLookup => _lookups.Value;
39-
#endif
40-
private static readonly global::System.Lazy<global::System.Collections.Generic.IReadOnlyList<global::Thinktecture.Tests.TestEnum>> _items
41-
= new global::System.Lazy<global::System.Collections.Generic.IReadOnlyList<global::Thinktecture.Tests.TestEnum>>(() => global::System.Linq.Enumerable.ToList(_itemsLookup.Values).AsReadOnly(), global::System.Threading.LazyThreadSafetyMode.PublicationOnly);
29+
private static readonly global::System.Lazy<Lookups> _lookups = new global::System.Lazy<Lookups>(GetLookups, global::System.Threading.LazyThreadSafetyMode.PublicationOnly);
4230

4331
/// <summary>
4432
/// Gets all valid items.
4533
/// </summary>
46-
public static global::System.Collections.Generic.IReadOnlyList<global::Thinktecture.Tests.TestEnum> Items => _items.Value;
34+
public static global::System.Collections.Generic.IReadOnlyList<global::Thinktecture.Tests.TestEnum> Items => _lookups.Value.List;
4735

4836
/// <summary>
4937
/// The identifier of this item.
@@ -152,7 +140,7 @@ static partial void ValidateConstructorArguments(
152140
if (@name is null)
153141
return default;
154142

155-
if (!_itemsLookup.TryGetValue(@name, out var item))
143+
if (!_lookups.Value.Lookup.TryGetValue(@name, out var item))
156144
{
157145
item = CreateAndCheckInvalidItem(@name);
158146
}
@@ -168,7 +156,7 @@ static partial void ValidateConstructorArguments(
168156
/// <returns>An instance of <see cref="TestEnum"/> if <paramref name="name"/> is not <c>null</c>; otherwise <c>null</c>.</returns>
169157
public static global::Thinktecture.Tests.TestEnum Get(global::System.ReadOnlySpan<char> @name)
170158
{
171-
if (!_lookups.Value.Item2.TryGetValue(@name, out var item))
159+
if (!_lookups.Value.AlternateLookup.TryGetValue(@name, out var item))
172160
{
173161
item = CreateAndCheckInvalidItem(@name.ToString());
174162
}
@@ -187,7 +175,7 @@ static partial void ValidateConstructorArguments(
187175
if (item.IsValid)
188176
throw new global::System.Exception("The implementation of method 'CreateInvalidItem' must return an instance with property 'IsValid' equals to 'false'.");
189177

190-
if (_itemsLookup.ContainsKey(item.Name))
178+
if (_lookups.Value.Lookup.ContainsKey(item.Name))
191179
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.");
192180

193181
return item;
@@ -207,7 +195,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
207195
return false;
208196
}
209197

210-
if(_itemsLookup.TryGetValue(@name, out item))
198+
if(_lookups.Value.Lookup.TryGetValue(@name, out item))
211199
return true;
212200

213201
item = CreateAndCheckInvalidItem(@name);
@@ -223,7 +211,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
223211
/// <returns><c>true</c> if a valid item with provided <paramref name="name"/> exists; <c>false</c> otherwise.</returns>
224212
public static bool TryGet(global::System.ReadOnlySpan<char> @name, [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out global::Thinktecture.Tests.TestEnum item)
225213
{
226-
if(_lookups.Value.Item2.TryGetValue(@name, out item))
214+
if(_lookups.Value.AlternateLookup.TryGetValue(@name, out item))
227215
return true;
228216

229217
item = CreateAndCheckInvalidItem(@name.ToString());
@@ -712,15 +700,10 @@ public TResult MapPartially<TResult>(
712700
return @default;
713701
}
714702

715-
private static
716-
#if NET9_0_OR_GREATER
717-
(global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum>, global::System.Collections.Frozen.FrozenDictionary<string, global::Thinktecture.Tests.TestEnum>.AlternateLookup<global::System.ReadOnlySpan<char>>)
718-
#else
719-
global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum>
720-
#endif
721-
GetLookup()
703+
private static Lookups GetLookups()
722704
{
723705
var lookup = new global::System.Collections.Generic.Dictionary<string, global::Thinktecture.Tests.TestEnum>(2, global::Thinktecture.ComparerAccessors.StringOrdinal.EqualityComparer);
706+
var list = new global::System.Collections.Generic.List<global::Thinktecture.Tests.TestEnum>(2);
724707

725708
void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName)
726709
{
@@ -737,6 +720,7 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName)
737720
throw new global::System.ArgumentException($"The type \"TestEnum\" has multiple items with the identifier \"{item.Name}\".");
738721

739722
lookup.Add(item.Name, item);
723+
list.Add(item);
740724
}
741725

742726
AddItem(@Item1, nameof(@Item1));
@@ -745,13 +729,20 @@ void AddItem(global::Thinktecture.Tests.TestEnum item, string itemName)
745729
#if NET8_0_OR_GREATER
746730
var frozenDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(lookup, global::Thinktecture.ComparerAccessors.StringOrdinal.EqualityComparer);
747731
#if NET9_0_OR_GREATER
748-
return (frozenDictionary, frozenDictionary.GetAlternateLookup<global::System.ReadOnlySpan<char>>());
732+
return new Lookups(frozenDictionary, frozenDictionary.GetAlternateLookup<global::System.ReadOnlySpan<char>>(), list.AsReadOnly());
749733
#else
750-
return frozenDictionary;
734+
return new Lookups(frozenDictionary, list.AsReadOnly());
751735
#endif
752736
#else
753-
return lookup;
737+
return new Lookups(lookup, list.AsReadOnly());
754738
#endif
755739
}
740+
741+
private record struct Lookups(
742+
global::System.Collections.Generic.IReadOnlyDictionary<string, global::Thinktecture.Tests.TestEnum> Lookup,
743+
#if NET9_0_OR_GREATER
744+
global::System.Collections.Frozen.FrozenDictionary<string, global::Thinktecture.Tests.TestEnum>.AlternateLookup<global::System.ReadOnlySpan<char>> AlternateLookup,
745+
#endif
746+
global::System.Collections.Generic.IReadOnlyList<global::Thinktecture.Tests.TestEnum> List);
756747
}
757748
}

0 commit comments

Comments
 (0)