private static void GenerateTypeQueryBuilder(GraphQlType type, StringBuilder builder)
        {
            var className = $"{type.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix}";

            ValidateClassName(className);

            builder.AppendLine($"public class {className} : GraphQlQueryBuilder<{className}>");
            builder.AppendLine("{");

            var fields = type.Fields.ToArray();

            builder.AppendLine("    protected override IList<FieldMetadata> AllFields { get; } =");
            builder.AppendLine("        new []");
            builder.AppendLine("        {");

            for (var i = 0; i < fields.Length; i++)
            {
                var comma     = i == fields.Length - 1 ? null : ",";
                var field     = fields[i];
                var fieldType = UnwrapNonNull(field.Type);
                var isList    = fieldType.Kind == GraphQlTypeKindList;
                var isComplex = isList || IsObjectScalar(fieldType) || fieldType.Kind == GraphQlTypeKindObject;

                builder.Append($"            new FieldMetadata {{ Name = \"{field.Name}\"");

                if (isComplex)
                {
                    builder.Append(", IsComplex = true");

                    fieldType = isList ? UnwrapNonNull(fieldType.OfType) : fieldType;
                    if (fieldType.Kind != GraphQlTypeKindScalar)
                    {
                        builder.Append($", QueryBuilderType = typeof({fieldType.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix})");
                    }
                }

                builder.AppendLine($" }}{comma}");
            }

            builder.AppendLine("        };");
            builder.AppendLine();

            for (var i = 0; i < fields.Length; i++)
            {
                var field     = fields[i];
                var fieldType = UnwrapNonNull(field.Type);
                if (fieldType.Kind == GraphQlTypeKindList)
                {
                    fieldType = fieldType.OfType;
                }
                fieldType = UnwrapNonNull(fieldType);

                var args             = field.Args?.Where(a => UnwrapNonNull(a.Type).Kind == GraphQlTypeKindScalar || UnwrapNonNull(a.Type).Kind == GraphQlTypeKindEnum).ToArray() ?? new GraphQlArgument[0];
                var methodParameters = String.Join(", ", args.Select(a => $"{(UnwrapNonNull(a.Type).Kind == GraphQlTypeKindEnum ? $"{UnwrapNonNull(a.Type).Name}?" : ScalarToNetType(UnwrapNonNull(a.Type).Name))} {a.Name} = null"));
                var requiresFullBody = GraphQlGeneratorConfiguration.CSharpVersion == CSharpVersion.Compatible || args.Any();
                var returnPrefix     = requiresFullBody ? "        return " :  String.Empty;

                if (fieldType.Kind == GraphQlTypeKindScalar || fieldType.Kind == GraphQlTypeKindEnum || fieldType.Kind == GraphQlTypeKindScalar)
                {
                    builder.Append($"    public {className} With{NamingHelper.CapitalizeFirst(field.Name)}({methodParameters})");

                    if (requiresFullBody)
                    {
                        builder.AppendLine();
                        builder.AppendLine("    {");
                        AppendArgumentDictionary(builder, args);
                    }
                    else
                    {
                        builder.Append(" => ");
                    }

                    builder.Append($"{returnPrefix}WithScalarField(\"{field.Name}\"");

                    if (args.Length > 0)
                    {
                        builder.Append(", args");
                    }

                    builder.AppendLine(");");

                    if (requiresFullBody)
                    {
                        builder.AppendLine("    }");
                    }
                }
                else
                {
                    if (String.IsNullOrEmpty(fieldType.Name))
                    {
                        throw new InvalidOperationException($"Field '{field.Name}' type name not resolved. ");
                    }

                    var builderParameterName = NamingHelper.LowerFirst(fieldType.Name);
                    builder.Append($"    public {className} With{NamingHelper.CapitalizeFirst(field.Name)}({fieldType.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix} {builderParameterName}QueryBuilder");

                    if (args.Length > 0)
                    {
                        builder.Append(", ");
                        builder.Append(methodParameters);
                    }

                    builder.Append(")");

                    if (requiresFullBody)
                    {
                        builder.AppendLine();
                        builder.AppendLine("    {");
                    }
                    else
                    {
                        builder.Append(" => ");
                    }

                    AppendArgumentDictionary(builder, args);

                    builder.Append($"{returnPrefix}WithObjectField(\"{field.Name}\", {builderParameterName}QueryBuilder");

                    if (args.Length > 0)
                    {
                        builder.Append(", args");
                    }

                    builder.AppendLine(");");

                    if (requiresFullBody)
                    {
                        builder.AppendLine("    }");
                    }
                }

                if (i < fields.Length - 1)
                {
                    builder.AppendLine();
                }
            }

            builder.AppendLine("}");
        }
        private static void GenerateTypeQueryBuilder(GraphQlType type, string queryPrefix, StringBuilder builder)
        {
            var className = $"{type.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix}";

            ValidateClassName(className);

            builder.AppendLine($"public {(GraphQlGeneratorConfiguration.GeneratePartialClasses ? "partial " : null)}class {className} : GraphQlQueryBuilder<{className}>");
            builder.AppendLine("{");

            builder.AppendLine("    private static readonly FieldMetadata[] AllFieldMetadata =");
            builder.AppendLine("        new []");
            builder.AppendLine("        {");

            var fields = type.Fields?.ToArray();

            for (var i = 0; i < fields?.Length; i++)
            {
                var comma     = i == fields.Length - 1 ? null : ",";
                var field     = fields[i];
                var fieldType = field.Type.UnwrapIfNonNull();
                var isList    = fieldType.Kind == GraphQlTypeKindList;
                var treatUnknownObjectAsComplex = IsUnknownObjectScalar(type, field.Name, fieldType) && !GraphQlGeneratorConfiguration.TreatUnknownObjectAsScalar;
                var isComplex = isList || treatUnknownObjectAsComplex || IsComplexType(fieldType.Kind);

                builder.Append($"            new FieldMetadata {{ Name = \"{field.Name}\"");

                if (isComplex)
                {
                    builder.Append(", IsComplex = true");

                    fieldType = isList ? fieldType.OfType.UnwrapIfNonNull() : fieldType;

                    if (fieldType.Kind != GraphQlTypeKindScalar && fieldType.Kind != GraphQlTypeKindEnum)
                    {
                        builder.Append($", QueryBuilderType = typeof({fieldType.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix})");
                    }
                }

                builder.AppendLine($" }}{comma}");
            }

            builder.AppendLine("        };");
            builder.AppendLine();

            if (!String.IsNullOrEmpty(queryPrefix))
            {
                WriteOverrideProperty("string", "Prefix", $"\"{queryPrefix}\"", builder);
            }

            WriteOverrideProperty("IList<FieldMetadata>", "AllFields", "AllFieldMetadata", builder);

            for (var i = 0; i < fields?.Length; i++)
            {
                var field     = fields[i];
                var fieldType = field.Type.UnwrapIfNonNull();
                if (fieldType.Kind == GraphQlTypeKindList)
                {
                    fieldType = fieldType.OfType;
                }
                fieldType = fieldType.UnwrapIfNonNull();

                bool IsCompatibleArgument(GraphQlFieldType argumentType)
                {
                    argumentType = argumentType.UnwrapIfNonNull();
                    switch (argumentType.Kind)
                    {
                    case GraphQlTypeKindScalar:
                    case GraphQlTypeKindEnum:
                    case GraphQlTypeKindInputObject:
                        return(true);

                    case GraphQlTypeKindList:
                        return(IsCompatibleArgument(argumentType.OfType));

                    default:
                        return(false);
                    }
                }

                var args             = field.Args?.Where(a => IsCompatibleArgument(a.Type)).ToArray() ?? new GraphQlArgument[0];
                var methodParameters =
                    String.Join(
                        ", ",
                        args
                        .OrderByDescending(a => a.Type.Kind == GraphQlTypeKindNonNull)
                        .Select(a => BuildMethodParameterDefinition(type, a)));

                var requiresFullBody = GraphQlGeneratorConfiguration.CSharpVersion == CSharpVersion.Compatible || args.Any();
                var returnPrefix     = requiresFullBody ? "        return " : String.Empty;

                if (fieldType.Kind == GraphQlTypeKindScalar || fieldType.Kind == GraphQlTypeKindEnum || fieldType.Kind == GraphQlTypeKindScalar)
                {
                    builder.Append($"    public {className} With{NamingHelper.ToPascalCase(field.Name)}({methodParameters})");

                    if (requiresFullBody)
                    {
                        builder.AppendLine();
                        builder.AppendLine("    {");
                        AppendArgumentDictionary(builder, args);
                    }
                    else
                    {
                        builder.Append(" => ");
                    }

                    builder.Append($"{returnPrefix}WithScalarField(\"{field.Name}\"");

                    if (args.Length > 0)
                    {
                        builder.Append(", args");
                    }

                    builder.AppendLine(");");

                    if (requiresFullBody)
                    {
                        builder.AppendLine("    }");
                    }
                }
                else
                {
                    if (String.IsNullOrEmpty(fieldType.Name))
                    {
                        throw new InvalidOperationException($"Field '{field.Name}' type name not resolved. ");
                    }

                    var builderParameterName = NamingHelper.LowerFirst(fieldType.Name);
                    builder.Append($"    public {className} With{NamingHelper.ToPascalCase(field.Name)}({fieldType.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix} {builderParameterName}QueryBuilder");

                    if (args.Length > 0)
                    {
                        builder.Append(", ");
                        builder.Append(methodParameters);
                    }

                    builder.Append(")");

                    if (requiresFullBody)
                    {
                        builder.AppendLine();
                        builder.AppendLine("    {");
                    }
                    else
                    {
                        builder.Append(" => ");
                    }

                    AppendArgumentDictionary(builder, args);

                    builder.Append($"{returnPrefix}WithObjectField(\"{field.Name}\", {builderParameterName}QueryBuilder");

                    if (args.Length > 0)
                    {
                        builder.Append(", args");
                    }

                    builder.AppendLine(");");

                    if (requiresFullBody)
                    {
                        builder.AppendLine("    }");
                    }
                }

                if (i < fields.Length - 1)
                {
                    builder.AppendLine();
                }
            }

            builder.AppendLine("}");
        }
Beispiel #3
0
 private static string GetBackingFieldName(string graphQlFieldName) => "_" + NamingHelper.LowerFirst(NamingHelper.ToPascalCase(graphQlFieldName));