예제 #1
0
        public void Generate()
        {
            _context.Register(_query);

            GenerateEnumTypes();

            var backlog = new Queue <FieldSelection>();

            foreach (var operation in
                     _document.Definitions.OfType <OperationDefinitionNode>())
            {
                Path root = Path.New(operation.Name !.Value);

                ObjectType operationType =
                    _schema.GetOperationType(operation.Operation);

                ICodeDescriptor resultType =
                    GenerateOperationSelectionSet(
                        operationType, operation, root, backlog);

                while (backlog.Any())
                {
                    FieldSelection current = backlog.Dequeue();
                    Path           path    = current.Path.Append(current.ResponseName);

                    if (!current.Field.Type.NamedType().IsLeafType())
                    {
                        GenerateFieldSelectionSet(
                            operation, current.Field.Type,
                            current.Selection, path, backlog);
                    }
                }

                GenerateResultParserDescriptor(operation, resultType);
            }

            var clientDescriptor = new ClientDescriptor(
                _context.ClientName,
                _namespace,
                _context.Descriptors.OfType <IOperationDescriptor>().ToList());

            var servicesDescriptor = new ServicesDescriptor(
                _context.ClientName + "ServiceCollectionExtensions",
                _context.Namespace,
                clientDescriptor,
                _context.Descriptors.OfType <IInputClassDescriptor>().ToList(),
                _context.Descriptors.OfType <IEnumDescriptor>().ToList(),
                _context.Descriptors.OfType <IResultParserDescriptor>().ToList());

            _context.Register(clientDescriptor);
            _context.Register(servicesDescriptor);

            FieldTypes  = _context.FieldTypes;
            Descriptors = _context.Descriptors;
        }
예제 #2
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));
        }
예제 #3
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);
        }
예제 #4
0
        public ICodeDescriptor Generate(IModelGeneratorContext context, EnumType enumType)
        {
            var values = new List <EnumValueDescriptor>();

            foreach (EnumValue value in enumType.Values)
            {
                IDirective directive = value.Directives.FirstOrDefault(t =>
                                                                       t.Name.Equals(GeneratorDirectives.Name) &&
                                                                       t.GetArgument <string>(GeneratorDirectives.ValueArgument) != null);

                string name = directive is null
                    ? GetPropertyName(value.Name.ToLowerInvariant())
                    : directive.GetArgument <string>(GeneratorDirectives.ValueArgument);

                values.Add(new EnumValueDescriptor(name, value.Name));
            }

            NameString typeName = context.GetOrCreateName(
                enumType.SyntaxNode,
                GetClassName(enumType.Name));

            var descriptor = new EnumDescriptor(
                typeName,
                context.Namespace,
                values);

            context.Register(descriptor);

            return(descriptor);
        }
예제 #5
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);
        }
예제 #6
0
        public ICodeDescriptor Generate(
            IModelGeneratorContext context,
            ObjectType operationType,
            OperationDefinitionNode operation,
            ICodeDescriptor resultType)
        {
            var arguments = new List <Descriptors.IArgumentDescriptor>();

            foreach (VariableDefinitionNode variableDefinition in
                     operation.VariableDefinitions)
            {
                string typeName = variableDefinition.Type.NamedType().Name.Value;

                if (!context.Schema.TryGetType(typeName, out INamedType namedType))
                {
                    throw new InvalidOperationException(
                              $"The variable type `{typeName}` is not supported by the schema.");
                }

                IType type = variableDefinition.Type.ToType(namedType);
                IInputClassDescriptor?inputClassDescriptor = null;

                if (namedType is InputObjectType inputObjectType)
                {
                    inputClassDescriptor = GenerateInputObjectType(context, inputObjectType);
                }

                arguments.Add(new ArgumentDescriptor(
                                  variableDefinition.Variable.Name.Value,
                                  type,
                                  variableDefinition,
                                  inputClassDescriptor));
            }

            string operationName = context.GetOrCreateName(
                operation,
                GetClassName(operation.Name !.Value) + "Operation");

            var descriptor = new OperationDescriptor(
                operationName,
                context.Namespace,
                operationType,
                operation,
                arguments,
                context.Query,
                resultType);

            context.Register(descriptor);

            return(descriptor);
        }
        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);
        }
예제 #8
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));
        }
예제 #9
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));
            }
        }
        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));
            }
        }