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);
        }
Exemplo n.º 2
0
        private static void RegisterOperationModel(
            IDocumentAnalyzerContext context,
            DocumentNode document,
            OperationDefinitionNode operationDefinition)
        {
            ComplexOutputTypeModel returnType =
                context.Types.OfType <ComplexOutputTypeModel>()
                .First(t => t.SelectionSet == operationDefinition.SelectionSet && t.IsInterface);

            var parser = new ParserModel(
                context.GetOrCreateName(
                    GetClassName(operationDefinition.Name !.Value, "ResultParser")),
                operationDefinition,
                returnType,
                context.FieldParsers.Where(t => t.Operation == operationDefinition).ToList());

            var operation = new OperationModel(
                returnType.Name,
                context.Schema.GetOperationType(operationDefinition.Operation),
                document,
                operationDefinition,
                parser,
                CreateOperationArguments(context, operationDefinition));

            context.Register(operation);
        }
Exemplo n.º 3
0
        private void CreateClassModels(
            IDocumentAnalyzerContext context,
            OperationDefinitionNode operation,
            FieldNode fieldSelection,
            PossibleSelections possibleSelections,
            ComplexOutputTypeModel returnType,
            IType fieldType,
            Path path)
        {
            IReadOnlyCollection <SelectionInfo> selections = possibleSelections.Variants;

            IReadOnlyList <ComplexOutputTypeModel> modelTypes =
                CreateClassModels(
                    context,
                    returnType,
                    fieldSelection,
                    selections,
                    path);

            CreateFieldParserModel(
                context,
                operation,
                fieldSelection,
                path,
                returnType,
                fieldType,
                modelTypes);
        }
Exemplo n.º 4
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);
        }
        public OutputTypeModel AnalyzeOperation(
            IDocumentAnalyzerContext context,
            SelectionSetVariants selectionSetVariants)
        {
            Path rootSelectionPath = Path.Root.Append(context.OperationName);

            FragmentNode returnTypeFragment =
                FragmentHelper.CreateFragmentNode(
                    context.OperationType,
                    rootSelectionPath,
                    selectionSetVariants.ReturnType);

            returnTypeFragment = FragmentHelper.RewriteForConcreteType(returnTypeFragment);

            OutputTypeModel returnType =
                FragmentHelper.CreateInterface(
                    context,
                    returnTypeFragment,
                    rootSelectionPath);

            FragmentHelper.CreateClass(
                context,
                returnTypeFragment,
                selectionSetVariants.ReturnType,
                returnType);

            return(returnType);
        }
Exemplo n.º 6
0
        private static void CollectOutputTypes(IDocumentAnalyzerContext context, DocumentNode document)
        {
            var backlog = new Queue <FieldSelection>();

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

                ObjectType operationType = context.Schema.GetOperationType(operation.Operation);

                VisitOperationSelectionSet(context, operation, operationType, root, backlog);

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

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

                RegisterOperationModel(context, document, operation);
            }
        }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
0
        private static void RegisterInputObjectType(
            IDocumentAnalyzerContext context,
            InputObjectType inputObjectType)
        {
            RenameDirective?rename;
            var             fields = new List <InputFieldModel>();

            foreach (IInputField inputField in inputObjectType.Fields)
            {
                rename = inputField.Directives.SingleOrDefault <RenameDirective>();

                fields.Add(new InputFieldModel(
                               GetClassName(rename?.Name ?? inputField.Name),
                               inputField.Description,
                               inputField,
                               inputField.Type));

                context.RegisterType(inputField.Type.NamedType());
            }

            rename = inputObjectType.Directives.SingleOrDefault <RenameDirective>();

            NameString typeName = context.ResolveTypeName(
                GetClassName(rename?.Name ?? inputObjectType.Name));

            context.RegisterModel(
                typeName,
                new InputObjectTypeModel(
                    GetClassName(rename?.Name ?? inputObjectType.Name),
                    inputObjectType.Description,
                    inputObjectType,
                    fields));
        }
Exemplo n.º 9
0
 public abstract void Analyze(
     IDocumentAnalyzerContext context,
     OperationDefinitionNode operation,
     FieldNode fieldSelection,
     PossibleSelections possibleSelections,
     IType fieldType,
     T namedType,
     Path path);
Exemplo n.º 10
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));
        }
Exemplo n.º 11
0
 private static void CollectOutputTypes(
     IDocumentAnalyzerContext context,
     IEnumerable <DocumentNode> documents)
 {
     foreach (DocumentNode document in documents)
     {
         context.SetDocument(document);
         CollectOutputTypes(context, document);
     }
 }
Exemplo n.º 12
0
        private static void VisitFieldSelectionSet(
            IDocumentAnalyzerContext context,
            OperationDefinitionNode operation,
            FieldNode fieldSelection,
            IType fieldType,
            Path path,
            Queue <FieldSelection> backlog)
        {
            var namedType = (INamedOutputType)fieldType.NamedType();

            PossibleSelections possibleSelections =
                context.CollectFields(
                    namedType,
                    fieldSelection.SelectionSet !,
                    path);

            foreach (SelectionInfo selectionInfo in possibleSelections.Variants)
            {
                EnqueueFields(backlog, selectionInfo.Fields, path);
            }

            if (namedType is UnionType unionType)
            {
                _unionTypeSelectionSetAnalyzer.Analyze(
                    context,
                    operation,
                    fieldSelection,
                    possibleSelections,
                    fieldType,
                    unionType,
                    path);
            }
            else if (namedType is InterfaceType interfaceType)
            {
                _interfaceTypeSelectionSetAnalyzer.Analyze(
                    context,
                    operation,
                    fieldSelection,
                    possibleSelections,
                    fieldType,
                    interfaceType,
                    path);
            }
            else if (namedType is ObjectType objectType)
            {
                _objectTypeSelectionSetAnalyzer.Analyze(
                    context,
                    operation,
                    fieldSelection,
                    possibleSelections,
                    fieldType,
                    objectType,
                    path);
            }
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
0
 protected static FieldParserModel CreateFieldParserModel(
     IDocumentAnalyzerContext context,
     OperationDefinitionNode operation,
     FieldNode fieldSelection,
     Path path,
     ComplexOutputTypeModel returnType,
     IType fieldType,
     ComplexOutputTypeModel modelType) =>
 CreateFieldParserModel(
     context, operation, fieldSelection,
     path, returnType, fieldType, new[] { modelType });
        private OutputTypeModel AnalyzeWithDefaults(
            IDocumentAnalyzerContext context,
            FieldSelection fieldSelection,
            SelectionSetVariants selectionVariants)
        {
            FragmentNode returnTypeFragment =
                FragmentHelper.CreateFragmentNode(
                    selectionVariants.ReturnType,
                    fieldSelection.Path);

            OutputTypeModel returnType =
                FragmentHelper.CreateInterface(
                    context,
                    returnTypeFragment,
                    fieldSelection.Path);

            context.RegisterSelectionSet(
                returnType.Type,
                selectionVariants.ReturnType.SyntaxNode,
                returnType.SelectionSet);

            foreach (SelectionSet selectionSet in selectionVariants.Variants)
            {
                returnTypeFragment = FragmentHelper.CreateFragmentNode(
                    selectionSet,
                    fieldSelection.Path,
                    appendTypeName: true);

                returnTypeFragment = FragmentHelper.RewriteForConcreteType(returnTypeFragment);

                OutputTypeModel @interface =
                    FragmentHelper.CreateInterface(
                        context,
                        returnTypeFragment,
                        fieldSelection.Path,
                        new[] { returnType });

                OutputTypeModel @class =
                    FragmentHelper.CreateClass(
                        context,
                        returnTypeFragment,
                        selectionSet,
                        @interface);

                context.RegisterSelectionSet(
                    selectionSet.Type,
                    selectionSet.SyntaxNode,
                    @class.SelectionSet);
            }

            return(returnType);
        }
Exemplo n.º 16
0
        private static void CollectEnumTypes(
            IDocumentAnalyzerContext context)
        {
            var analyzer = new EnumTypeUsageAnalyzer(context.Schema);

            analyzer.Analyze(context.Document);

            foreach (EnumType enumType in analyzer.EnumTypes)
            {
                RenameDirective?rename;
                var             values = new List <EnumValueModel>();

                foreach (IEnumValue enumValue in enumType.Values)
                {
                    rename = enumValue.Directives.SingleOrDefault <RenameDirective>();

                    EnumValueDirective?value =
                        enumValue.Directives.SingleOrDefault <EnumValueDirective>();

                    values.Add(new EnumValueModel(
                                   rename?.Name ?? GetEnumValue(enumValue.Name),
                                   enumValue.Description,
                                   enumValue,
                                   value?.Value));
                }

                rename = enumType.Directives.SingleOrDefault <RenameDirective>();

                SerializationTypeDirective?serializationType =
                    enumType.Directives.SingleOrDefault <SerializationTypeDirective>();

                NameString typeName = context.ResolveTypeName(
                    rename?.Name ?? GetClassName(enumType.Name));

                context.RegisterModel(
                    typeName,
                    new EnumTypeModel(
                        typeName,
                        enumType.Description,
                        enumType,
                        serializationType?.Name,
                        values));
            }
        }
Exemplo n.º 17
0
        private static void CollectEnumTypes(
            IDocumentAnalyzerContext context,
            IEnumerable <DocumentNode> documents)
        {
            var analyzer = new EnumTypeUsageAnalyzer(context.Schema);

            foreach (DocumentNode document in documents)
            {
                analyzer.Analyze(document);
            }

            foreach (EnumType enumType in analyzer.EnumTypes)
            {
                RenameDirective?rename;
                var             values = new List <EnumValueModel>();

                foreach (EnumValue enumValue in enumType.Values)
                {
                    rename = enumValue.Directives.SingleOrDefault <RenameDirective>();

                    EnumValueDirective?value =
                        enumValue.Directives.SingleOrDefault <EnumValueDirective>();

                    values.Add(new EnumValueModel(
                                   GetClassName(rename?.Name ?? enumValue.Name),
                                   enumValue,
                                   enumValue.Description,
                                   value?.Value));
                }

                rename = enumType.Directives.SingleOrDefault <RenameDirective>();

                SerializationTypeDirective?serializationType =
                    enumType.Directives.SingleOrDefault <SerializationTypeDirective>();

                context.Register(new EnumTypeModel(
                                     GetClassName(rename?.Name ?? enumType.Name),
                                     enumType.Description,
                                     enumType,
                                     serializationType?.Name,
                                     values));
            }
        }
Exemplo n.º 18
0
        private static void CollectInputObjectTypes(
            IDocumentAnalyzerContext context)
        {
            var analyzer = new InputObjectTypeUsageAnalyzer(context.Schema);

            analyzer.Analyze(context.Document);

            foreach (INamedInputType namedInputType in analyzer.InputTypes)
            {
                if (namedInputType is InputObjectType inputObjectType)
                {
                    RegisterInputObjectType(context, inputObjectType);
                }
                else if (namedInputType is ILeafType)
                {
                    context.RegisterType(namedInputType);
                }
            }
        }
Exemplo n.º 19
0
        protected static FieldParserModel CreateFieldParserModel(
            IDocumentAnalyzerContext context,
            OperationDefinitionNode operation,
            FieldNode fieldSelection,
            Path path,
            ComplexOutputTypeModel returnType,
            IType fieldType,
            IReadOnlyList <ComplexOutputTypeModel> possibleTypes)
        {
            var parserModel = new FieldParserModel(
                operation,
                fieldSelection,
                path,
                returnType,
                fieldType,
                possibleTypes);

            context.Register(parserModel);

            return(parserModel);
        }
        public override OutputTypeModel Analyze(
            IDocumentAnalyzerContext context,
            FieldSelection fieldSelection,
            SelectionSetVariants selectionVariants)
        {
            var returnTypeFragmentName = FragmentHelper.GetReturnTypeName(fieldSelection);

            if (returnTypeFragmentName is null)
            {
                return(AnalyzeWithDefaults(
                           context,
                           fieldSelection,
                           selectionVariants));
            }

            return(AnalyzeWithHoistedFragment(
                       context,
                       fieldSelection,
                       selectionVariants,
                       returnTypeFragmentName));
        }
Exemplo n.º 21
0
        private static IReadOnlyList <ArgumentModel> CreateOperationArguments(
            IDocumentAnalyzerContext context,
            OperationDefinitionNode operationDefinition)
        {
            var arguments = new List <ArgumentModel>();

            foreach (VariableDefinitionNode variableDefinition in
                     operationDefinition.VariableDefinitions)
            {
                INamedInputType namedInputType = context.Schema.GetType <INamedInputType>(
                    variableDefinition.Type.NamedType().Name.Value);

                arguments.Add(new ArgumentModel(
                                  variableDefinition.Variable.Name.Value,
                                  (IInputType)variableDefinition.Type.ToType(namedInputType),
                                  variableDefinition,
                                  variableDefinition.DefaultValue));
            }

            return(arguments);
        }
Exemplo n.º 22
0
        private static DocumentModel CreateDocumentModel(
            IDocumentAnalyzerContext context,
            string name,
            DocumentNode original,
            IDocumentHashProvider hashProvider)
        {
            DocumentNode optimized = TypeNameQueryRewriter.Rewrite(original);

            string serialized = QuerySyntaxSerializer.Serialize(optimized, false);

            byte[] buffer = Encoding.UTF8.GetBytes(serialized);
            string hash   = hashProvider.ComputeHash(buffer);

            return(new DocumentModel(
                       name,
                       context.Operations.Where(t => t.Document == original).ToArray(),
                       original,
                       optimized,
                       buffer,
                       hashProvider.Name,
                       hash));
        }
Exemplo n.º 23
0
        private static void CollectInputObjectTypes(
            IDocumentAnalyzerContext context)
        {
            var analyzer = new InputObjectTypeUsageAnalyzer(context.Schema);

            analyzer.Analyze(context.Document);

            foreach (InputObjectType inputObjectType in analyzer.InputObjectTypes)
            {
                RenameDirective?rename;
                var             fields = new List <InputFieldModel>();

                foreach (IInputField inputField in inputObjectType.Fields)
                {
                    rename = inputField.Directives.SingleOrDefault <RenameDirective>();

                    fields.Add(new InputFieldModel(
                                   GetClassName(rename?.Name ?? inputField.Name),
                                   inputField.Description,
                                   inputField,
                                   inputField.Type));
                }

                rename = inputObjectType.Directives.SingleOrDefault <RenameDirective>();

                NameString typeName = context.ResolveTypeName(
                    GetClassName(rename?.Name ?? inputObjectType.Name));

                context.RegisterModel(
                    typeName,
                    new InputObjectTypeModel(
                        GetClassName(rename?.Name ?? inputObjectType.Name),
                        inputObjectType.Description,
                        inputObjectType,
                        fields));
            }
        }
        private static void CollectInputObjectTypes(
            IDocumentAnalyzerContext context,
            IEnumerable <DocumentNode> documents)
        {
            var analyzer = new InputObjectTypeUsageAnalyzer(context.Schema);

            foreach (DocumentNode document in documents)
            {
                analyzer.Analyze(document);
            }

            foreach (InputObjectType inputObjectType in analyzer.InputObjectTypes)
            {
                RenameDirective?rename;
                var             fields = new List <InputFieldModel>();

                foreach (IInputField inputField in inputObjectType.Fields)
                {
                    rename = inputField.Directives.SingleOrDefault <RenameDirective>();

                    fields.Add(new InputFieldModel(
                                   GetClassName(rename?.Name ?? inputField.Name),
                                   inputField.Description,
                                   inputField,
                                   inputField.Type));
                }

                rename = inputObjectType.Directives.SingleOrDefault <RenameDirective>();

                context.Register(new ComplexInputTypeModel(
                                     GetClassName(rename?.Name ?? inputObjectType.Name),
                                     inputObjectType.Description,
                                     inputObjectType,
                                     fields));
            }
        }
Exemplo n.º 25
0
        private static void VisitOperationSelectionSet(
            IDocumentAnalyzerContext context,
            OperationDefinitionNode operation,
            ObjectType operationType,
            Path path,
            Queue <FieldSelection> backlog)
        {
            PossibleSelections possibleSelections =
                context.CollectFields(
                    operationType,
                    operation.SelectionSet,
                    path);

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

            _objectTypeSelectionSetAnalyzer.Analyze(
                context,
                operation,
                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,
                new NonNullType(operationType),
                operationType,
                path);
        }
Exemplo n.º 26
0
 public abstract OutputTypeModel Analyze(
     IDocumentAnalyzerContext context,
     FieldSelection fieldSelection,
     SelectionSetVariants selectionSetVariants);
        private OutputTypeModel AnalyzeWithHoistedFragment(
            IDocumentAnalyzerContext context,
            FieldSelection fieldSelection,
            SelectionSetVariants selectionVariants,
            string fragmentName)
        {
            FragmentNode?returnTypeFragment =
                FragmentHelper.CreateFragmentNode(
                    selectionVariants.Variants[0],
                    fieldSelection.Path,
                    appendTypeName: true);

            returnTypeFragment = FragmentHelper.GetFragment(returnTypeFragment, fragmentName);

            if (returnTypeFragment is null)
            {
                // TODO : throw helper
                throw new GraphQLException(
                          "The specified return fragment does not exist.");
            }

            OutputTypeModel returnType =
                FragmentHelper.CreateInterface(context, returnTypeFragment, fieldSelection.Path);

            context.RegisterSelectionSet(
                returnType.Type,
                selectionVariants.ReturnType.SyntaxNode,
                returnType.SelectionSet);

            foreach (SelectionSet selectionSet in selectionVariants.Variants)
            {
                returnTypeFragment = FragmentHelper.CreateFragmentNode(
                    selectionSet,
                    fieldSelection.Path,
                    appendTypeName: true);

                returnTypeFragment = FragmentHelper.RewriteForConcreteType(returnTypeFragment);

                if (FragmentHelper.GetFragment(returnTypeFragment, fragmentName) is null)
                {
                    // TODO : throw helper
                    throw new GraphQLException(
                              "The specified return fragment must be implement by all type fragments.");
                }

                OutputTypeModel @interface =
                    FragmentHelper.CreateInterface(
                        context,
                        returnTypeFragment,
                        fieldSelection.Path,
                        new[] { returnType });

                OutputTypeModel @class =
                    FragmentHelper.CreateClass(
                        context,
                        returnTypeFragment,
                        selectionSet,
                        @interface);

                context.RegisterSelectionSet(
                    selectionSet.Type,
                    selectionSet.SyntaxNode,
                    @class.SelectionSet);
            }

            return(returnType);
        }
        private OutputTypeModel AnalyzeWithHoistedFragment(
            IDocumentAnalyzerContext context,
            FieldSelection fieldSelection,
            SelectionSetVariants selectionVariants,
            string fragmentName)
        {
            FragmentNode?returnTypeFragment =
                FragmentHelper.CreateFragmentNode(
                    selectionVariants.Variants[0],
                    fieldSelection.Path,
                    appendTypeName: true);

            returnTypeFragment = FragmentHelper.GetFragment(returnTypeFragment, fragmentName);

            if (returnTypeFragment is null)
            {
                throw ThrowHelper.ReturnFragmentDoesNotExist();
            }

            OutputTypeModel returnType =
                FragmentHelper.CreateInterface(context, returnTypeFragment, fieldSelection.Path);

            context.RegisterSelectionSet(
                returnType.Type,
                selectionVariants.ReturnType.SyntaxNode,
                returnType.SelectionSet);

            foreach (SelectionSet selectionSet in selectionVariants.Variants)
            {
                returnTypeFragment = FragmentHelper.CreateFragmentNode(
                    selectionSet,
                    fieldSelection.Path,
                    appendTypeName: true);

                returnTypeFragment = FragmentHelper.RewriteForConcreteType(returnTypeFragment);

                if (FragmentHelper.GetFragment(returnTypeFragment, fragmentName) is null)
                {
                    throw ThrowHelper.FragmentMustBeImplementedByAllTypeFragments();
                }

                OutputTypeModel @interface =
                    FragmentHelper.CreateInterface(
                        context,
                        returnTypeFragment,
                        fieldSelection.Path,
                        new[] { returnType });

                OutputTypeModel @class =
                    FragmentHelper.CreateClass(
                        context,
                        returnTypeFragment,
                        selectionSet,
                        @interface);

                context.RegisterSelectionSet(
                    selectionSet.Type,
                    selectionSet.SyntaxNode,
                    @class.SelectionSet);
            }

            return(returnType);
        }
Exemplo n.º 29
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);
        }