Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }