Пример #1
0
        private void CompleteSelectionSet(CompilerContext context)
        {
            foreach (Selection selection in context.Fields.Values)
            {
                // we now mark the selection read-only and add it to the final selection-set.
                selection.MakeReadOnly();
                context.Selections.Add(selection);

                // if one selection of a selection-set is conditional,
                // then the whole set is conditional and has to be post processed during execution.
                if (!context.IsConditional && (selection.IsConditional || selection.IsInternal))
                {
                    context.IsConditional = true;
                }

                // if the field of the selection returns a composite type we will traverse
                // the child selection-sets as well.
                INamedType fieldType = selection.Field.Type.NamedType();
                if (fieldType.IsCompositeType())
                {
                    if (selection.SelectionSet is null)
                    {
                        // composite fields always have to have a selection-set
                        // otherwise we need to throw.
                        throw QueryCompiler_CompositeTypeSelectionSet(selection.SyntaxNode);
                    }

                    IReadOnlyList <ObjectType> possibleTypes = _schema.GetPossibleTypes(fieldType);

                    for (var i = possibleTypes.Count - 1; i >= 0; i--)
                    {
                        // we branch the context which will enqueue the new context
                        // to the work backlog.
                        context.TryBranch(possibleTypes[i], selection);
                    }
                }
            }

            context.Complete();
        }
Пример #2
0
        private void Visit(
            SelectionSetNode selectionSet,
            ObjectType typeContext,
            Stack <IObjectField> fieldContext,
            PSS current,
            Action <PSS> register,
            IDictionary <ISelectionNode, SelectionIncludeCondition> includeConditionLookup,
            List <ISelectionSetOptimizer> optimizers,
            bool internalSelection = false)
        {
            // we first collect the fields that we find in the selection set ...
            IDictionary <string, PreparedSelection> fields =
                CollectFields(typeContext, selectionSet, includeConditionLookup, internalSelection);

            // ... after that is done we will check if there are query optimizer that want
            // to provide additional fields.
            OptimizeSelectionSet(fieldContext, typeContext, selectionSet, fields, optimizers);

            var selections    = new List <PreparedSelection>();
            var isConditional = false;

            foreach (PreparedSelection selection in fields.Values)
            {
                // we now make the selection read-only and add it to the final selection-set.
                selection.MakeReadOnly();
                selections.Add(selection);

                // if one selection of a selection-set is conditional,
                // then the whole set is conditional.
                if (!isConditional && (selection.IsConditional || selection.IsInternal))
                {
                    isConditional = true;
                }

                // if the field of the selection returns a composite type we will traverse
                // the child selection-sets as well.
                INamedType fieldType = selection.Field.Type.NamedType();
                if (fieldType.IsCompositeType())
                {
                    if (selection.SelectionSet is null)
                    {
                        // composite fields always have to have a selection-set
                        // otherwise we need to throw.
                        throw QueryCompiler_CompositeTypeSelectionSet(selection.Selection);
                    }

                    var next = new PSS(selection.SelectionSet);
                    register(next);

                    IReadOnlyList <ObjectType> possibleTypes = _schema.GetPossibleTypes(fieldType);
                    for (var i = 0; i < possibleTypes.Count; i++)
                    {
                        // we prepare the field context and check if there are field specific
                        // optimizers that we might want to include.
                        fieldContext.Push(selection.Field);
                        var initialCount = optimizers.Count;
                        var registered   = RegisterOptimizers(optimizers, selection.Field);

                        Visit(
                            selection.SelectionSet,
                            possibleTypes[i],
                            fieldContext,
                            next,
                            register,
                            includeConditionLookup,
                            optimizers,
                            selection.IsInternal);

                        // lets clean up the context again and move on to the next.
                        UnregisterOptimizers(optimizers, initialCount, registered);
                        fieldContext.Pop();
                    }
                }
            }

            current.AddSelections(
                typeContext,
                new PreparedSelectionList(selections, isConditional));
        }