public void ParseQueryWithFragment()
        {
            // arrange
            byte[] sourceText = Encoding.UTF8.GetBytes(
                "query a { x { ... y } } fragment y on Type { z } ");

            // act
            var parser = new Utf8GraphQLParser(
                sourceText, ParserOptions.Default);
            DocumentNode document = parser.Parse();

            // assert
            Assert.Collection(document.Definitions,
                              t =>
            {
                Assert.IsType <OperationDefinitionNode>(t);
                var operationDefinition = (OperationDefinitionNode)t;
                Assert.Equal(SyntaxKind.OperationDefinition, operationDefinition.Kind);
                Assert.Equal("a", operationDefinition.Name.Value);
                Assert.Equal(OperationType.Query, operationDefinition.Operation);
                Assert.Empty(operationDefinition.VariableDefinitions);
                Assert.Empty(operationDefinition.Directives);

                Assert.Collection(operationDefinition.SelectionSet.Selections,
                                  s1 =>
                {
                    Assert.IsType <FieldNode>(s1);

                    FieldNode field1 = (FieldNode)s1;
                    Assert.Null(field1.Alias);
                    Assert.Equal("x", field1.Name.Value);
                    Assert.Empty(field1.Arguments);
                    Assert.Empty(field1.Directives);

                    Assert.Collection(field1.SelectionSet.Selections,
                                      s2 =>
                    {
                        Assert.IsType <FragmentSpreadNode>(s2);

                        FragmentSpreadNode spread = (FragmentSpreadNode)s2;
                        Assert.Equal("y", spread.Name.Value);
                        Assert.Empty(spread.Directives);
                    });
                });
            },
                              t =>
            {
                Assert.IsType <FragmentDefinitionNode>(t);
                var fragmentDefinition = (FragmentDefinitionNode)t;
                Assert.Equal("y", fragmentDefinition.Name.Value);
                Assert.Equal("Type", fragmentDefinition.TypeCondition.Name.Value);
                Assert.Empty(fragmentDefinition.VariableDefinitions);
                Assert.Empty(fragmentDefinition.Directives);

                ISelectionNode selectionNode = fragmentDefinition
                                               .SelectionSet.Selections.Single();
                Assert.IsType <FieldNode>(selectionNode);
                Assert.Equal("z", ((FieldNode)selectionNode).Name.Value);
            });
        }
Beispiel #2
0
        private void ResolveFields(
            CompilerContext context,
            ISelectionNode selection,
            SelectionIncludeCondition?includeCondition)
        {
            switch (selection.Kind)
            {
            case SyntaxKind.Field:
                ResolveFieldSelection(
                    context,
                    (FieldNode)selection,
                    includeCondition);
                break;

            case SyntaxKind.InlineFragment:
                ResolveInlineFragment(
                    context,
                    (InlineFragmentNode)selection,
                    includeCondition);
                break;

            case SyntaxKind.FragmentSpread:
                ResolveFragmentSpread(
                    context,
                    (FragmentSpreadNode)selection,
                    includeCondition);
                break;
            }
        }
Beispiel #3
0
        private void CollectFields(
            ObjectType typeContext,
            SelectionSetNode selectionSet,
            SelectionIncludeCondition?includeCondition,
            IDictionary <ISelectionNode, SelectionIncludeCondition> includeConditionLookup,
            IDictionary <string, PreparedSelection> fields,
            bool internalSelection)
        {
            for (var i = 0; i < selectionSet.Selections.Count; i++)
            {
                ISelectionNode            selection           = selectionSet.Selections[i];
                SelectionIncludeCondition?selectionVisibility = includeCondition;

                if (selectionVisibility is null)
                {
                    includeConditionLookup.TryGetValue(selection, out selectionVisibility);
                }

                ResolveFields(
                    typeContext,
                    selection,
                    ExtractVisibility(selection, selectionVisibility),
                    includeConditionLookup,
                    fields,
                    internalSelection);
            }
        }
Beispiel #4
0
 private void ResolveFields(
     ObjectType type,
     ISelectionNode selection,
     Path path,
     FieldVisibility fieldVisibility,
     IDictionary <string, FieldInfo> fields)
 {
     if (selection is FieldNode fs)
     {
         ResolveFieldSelection(
             type,
             fs,
             path,
             fieldVisibility,
             fields);
     }
     else if (selection is FragmentSpreadNode fragSpread)
     {
         ResolveFragmentSpread(
             type,
             fragSpread,
             path,
             fieldVisibility,
             fields);
     }
     else if (selection is InlineFragmentNode inlineFrag)
     {
         ResolveInlineFragment(
             type,
             inlineFrag,
             path,
             fieldVisibility,
             fields);
     }
 }
 /// <summary>
 /// Adds the sub selection.
 /// </summary>
 /// <param name="selection">The <see cref="ISelectionNode"/> to which the sub selection is added.</param>
 /// <param name="child">The sub selection.</param>
 /// <returns>The <see cref="ISelectionNode"/></returns>
 public static ISelectionNode AddSubSelection(this ISelectionNode selection, ISelectionNode child)
 {
     Guard.ArgumentNotNull(selection, nameof(selection));
     Guard.ArgumentNotNull(child, nameof(child));
     selection.SelectionSet.Add(child);
     return(selection);
 }
        private bool TryGetFragment(object container, ISelectionNode selection, out IFragment fragment)
        {
            var fragments = selection.SelectionSet.OfType <IFragment>().ToDictionary(it => it.GraphType, it => it);

            if (fragments.Count == 0 || null == container)
            {
                return((fragment = null) != null);
            }
            var containerType = container.GetType();
            var graphTypes    = fragments.Select(it => it.Key).ToArray();
            var graphType     = SelectBest(containerType);

            if (null == graphType)
            {
                return((fragment = null) != null);
            }

            return((fragment = fragments[graphType]) != null);

            IGraphType SelectBest(Type type)
            {
                var best = graphTypes.SingleOrDefault(it => it.Type == type);

                if (null != best)
                {
                    return(best);
                }

                var parent = type.BaseType;

                return(parent == null
                    ? null
                    : SelectBest(parent));
            }
        }
        public void ParseQueryWithFragment()
        {
            // arrange
            string sourceText = "query a { x { ... y } } fragment y on Type { z } ";
            Source source     = new Source(sourceText);

            // act
            Parser       parser   = new Parser();
            DocumentNode document = parser.Parse(sourceText);

            // assert
            Assert.Collection(document.Definitions,
                              t =>
            {
                Assert.IsType <OperationDefinitionNode>(t);
                var operationDefinition = (OperationDefinitionNode)t;
                Assert.Equal(NodeKind.OperationDefinition, operationDefinition.Kind);
                Assert.Equal("a", operationDefinition.Name.Value);
                Assert.Equal(OperationType.Query, operationDefinition.Operation);
                Assert.Empty(operationDefinition.VariableDefinitions);
                Assert.Empty(operationDefinition.Directives);

                Assert.Collection(operationDefinition.SelectionSet.Selections,
                                  s1 =>
                {
                    Assert.IsType <FieldNode>(s1);

                    FieldNode field1 = (FieldNode)s1;
                    Assert.Null(field1.Alias);
                    Assert.Equal("x", field1.Name.Value);
                    Assert.Empty(field1.Arguments);
                    Assert.Empty(field1.Directives);

                    Assert.Collection(field1.SelectionSet.Selections,
                                      s2 =>
                    {
                        Assert.IsType <FragmentSpreadNode>(s2);

                        FragmentSpreadNode spread = (FragmentSpreadNode)s2;
                        Assert.Equal("y", spread.Name.Value);
                        Assert.Empty(spread.Directives);
                    });
                });
            },
                              t =>
            {
                Assert.IsType <FragmentDefinitionNode>(t);
                var fragmentDefinition = (FragmentDefinitionNode)t;
                Assert.Equal("y", fragmentDefinition.Name.Value);
                Assert.Equal("Type", fragmentDefinition.TypeCondition.Name.Value);
                Assert.Empty(fragmentDefinition.VariableDefinitions);
                Assert.Empty(fragmentDefinition.Directives);

                ISelectionNode selectionNode = fragmentDefinition
                                               .SelectionSet.Selections.Single();
                Assert.IsType <FieldNode>(selectionNode);
                Assert.Equal("z", ((FieldNode)selectionNode).Name.Value);
            });
        }
Beispiel #8
0
 private bool ShouldBeIncluded(ISelectionNode selection)
 {
     if (selection.Directives.Skip(_variables))
     {
         return(false);
     }
     return(selection.Directives.Include(_variables));
 }
Beispiel #9
0
        private void ResolveFieldSelection(
            CompilerContext context,
            FieldNode selection,
            SelectionIncludeCondition?includeCondition)
        {
            NameString fieldName    = selection.Name.Value;
            NameString responseName = selection.Alias is null
                ? selection.Name.Value
                : selection.Alias.Value;

            if (context.Type.Fields.TryGetField(fieldName, out IObjectField? field))
            {
                if ((selection.SelectionSet is null ||
                     selection.SelectionSet.Selections.Count == 0) &&
                    field.Type.NamedType().IsCompositeType())
                {
                    throw OperationCompiler_NoCompositeSelections(selection);
                }

                if (context.Fields.TryGetValue(responseName, out Selection? preparedSelection))
                {
                    preparedSelection.AddSelection(selection, includeCondition);
                }
                else
                {
                    // if this is the first time we find a selection to this field we have to
                    // create a new prepared selection.
                    preparedSelection = new Selection(
                        context.Type,
                        field,
                        selection,
                        responseName: responseName,
                        resolverPipeline: CreateFieldMiddleware(field, selection),
                        arguments: CoerceArgumentValues(field, selection, responseName),
                        includeCondition: includeCondition,
                        internalSelection: context.IsInternalSelection);

                    context.Fields.Add(responseName, preparedSelection);
                }

                if (includeCondition is not null && selection.SelectionSet is not null)
                {
                    for (var i = 0; i < selection.SelectionSet.Selections.Count; i++)
                    {
                        ISelectionNode child = selection.SelectionSet.Selections[i];
                        if (!context.IncludeConditionLookup.ContainsKey(child))
                        {
                            context.IncludeConditionLookup.Add(child, includeCondition);
                        }
                    }
                }
            }
            else
            {
                throw FieldDoesNotExistOnType(selection, context.Type.Name);
            }
        }
        public override void VisitSelectionNode <T>(LogContext context, ISelectionNode <T> node)
        {
            using (_log.BeginScope <SelectionNode <T> >())
            {
                _log.LogDebug("Condition: {0}", node.Condition);

                base.VisitAlphaNode(context, node);
            }
        }
        private bool IsRelevant(ISelectionNode selection, string schemaName)
        {
            if (selection.Directives.Any(t => t.IsDelegateDirective()))
            {
                return(false);
            }

            return(selection.Directives
                   .Any(t => t.IsSchemaDirective(schemaName)));
        }
        public virtual void VisitSelectionNode <T>(TContext context, ISelectionNode <T> node)
            where T : class
        {
            VisitAlphaMemoryNode(context, node.MemoryNode);

            foreach (var childNode in node.GetChildNodes <INode>())
            {
                childNode.Accept(this, context);
            }
        }
        public override void VisitSelectionNode <T>(GraphContext context, ISelectionNode <T> node)
        {
            var nodeInfo = new Node(Interlocked.Increment(ref _id), node, typeof(T), "selection");

            context.Add(nodeInfo);
            context.Link(nodeInfo, new Node(-1, node.MemoryNode, typeof(T), ""));

            foreach (var childNode in node.GetChildNodes <INode>())
            {
                context.Link(nodeInfo, new Node(-1, childNode, typeof(T), ""));
            }

            base.VisitSelectionNode(context, node);
        }
Beispiel #14
0
 private void ResolveFields(
     INamedOutputType type,
     ISelectionNode selection,
     Path path,
     IDictionary <string, FieldSelection> fields,
     ICollection <IFragmentNode> fragments)
 {
     if (selection is FieldNode fs && type is IComplexOutputType ct)
     {
         ResolveFieldSelection(
             ct,
             fs,
             path,
             fields);
     }
Beispiel #15
0
        public SelectionSetNode AddSelection(
            ISelectionNode selection)
        {
            if (selection == null)
            {
                throw new ArgumentNullException(nameof(selection));
            }

            var selections = new List <ISelectionNode>(Selections);

            selections.Add(selection);

            return(new SelectionSetNode(
                       Location, selections));
        }
 private static bool HasFields(SelectionSetNode selectionSet)
 {
     for (int i = 0; i < selectionSet.Selections.Count; i++)
     {
         ISelectionNode selection = selectionSet.Selections[i];
         if (selection.Kind == NodeKind.Field)
         {
             if (!IsTypeNameField(((FieldNode)selection).Name.Value))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Beispiel #17
0
 private void ResolveFields(
     ObjectType type,
     ISelectionNode selection,
     Action <QueryError> reportError,
     Dictionary <string, FieldSelection> fields)
 {
     if (selection is FieldNode fs)
     {
         ResolveFieldSelection(type, fs, reportError, fields);
     }
     else if (selection is FragmentSpreadNode fragSpread)
     {
         ResolveFragmentSpread(type, fragSpread, reportError, fields);
     }
     else if (selection is InlineFragmentNode inlineFrag)
     {
         ResolveInlineFragment(type, inlineFrag, reportError, fields);
     }
 }
Beispiel #18
0
        protected virtual ISelectionNode RewriteSelection(
            ISelectionNode node,
            TContext context)
        {
            switch (node)
            {
            case FieldNode value:
                return(RewriteField(value, context));

            case FragmentSpreadNode value:
                return(RewriteFragmentSpread(value, context));

            case InlineFragmentNode value:
                return(RewriteInlineFragment(value, context));

            default:
                throw new NotSupportedException();
            }
        }
Beispiel #19
0
 private void ResolveFields(
     ObjectType type,
     ISelectionNode selection,
     Action <QueryError> reportError,
     Dictionary <string, FieldSelection> fields)
 {
     if (selection is FieldNode fs)
     {
         string fieldName = fs.Name.Value;
         if (fieldName.StartsWith("__"))
         {
             ResolveIntrospectionField(type, fs, reportError, fields);
         }
         else if (type.Fields.TryGetValue(fieldName, out Field field))
         {
             string name = fs.Alias == null ? fs.Name.Value : fs.Alias.Value;
             fields[name] = new FieldSelection(fs, field, name);
         }
         else
         {
             reportError(new FieldError(
                             "Could not resolve the specified field.",
                             fs));
         }
     }
     else if (selection is FragmentSpreadNode fragmentSpread)
     {
         Fragment fragment = _fragments.GetFragments(fragmentSpread.Name.Value)
                             .FirstOrDefault(t => DoesFragmentTypeApply(type, t.TypeCondition));
         if (fragment != null)
         {
             CollectFields(type, fragment.SelectionSet, reportError, fields);
         }
     }
     else if (selection is InlineFragmentNode inlineFragment)
     {
         Fragment fragment = _fragments.GetFragment(inlineFragment);
         if (DoesFragmentTypeApply(type, fragment.TypeCondition))
         {
             CollectFields(type, fragment.SelectionSet, reportError, fields);
         }
     }
 }
Beispiel #20
0
        protected virtual void VisitSelection(ISelectionNode node)
        {
            switch (node)
            {
            case FieldNode value:
                VisitField(value);
                break;

            case FragmentSpreadNode value:
                VisitFragmentSpread(value);
                break;

            case InlineFragmentNode value:
                VisitInlineFragment(value);
                break;

            default:
                throw new NotSupportedException();
            }
        }
Beispiel #21
0
        private void ResolveFields(
            ObjectType typeContext,
            ISelectionNode selection,
            SelectionIncludeCondition?includeCondition,
            IDictionary <ISelectionNode, SelectionIncludeCondition> includeConditionLookup,
            IDictionary <string, PreparedSelection> fields,
            bool internalSelection)
        {
            switch (selection.Kind)
            {
            case SyntaxKind.Field:
                ResolveFieldSelection(
                    typeContext,
                    (FieldNode)selection,
                    includeCondition,
                    includeConditionLookup,
                    fields,
                    internalSelection);
                break;

            case SyntaxKind.InlineFragment:
                ResolveInlineFragment(
                    typeContext,
                    (InlineFragmentNode)selection,
                    includeCondition,
                    includeConditionLookup,
                    fields,
                    internalSelection);
                break;

            case SyntaxKind.FragmentSpread:
                ResolveFragmentSpread(
                    typeContext,
                    (FragmentSpreadNode)selection,
                    includeCondition,
                    includeConditionLookup,
                    fields,
                    internalSelection);
                break;
            }
        }
Beispiel #22
0
        private void CollectFields(
            CompilerContext context,
            SelectionSetNode selectionSet,
            SelectionIncludeCondition?includeCondition)
        {
            for (var i = 0; i < selectionSet.Selections.Count; i++)
            {
                ISelectionNode            selection          = selectionSet.Selections[i];
                SelectionIncludeCondition?selectionCondition = includeCondition;

                if (selectionCondition is null)
                {
                    context.IncludeConditionLookup.TryGetValue(selection, out selectionCondition);
                }

                ResolveFields(
                    context,
                    selection,
                    ExtractVisibility(selection, selectionCondition));
            }
        }
Beispiel #23
0
 public virtual void VisitSelectionNode <T>(TContext context, ISelectionNode <T> node)
     where T : class
 {
     VisitAlphaNode(context, node);
 }
Beispiel #24
0
        private void ResolveFieldSelection(
            CompilerContext context,
            FieldNode selection,
            SelectionIncludeCondition?includeCondition)
        {
            NameString fieldName    = selection.Name.Value;
            NameString responseName = selection.Alias is null
                ? selection.Name.Value
                : selection.Alias.Value;

            if (context.Type.Fields.TryGetField(fieldName, out IObjectField? field))
            {
                if ((selection.SelectionSet is null ||
                     selection.SelectionSet.Selections.Count == 0) &&
                    field.Type.NamedType().IsCompositeType())
                {
                    throw OperationCompiler_NoCompositeSelections(selection);
                }

                if (context.Fields.TryGetValue(responseName, out Selection? preparedSelection))
                {
                    preparedSelection.AddSelection(selection, includeCondition);
                }
                else
                {
                    Func <object, IAsyncEnumerable <object?> >?createStream = null;
                    bool isStreamable = selection.IsStreamable();

                    if (field.MaybeStream || field.Type.IsListType() && isStreamable)
                    {
                        IType elementType = field.Type.ElementType();

                        if (elementType.IsCompositeType())
                        {
                            Type runtimeType = elementType.ToRuntimeType();
                            CreateStreamDelegate streamDelegate = CreateStream(runtimeType);
                            createStream = o => streamDelegate(o);
                        }
                    }

                    // if this is the first time we find a selection to this field we have to
                    // create a new prepared selection.
                    preparedSelection = new Selection(
                        GetNextId(),
                        context.Type,
                        field,
                        selection.SelectionSet is not null
                            ? selection.WithSelectionSet(
                            selection.SelectionSet.WithSelections(
                                selection.SelectionSet.Selections))
                            : selection,
                        responseName: responseName,
                        resolverPipeline: CreateFieldMiddleware(field, selection),
                        pureResolver: TryCreatePureField(field, selection),
                        strategy: field.IsParallelExecutable
                            ? null // use default strategy
                            : SelectionExecutionStrategy.Serial,
                        arguments: CoerceArgumentValues(field, selection, responseName),
                        includeCondition: includeCondition,
                        internalSelection: context.IsInternalSelection,
                        createStream: createStream,
                        isStreamable: isStreamable);

                    context.Fields.Add(responseName, preparedSelection);
                }

                if (includeCondition is not null && selection.SelectionSet is not null)
                {
                    SelectionPath selectionPath = context.SelectionPath.Append(responseName);

                    for (var i = 0; i < selection.SelectionSet.Selections.Count; i++)
                    {
                        ISelectionNode child     = selection.SelectionSet.Selections[i];
                        var            reference = new SelectionReference(selectionPath, child);

                        if (!context.IncludeConditionLookup.ContainsKey(reference))
                        {
                            context.IncludeConditionLookup.Add(reference, includeCondition);
                        }
                    }
                }
            }
            else
            {
                throw FieldDoesNotExistOnType(selection, context.Type.Name);
            }
        }