private void AddArrayHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder methodBuilder, ListTypeDescriptor listTypeDescriptor, HashSet <string> processed, bool isNonNullable) { methodBuilder.AddParameter( ParameterBuilder.New() .SetType(listTypeDescriptor.ToEntityIdBuilder()) .SetName(ListParamName)); var listVarName = listTypeDescriptor.Name.WithLowerFirstChar() + "s"; if (!isNonNullable) { methodBuilder.AddCode(EnsureProperNullability(ListParamName, isNonNullable)); } methodBuilder.AddCode( AssignmentBuilder.New() .SetLefthandSide($"var {listVarName}") .SetRighthandSide( CodeBlockBuilder.New() .AddCode("new ") .AddCode(TypeNames.List) .AddCode("<") .AddCode( listTypeDescriptor.InnerType.ToBuilder() .SkipTrailingSpace()) .AddCode(">") .AddCode("()"))); methodBuilder.AddEmptyLine(); var loopbuilder = ForEachBuilder.New() .SetLoopHeader( CodeBlockBuilder.New() .AddCode(listTypeDescriptor.InnerType.ToEntityIdBuilder()) .AddCode($"child in {ListParamName}")) .AddCode( MethodCallBuilder.New() .SetPrefix($"{listVarName}.") .SetMethodName("Add") .AddArgument( BuildMapMethodCall( listTypeDescriptor.InnerType, "child"))); methodBuilder.AddCode(loopbuilder); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {listVarName};"); AddMapMethod( listVarName, listTypeDescriptor.InnerType, classBuilder, constructorBuilder, processed); }
public static MethodBuilder AddParameter( this MethodBuilder builder, string name, Action <ParameterBuilder> configure) { ParameterBuilder?parameterBuilder = ParameterBuilder.New().SetName(name); configure(parameterBuilder); builder.AddParameter(parameterBuilder); return(builder); }
private void AddDeserializeMethod( ITypeDescriptor typeReference, ClassBuilder classBuilder, HashSet <string> processed) { string methodName = DeserializerMethodNameFromTypeName(typeReference); if (processed.Add(methodName)) { MethodBuilder methodBuilder = classBuilder .AddMethod() .SetPrivate() .SetReturnType(typeReference.ToEntityIdBuilder()) .SetName(methodName); methodBuilder .AddParameter(_obj) .SetType(TypeNames.JsonElement.MakeNullable()); if (typeReference.IsEntityType() || typeReference.ContainsEntity()) { methodBuilder .AddParameter(_entityIds) .SetType(TypeNames.ISet.WithGeneric(TypeNames.EntityId)); } IfBuilder jsonElementNullCheck = IfBuilder .New() .SetCondition($"!{_obj}.HasValue") .AddCode( typeReference.IsNonNullableType() ? ExceptionBuilder.New(TypeNames.ArgumentNullException) : CodeLineBuilder.From("return null;")); methodBuilder .AddCode(jsonElementNullCheck) .AddEmptyLine(); AddDeserializeMethodBody(classBuilder, methodBuilder, typeReference, processed); } }
public static ParameterBuilder AddParameter( this MethodBuilder builder, string?name = null) { ParameterBuilder parameterBuilder = ParameterBuilder.New(); if (name is not null) { parameterBuilder.SetName(name); } builder.AddParameter(parameterBuilder); return(parameterBuilder); }
private void AddEntityHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, ComplexTypeDescriptor complexTypeDescriptor, HashSet <string> processed, bool isNonNullable) { method.AddParameter( EntityIdParamName, x => x.SetType(TypeNames.EntityId.MakeNullable(!isNonNullable))); if (!isNonNullable) { method.AddCode( EnsureProperNullability( EntityIdParamName, isNonNullable)); } if (complexTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) { foreach (ObjectTypeDescriptor implementee in interfaceTypeDescriptor.ImplementedBy) { NameString dataMapperName = CreateEntityMapperName( implementee.RuntimeType.Name, implementee.Name); if (processed.Add(dataMapperName)) { var dataMapperType = TypeNames.IEntityMapper.WithGeneric( CreateEntityTypeName(implementee.Name), implementee.RuntimeType.Name); AddConstructorAssignedField( dataMapperType, GetFieldName(dataMapperName), classBuilder, constructorBuilder); } method.AddCode(GenerateEntityHandlerIfClause(implementee, isNonNullable)); } } method.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); }
private void AddComplexDataHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, ComplexTypeDescriptor complexTypeDescriptor, HashSet <string> processed, bool isNonNullable) { if (complexTypeDescriptor.ParentRuntimeType is null) { throw new InvalidOperationException(); } method.AddParameter( ParameterBuilder.New() .SetType(complexTypeDescriptor.ParentRuntimeType.ToString()) .SetName(_dataParameterName)); if (!isNonNullable) { method.AddCode( EnsureProperNullability( _dataParameterName, isNonNullable)); } var variableName = "returnValue"; method.AddCode($"{complexTypeDescriptor.RuntimeType.Name} {variableName} = default!;"); method.AddEmptyLine(); GenerateIfForEachImplementedBy( method, complexTypeDescriptor, o => GenerateComplexDataInterfaceIfClause(o, variableName)); method.AddCode($"return {variableName};"); AddRequiredMapMethods( _dataParameterName, complexTypeDescriptor, classBuilder, constructorBuilder, processed); }
private void AddDataHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, ComplexTypeDescriptor namedTypeDescriptor, HashSet <string> processed, bool isNonNullable) { method.AddParameter( _dataParameterName, x => x.SetType(namedTypeDescriptor.ParentRuntimeType !.ToString())); if (!isNonNullable) { method.AddCode(EnsureProperNullability(_dataParameterName, isNonNullable)); } var variableName = "returnValue"; method.AddCode($"{namedTypeDescriptor.RuntimeType.Name} {variableName} = default!;"); method.AddEmptyLine(); GenerateIfForEachImplementedBy( method, namedTypeDescriptor, o => GenerateDataInterfaceIfClause(o, isNonNullable, variableName)); method.AddCode($"return {variableName};"); AddRequiredMapMethods( _dataParameterName, namedTypeDescriptor, classBuilder, constructorBuilder, processed); }
private void AddDataHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, NamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed, bool isNonNullable) { method.AddParameter( ParameterBuilder.New() .SetType( $"global::{namedTypeDescriptor.Namespace}.State." + DataTypeNameFromTypeName(namedTypeDescriptor.GraphQLTypeName)) .SetName(DataParamName)); if (!isNonNullable) { method.AddCode( EnsureProperNullability( DataParamName, isNonNullable)); } var variableName = "returnValue"; method.AddCode($"{namedTypeDescriptor.Name} {variableName} = default!;"); method.AddEmptyLine(); if (namedTypeDescriptor.ImplementedBy.Any()) { var ifChain = InterfaceImplementeeIf(namedTypeDescriptor.ImplementedBy[0]); foreach (NamedTypeDescriptor interfaceImplementee in namedTypeDescriptor.ImplementedBy.Skip(1)) { var singleIf = InterfaceImplementeeIf(interfaceImplementee).SkipIndents(); ifChain.AddIfElse(singleIf); } ifChain.AddElse( CodeInlineBuilder.New() .SetText($"throw new {TypeNames.NotSupportedException}();")); method.AddCode(ifChain); } IfBuilder InterfaceImplementeeIf(NamedTypeDescriptor interfaceImplementee) { var ifCorrectType = IfBuilder.New(); if (isNonNullable) { ifCorrectType.SetCondition( $"{DataParamName}.__typename.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } else { ifCorrectType.SetCondition( $"{DataParamName}?.__typename.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson}) ?? false"); } var constructorCall = MethodCallBuilder.New() .SetPrefix($"{variableName} = new ") .SetMethodName(interfaceImplementee.Name); foreach (PropertyDescriptor prop in interfaceImplementee.Properties) { var propAccess = $"{DataParamName}.{prop.Name}"; if (prop.Type.IsEntityType()) { constructorCall.AddArgument( BuildMapMethodCall( DataParamName, prop, true)); } else { constructorCall.AddArgument( $"{propAccess} ?? throw new {TypeNames.ArgumentNullException}()"); } } ifCorrectType.AddCode(constructorCall); return(ifCorrectType); } method.AddCode($"return {variableName};"); AddRequiredMapMethods( DataParamName, namedTypeDescriptor, classBuilder, constructorBuilder, processed); }
private void AddArrayHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder methodBuilder, ListTypeDescriptor listTypeDescriptor, HashSet <string> processed, bool isNonNullable) { methodBuilder .AddParameter(_list) .SetType(listTypeDescriptor.ToEntityIdBuilder()); var listVarName = GetParameterName(listTypeDescriptor.Name) + "s"; if (!isNonNullable) { methodBuilder.AddCode(EnsureProperNullability(_list, isNonNullable)); } methodBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {listVarName}") .SetRighthandSide( CodeBlockBuilder .New() .AddCode("new ") .AddCode(TypeNames.List) .AddCode("<") .AddCode(listTypeDescriptor.InnerType.ToBuilder().SkipTrailingSpace()) .AddCode(">") .AddCode("()"))); methodBuilder.AddEmptyLine(); ForEachBuilder forEachBuilder = ForEachBuilder .New() .SetLoopHeader( CodeBlockBuilder .New() .AddCode(listTypeDescriptor.InnerType.ToEntityIdBuilder()) .AddCode($"{_child} in {_list}")) .AddCode( MethodCallBuilder .New() .SetMethodName(listVarName, nameof(List <object> .Add)) .AddArgument(MethodCallBuilder .Inline() .SetMethodName(MapMethodNameFromTypeName(listTypeDescriptor.InnerType)) .AddArgument(_child))); methodBuilder .AddCode(forEachBuilder) .AddEmptyLine() .AddCode($"return {listVarName};"); AddMapMethod( listVarName, listTypeDescriptor.InnerType, classBuilder, constructorBuilder, processed); }
private void AddEntityHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, NamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed, bool isNonNullable) { var nullabilityAdditive = "?"; if (isNonNullable) { nullabilityAdditive = ""; } method.AddParameter( ParameterBuilder.New() .SetType(TypeNames.EntityId + nullabilityAdditive) .SetName(EntityIdParamName)); if (!isNonNullable) { method.AddCode( EnsureProperNullability( EntityIdParamName, isNonNullable)); } foreach (NamedTypeDescriptor implementee in namedTypeDescriptor.ImplementedBy) { var dataMapperName = EntityMapperNameFromGraphQLTypeName( implementee.Name, implementee.GraphQLTypeName); if (processed.Add(dataMapperName)) { var dataMapperType = $"{TypeNames.IEntityMapper}<" + $"{EntityTypeNameFromGraphQLTypeName(implementee.GraphQLTypeName)}, " + $"{implementee.Name}>"; AddConstructorAssignedField( dataMapperType, dataMapperName.ToFieldName(), classBuilder, constructorBuilder); } } foreach (NamedTypeDescriptor interfaceImplementee in namedTypeDescriptor.ImplementedBy) { method.AddCode(InterfaceImplementeeIf(interfaceImplementee)); } method.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); IfBuilder InterfaceImplementeeIf(NamedTypeDescriptor interfaceImplementee) { var dataMapperName = EntityMapperNameFromGraphQLTypeName( interfaceImplementee.Name, interfaceImplementee.GraphQLTypeName) .ToFieldName(); var ifCorrectType = IfBuilder.New(); if (isNonNullable) { ifCorrectType.SetCondition( $"{EntityIdParamName}.Name.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } else { ifCorrectType.SetCondition( $"{EntityIdParamName}.Value.Name.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } MethodCallBuilder constructorCall = MethodCallBuilder.New() .SetPrefix($"return {dataMapperName}.") .SetWrapArguments() .SetMethodName(nameof(IEntityMapper <object, object> .Map)); MethodCallBuilder argument = MethodCallBuilder.New() .SetMethodName($"{StoreFieldName}.{nameof(IEntityStore.GetEntity)}") .SetDetermineStatement(false) .AddGeneric( EntityTypeNameFromGraphQLTypeName(interfaceImplementee.GraphQLTypeName)) .AddArgument(isNonNullable ? EntityIdParamName : $"{EntityIdParamName}.Value"); constructorCall.AddArgument( NullCheckBuilder.New() .SetDetermineStatement(false) .SetCondition(argument) .SetCode(ExceptionBuilder .New(TypeNames.GraphQLClientException) .SetDetermineStatement(false))); method.AddEmptyLine(); ifCorrectType.AddCode(constructorCall); return(ifCorrectType); } }