private List <SelectionItem> BuildSelectionItemsList(Node selSetNode, NamedRequestObject parentItem) { var selItems = new List <SelectionItem>(); foreach (var selNode in selSetNode.ChildNodes) { SelectionItem selItem = null; switch (selNode.Term.Name) { case TermNames.SelField: selItem = BuildSelectionField(selNode, parentItem); break; case TermNames.FragmSpread: var name = selNode.ChildNodes[1].GetText(); selItem = new FragmentSpread() { Name = name, SourceLocation = selNode.GetLocation() }; var dirListNode = selNode.FindChild(TermNames.DirListOpt); selItem.Directives = BuildDirectives(dirListNode, DirectiveLocation.Field, selItem); break; case TermNames.InlineFragm: selItem = BuildInlineFragment(selNode); break; } if (selItem != null) { selItems.Add(selItem); } } return(selItems); }
private string PrintFragmentSpread(FragmentSpread node) { var name = PrintName(node.FragmentName); var directives = node.Directives?.Select(PrintDirective) ?? Array.Empty <string>(); return($"...{name}{Wrap(string.Empty, Join(directives, " "))}"); }
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 { 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)); }
} //method private bool Fragments_CheckFragmentSpreadCompatible(FragmentSpread fragmentSpread, TypeDefBase parentType) { var fragmOnTypeDef = fragmentSpread.Fragment.OnTypeRef.TypeDef; if (parentType == fragmOnTypeDef) { return(true); //trivial case } var fragmName = fragmentSpread.Name; switch (parentType) { case ObjectTypeDef parObjType: // parent type is object type; the only allowed (non-trivial) case is fragment on interface if (!parObjType.Implements.Contains(fragmOnTypeDef)) { AddError($"Fragment ref '{fragmName}': fragment is defined on type '{fragmOnTypeDef.Name}'" + $" which is not compatible with type '{parentType.Name}'.", fragmentSpread); return(false); } break; case InterfaceTypeDef parIntfType: // parent type is interface; fragment's type must be object implementing interface if (!parIntfType.PossibleTypes.Contains(fragmOnTypeDef)) { AddError($"Fragment ref {fragmName}: fragment is defined on type '{fragmOnTypeDef.Name}'" + $" which is not compatible with type '{parentType.Name}'.", fragmentSpread); return(false); } break; case UnionTypeDef parUnionType: // fragment's on-type must be one of the unioned types; of if fragm is on interface, implemented by at least one of the types if (fragmOnTypeDef is InterfaceTypeDef fragmIntType) { if (!parUnionType.PossibleTypes.Any(t => t.Implements.Contains(fragmIntType))) { AddError($"Fragment ref {fragmName}: fragment is defined on interface '{fragmIntType.Name}' which is " + $"not implemented by any of the unioned types in '{parentType.Name}'.", fragmentSpread); return(false); } } else { // fragm is on object type if (!parUnionType.PossibleTypes.Contains(fragmOnTypeDef)) { AddError($"Fragment ref {fragmName}: fragment is defined on type '{fragmOnTypeDef.Name}' which is not " + $"one of the unioned types in '{parentType.Name}'.", fragmentSpread); return(false); } } break; } return(true); }
private void VisitFragmentSpread(FragmentSpread node) { EnterNode(node); Visit(node.Directives); ExitNode(node); }
public override FragmentSpread BeginVisitFragmentSpread( FragmentSpread fragmentSpread) { { Tracker.EnterFragmentSpread?.Invoke(fragmentSpread); } return(base.BeginVisitFragmentSpread(fragmentSpread)); }
private FragmentSpread BuildInlineFragment(Node selNode) { // Create fragment def and fragment spread var fragmDefs = _requestContext.ParsedRequest.Fragments; var fragmDef = new FragmentDef() { IsInline = true, Name = "_inline_" + fragmDefs.Count }; fragmDefs.Add(fragmDef); // note: On-type is optional, spec mentions this: https://spec.graphql.org/June2018/#sec-Inline-Fragments var typeNameNode = selNode.FindChild(TermNames.TypeCondOpt)?.FindChild(TermNames.Name); if (typeNameNode != null) { var onTypeName = typeNameNode.GetText(); fragmDef.OnTypeRef = new OnTypeRef() { Name = onTypeName, SourceLocation = typeNameNode.GetLocation(), Parent = fragmDef }; } //if // Selection set var selSetNode = selNode.FindChild(TermNames.SelSet); var items = BuildSelectionItemsList(selSetNode, fragmDef); fragmDef.SelectionSubset = new SelectionSubset(fragmDef, items, selSetNode.GetLocation()); // fragment spread var fragm = new FragmentSpread() { Fragment = fragmDef, Name = fragmDef.Name, IsInline = true, SourceLocation = selNode.GetLocation() }; //Directives var dirListNode = selNode.FindChild(TermNames.DirListOpt); fragm.Directives = BuildDirectives(dirListNode, DirectiveLocation.InlineFragment, fragm); return(fragm); }
private MappedFragmentSpread MapFragmentSpread(FragmentSpread fs, ObjectTypeDef objectTypeDef, bool isForUnion) { // if it is not inline fragment, it might need to map to FragmentDef; inline fragments are auto-mapped at construction if (fs.Fragment == null) { fs.Fragment = GetFragmentDef(fs.Name); } if (fs.Fragment == null) { AddError($"Fragment {fs.Name} not defined.", fs); return(null); } // inline fragments are mapped in-place, here. // we need to map them here, once we know the target type if (fs.IsInline) { var onTypeRef = fs.Fragment.OnTypeRef; var skip = onTypeRef != null && onTypeRef.TypeDef != objectTypeDef; if (skip) { return(null); } MapObjectSelectionSubset(fs.Fragment.SelectionSubset, objectTypeDef, fs.Directives, isForUnion); } // there must be mapped field set now var mappedFragmItemSet = fs.Fragment.SelectionSubset.MappedItemSets.FirstOrDefault(fset => fset.ObjectTypeDef == objectTypeDef); if (mappedFragmItemSet == null) { AddError($"FATAL: Could not retrieve mapped item list for fragment spread {fs.Name}", fs, ErrorCodes.ServerError); return(null); } var mappedSpread = new MappedFragmentSpread(fs, mappedFragmItemSet.Items); return(mappedSpread); }
public virtual void Leave(FragmentSpread selection) { }
public virtual void Enter(FragmentSpread selection) { }
private void Serialize(FragmentSpread fragmentSpread, StringBuilder builder) { builder.Append("..."); builder.Append(fragmentSpread.Name); }
public virtual FragmentSpread BeginVisitFragmentSpread( FragmentSpread fragmentSpread) { return(fragmentSpread); }
/// <summary> /// Initializes a new instance with the specified properties. /// </summary> public PossibleFragmentSpreadsError(ValidationContext context, FragmentSpread node, IGraphType parentType, IGraphType fragType) : base(context.OriginalQuery, NUMBER, TypeIncompatibleSpreadMessage(node.Name, context.Print(parentType), context.Print(fragType)), node) { }
/// <summary> /// Initializes a new instance with the specified properties. /// </summary> public KnownFragmentNamesError(ValidationContext context, FragmentSpread node, string fragmentName) : base(context.Document.OriginalQuery !, NUMBER, UnknownFragmentMessage(fragmentName), node)
protected override void EnterFragmentSpread(PrinterContext context, FragmentSpread fragmentSpread) { context.Append("..."); context.Append(fragmentSpread.FragmentName); }
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); }
protected virtual void ExitFragmentSpread(TContext context, FragmentSpread fragmentSpread) { }