Skip to content

Commit 4bf9411

Browse files
Remove generic method from TypeGenerationContext. (#317)
1 parent 05ecdc7 commit 4bf9411

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

src/PolyType/Utilities/Caching/TypeGenerationContext.cs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ internal TypeGenerationContext(TypeCache parentCache)
3434
public TypeCache? ParentCache { get; }
3535

3636
/// <summary>
37-
/// Gets a factory method governing the creation of values when invoking the <see cref="GetOrAdd{TKey}" /> method.
37+
/// Gets a factory method governing the creation of values when invoking the <see cref="GetOrAdd" /> method.
3838
/// </summary>
3939
public ITypeShapeFunc? ValueBuilder { get; init; }
4040

@@ -67,11 +67,10 @@ internal TypeGenerationContext(TypeCache parentCache)
6767
/// <summary>
6868
/// Gets or adds a value keyed on the type represented by <paramref name="typeShape"/>.
6969
/// </summary>
70-
/// <typeparam name="TKey">The type key to be looked up.</typeparam>
7170
/// <param name="typeShape">The type shape representing the key type.</param>
7271
/// <param name="state">The state object to be passed to the visitor.</param>
7372
/// <returns>The final computed value.</returns>
74-
public object? GetOrAdd<TKey>(ITypeShape<TKey> typeShape, object? state = null)
73+
public object? GetOrAdd(ITypeShape typeShape, object? state = null)
7574
{
7675
Throw.IfNull(typeShape);
7776
if (ValueBuilder is null)
@@ -90,28 +89,27 @@ internal TypeGenerationContext(TypeCache parentCache)
9089
}
9190

9291
/// <summary>
93-
/// Looks up the value for type <typeparamref name="TKey"/>.
92+
/// Looks up the value for the specified <see cref="ITypeShape"/>.
9493
/// </summary>
95-
/// <typeparam name="TKey">The type key to be looked up.</typeparam>
9694
/// <param name="typeShape">The type shape representing the key type.</param>
9795
/// <param name="value">The value returned by the lookup operation.</param>
9896
/// <returns>True if either a completed or delayed value have been returned.</returns>
99-
public bool TryGetValue<TKey>(ITypeShape<TKey> typeShape, [MaybeNullWhen(false)] out object? value)
97+
public bool TryGetValue(ITypeShape typeShape, [MaybeNullWhen(false)] out object? value)
10098
{
10199
Throw.IfNull(typeShape);
102100
ParentCache?.ValidateProvider(typeShape.Provider);
103101

104102
// Consult the parent cache first to avoid creating duplicate values.
105-
if (ParentCache?.TryGetValue(typeof(TKey), out value) is true)
103+
if (ParentCache?.TryGetValue(typeShape.Type, out value) is true)
106104
{
107105
return true;
108106
}
109107

110108
#if NET
111-
ref Entry entry = ref CollectionsMarshal.GetValueRefOrNullRef(_entries, typeof(TKey));
109+
ref Entry entry = ref CollectionsMarshal.GetValueRefOrNullRef(_entries, typeShape.Type);
112110
bool exists = !Unsafe.IsNullRef(ref entry);
113111
#else
114-
bool exists = _entries.TryGetValue(typeof(TKey), out Entry entry);
112+
bool exists = _entries.TryGetValue(typeShape.Type, out Entry entry);
115113
#endif
116114

117115
if (!exists)
@@ -120,7 +118,7 @@ public bool TryGetValue<TKey>(ITypeShape<TKey> typeShape, [MaybeNullWhen(false)]
120118
{
121119
// First time visiting this type, add an empty entry to the
122120
// dictionary to record that it has been visited and return false.
123-
_entries[typeof(TKey)] = new(EntryKind.Empty);
121+
_entries[typeShape.Type] = new(EntryKind.Empty);
124122
}
125123

126124
value = default;
@@ -134,11 +132,11 @@ public bool TryGetValue<TKey>(ITypeShape<TKey> typeShape, [MaybeNullWhen(false)]
134132
DebugExt.Assert(DelayedValueFactory is not null);
135133

136134
// Create a delayed value and return the uninitialized result.
137-
DelayedValue delayedValue = DelayedValueFactory.Create(typeShape);
135+
DelayedValue delayedValue = (DelayedValue)typeShape.Invoke(UntypedDelayedValueFactoryInvoker.Instance, DelayedValueFactory)!;
138136
value = delayedValue.PotentiallyDelayedResult;
139137
entry = new(EntryKind.DelayedValue, delayedValue);
140138
#if !NET
141-
_entries[typeof(TKey)] = entry;
139+
_entries[typeShape.Type] = entry;
142140
#endif
143141
return true;
144142

@@ -304,4 +302,10 @@ private enum EntryKind
304302
IEnumerable<Type> IReadOnlyDictionary<Type, object?>.Keys => GetCompletedValues().Select(kvp => kvp.Key);
305303
IEnumerable<object?> IReadOnlyDictionary<Type, object?>.Values => GetCompletedValues().Select(kvp => kvp.Value.Value);
306304
private IEnumerable<KeyValuePair<Type, Entry>> GetCompletedValues() => _entries.Where(kvp => kvp.Value.Kind is EntryKind.CompletedValue);
305+
306+
private sealed class UntypedDelayedValueFactoryInvoker : ITypeShapeFunc
307+
{
308+
public static readonly UntypedDelayedValueFactoryInvoker Instance = new();
309+
object? ITypeShapeFunc.Invoke<T>(ITypeShape<T> typeShape, object? state) => ((IDelayedValueFactory)state!).Create(typeShape);
310+
}
307311
}

tests/PolyType.Tests/CacheTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,11 @@ public static void TypeGenerationContext_InvalidMethodParameters_ThrowsArgumentE
251251
ITypeShape<int> shapeFromOtherProvider = ReflectionTypeShapeProvider.Default.GetTypeShapeOrThrow<int>();
252252
Assert.NotNull(generationContext.ValueBuilder);
253253

254-
Assert.Throws<ArgumentNullException>(() => generationContext.TryGetValue<int>(null!, out _));
255-
Assert.Throws<ArgumentException>(() => generationContext.TryGetValue<int>(shapeFromOtherProvider, out _));
254+
Assert.Throws<ArgumentNullException>(() => generationContext.TryGetValue(default(ITypeShape<int>)!, out _));
255+
Assert.Throws<ArgumentException>(() => generationContext.TryGetValue(shapeFromOtherProvider, out _));
256256

257-
Assert.Throws<ArgumentNullException>(() => generationContext.GetOrAdd<int>(null!));
258-
Assert.Throws<ArgumentException>(() => generationContext.GetOrAdd<int>(shapeFromOtherProvider));
257+
Assert.Throws<ArgumentNullException>(() => generationContext.GetOrAdd(default(ITypeShape<int>)!));
258+
Assert.Throws<ArgumentException>(() => generationContext.GetOrAdd(shapeFromOtherProvider));
259259

260260
Assert.Throws<ArgumentNullException>(() => generationContext.Add(null!, "42"));
261261
}

0 commit comments

Comments
 (0)