Example #1
0
    protected override void EnterFragmentDefinition(PrinterContext context, FragmentDefinition fragmentDefinition)
    {
        context.Append("fragment");
        context.Append(' ');
        context.Append(fragmentDefinition.FragmentName);

        context.Append(' ');
        context.Append("on");
        context.Append(' ');
    }
    private void VisitFragmentDefinition(FragmentDefinition node)
    {
        EnterNode(node);

        Visit(node.TypeCondition);
        Visit(node.Directives);
        Visit(node.SelectionSet);

        ExitNode(node);
    }
Example #3
0
        public virtual FragmentDefinition BeginVisitFragmentDefinition(
            FragmentDefinition node)
        {
            BeginVisitNode(node.TypeCondition);
            if (node.SelectionSet != null)
            {
                BeginVisitNode(node.SelectionSet);
            }

            _fragments.Add(node);
            return(node);
        }
Example #4
0
        public override FragmentDefinition BeginVisitFragmentDefinition(
            FragmentDefinition node)
        {
            {
                Tracker.EnterFragmentDefinition?.Invoke(node);
            }

            var result = base.BeginVisitFragmentDefinition(node);


            {
                Tracker.LeaveFragmentDefinition?.Invoke(node);
            }

            return(result);
        }
Example #5
0
    public void FragmentDefinition_EnterAndLeave()
    {
        /* Given */
        FragmentDefinition definition = @"fragment Name on Human { field }";

        var visitor = Substitute.For <VisitAllBase>();
        var sut     = new ReadOnlyExecutionDocumentWalker(
            new ExecutionDocumentWalkerOptions().Add(visitor));

        /* When */
        sut.Visit(definition);

        /* Then */
        visitor.Received().Enter(definition);
        visitor.Received().Leave(definition);
    }
        // Given a reference to a fragment, return the represented collection of fields
        // as well as a list of nested fragment names referenced via fragment spreads.
        private CachedField GetReferencedFieldsAndFragmentNames(
            Dictionary <SelectionSet, CachedField> cachedFieldsAndFragmentNames,
            FragmentDefinition fragment)
        {
            // Short-circuit building a type from the node if possible.
            if (cachedFieldsAndFragmentNames.ContainsKey(fragment.SelectionSet))
            {
                return(cachedFieldsAndFragmentNames[fragment.SelectionSet]);
            }

            var fragmentType = Ast.TypeFromAst(_context.Schema, fragment.TypeCondition);

            return(GetFieldsAndFragmentNames(
                       cachedFieldsAndFragmentNames,
                       fragmentType,
                       fragment.SelectionSet));
        }
Example #7
0
    // Given a reference to a fragment, return the represented collection of fields
    // as well as a list of nested fragment names referenced via fragment spreads.
    private CachedField GetReferencedFieldsAndFragmentNames(
        Dictionary <SelectionSet, CachedField> cachedFieldsAndFragmentNames,
        FragmentDefinition fragment)
    {
        // Short-circuit building a type from the node if possible.
        if (cachedFieldsAndFragmentNames.ContainsKey(fragment.SelectionSet))
        {
            return(cachedFieldsAndFragmentNames[fragment.SelectionSet]);
        }

        var fragmentType = fragment.TypeCondition;

        return(GetFieldsAndFragmentNames(
                   cachedFieldsAndFragmentNames,
                   _context.Schema.GetNamedType(fragmentType.Name) ??
                   throw new InvalidOperationException($"Could not find type '{fragmentType.Name}' from schema."),
                   fragment.SelectionSet));
    }
    public void Visit(FragmentDefinition definition)
    {
        // enter
        foreach (var visitor in _options.FragmentDefinition)
        {
            visitor.Enter(definition);
        }

        // children
        Visit(definition.Directives);
        Visit(definition.SelectionSet);

        // leave
        foreach (var visitor in _options.FragmentDefinition)
        {
            visitor.Leave(definition);
        }
    }
        // Given a reference to a fragment, return the represented collection of fields
        // as well as a list of nested fragment names referenced via fragment spreads.
        public CachedField GetReferencedFieldsAndFragmentNames(
            ValidationContext context,
            Dictionary <SelectionSet, CachedField> cachedFieldsAndFragmentNames,
            FragmentDefinition fragment)
        {
            // Short-circuit building a type from the node if possible.
            if (cachedFieldsAndFragmentNames.ContainsKey(fragment.SelectionSet))
            {
                return(cachedFieldsAndFragmentNames[fragment.SelectionSet]);
            }

            var fragmentType = fragment.Type.GraphTypeFromType(context.Schema);

            return(GetFieldsAndFragmentNames(
                       context,
                       cachedFieldsAndFragmentNames,
                       fragmentType,
                       fragment.SelectionSet));
        }
Example #10
0
        public void MergeFieldAndFragment()
        {
            var fragment          = new FragmentDefinition(new NameNode("fragment"));
            var fragmentSelection = new SelectionSet();

            fragmentSelection.Add(FirstTestField);
            fragment.SelectionSet = fragmentSelection;
            fragment.Type         = new GraphQL.Language.AST.NamedType(
                new NameNode("Person"));

            var fragments = new Fragments();

            fragments.Add(fragment);

            var schema = new Schema();

            schema.RegisterType(new PersonType());

            var context = new ExecutionContext
            {
                Fragments = fragments,
                Schema    = schema
            };

            var fragSpread     = new FragmentSpread(new NameNode("fragment"));
            var outerSelection = new SelectionSet();

            outerSelection.Add(fragSpread);
            outerSelection.Add(SecondTestField);

            var fields = ExecutionHelper.CollectFields(
                context,
                new PersonType(),
                outerSelection);

            fields.ShouldHaveSingleItem();
            fields["test"].SelectionSet.Selections.ShouldContain(x => x.IsEqualTo(FirstInnerField));
            fields["test"].SelectionSet.Selections.ShouldContain(x => x.IsEqualTo(SecondInnerField));
        }
Example #11
0
        private LambdaExpression VisitFragment(IFragment fragment)
        {
            LambdaExpression lambda;

            if (!syntax.Root.FragmentDefinitions.ContainsKey(fragment.Name))
            {
                currentFragment = syntax.AddFragment(fragment);
                using (syntax.Bookmark())
                {
                    var fragmentExpressionLambda = Visit(fragment.Expression).GetLambda();
                    var castedFragmentExpression = fragmentExpressionLambda.Body.AddCast(fragment.ReturnType);
                    lambda = Expression.Lambda(castedFragmentExpression, fragmentExpressionLambda.Parameters);
                }

                currentFragment = null;
                fragmentExpressions.Add(fragment.Name, lambda);
            }
            else
            {
                lambda = fragmentExpressions[fragment.Name];
            }

            return(lambda);
        }
 /// <summary>
 /// Initializes a new instance with the specified properties.
 /// </summary>
 public NoUnusedFragmentsError(ValidationContext context, FragmentDefinition node)
     : base(context.OriginalQuery, NUMBER, UnusedFragMessage(node.Name), node)
 {
 }
Example #13
0
 /// <summary>
 /// Initializes a new instance with the specified properties.
 /// </summary>
 public FragmentsOnCompositeTypesError(ValidationContext context, FragmentDefinition node)
     : base(context.OriginalQuery, NUMBER, FragmentOnNonCompositeErrorMessage(node.Name, context.Print(node.Type)), node.Type)
 {
 }
        private void CollectConflictsBetweenFieldsAndFragment(
            ValidationContext context,
            List <Conflict> conflicts,
            Dictionary <SelectionSet, CachedField> cachedFieldsAndFragmentNames,
            ObjMap <bool> comparedFragments,
            PairSet comparedFragmentPairs,
            bool areMutuallyExclusive,
            Dictionary <string, List <FieldDefPair> > fieldMap,
            string fragmentName)
        {
            // Memoize so a fragment is not compared for conflicts more than once.
            if (comparedFragments.ContainsKey(fragmentName))
            {
                return;
            }

            comparedFragments[fragmentName] = true;

            FragmentDefinition fragment = context.GetFragment(fragmentName);

            if (fragment == null)
            {
                return;
            }

            var cachedField =
                GetReferencedFieldsAndFragmentNames(
                    context,
                    cachedFieldsAndFragmentNames,
                    fragment);

            var fieldMap2      = cachedField.NodeAndDef;
            var fragmentNames2 = cachedField.Names;

            // Do not compare a fragment's fieldMap to itself.
            if (fieldMap == fieldMap2)
            {
                return;
            }

            // (D) First collect any conflicts between the provided collection of fields
            // and the collection of fields represented by the given fragment.
            CollectConflictsBetween(
                context,
                conflicts,
                cachedFieldsAndFragmentNames,
                comparedFragmentPairs,
                areMutuallyExclusive,
                fieldMap,
                fieldMap2);

            // (E) Then collect any conflicts between the provided collection of fields
            // and any fragment names found in the given fragment.
            for (var i = 0; i < fragmentNames2.Count; i++)
            {
                CollectConflictsBetweenFieldsAndFragment(
                    context,
                    conflicts,
                    cachedFieldsAndFragmentNames,
                    comparedFragments,
                    comparedFragmentPairs,
                    areMutuallyExclusive,
                    fieldMap,
                    fragmentNames2[i]);
            }
        }
Example #15
0
 public virtual void Leave(FragmentDefinition definition)
 {
 }
Example #16
0
 public virtual void Enter(FragmentDefinition definition)
 {
 }
Example #17
0
 public UniqueFragmentNamesError(ValidationContext context, FragmentDefinition node, FragmentDefinition altNode)
     : base(context.OriginalQuery, NUMBER, DuplicateFragmentNameMessage(node.Name), node, altNode)
 {
 }
 protected virtual void ExitFragmentDefinition(TContext context, FragmentDefinition fragmentDefinition)
 {
 }
        public ExecutionDocumentWalkerOptions Add(object visitor)
        {
            if (visitor is IVisit <ExecutableDocument> ed)
            {
                ExecutableDocument.Add(ed);
            }

            if (visitor is IVisit <FragmentDefinition> fd)
            {
                FragmentDefinition.Add(fd);
            }

            if (visitor is IVisit <OperationDefinition> od)
            {
                OperationDefinition.Add(od);
            }

            if (visitor is IVisit <SelectionSet> ss)
            {
                SelectionSet.Add(ss);
            }


            if (visitor is IVisit <ISelection> s)
            {
                Selection.Add(s);
            }

            if (visitor is IVisit <FieldSelection> fs)
            {
                FieldSelection.Add(fs);
            }

            if (visitor is IVisit <InlineFragment> ift)
            {
                InlineFragment.Add(ift);
            }

            if (visitor is IVisit <FragmentSpread> fgs)
            {
                FragmentSpread.Add(fgs);
            }

            if (visitor is IVisit <Argument> arg)
            {
                Argument.Add(arg);
            }

            if (visitor is IVisit <NamedType> nt)
            {
                NamedType.Add(nt);
            }

            if (visitor is IVisit <VariableDefinition> vd)
            {
                VariableDefinition.Add(vd);
            }

            if (visitor is IVisit <DefaultValue> dv)
            {
                DefaultValue.Add(dv);
            }

            if (visitor is IVisit <Value> v)
            {
                Value.Add(v);
            }

            if (visitor is IVisit <Directive> d)
            {
                Directive.Add(d);
            }

            if (visitor is IVisit <TypeBase> t)
            {
                Type.Add(t);
            }

            return(this);
        }
        private void detectCycleRecursive(
            FragmentDefinition fragment,
            Stack <FragmentSpread> spreadPath,
            LightweightCache <string, bool> visitedFrags,
            LightweightCache <string, int> spreadPathIndexByName,
            ValidationContext context)
        {
            var fragmentName = fragment.Name;

            visitedFrags[fragmentName] = true;

            var spreadNodes = context.GetFragmentSpreads(fragment.SelectionSet);

            if (spreadNodes.Count == 0)
            {
                return;
            }

            spreadPathIndexByName[fragmentName] = spreadPath.Count;

            foreach (var spreadNode in spreadNodes)
            {
                var spreadName = spreadNode.Name;
                var cycleIndex = spreadPathIndexByName[spreadName];

                if (cycleIndex == -1)
                {
                    spreadPath.Push(spreadNode);

                    if (!visitedFrags[spreadName])
                    {
                        var spreadFragment = context.GetFragment(spreadName);
                        if (spreadFragment != null)
                        {
                            detectCycleRecursive(
                                spreadFragment,
                                spreadPath,
                                visitedFrags,
                                spreadPathIndexByName,
                                context);
                        }
                    }

                    spreadPath.Pop();
                }
                else
                {
                    var cyclePath = spreadPath.Reverse().Skip(cycleIndex).ToArray();
                    var nodes     = cyclePath.OfType <INode>().Concat(new[] { spreadNode }).ToArray();

                    context.ReportError(new ValidationError(
                                            context.OriginalQuery,
                                            "5.4",
                                            CycleErrorMessage(spreadName, cyclePath.Select(x => x.Name).ToArray()),
                                            nodes)
                    {
                        Path = context.TypeInfo.GetPath()
                    });
                }
            }

            spreadPathIndexByName[fragmentName] = -1;
        }