Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore items in lists where the type is unknown #6467

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/StrawberryShake/Client/src/Core/IEntityIdSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ public interface IEntityIdSerializer
/// </returns>
EntityId Parse(JsonElement obj);

/// <summary>
/// Try parse an entity ID from a JSON object.
/// </summary>
/// <param name="obj">
/// The JSON object.
/// </param>
/// <param name="entityId">The parsed entity id</param>
/// <returns>
/// Returns true if entity id could be parsed otherwise false.
/// </returns>
bool TryParse(JsonElement obj, out EntityId entityId);

/// <summary>
/// Formats the <paramref name="entityId"/> to a JSON object.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class ParameterBuilder : ICodeBuilder
private string? _name;
private string? _default;
private bool _this;
private bool _isOut;

public static ParameterBuilder New() => new();

Expand Down Expand Up @@ -38,6 +39,12 @@ public ParameterBuilder SetThis(bool value = true)
return this;
}

public ParameterBuilder SetIsOut(bool isOut = true)
{
_isOut = isOut;
return this;
}

public ParameterBuilder SetDefault(string value = "default", bool condition = true)
{
if (condition)
Expand All @@ -64,6 +71,11 @@ public void Build(CodeWriter writer)
writer.Write("this ");
}

if (_isOut)
{
writer.Write("out ");
}

_type.Build(writer);

writer.Write(_name);
Expand All @@ -73,4 +85,4 @@ public void Build(CodeWriter writer)
writer.Write($" = {_default}");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ public class EntityIdFactoryGenerator : CodeGenerator<EntityIdFactoryDescriptor>
.AddParameter(_obj, x => x.SetType(TypeNames.JsonElement))
.AddCode(ParseEntityIdBody(descriptor));

classBuilder.AddMethod("TryParse")
.SetAccessModifier(AccessModifier.Public)
.SetReturnType(TypeNames.Boolean)
.AddParameter(_obj, x => x.SetType(TypeNames.JsonElement))
.AddParameter("entityId", x => x.SetType(TypeNames.EntityId).SetIsOut())
.AddCode(TryParseBody());

classBuilder
.AddMethod("Format")
.SetAccessModifier(AccessModifier.Public)
Expand Down Expand Up @@ -189,6 +196,23 @@ private ICode FormatEntityIdBody(EntityIdFactoryDescriptor descriptor)
.AddCode(typeNameSwitch);
}

private ICode TryParseBody()
{
var body = TryCatchBuilder
.New();

body.AddTryCode(CodeBlockBuilder
.New()
.AddLine("entityId = Parse(obj);")
.AddLine("return true;"))
.AddCatchBlock(CatchBlockBuilder
.New()
.AddCode(CodeBlockBuilder
.New()
.AddLine("return false;")));
return body;
}

private ICode FormatSpecificEntityIdBody(EntityIdDescriptor entity)
{
var body = CodeBlockBuilder
Expand Down Expand Up @@ -273,4 +297,4 @@ private ICode FormatSpecificEntityIdBody(EntityIdDescriptor entity)

return body;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
using StrawberryShake.CodeGeneration.CSharp.Builders;
using StrawberryShake.CodeGeneration.CSharp.Extensions;
using StrawberryShake.CodeGeneration.Descriptors.TypeDescriptors;
using StrawberryShake.CodeGeneration.Extensions;
using static StrawberryShake.CodeGeneration.Utilities.NameUtils;

namespace StrawberryShake.CodeGeneration.CSharp.Generators;

public partial class JsonResultBuilderGenerator
{
private const string _child = "child";
private const string _parsedValue = "parsedValue";

private void AddArrayHandler(
ClassBuilder classBuilder,
Expand All @@ -18,6 +20,28 @@ public partial class JsonResultBuilderGenerator
{
var listVarName = GetParameterName(listTypeDescriptor.Name) + "s";

var listType = listTypeDescriptor.InnerType
.ToStateTypeReference()
.SkipTrailingSpace();

if (listTypeDescriptor.InnerType.IsNonNull())
{
AddNonNullableInnerTypeBody(methodBuilder, listTypeDescriptor, listVarName);
}
else
{
AddNullableInnerTypeBody(methodBuilder, listTypeDescriptor, listVarName, listType);
}


AddDeserializeMethod(listTypeDescriptor.InnerType, classBuilder, processed);
}

private static void AddNonNullableInnerTypeBody(
MethodBuilder methodBuilder,
ListTypeDescriptor listTypeDescriptor,
string listVarName)
{
methodBuilder
.AddCode(
AssignmentBuilder
Expand Down Expand Up @@ -52,7 +76,51 @@ public partial class JsonResultBuilderGenerator
setNullForgiving: false))))
.AddEmptyLine()
.AddCode($"return {listVarName};");
}

AddDeserializeMethod(listTypeDescriptor.InnerType, classBuilder, processed);
private static void AddNullableInnerTypeBody(
MethodBuilder methodBuilder,
ListTypeDescriptor listTypeDescriptor,
string listVarName, TypeReferenceBuilder listType)
{
methodBuilder
.AddCode(
AssignmentBuilder
.New()
.SetLefthandSide($"var {listVarName}")
.SetRighthandSide(
CodeBlockBuilder
.New()
.AddCode("new ")
.AddCode(TypeNames.List)
.AddCode("<")
.AddCode(listType)
.AddCode(">")
.AddCode("()")))
.AddEmptyLine()
.AddCode(
ForEachBuilder
.New()
.SetLoopHeader(
$"{TypeNames.JsonElement} {_child} in {_obj}.Value.EnumerateArray()")
.AddCode(
CodeBlockBuilder
.New()
.AddCode(AssignmentBuilder
.New()
.SetLefthandSide($"{listType} {_parsedValue}")
.SetRighthandSide(BuildUpdateMethodCall(
listTypeDescriptor.InnerType,
CodeInlineBuilder.From(_child),
setNullForgiving: false)))
.AddCode(IfBuilder
.New()
.SetCondition($"{_parsedValue} is not null")
.AddCode(MethodCallBuilder
.New()
.SetMethodName(listVarName, nameof(List<object>.Add))
.AddArgument($"{_parsedValue}")))))
.AddEmptyLine()
.AddCode($"return {listVarName};");
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using HotChocolate.Types;
using StrawberryShake.CodeGeneration.CSharp.Builders;
using StrawberryShake.CodeGeneration.Descriptors.TypeDescriptors;
using StrawberryShake.CodeGeneration.Extensions;
Expand All @@ -12,22 +13,23 @@ public partial class JsonResultBuilderGenerator
{
private const string _entityId = "entityId";
private const string _entity = "entity";
private const string _parseSuccess = "parseSuccess";

private void AddUpdateEntityMethod(
ClassBuilder classBuilder,
MethodBuilder methodBuilder,
INamedTypeDescriptor namedTypeDescriptor,
HashSet<string> processed)
{
methodBuilder.AddCode(
AssignmentBuilder
.New()
.SetLefthandSide($"{TypeNames.EntityId} {_entityId}")
.SetRighthandSide(
MethodCallBuilder
.Inline()
.SetMethodName(GetFieldName(_idSerializer), "Parse")
.AddArgument($"{_obj}.Value")));
if (namedTypeDescriptor.IsNonNull())
{
AddNonNullTypeBody(methodBuilder);
}
else
{
AddNullTypeBody(methodBuilder);
}


methodBuilder.AddCode(
MethodCallBuilder
Expand Down Expand Up @@ -67,6 +69,45 @@ public partial class JsonResultBuilderGenerator
AddRequiredDeserializeMethods(namedTypeDescriptor, classBuilder, processed);
}

private static void AddNullTypeBody(MethodBuilder methodBuilder)
{
methodBuilder.AddCode(
AssignmentBuilder
.New()
.SetLefthandSide($"{TypeNames.Boolean} {_parseSuccess}")
.SetRighthandSide(
MethodCallBuilder
.Inline()
.SetMethodName(GetFieldName(_idSerializer), "TryParse")
.AddArgument($"{_obj}.Value")
.AddArgument($"out {TypeNames.EntityId} {_entityId}")));

methodBuilder.AddCode(
IfBuilder
.New()
.SetCondition($"!{_parseSuccess}")
.AddCode("return default;"));
}

private static void AddNonNullTypeBody(MethodBuilder methodBuilder)
{
methodBuilder.AddCode(
AssignmentBuilder
.New()
.SetLefthandSide($"{TypeNames.EntityId} {_entityId}")
.SetRighthandSide(
MethodCallBuilder
.Inline()
.SetMethodName(GetFieldName(_idSerializer), "Parse")
.AddArgument($"{_obj}.Value")));

methodBuilder.AddCode(
MethodCallBuilder
.New()
.SetMethodName(_entityIds, nameof(List<object>.Add))
.AddArgument(_entityId));
}

private IfBuilder CreateUpdateEntityStatement(
ObjectTypeDescriptor concreteType)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,19 @@ public partial class AnyScalarDefaultSerializationClientEntityIdFactory : global
_ => throw new global::System.NotSupportedException()};
}

public global::System.Boolean TryParse(global::System.Text.Json.JsonElement obj, out global::StrawberryShake.EntityId entityId)
{
try
{
entityId = Parse(obj);
return true;
}
catch
{
return false;
}
}

public global::System.String Format(global::StrawberryShake.EntityId entityId)
{
return entityId.Name switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,11 @@ public GetFooBuilder(global::StrawberryShake.IEntityStore entityStore, global::S
var bars = new global::System.Collections.Generic.List<global::StrawberryShake.EntityIdOrData?>();
foreach (global::System.Text.Json.JsonElement child in obj.Value.EnumerateArray())
{
bars.Add(Deserialize_IBarData(session, child, entityIds));
global::StrawberryShake.EntityIdOrData? parsedValue = Deserialize_IBarData(session, child, entityIds);
if (parsedValue is not null)
{
bars.Add(parsedValue);
}
}

return bars;
Expand Down Expand Up @@ -1036,6 +1040,19 @@ public partial class EntityIdOrDataClientEntityIdFactory : global::StrawberrySha
_ => throw new global::System.NotSupportedException()};
}

public global::System.Boolean TryParse(global::System.Text.Json.JsonElement obj, out global::StrawberryShake.EntityId entityId)
{
try
{
entityId = Parse(obj);
return true;
}
catch
{
return false;
}
}

public global::System.String Format(global::StrawberryShake.EntityId entityId)
{
return entityId.Name switch
Expand Down
Loading
Loading