Skip to content

Commit

Permalink
Nullable references returned as not found when it does exists
Browse files Browse the repository at this point in the history
  • Loading branch information
joh-pot committed Dec 3, 2020
1 parent 47959b4 commit a558785
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 65 deletions.
132 changes: 68 additions & 64 deletions DeeDee/Builders/Models/FrugalDictionaryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,161 +43,165 @@ private static bool TryCheck(ref KeyValuePair<object, object?> kvp, object key,
public bool TryGetValue(object key, out object? value)
{
value = FindEntry(key);
return value != null;
var (found, val) = FindEntry(key);
value = val;
return found;
}
private object? FindEntry(object key)
private static (bool Found, object? Value) Found(object? value) => (true, value);
private static (bool Found, object? Value) NotFound() => (false, null);
private (bool Found, object? Value) FindEntry(object key)
{
switch (_allocated)
{
case 0: return null;
case 0: return NotFound();
case 1:
{
return TryCheck(ref _one, key, out var val) ? val : null;
return TryCheck(ref _one, key, out var val) ? Found(val) : NotFound();
}
case 2:
{
if (TryCheck(ref _one, key, out var val))
return val;
return TryCheck(ref _two, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _two, key, out val) ? Found(val) : NotFound();
}
case 3:
{
if (TryCheck(ref _one, key, out var val))
return val;
return Found(val);
if (TryCheck(ref _two, key, out val))
return val;
return TryCheck(ref _three, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _three, key, out val) ? Found(val) : NotFound();
}
case 4:
{
if (TryCheck(ref _one, key, out var val))
return val;
return Found(val);
if (TryCheck(ref _two, key, out val))
return val;
return Found(val);
if (TryCheck(ref _three, key, out val))
return val;
return TryCheck(ref _four, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _four, key, out val) ? Found(val) : NotFound();
}
case 5:
{
if (TryCheck(ref _one, key, out var val))
return val;
return Found(val);
if (TryCheck(ref _two, key, out val))
return val;
return Found(val);
if (TryCheck(ref _three, key, out val))
return val;
return Found(val);
if (TryCheck(ref _four, key, out val))
return val;
return TryCheck(ref _five, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _five, key, out val) ? Found(val) : NotFound();
}
case 6:
{
if (TryCheck(ref _one, key, out var val))
return val;
return Found(val);
if (TryCheck(ref _two, key, out val))
return val;
return Found(val);
if (TryCheck(ref _three, key, out val))
return val;
return Found(val);
if (TryCheck(ref _four, key, out val))
return val;
return Found(val);
if (TryCheck(ref _five, key, out val))
return val;
return TryCheck(ref _six, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _six, key, out val) ? Found(val) : NotFound();
}
case 7:
{
if (TryCheck(ref _one, key, out var val))
return val;
return Found(val);
if (TryCheck(ref _two, key, out val))
return val;
return Found(val);
if (TryCheck(ref _three, key, out val))
return val;
return Found(val);
if (TryCheck(ref _four, key, out val))
return val;
return Found(val);
if (TryCheck(ref _five, key, out val))
return val;
return Found(val);
if (TryCheck(ref _six, key, out val))
return val;
return TryCheck(ref _seven, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _seven, key, out val) ? Found(val) : NotFound();
}
case 8:
{
if (TryCheck(ref _one, key, out var val))
return val;
return Found(val);
if (TryCheck(ref _two, key, out val))
return val;
return Found(val);
if (TryCheck(ref _three, key, out val))
return val;
return Found(val);
if (TryCheck(ref _four, key, out val))
return val;
return Found(val);
if (TryCheck(ref _five, key, out val))
return val;
return Found(val);
if (TryCheck(ref _six, key, out val))
return val;
return Found(val);
if (TryCheck(ref _seven, key, out val))
return val;
return TryCheck(ref _eight, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _eight, key, out val) ? Found(val) : NotFound();
}
case 9:
{
if (TryCheck(ref _one, key, out var val))
return val;
return Found(val);
if (TryCheck(ref _two, key, out val))
return val;
return Found(val);
if (TryCheck(ref _three, key, out val))
return val;
return Found(val);
if (TryCheck(ref _four, key, out val))
return val;
return Found(val);
if (TryCheck(ref _five, key, out val))
return val;
return Found(val);
if (TryCheck(ref _six, key, out val))
return val;
return Found(val);
if (TryCheck(ref _seven, key, out val))
return val;
return Found(val);
if (TryCheck(ref _eight, key, out val))
return val;
return TryCheck(ref _nine, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _nine, key, out val) ? Found(val) : NotFound();
}
case 10:
{
if (TryCheck(ref _one, key, out var val))
return val;
return Found(val);
if (TryCheck(ref _two, key, out val))
return val;
return Found(val);
if (TryCheck(ref _three, key, out val))
return val;
return Found(val);
if (TryCheck(ref _four, key, out val))
return val;
return Found(val);
if (TryCheck(ref _five, key, out val))
return val;
return Found(val);
if (TryCheck(ref _six, key, out val))
return val;
return Found(val);
if (TryCheck(ref _seven, key, out val))
return val;
return Found(val);
if (TryCheck(ref _eight, key, out val))
return val;
return Found(val);
if (TryCheck(ref _nine, key, out val))
return val;
return TryCheck(ref _ten, key, out val) ? val : null;
return Found(val);
return TryCheck(ref _ten, key, out val) ? Found(val) : NotFound();
}
default:
{
return _values!.TryGetValue(key, out var val) ? val : null;
return _values!.TryGetValue(key, out var val) ? Found(val) : NotFound();
}
}
}
public object this[object key]
public object? this[object key]
{
get
{
var entry = FindEntry(key);
if (entry == null)
throw new KeyNotFoundException();
return entry;
if (!entry.Found)
ThrowHelper.ThrowKeyNotFound();
return entry.Value;
}
}
Expand Down
25 changes: 25 additions & 0 deletions DeeDee/Builders/Models/ThrowHelperBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace DeeDee.Builders.Models
{
internal static class ThrowHelperBuilder
{
public static string Build()
{
return @"
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace DeeDee.Models
{
internal static class ThrowHelper
{
[DoesNotReturn]
public static void ThrowKeyNotFound()
{
throw new KeyNotFoundException();
}
}
}
";
}
}
}
2 changes: 1 addition & 1 deletion DeeDee/DeeDee.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageProjectUrl>https://github.com/joh-pot/DeeDee/wiki</PackageProjectUrl>
<RepositoryUrl>https://github.com/joh-pot/DeeDee</RepositoryUrl>
<PackageTags>CQRS, command, queries, request, response, source generation</PackageTags>
<Version>1.0.5</Version>
<Version>1.0.6</Version>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression> <!-- Do not include the generator as a lib dependency -->
</PropertyGroup>

Expand Down
2 changes: 2 additions & 0 deletions DeeDee/SourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public void Execute(GeneratorExecutionContext context)
var pipelineContext = PipelineContextBuilder.Build();
var serviceProviderDelegate = ServiceProviderDelegateBuilder.Build();
var stepAttribute = StepAttributeBuilder.Build();
var throwHelper = ThrowHelperBuilder.Build();

context.AddSource("FrugalDictionary.cs", frugalDictionary);
context.AddSource("IPipelineAction.cs", ipipelineAction);
Expand All @@ -34,6 +35,7 @@ public void Execute(GeneratorExecutionContext context)
context.AddSource("PipelineContext.cs", pipelineContext);
context.AddSource("ServiceProviderDelegate.cs", serviceProviderDelegate);
context.AddSource("StepAttribute.cs", stepAttribute);
context.AddSource("ThrowHelper.cs", throwHelper);

var options = (context.Compilation as CSharpCompilation)!.SyntaxTrees[0].Options as CSharpParseOptions;

Expand Down

0 comments on commit a558785

Please sign in to comment.