private void GenerateIfForEachImplementedBy( MethodBuilder method, ComplexTypeDescriptor complexTypeDescriptor, Func <ObjectTypeDescriptor, IfBuilder> generator) { if (!(complexTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) || !interfaceTypeDescriptor.ImplementedBy.Any()) { return; } var ifChain = generator(interfaceTypeDescriptor.ImplementedBy.First()); foreach (ObjectTypeDescriptor objectTypeDescriptor in interfaceTypeDescriptor.ImplementedBy.Skip(1)) { ifChain.AddIfElse( generator(objectTypeDescriptor) .SkipIndents()); } ifChain.AddElse( CodeInlineBuilder.New() .SetText($"throw new {TypeNames.NotSupportedException}();")); method.AddCode(ifChain); }
private static ICode BuildPropertyComparison( ITypeDescriptor type, string propertyName) { const string other = nameof(other); return(BuildPropertyInternal(type, true)); ICode BuildPropertyInternal( ITypeDescriptor currentType, bool isNullable) { return(currentType switch { NonNullTypeDescriptor d => BuildPropertyInternal(d.InnerType, false), ILeafTypeDescriptor d when d.SerializationType.IsValueType => CodeInlineBuilder .New() .SetText($"{propertyName} == {other}.{propertyName}"), INamedTypeDescriptor when isNullable => ConditionBuilder .New() .Set($"({propertyName} is null && {other}.{propertyName} is null) ||" + $"{propertyName} != null && {propertyName}.{nameof(Equals)}(" + $"{other}.{propertyName})"), INamedTypeDescriptor => MethodCallBuilder .Inline() .SetMethodName(propertyName, nameof(Equals)) .AddArgument($"{other}.{propertyName}"), ListTypeDescriptor => MethodCallBuilder .Inline() .SetMethodName(TypeNames.SequenceEqual) .AddArgument(propertyName) .AddArgument($"{other}.{propertyName}"), _ => throw new ArgumentOutOfRangeException() }); }
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); }