Esempio n. 1
0
        private IReadOnlyList <ComplexOutputTypeModel> CreateChildInterfaceModels(
            IDocumentAnalyzerContext context,
            IFragmentNode fragmentNode,
            Path path,
            Stack <ISet <string> > levels,
            ISet <string> implementedFields)
        {
            if (fragmentNode.Children.Count == 0)
            {
                return(Array.Empty <ComplexOutputTypeModel>());
            }

            var implementedByChildren = new HashSet <string>();

            levels.Push(implementedByChildren);

            var implements = new List <ComplexOutputTypeModel>();

            foreach (IFragmentNode child in fragmentNode.Children)
            {
                implements.Add(CreateInterfaceModel(context, child, path, levels));
            }

            levels.Pop();

            foreach (string fieldName in implementedByChildren)
            {
                implementedFields.Add(fieldName);
            }

            return(implements);
        }
Esempio n. 2
0
        protected ComplexOutputTypeModel CreateClassModel(
            IDocumentAnalyzerContext context,
            IFragmentNode returnTypeFragment,
            ComplexOutputTypeModel returnType,
            SelectionInfo selection,
            Path path)
        {
            var fieldNames = new HashSet <string>(
                selection.Fields.Select(t => GetPropertyName(t.ResponseName)));

            string className = context.GetOrCreateName(
                returnTypeFragment.Fragment.SelectionSet,
                GetClassName(returnTypeFragment.Name),
                fieldNames);

            var modelClass = new ComplexOutputTypeModel(
                className,
                returnTypeFragment.Fragment.TypeCondition.Description,
                false,
                returnTypeFragment.Fragment.TypeCondition,
                returnTypeFragment.Fragment.SelectionSet,
                new[] { returnType },
                CreateFields(
                    (IComplexOutputType)returnTypeFragment.Fragment.TypeCondition,
                    selection.SelectionSet.Selections,
                    n => true,
                    path));

            context.Register(modelClass);

            return(modelClass);
        }
        public override void Analyze(
            IDocumentAnalyzerContext context,
            OperationDefinitionNode operation,
            FieldNode fieldSelection,
            PossibleSelections possibleSelections,
            IType fieldType,
            InterfaceType namedType,
            Path path)
        {
            IFragmentNode returnTypeFragment =
                ResolveReturnType(
                    namedType,
                    fieldSelection,
                    possibleSelections.ReturnType);

            ComplexOutputTypeModel returnType =
                CreateInterfaceModel(
                    context,
                    returnTypeFragment,
                    path);

            CreateClassModels(
                context,
                operation,
                fieldSelection,
                possibleSelections,
                returnTypeFragment,
                returnType,
                fieldType,
                path);
        }
Esempio n. 4
0
        private void CreateClassModels(
            IModelGeneratorContext context,
            OperationDefinitionNode operation,
            IType fieldType,
            FieldNode fieldSelection,
            PossibleSelections possibleSelections,
            IFragmentNode returnType,
            IInterfaceDescriptor interfaceDescriptor,
            Path path)
        {
            var resultParserTypes = new List <ResultParserTypeDescriptor>();
            IReadOnlyCollection <SelectionInfo> selections = possibleSelections.Variants;

            CreateClassModels(
                context,
                fieldSelection,
                returnType,
                interfaceDescriptor,
                selections,
                resultParserTypes,
                path);

            context.Register(
                new ResultParserMethodDescriptor(
                    GetPathName(path),
                    operation,
                    fieldType,
                    fieldSelection,
                    path,
                    interfaceDescriptor,
                    resultParserTypes));
        }
        private IReadOnlyList <IInterfaceDescriptor> CreateChildInterfaceModels(
            IModelGeneratorContext context,
            IFragmentNode fragmentNode,
            Path path,
            Stack <ISet <string> > levels,
            ISet <string> implementedFields)
        {
            var implementedByChildren = new HashSet <string>();

            levels.Push(implementedByChildren);

            var implements = new List <IInterfaceDescriptor>();

            foreach (IFragmentNode child in fragmentNode.Children)
            {
                implements.Add(CreateInterfaceModel(context, child, path, levels));
            }

            levels.Pop();

            foreach (string fieldName in implementedByChildren)
            {
                implementedFields.Add(fieldName);
            }

            return(implements);
        }
Esempio n. 6
0
        public override ICodeDescriptor Generate(
            IModelGeneratorContext context,
            OperationDefinitionNode operation,
            UnionType namedType,
            IType fieldType,
            FieldNode fieldSelection,
            PossibleSelections possibleSelections,
            Path path)
        {
            IFragmentNode returnType = ResolveReturnType(
                context,
                namedType,
                fieldSelection,
                possibleSelections.ReturnType);

            IInterfaceDescriptor interfaceDescriptor = CreateInterfaceModel(
                context, returnType, path);

            context.Register(fieldSelection, interfaceDescriptor);

            CreateClassModels(
                context,
                operation,
                fieldType,
                fieldSelection,
                possibleSelections,
                returnType,
                interfaceDescriptor,
                path);

            return(interfaceDescriptor);
        }
        private InterfaceDescriptor CreateInterface(
            IFragmentNode fragmentNode,
            Path path)
        {
            var levels = new Stack <HashSet <string> >();

            levels.Push(new HashSet <string>());
            return(CreateInterface(fragmentNode, path, levels));
        }
        private InterfaceDescriptor CreateInterface(
            IFragmentNode fragmentNode,
            Path path,
            Stack <HashSet <string> > levels)
        {
            HashSet <string> implementedFields = levels.Peek();

            var implementedByChildren = new HashSet <string>();

            levels.Push(implementedByChildren);

            var implements = new List <IInterfaceDescriptor>();

            foreach (IFragmentNode child in fragmentNode.Children)
            {
                implements.Add(CreateInterface(child, path, levels));
            }

            levels.Pop();

            foreach (string fieldName in implementedByChildren)
            {
                implementedFields.Add(fieldName);
            }

            IReadOnlyList <IFieldDescriptor> fieldDescriptors =
                Array.Empty <IFieldDescriptor>();

            if (fragmentNode.Fragment.TypeCondition is IComplexOutputType type)
            {
                fieldDescriptors = CreateFields(
                    type,
                    fragmentNode.Fragment.SelectionSet.Selections,
                    name =>
                {
                    if (implementedByChildren.Add(name))
                    {
                        implementedFields.Add(name);
                        return(true);
                    }
                    return(false);
                },
                    path);
            }

            string typeName = CreateName(
                Utilities.NameUtils.GetInterfaceName(
                    fragmentNode.Fragment.Name));

            return(new InterfaceDescriptor(
                       typeName,
                       _namespace,
                       fragmentNode.Fragment.TypeCondition,
                       fieldDescriptors,
                       implements));
        }
Esempio n. 9
0
        protected ComplexOutputTypeModel CreateInterfaceModel(
            IDocumentAnalyzerContext context,
            IFragmentNode returnTypeFragment,
            Path path)
        {
            var levels = new Stack <ISet <string> >();

            levels.Push(new HashSet <string>());
            return(CreateInterfaceModel(context, returnTypeFragment, path, levels));
        }
Esempio n. 10
0
        private ComplexOutputTypeModel CreateInterfaceModel(
            IDocumentAnalyzerContext context,
            IFragmentNode fragmentNode,
            Path path,
            Stack <ISet <string> > levels)
        {
            NameString name = context.GetOrCreateName(
                fragmentNode.Fragment.SelectionSet,
                GetInterfaceName(fragmentNode.Name));

            if (context.TryGetModel(name, out ComplexOutputTypeModel? typeModel))
            {
                return(typeModel);
            }

            ISet <string> implementedFields = levels.Peek();
            IReadOnlyList <OutputFieldModel> fieldModels = Array.Empty <OutputFieldModel>();

            IReadOnlyList <ComplexOutputTypeModel> implements =
                CreateChildInterfaceModels(
                    context,
                    fragmentNode,
                    path,
                    levels,
                    implementedFields);

            if (fragmentNode.Fragment.TypeCondition is IComplexOutputType type)
            {
                fieldModels = CreateFields(
                    type,
                    fragmentNode.Fragment.SelectionSet.Selections,
                    name =>
                {
                    if (implementedFields.Add(name))
                    {
                        return(true);
                    }
                    return(false);
                },
                    path);
            }

            typeModel = new ComplexOutputTypeModel(
                name,
                fragmentNode.Fragment.TypeCondition.Description,
                true,
                fragmentNode.Fragment.TypeCondition,
                fragmentNode.Fragment.SelectionSet,
                implements,
                fieldModels);

            context.Register(typeModel);

            return(typeModel);
        }
Esempio n. 11
0
        private ICodeDescriptor GenerateObjectSelectionSet(
            OperationDefinitionNode operation,
            ObjectType objectType,
            IType fieldType,
            WithDirectives fieldOrOperation,
            FieldCollectionResult typeCase,
            Path path)
        {
            IFragmentNode returnType = HoistFragment(
                objectType, typeCase.SelectionSet, typeCase.Fragments);

            IReadOnlyList <IFragmentNode> fragments;
            string className;

            if (returnType is null)
            {
                fragments = typeCase.Fragments;
                className = CreateName(fieldOrOperation, objectType, GetClassName);
            }
            else
            {
                fragments = returnType.Children;
                className = CreateName(GetClassName(returnType.Fragment.Name));
            }

            var modelSelectionSet = new SelectionSetNode(
                typeCase.Fields.Select(t => t.Selection).ToList());

            var modelFragment = new FragmentNode(new Fragment(
                                                     className, objectType, modelSelectionSet));

            modelFragment.Children.AddRange(fragments);

            IInterfaceDescriptor modelInterface =
                CreateInterface(modelFragment, path);

            var modelClass = new ClassDescriptor(
                className, _namespace, typeCase.Type, modelInterface);

            RegisterDescriptor(modelInterface);
            RegisterDescriptor(modelClass);

            RegisterDescriptor(
                new ResultParserMethodDescriptor(
                    GetPathName(path),
                    operation,
                    fieldType,
                    fieldOrOperation as FieldNode,
                    path,
                    modelInterface,
                    new[] { new ResultParserTypeDescriptor(modelClass) }));

            return(modelInterface);
        }
Esempio n. 12
0
        private ICodeDescriptor GenerateInterfaceSelectionSet(
            OperationDefinitionNode operation,
            InterfaceType interfaceType,
            IType fieldType,
            FieldNode fieldSelection,
            IReadOnlyCollection <FieldCollectionResult> typeCases,
            Path path)
        {
            FieldCollectionResult firstCase = typeCases.First();

            IFragmentNode returnType = HoistFragment(
                interfaceType, firstCase.SelectionSet, firstCase.Fragments);

            InterfaceDescriptor interfaceDescriptor;

            if (returnType is null)
            {
                firstCase = _fieldCollector.CollectFields(
                    interfaceType, firstCase.SelectionSet, path);
                string name = CreateName(fieldSelection, interfaceType, GetClassName);

                var interfaceSelectionSet = new SelectionSetNode(
                    firstCase.Fields.Select(t => t.Selection).ToList());

                returnType = new FragmentNode(new Fragment(
                                                  name, interfaceType, interfaceSelectionSet));
                _usedNames.Remove(name);
            }

            interfaceDescriptor = CreateInterface(returnType, path);

            var resultParserTypes = new List <ResultParserTypeDescriptor>();

            foreach (FieldCollectionResult typeCase in typeCases)
            {
                GenerateInterfaceTypeCaseModel(
                    typeCase, returnType, resultParserTypes, path);
            }

            RegisterDescriptor(interfaceDescriptor);

            RegisterDescriptor(
                new ResultParserMethodDescriptor(
                    GetPathName(path),
                    operation,
                    fieldType,
                    fieldSelection,
                    path,
                    interfaceDescriptor,
                    resultParserTypes));

            return(interfaceDescriptor);
        }
Esempio n. 13
0
        private void GenerateInterfaceTypeCaseModel(
            FieldCollectionResult typeCase,
            IFragmentNode returnType,
            ICollection <ResultParserTypeDescriptor> resultParser,
            Path path)
        {
            string className;
            IReadOnlyList <IFragmentNode> fragments;

            IFragmentNode modelType = HoistFragment(
                (ObjectType)typeCase.Type,
                typeCase.SelectionSet,
                typeCase.Fragments);

            if (modelType is null)
            {
                fragments = typeCase.Fragments;
                className = CreateName(GetClassName(typeCase.Type.Name));
            }
            else
            {
                fragments = modelType.Children;
                className = CreateName(GetClassName(modelType.Fragment.Name));
            }

            var modelSelectionSet = new SelectionSetNode(
                typeCase.Fields.Select(t => t.Selection).ToList());

            var modelFragment = new FragmentNode(new Fragment(
                                                     className, typeCase.Type, modelSelectionSet));

            modelFragment.Children.AddRange(fragments);
            if (modelFragment.Children.All(t =>
                                           t.Fragment.SelectionSet != returnType.Fragment.SelectionSet))
            {
                modelFragment.Children.Add(returnType);
            }

            IInterfaceDescriptor modelInterface =
                CreateInterface(modelFragment, path);

            var modelClass = new ClassDescriptor(
                className, _namespace, typeCase.Type, modelInterface);


            RegisterDescriptor(modelInterface);
            RegisterDescriptor(modelClass);

            resultParser.Add(new ResultParserTypeDescriptor(modelClass));
        }
        private void CreateClassModels(
            IDocumentAnalyzerContext context,
            OperationDefinitionNode operation,
            FieldNode fieldSelection,
            PossibleSelections possibleSelections,
            IFragmentNode returnTypeFragment,
            ComplexOutputTypeModel returnType,
            IType fieldType,
            Path path)
        {
            IReadOnlyCollection <SelectionInfo> selections = possibleSelections.Variants;

            if (selections.Count == 1)
            {
                ComplexOutputTypeModel modelType = CreateClassModel(
                    context,
                    returnTypeFragment,
                    returnType,
                    selections.Single(),
                    path);

                CreateFieldParserModel(
                    context,
                    operation,
                    fieldSelection,
                    path,
                    returnType,
                    fieldType,
                    modelType);
            }
            else
            {
                IReadOnlyList <ComplexOutputTypeModel> modelTypes =
                    CreateClassModels(
                        context,
                        returnType,
                        fieldSelection,
                        selections,
                        path);

                CreateFieldParserModel(
                    context,
                    operation,
                    fieldSelection,
                    path,
                    returnType,
                    fieldType,
                    modelTypes);
            }
        }
        protected IInterfaceDescriptor CreateInterfaceModel(
            IModelGeneratorContext context,
            IFragmentNode fragmentNode,
            Path path)
        {
            var levels = new Stack <ISet <string> >();

            levels.Push(new HashSet <string>());
            return(CreateInterfaceModel(
                       context,
                       fragmentNode,
                       path,
                       levels));
        }
        private IInterfaceDescriptor CreateInterfaceModel(
            IModelGeneratorContext context,
            IFragmentNode fragmentNode,
            Path path,
            Stack <ISet <string> > levels)
        {
            ISet <string> implementedFields = levels.Peek();
            IReadOnlyList <IFieldDescriptor> fieldDescriptors =
                Array.Empty <IFieldDescriptor>();

            IReadOnlyList <IInterfaceDescriptor> implements =
                CreateChildInterfaceModels(
                    context,
                    fragmentNode,
                    path,
                    levels,
                    implementedFields);

            if (fragmentNode.Fragment.TypeCondition is IComplexOutputType type)
            {
                fieldDescriptors = CreateFields(
                    type,
                    fragmentNode.Fragment.SelectionSet.Selections,
                    name =>
                {
                    if (implementedFields.Add(name))
                    {
                        return(true);
                    }
                    return(false);
                },
                    path);
            }

            NameString interfaceName = context.GetOrCreateName(
                fragmentNode.Fragment.SelectionSet,
                GetInterfaceName(fragmentNode.Name));

            var descriptor = new InterfaceDescriptor(
                interfaceName,
                context.Namespace,
                fragmentNode.Fragment.TypeCondition,
                fieldDescriptors,
                implements);

            context.Register(descriptor);
            return(descriptor);
        }
Esempio n. 17
0
        protected void CreateClassModel(
            IModelGeneratorContext context,
            IFragmentNode returnType,
            IInterfaceDescriptor interfaceDescriptor,
            SelectionInfo selection,
            List <ResultParserTypeDescriptor> resultParserTypes)
        {
            var modelClass = new ClassDescriptor(
                GetClassName(returnType.Name),
                context.Namespace,
                selection.Type,
                new[] { interfaceDescriptor });

            context.Register(modelClass);
            resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass));
        }
Esempio n. 18
0
        protected static IFragmentNode HoistFragment(
            INamedType type,
            IFragmentNode fragmentNode)
        {
            (SelectionSetNode s, IReadOnlyList <IFragmentNode> f)current =
                (fragmentNode.Fragment.SelectionSet, fragmentNode.Children);
            IFragmentNode selected = fragmentNode;

            while (!current.s.Selections.OfType <FieldNode>().Any() &&
                   current.f.Count == 1 &&
                   TypeHelpers.DoesTypeApply(current.f[0].Fragment.TypeCondition, type))
            {
                selected = current.f[0];
                current  = (selected.Fragment.SelectionSet, selected.Children);
            }

            return(selected);
        }
Esempio n. 19
0
        private IFragmentNode HoistFragment(
            INamedType typeContext,
            SelectionSetNode selectionSet,
            IReadOnlyList <IFragmentNode> fragments)
        {
            (SelectionSetNode s, IReadOnlyList <IFragmentNode> f)current =
                (selectionSet, fragments);
            IFragmentNode selected = null;

            while (!current.s.Selections.OfType <FieldNode>().Any() &&
                   current.f.Count == 1 &&
                   current.f[0].Fragment.TypeCondition == typeContext)
            {
                selected = current.f[0];
                current  = (selected.Fragment.SelectionSet, selected.Children);
            }

            return(selected);
        }
Esempio n. 20
0
        protected void CreateClassModels(
            IModelGeneratorContext context,
            FieldNode fieldSelection,
            IFragmentNode returnType,
            IInterfaceDescriptor interfaceDescriptor,
            IReadOnlyCollection <SelectionInfo> selections,
            List <ResultParserTypeDescriptor> resultParserTypes,
            Path path)
        {
            foreach (SelectionInfo selection in selections)
            {
                IFragmentNode modelType = ResolveReturnType(
                    context,
                    selection.Type,
                    fieldSelection,
                    selection);

                var interfaces = new List <IInterfaceDescriptor>();

                foreach (IFragmentNode fragment in
                         ShedNonMatchingFragments(selection.Type, modelType))
                {
                    interfaces.Add(CreateInterfaceModel(context, fragment, path));
                }

                interfaces.Insert(0, interfaceDescriptor);

                NameString typeName = HoistName(selection.Type, modelType);

                string className = context.GetOrCreateName(
                    modelType.Fragment.SelectionSet,
                    GetClassName(typeName));

                var modelClass = new ClassDescriptor(
                    className,
                    context.Namespace,
                    selection.Type,
                    interfaces);

                context.Register(modelClass);
                resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass));
            }
        }
Esempio n. 21
0
        protected NameString HoistName(
            INamedType type,
            IFragmentNode fragmentNode)
        {
            if (fragmentNode.Fragment.TypeCondition.Name.EqualsOrdinal(type.Name))
            {
                return(fragmentNode.Name);
            }
            else
            {
                foreach (IFragmentNode child in fragmentNode.Children)
                {
                    NameString name = HoistName(type, child);
                    if (name.HasValue)
                    {
                        return(name);
                    }
                }

                return(default);
Esempio n. 22
0
        public override ICodeDescriptor Generate(
            IModelGeneratorContext context,
            OperationDefinitionNode operation,
            ObjectType namedType,
            IType fieldType,
            FieldNode fieldSelection,
            PossibleSelections possibleSelections,
            Path path)
        {
            IFragmentNode returnType = ResolveReturnType(
                context,
                namedType,
                fieldSelection,
                possibleSelections.ReturnType);

            IInterfaceDescriptor interfaceDescriptor = CreateInterfaceModel(
                context, returnType, path);

            context.Register(fieldSelection, interfaceDescriptor);

            var resultParserTypes = new List <ResultParserTypeDescriptor>();

            CreateClassModel(
                context,
                returnType,
                interfaceDescriptor,
                possibleSelections.ReturnType,
                resultParserTypes);

            context.Register(
                new ResultParserMethodDescriptor(
                    GetPathName(path),
                    operation,
                    fieldType,
                    fieldSelection,
                    path,
                    interfaceDescriptor,
                    resultParserTypes));

            return(interfaceDescriptor);
        }
        protected void CreateClassModel(
            IModelGeneratorContext context,
            IFragmentNode returnType,
            IInterfaceDescriptor interfaceDescriptor,
            SelectionInfo selection,
            List <ResultParserTypeDescriptor> resultParserTypes)
        {
            var fieldNames = new HashSet <string>(
                selection.Fields.Select(t => GetPropertyName(t.ResponseName)));

            string className = context.GetOrCreateName(
                returnType.Fragment.SelectionSet,
                GetClassName(returnType.Name),
                fieldNames);

            var modelClass = new ClassDescriptor(
                className,
                context.Namespace,
                selection.Type,
                new[] { interfaceDescriptor });

            context.Register(modelClass);
            resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass));
        }
        protected void CreateClassModels(
            IModelGeneratorContext context,
            FieldNode fieldSelection,
            IFragmentNode returnType,
            IInterfaceDescriptor interfaceDescriptor,
            IReadOnlyCollection <SelectionInfo> selections,
            List <ResultParserTypeDescriptor> resultParserTypes,
            Path path)
        {
            foreach (SelectionInfo selection in selections)
            {
                IFragmentNode modelType = ResolveReturnType(
                    context,
                    selection.Type,
                    fieldSelection,
                    selection);

                var interfaces = new List <IInterfaceDescriptor>();

                foreach (IFragmentNode fragment in
                         ShedNonMatchingFragments(selection.Type, modelType))
                {
                    interfaces.Add(CreateInterfaceModel(context, fragment, path));
                }

                interfaces.Insert(0, interfaceDescriptor);

                NameString typeName = HoistName(selection.Type, modelType);
                if (typeName.IsEmpty)
                {
                    typeName = selection.Type.Name;
                }

                bool update = false;

                var fieldNames = new HashSet <string>(
                    selection.Fields.Select(t => GetPropertyName(t.ResponseName)));

                string className = context.GetOrCreateName(
                    modelType.Fragment.SelectionSet,
                    GetClassName(typeName),
                    fieldNames);

                if (context.TryGetDescriptor(className, out ClassDescriptor? modelClass))
                {
                    var interfaceNames = new HashSet <string>(interfaces.Select(t => t.Name));
                    foreach (IInterfaceDescriptor item in modelClass !.Implements.Reverse())
                    {
                        if (!interfaceNames.Contains(item.Name))
                        {
                            interfaces.Insert(0, item);
                        }
                    }
                    update = true;
                }

                modelClass = new ClassDescriptor(
                    className,
                    context.Namespace,
                    selection.Type,
                    interfaces);

                context.Register(modelClass, update);
                resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass));
            }
        }
Esempio n. 25
0
        protected IReadOnlyList <ComplexOutputTypeModel> CreateClassModels(
            IDocumentAnalyzerContext context,
            ComplexOutputTypeModel returnType,
            FieldNode fieldSelection,
            IReadOnlyCollection <SelectionInfo> selections,
            Path path)
        {
            var possibleModelTypes = new List <ComplexOutputTypeModel>();

            foreach (SelectionInfo selection in selections)
            {
                IFragmentNode modelType = ResolveReturnType(
                    selection.Type, fieldSelection, selection);

                var interfaces = new List <ComplexOutputTypeModel>();

                foreach (IFragmentNode fragment in ShedNonMatchingFragments(
                             selection.Type, modelType))
                {
                    interfaces.Add(CreateInterfaceModel(context, fragment, path));
                }

                interfaces.Insert(0, returnType);

                NameString typeName = HoistName(selection.Type, modelType);

                if (typeName.IsEmpty)
                {
                    typeName = selection.Type.Name;
                }

                bool update = false;

                var fieldNames = new HashSet <string>(
                    selection.Fields.Select(t => GetPropertyName(t.ResponseName)));

                string className = context.GetOrCreateName(
                    modelType.Fragment.SelectionSet,
                    GetClassName(typeName),
                    fieldNames);

                if (context.TryGetModel(className, out ComplexOutputTypeModel? model))
                {
                    var interfaceNames = new HashSet <string>(interfaces.Select(t => t.Name));
                    foreach (ComplexOutputTypeModel type in model.Types.Reverse())
                    {
                        if (interfaceNames.Add(type.Name))
                        {
                            interfaces.Insert(0, type);
                        }
                    }
                    update = true;
                }

                model = new ComplexOutputTypeModel(
                    className,
                    modelType.Fragment.TypeCondition.Description,
                    false,
                    modelType.Fragment.TypeCondition,
                    selection.SelectionSet,
                    interfaces,
                    CreateFields(
                        (IComplexOutputType)modelType.Fragment.TypeCondition,
                        selection.SelectionSet.Selections,
                        n => true,
                        path));

                context.Register(model, update);

                possibleModelTypes.Add(model);
            }

            return(possibleModelTypes);
        }
Esempio n. 26
0
        private ICodeDescriptor GenerateUnionSelectionSet(
            OperationDefinitionNode operation,
            UnionType unionType,
            IType fieldType,
            FieldNode fieldSelection,
            IReadOnlyCollection <FieldCollectionResult> typeCases,
            Path path)
        {
            IFragmentNode                 returnType = null;
            FieldCollectionResult         result     = typeCases.First();
            IReadOnlyList <IFragmentNode> fragments  = result.Fragments;

            while (fragments.Count == 1)
            {
                if (fragments[0].Fragment.TypeCondition == unionType)
                {
                    returnType = fragments[0];
                    fragments  = fragments[0].Children;
                }
                else
                {
                    break;
                }
            }

            InterfaceDescriptor unionInterface;

            if (returnType is null)
            {
                string name = CreateName(
                    fieldSelection,
                    unionType,
                    Utilities.NameUtils.GetInterfaceName);
                unionInterface = new InterfaceDescriptor(
                    name, _namespace, unionType);
            }
            else
            {
                unionInterface = CreateInterface(returnType, path);
                unionInterface = unionInterface.RemoveAllImplements();
            }

            var resultParserTypes = new List <ResultParserTypeDescriptor>();

            foreach (var typeCase in typeCases)
            {
                string className;
                string interfaceName;

                IFragmentNode fragment = typeCase.Fragments.FirstOrDefault(
                    t => t.Fragment.TypeCondition == typeCase.Type);

                if (fragment is null)
                {
                    className     = CreateName(typeCase.Type.Name);
                    interfaceName = CreateName(GetInterfaceName(className));
                }
                else
                {
                    className     = CreateName(fragment.Fragment.Name);
                    interfaceName = CreateName(GetInterfaceName(fragment.Fragment.Name));
                }

                var modelInterfaces = new List <IInterfaceDescriptor>();
                modelInterfaces.Add(
                    new InterfaceDescriptor(
                        interfaceName,
                        _namespace,
                        typeCase.Type,
                        typeCase.Fields.Select(t =>
                {
                    string responseName = (t.Selection.Alias ?? t.Selection.Name).Value;
                    return(new FieldDescriptor(
                               t.Field,
                               t.Selection,
                               t.Field.Type,
                               t.Path.Append(responseName)));
                }).ToList(),
                        new[] { unionInterface }));
                modelInterfaces.AddRange(CreateInterfaces(typeCase.Fragments, path));

                var modelClass = new ClassDescriptor(
                    className, _namespace, typeCase.Type, modelInterfaces);

                RegisterDescriptors(modelInterfaces);
                RegisterDescriptor(modelClass);

                resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass));
            }

            RegisterDescriptor(unionInterface);

            RegisterDescriptor(
                new ResultParserMethodDescriptor(
                    GetPathName(path),
                    operation,
                    fieldType,
                    fieldSelection,
                    path,
                    unionInterface,
                    resultParserTypes));

            return(unionInterface);
        }