public async Task WriteAsync(
            CodeWriter writer,
            ICodeDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            await WriteUsings(writer, _innerGenerator).ConfigureAwait(false);

            await writer.WriteLineAsync().ConfigureAwait(false);

            await writer.WriteAsync($"namespace {_namespace}").ConfigureAwait(false);

            await writer.WriteLineAsync().ConfigureAwait(false);

            await writer.WriteAsync('{').ConfigureAwait(false);

            await writer.WriteLineAsync().ConfigureAwait(false);

            using (writer.IncreaseIndent())
            {
                await _innerGenerator.WriteAsync(
                    writer, descriptor, typeLookup)
                .ConfigureAwait(false);
            }

            await writer.WriteAsync('}').ConfigureAwait(false);

            await writer.WriteLineAsync().ConfigureAwait(false);
        }
        public Task WriteAsync(
            CodeWriter writer,
            ICodeDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            if (typeLookup is null)
            {
                throw new ArgumentNullException(nameof(typeLookup));
            }

            if (descriptor is T t)
            {
                return(WriteAsync(writer, t, typeLookup));
            }

            throw new ArgumentException(
                      "The code generator expected " +
                      $"descriptor type `{typeof(T).FullName}`.");
        }
        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;
        }
Beispiel #4
0
 public void Register(
     ICodeDescriptor descriptor,
     ICodeGenerator generator)
 {
     _tasks.Add(new GeneratorTask
     {
         Descriptor = descriptor,
         Generator  = new NamespaceGenerator(
             generator,
             ((IHasNamespace)descriptor).Namespace)
     });
 }
        public void Register(FieldNode field, ICodeDescriptor descriptor)
        {
            if (!_descriptors.TryGetValue(descriptor.Name, out ICodeDescriptor? d))
            {
                d = descriptor;
                Register(d);
            }

            if (!_fieldTypes.ContainsKey(field))
            {
                _fieldTypes.Add(field, descriptor);
            }
        }
Beispiel #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);
        }
Beispiel #7
0
        private CSharpDocument WriteDocument(
            ICodeGenerator generator,
            ICodeDescriptor descriptor,
            StringBuilder code)
        {
            code.Clear();

            using var writer = new CodeWriter(code);

            generator.Generate(writer, descriptor, out string fileName);

            writer.Flush();
            return(new(fileName, code.ToString()));
        }
Beispiel #8
0
        public void Generate(CodeWriter writer, ICodeDescriptor descriptor, out string fileName)
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            Generate(writer, (TDescriptor)descriptor, out fileName);
        }
        public CSharpSyntaxGeneratorResult Generate(
            ICodeDescriptor descriptor,
            CSharpSyntaxGeneratorSettings settings)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            if (settings is null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            return(Generate((TDescriptor)descriptor, settings));
        }
        public string CreateFileName(ICodeDescriptor descriptor)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            if (descriptor is T t)
            {
                return(CreateFileName(t));
            }

            throw new ArgumentException(
                      "The code generator expected " +
                      $"descriptor type `{typeof(T).FullName}`.");
        }
        private ICodeDescriptor GenerateOperation(
            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 (!_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(inputObjectType);
                }

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

            string operationName =
                CreateName(GetClassName(operation.Name.Value) + "Operation");

            return(new OperationDescriptor(
                       operationName,
                       _namespace,
                       operationType,
                       operation,
                       arguments,
                       _query,
                       resultType));
        }
Beispiel #12
0
        private static CSharpDocument WriteDocument(
            ICodeGenerator generator,
            ICodeDescriptor descriptor,
            StringBuilder code)
        {
            code.Clear();

            using var writer = new CodeWriter(code);

#if DEBUG
            writer.WriteLine("// " + generator.GetType().FullName);
            writer.WriteLine();
#endif

            generator.Generate(writer, descriptor, out string fileName);

            writer.Flush();
            return(new(fileName, code.ToString()));
        }
        private ICodeDescriptor GenerateOperationSelectionSet(
            ObjectType operationType,
            OperationDefinitionNode operation,
            Path path,
            Queue <FieldSelection> backlog)
        {
            PossibleSelections possibleSelections =
                _fieldCollector.CollectFields(
                    operationType,
                    operation.SelectionSet,
                    path);

            EnqueueFields(backlog, possibleSelections.ReturnType.Fields, path);

            ICodeDescriptor resultDescriptor = _objectModelGenerator.Generate(
                _context,
                operation,
                operationType,
                new NonNullType(operationType),
                new FieldNode(
                    null,
                    new NameNode(operation.Name !.Value),
                    null,
                    new[]
            {
                new DirectiveNode(
                    GeneratorDirectives.Type,
                    new ArgumentNode("name", operation.Name.Value)),
                new DirectiveNode(GeneratorDirectives.Operation)
            },
                    Array.Empty <ArgumentNode>(),
                    null),
                possibleSelections,
                path);

            _operationModelGenerator.Generate(
                _context,
                operationType,
                operation,
                resultDescriptor);

            return(resultDescriptor);
        }
Beispiel #14
0
        public ResultParserDescriptor(
            string name,
            string ns,
            OperationDefinitionNode operation,
            ICodeDescriptor resultDescriptor,
            IReadOnlyList <IResultParserMethodDescriptor> parseMethods)
        {
            Name = name
                   ?? throw new ArgumentNullException(nameof(name));
            Namespace = ns ?? throw new ArgumentNullException(nameof(ns));
            Operation = operation
                        ?? throw new ArgumentNullException(nameof(operation));
            ResultDescriptor = resultDescriptor
                               ?? throw new ArgumentNullException(nameof(resultDescriptor));
            ParseMethods = parseMethods
                           ?? throw new ArgumentNullException(nameof(parseMethods));

            InvolvedLeafTypes = CollectLeafTypes(parseMethods);
        }
        public void Generate()
        {
            RegisterDescriptor(_query);

            var  backlog = new Queue <FieldSelection>();
            Path root    = Path.New("root");

            foreach (var operation in
                     _document.Definitions.OfType <OperationDefinitionNode>())
            {
                ObjectType operationType =
                    _schema.GetOperationType(operation.Operation);

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

                RegisterDescriptor(GenerateOperation(
                                       operationType, operation, resultDescriptor));

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

                    GenerateFieldSelectionSet(
                        operation, current.Field.Type,
                        current.Selection, path, backlog);
                }

                RegisterDescriptor(
                    CreateResultParserDescriptor(operation, resultDescriptor));
            }

            RegisterDescriptor(new ClientDescriptor(
                                   _clientName,
                                   _namespace,
                                   _descriptors.Values.OfType <IOperationDescriptor>().ToList()));

            FieldTypes  = _fieldTypes.ToDictionary(t => t.Key, t => t.Value.Name);
            Descriptors = _descriptors.Values;
        }
        public void Register(ICodeDescriptor descriptor)
        {
            var queue = new Queue <ICodeDescriptor>();

            queue.Enqueue(descriptor);

            while (queue.Count > 0)
            {
                ICodeDescriptor current = queue.Dequeue();

                if (!_descriptors.ContainsKey(current.Name))
                {
                    _descriptors.Add(current.Name, current);

                    foreach (ICodeDescriptor child in current.GetChildren())
                    {
                        queue.Enqueue(child);
                    }
                }
            }
        }
        private IResultParserDescriptor CreateResultParserDescriptor(
            OperationDefinitionNode operation,
            ICodeDescriptor resultDescriptor)
        {
            string name = resultDescriptor is IInterfaceDescriptor
                ? resultDescriptor.Name.Substring(1)
                : resultDescriptor.Name;

            name += "ResultParser";

            return(new ResultParserDescriptor
                   (
                       name,
                       _namespace,
                       operation,
                       resultDescriptor,
                       _descriptors.Values
                       .OfType <IResultParserMethodDescriptor>()
                       .Where(t => t.Operation == operation).ToList()
                   ));
        }
        private void GenerateResultParserDescriptor(
            OperationDefinitionNode operation,
            ICodeDescriptor resultDescriptor)
        {
            string name = resultDescriptor is IInterfaceDescriptor
                ? resultDescriptor.Name.Substring(1)
                : resultDescriptor.Name;

            name += "ResultParser";

            _context.Register(new ResultParserDescriptor
                              (
                                  name,
                                  _context.Namespace,
                                  operation,
                                  resultDescriptor,
                                  _context.Descriptors
                                  .OfType <IResultParserMethodDescriptor>()
                                  .Where(t => t.Operation == operation).ToList()
                              ));
        }
Beispiel #19
0
        public CSharpSyntaxGeneratorResult Generate(
            ICodeDescriptor descriptor,
            CSharpSyntaxGeneratorSettings settings)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            if (settings is null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            var code = new StringBuilder();

            using var stringWriter = new StringWriter(code);
            using var codeWriter   = new CodeWriter(stringWriter);

            Generate(
                (TDescriptor)descriptor,
                settings,
                codeWriter,
                out var fileName,
                out var path,
                out var ns);

            codeWriter.Flush();

            var        sourceText = SourceText.From(code.ToString());
            SyntaxTree tree       = CSharpSyntaxTree.ParseText(sourceText);

            return(new CSharpSyntaxGeneratorResult(
                       fileName,
                       path,
                       ns,
                       tree.GetRoot().DescendantNodes().OfType <BaseTypeDeclarationSyntax>().First()));
        }
Beispiel #20
0
 public OperationDescriptor(
     string name,
     string ns,
     ObjectType operationType,
     OperationDefinitionNode operation,
     IReadOnlyList <IArgumentDescriptor> arguments,
     IQueryDescriptor query,
     ICodeDescriptor resultType)
 {
     Name = name
            ?? throw new ArgumentNullException(nameof(name));
     Namespace     = ns ?? throw new ArgumentNullException(nameof(ns));
     OperationType = operationType
                     ?? throw new ArgumentNullException(nameof(operationType));
     Operation = operation
                 ?? throw new ArgumentNullException(nameof(operation));
     Arguments = arguments
                 ?? throw new ArgumentNullException(nameof(arguments));
     Query = query
             ?? throw new ArgumentNullException(nameof(query));
     ResultType = resultType
                  ?? throw new ArgumentNullException(nameof(resultType));
 }
 public bool CanHandle(ICodeDescriptor descriptor) =>
 descriptor is TDescriptor d && CanHandle(d);
Beispiel #22
0
 public void Register(ICodeDescriptor descriptor)
 {
     Register(descriptor, false);
 }
 public string CreateFileName(ICodeDescriptor descriptor) =>
 _innerGenerator.CreateFileName(descriptor);
 public bool CanHandle(ICodeDescriptor descriptor) =>
 _innerGenerator.CanHandle(descriptor);
 public Task WriteAsync(
     CodeWriter writer,
     ICodeDescriptor descriptor) =>
 WriteAsync(writer, (TDescriptor)descriptor);
 public bool CanHandle(ICodeDescriptor descriptor)
 {
     return(descriptor is T);
 }
 public bool CanHandle(
     ICodeDescriptor descriptor,
     CSharpSyntaxGeneratorSettings settings) =>
 descriptor is TDescriptor d && CanHandle(d, settings);
 public GeneratorTask(ICodeDescriptor descriptor, ICodeGenerator generator)
 {
     Descriptor = descriptor;
     Generator  = generator;
 }