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); }
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); }
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); }
private void CreateClassModels( IModelGeneratorContext context, OperationDefinitionNode operation, IType fieldType, FieldNode fieldSelection, PossibleSelections possibleSelections, IFragmentNode returnType, IInterfaceDescriptor interfaceDescriptor, Path path) { var resultParserTypes = new List <ResultParserTypeDescriptor>(); IReadOnlyCollection <SelectionInfo> selections = possibleSelections.Variants; CreateClassModels( context, fieldSelection, returnType, interfaceDescriptor, selections, resultParserTypes, path); context.Register( new ResultParserMethodDescriptor( GetPathName(path), operation, fieldType, fieldSelection, path, interfaceDescriptor, resultParserTypes)); }
private IReadOnlyList <IInterfaceDescriptor> CreateChildInterfaceModels( IModelGeneratorContext context, IFragmentNode fragmentNode, Path path, Stack <ISet <string> > levels, ISet <string> implementedFields) { var implementedByChildren = new HashSet <string>(); levels.Push(implementedByChildren); var implements = new List <IInterfaceDescriptor>(); 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 override ICodeDescriptor Generate( IModelGeneratorContext context, OperationDefinitionNode operation, UnionType namedType, IType fieldType, FieldNode fieldSelection, PossibleSelections possibleSelections, Path path) { IFragmentNode returnType = ResolveReturnType( context, namedType, fieldSelection, possibleSelections.ReturnType); IInterfaceDescriptor interfaceDescriptor = CreateInterfaceModel( context, returnType, path); context.Register(fieldSelection, interfaceDescriptor); CreateClassModels( context, operation, fieldType, fieldSelection, possibleSelections, returnType, interfaceDescriptor, path); return(interfaceDescriptor); }
private InterfaceDescriptor CreateInterface( IFragmentNode fragmentNode, Path path) { var levels = new Stack <HashSet <string> >(); levels.Push(new HashSet <string>()); return(CreateInterface(fragmentNode, path, levels)); }
private InterfaceDescriptor CreateInterface( IFragmentNode fragmentNode, Path path, Stack <HashSet <string> > levels) { HashSet <string> implementedFields = levels.Peek(); var implementedByChildren = new HashSet <string>(); levels.Push(implementedByChildren); var implements = new List <IInterfaceDescriptor>(); foreach (IFragmentNode child in fragmentNode.Children) { implements.Add(CreateInterface(child, path, levels)); } levels.Pop(); foreach (string fieldName in implementedByChildren) { implementedFields.Add(fieldName); } IReadOnlyList <IFieldDescriptor> fieldDescriptors = Array.Empty <IFieldDescriptor>(); if (fragmentNode.Fragment.TypeCondition is IComplexOutputType type) { fieldDescriptors = CreateFields( type, fragmentNode.Fragment.SelectionSet.Selections, name => { if (implementedByChildren.Add(name)) { implementedFields.Add(name); return(true); } return(false); }, path); } string typeName = CreateName( Utilities.NameUtils.GetInterfaceName( fragmentNode.Fragment.Name)); return(new InterfaceDescriptor( typeName, _namespace, fragmentNode.Fragment.TypeCondition, fieldDescriptors, implements)); }
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)); }
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); }
private ICodeDescriptor GenerateObjectSelectionSet( OperationDefinitionNode operation, ObjectType objectType, IType fieldType, WithDirectives fieldOrOperation, FieldCollectionResult typeCase, Path path) { IFragmentNode returnType = HoistFragment( objectType, typeCase.SelectionSet, typeCase.Fragments); IReadOnlyList <IFragmentNode> fragments; string className; if (returnType is null) { fragments = typeCase.Fragments; className = CreateName(fieldOrOperation, objectType, GetClassName); } else { fragments = returnType.Children; className = CreateName(GetClassName(returnType.Fragment.Name)); } var modelSelectionSet = new SelectionSetNode( typeCase.Fields.Select(t => t.Selection).ToList()); var modelFragment = new FragmentNode(new Fragment( className, objectType, modelSelectionSet)); modelFragment.Children.AddRange(fragments); IInterfaceDescriptor modelInterface = CreateInterface(modelFragment, path); var modelClass = new ClassDescriptor( className, _namespace, typeCase.Type, modelInterface); RegisterDescriptor(modelInterface); RegisterDescriptor(modelClass); RegisterDescriptor( new ResultParserMethodDescriptor( GetPathName(path), operation, fieldType, fieldOrOperation as FieldNode, path, modelInterface, new[] { new ResultParserTypeDescriptor(modelClass) })); return(modelInterface); }
private ICodeDescriptor GenerateInterfaceSelectionSet( OperationDefinitionNode operation, InterfaceType interfaceType, IType fieldType, FieldNode fieldSelection, IReadOnlyCollection <FieldCollectionResult> typeCases, Path path) { FieldCollectionResult firstCase = typeCases.First(); IFragmentNode returnType = HoistFragment( interfaceType, firstCase.SelectionSet, firstCase.Fragments); InterfaceDescriptor interfaceDescriptor; if (returnType is null) { firstCase = _fieldCollector.CollectFields( interfaceType, firstCase.SelectionSet, path); string name = CreateName(fieldSelection, interfaceType, GetClassName); var interfaceSelectionSet = new SelectionSetNode( firstCase.Fields.Select(t => t.Selection).ToList()); returnType = new FragmentNode(new Fragment( name, interfaceType, interfaceSelectionSet)); _usedNames.Remove(name); } interfaceDescriptor = CreateInterface(returnType, path); var resultParserTypes = new List <ResultParserTypeDescriptor>(); foreach (FieldCollectionResult typeCase in typeCases) { GenerateInterfaceTypeCaseModel( typeCase, returnType, resultParserTypes, path); } RegisterDescriptor(interfaceDescriptor); RegisterDescriptor( new ResultParserMethodDescriptor( GetPathName(path), operation, fieldType, fieldSelection, path, interfaceDescriptor, resultParserTypes)); return(interfaceDescriptor); }
private void GenerateInterfaceTypeCaseModel( FieldCollectionResult typeCase, IFragmentNode returnType, ICollection <ResultParserTypeDescriptor> resultParser, Path path) { string className; IReadOnlyList <IFragmentNode> fragments; IFragmentNode modelType = HoistFragment( (ObjectType)typeCase.Type, typeCase.SelectionSet, typeCase.Fragments); if (modelType is null) { fragments = typeCase.Fragments; className = CreateName(GetClassName(typeCase.Type.Name)); } else { fragments = modelType.Children; className = CreateName(GetClassName(modelType.Fragment.Name)); } var modelSelectionSet = new SelectionSetNode( typeCase.Fields.Select(t => t.Selection).ToList()); var modelFragment = new FragmentNode(new Fragment( className, typeCase.Type, modelSelectionSet)); modelFragment.Children.AddRange(fragments); if (modelFragment.Children.All(t => t.Fragment.SelectionSet != returnType.Fragment.SelectionSet)) { modelFragment.Children.Add(returnType); } IInterfaceDescriptor modelInterface = CreateInterface(modelFragment, path); var modelClass = new ClassDescriptor( className, _namespace, typeCase.Type, modelInterface); RegisterDescriptor(modelInterface); RegisterDescriptor(modelClass); resultParser.Add(new ResultParserTypeDescriptor(modelClass)); }
private void CreateClassModels( IDocumentAnalyzerContext context, OperationDefinitionNode operation, FieldNode fieldSelection, PossibleSelections possibleSelections, IFragmentNode returnTypeFragment, ComplexOutputTypeModel returnType, IType fieldType, Path path) { IReadOnlyCollection <SelectionInfo> selections = possibleSelections.Variants; if (selections.Count == 1) { ComplexOutputTypeModel modelType = CreateClassModel( context, returnTypeFragment, returnType, selections.Single(), path); CreateFieldParserModel( context, operation, fieldSelection, path, returnType, fieldType, modelType); } else { IReadOnlyList <ComplexOutputTypeModel> modelTypes = CreateClassModels( context, returnType, fieldSelection, selections, path); CreateFieldParserModel( context, operation, fieldSelection, path, returnType, fieldType, modelTypes); } }
protected IInterfaceDescriptor CreateInterfaceModel( IModelGeneratorContext context, IFragmentNode fragmentNode, Path path) { var levels = new Stack <ISet <string> >(); levels.Push(new HashSet <string>()); return(CreateInterfaceModel( context, fragmentNode, path, levels)); }
private IInterfaceDescriptor CreateInterfaceModel( IModelGeneratorContext context, IFragmentNode fragmentNode, Path path, Stack <ISet <string> > levels) { ISet <string> implementedFields = levels.Peek(); IReadOnlyList <IFieldDescriptor> fieldDescriptors = Array.Empty <IFieldDescriptor>(); IReadOnlyList <IInterfaceDescriptor> implements = CreateChildInterfaceModels( context, fragmentNode, path, levels, implementedFields); if (fragmentNode.Fragment.TypeCondition is IComplexOutputType type) { fieldDescriptors = CreateFields( type, fragmentNode.Fragment.SelectionSet.Selections, name => { if (implementedFields.Add(name)) { return(true); } return(false); }, path); } NameString interfaceName = context.GetOrCreateName( fragmentNode.Fragment.SelectionSet, GetInterfaceName(fragmentNode.Name)); var descriptor = new InterfaceDescriptor( interfaceName, context.Namespace, fragmentNode.Fragment.TypeCondition, fieldDescriptors, implements); context.Register(descriptor); return(descriptor); }
protected void CreateClassModel( IModelGeneratorContext context, IFragmentNode returnType, IInterfaceDescriptor interfaceDescriptor, SelectionInfo selection, List <ResultParserTypeDescriptor> resultParserTypes) { var modelClass = new ClassDescriptor( GetClassName(returnType.Name), context.Namespace, selection.Type, new[] { interfaceDescriptor }); context.Register(modelClass); resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass)); }
protected static IFragmentNode HoistFragment( INamedType type, IFragmentNode fragmentNode) { (SelectionSetNode s, IReadOnlyList <IFragmentNode> f)current = (fragmentNode.Fragment.SelectionSet, fragmentNode.Children); IFragmentNode selected = fragmentNode; while (!current.s.Selections.OfType <FieldNode>().Any() && current.f.Count == 1 && TypeHelpers.DoesTypeApply(current.f[0].Fragment.TypeCondition, type)) { selected = current.f[0]; current = (selected.Fragment.SelectionSet, selected.Children); } return(selected); }
private IFragmentNode HoistFragment( INamedType typeContext, SelectionSetNode selectionSet, IReadOnlyList <IFragmentNode> fragments) { (SelectionSetNode s, IReadOnlyList <IFragmentNode> f)current = (selectionSet, fragments); IFragmentNode selected = null; while (!current.s.Selections.OfType <FieldNode>().Any() && current.f.Count == 1 && current.f[0].Fragment.TypeCondition == typeContext) { selected = current.f[0]; current = (selected.Fragment.SelectionSet, selected.Children); } return(selected); }
protected void CreateClassModels( IModelGeneratorContext context, FieldNode fieldSelection, IFragmentNode returnType, IInterfaceDescriptor interfaceDescriptor, IReadOnlyCollection <SelectionInfo> selections, List <ResultParserTypeDescriptor> resultParserTypes, Path path) { foreach (SelectionInfo selection in selections) { IFragmentNode modelType = ResolveReturnType( context, selection.Type, fieldSelection, selection); var interfaces = new List <IInterfaceDescriptor>(); foreach (IFragmentNode fragment in ShedNonMatchingFragments(selection.Type, modelType)) { interfaces.Add(CreateInterfaceModel(context, fragment, path)); } interfaces.Insert(0, interfaceDescriptor); NameString typeName = HoistName(selection.Type, modelType); string className = context.GetOrCreateName( modelType.Fragment.SelectionSet, GetClassName(typeName)); var modelClass = new ClassDescriptor( className, context.Namespace, selection.Type, interfaces); context.Register(modelClass); resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass)); } }
protected NameString HoistName( INamedType type, IFragmentNode fragmentNode) { if (fragmentNode.Fragment.TypeCondition.Name.EqualsOrdinal(type.Name)) { return(fragmentNode.Name); } else { foreach (IFragmentNode child in fragmentNode.Children) { NameString name = HoistName(type, child); if (name.HasValue) { return(name); } } return(default);
public override ICodeDescriptor Generate( IModelGeneratorContext context, OperationDefinitionNode operation, ObjectType namedType, IType fieldType, FieldNode fieldSelection, PossibleSelections possibleSelections, Path path) { IFragmentNode returnType = ResolveReturnType( context, namedType, fieldSelection, possibleSelections.ReturnType); IInterfaceDescriptor interfaceDescriptor = CreateInterfaceModel( context, returnType, path); context.Register(fieldSelection, interfaceDescriptor); var resultParserTypes = new List <ResultParserTypeDescriptor>(); CreateClassModel( context, returnType, interfaceDescriptor, possibleSelections.ReturnType, resultParserTypes); context.Register( new ResultParserMethodDescriptor( GetPathName(path), operation, fieldType, fieldSelection, path, interfaceDescriptor, resultParserTypes)); return(interfaceDescriptor); }
protected void CreateClassModel( IModelGeneratorContext context, IFragmentNode returnType, IInterfaceDescriptor interfaceDescriptor, SelectionInfo selection, List <ResultParserTypeDescriptor> resultParserTypes) { var fieldNames = new HashSet <string>( selection.Fields.Select(t => GetPropertyName(t.ResponseName))); string className = context.GetOrCreateName( returnType.Fragment.SelectionSet, GetClassName(returnType.Name), fieldNames); var modelClass = new ClassDescriptor( className, context.Namespace, selection.Type, new[] { interfaceDescriptor }); context.Register(modelClass); resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass)); }
protected void CreateClassModels( IModelGeneratorContext context, FieldNode fieldSelection, IFragmentNode returnType, IInterfaceDescriptor interfaceDescriptor, IReadOnlyCollection <SelectionInfo> selections, List <ResultParserTypeDescriptor> resultParserTypes, Path path) { foreach (SelectionInfo selection in selections) { IFragmentNode modelType = ResolveReturnType( context, selection.Type, fieldSelection, selection); var interfaces = new List <IInterfaceDescriptor>(); foreach (IFragmentNode fragment in ShedNonMatchingFragments(selection.Type, modelType)) { interfaces.Add(CreateInterfaceModel(context, fragment, path)); } interfaces.Insert(0, interfaceDescriptor); 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.TryGetDescriptor(className, out ClassDescriptor? modelClass)) { var interfaceNames = new HashSet <string>(interfaces.Select(t => t.Name)); foreach (IInterfaceDescriptor item in modelClass !.Implements.Reverse()) { if (!interfaceNames.Contains(item.Name)) { interfaces.Insert(0, item); } } update = true; } modelClass = new ClassDescriptor( className, context.Namespace, selection.Type, interfaces); context.Register(modelClass, update); resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass)); } }
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); }
private ICodeDescriptor GenerateUnionSelectionSet( OperationDefinitionNode operation, UnionType unionType, IType fieldType, FieldNode fieldSelection, IReadOnlyCollection <FieldCollectionResult> typeCases, Path path) { IFragmentNode returnType = null; FieldCollectionResult result = typeCases.First(); IReadOnlyList <IFragmentNode> fragments = result.Fragments; while (fragments.Count == 1) { if (fragments[0].Fragment.TypeCondition == unionType) { returnType = fragments[0]; fragments = fragments[0].Children; } else { break; } } InterfaceDescriptor unionInterface; if (returnType is null) { string name = CreateName( fieldSelection, unionType, Utilities.NameUtils.GetInterfaceName); unionInterface = new InterfaceDescriptor( name, _namespace, unionType); } else { unionInterface = CreateInterface(returnType, path); unionInterface = unionInterface.RemoveAllImplements(); } var resultParserTypes = new List <ResultParserTypeDescriptor>(); foreach (var typeCase in typeCases) { string className; string interfaceName; IFragmentNode fragment = typeCase.Fragments.FirstOrDefault( t => t.Fragment.TypeCondition == typeCase.Type); if (fragment is null) { className = CreateName(typeCase.Type.Name); interfaceName = CreateName(GetInterfaceName(className)); } else { className = CreateName(fragment.Fragment.Name); interfaceName = CreateName(GetInterfaceName(fragment.Fragment.Name)); } var modelInterfaces = new List <IInterfaceDescriptor>(); modelInterfaces.Add( new InterfaceDescriptor( interfaceName, _namespace, typeCase.Type, typeCase.Fields.Select(t => { string responseName = (t.Selection.Alias ?? t.Selection.Name).Value; return(new FieldDescriptor( t.Field, t.Selection, t.Field.Type, t.Path.Append(responseName))); }).ToList(), new[] { unionInterface })); modelInterfaces.AddRange(CreateInterfaces(typeCase.Fragments, path)); var modelClass = new ClassDescriptor( className, _namespace, typeCase.Type, modelInterfaces); RegisterDescriptors(modelInterfaces); RegisterDescriptor(modelClass); resultParserTypes.Add(new ResultParserTypeDescriptor(modelClass)); } RegisterDescriptor(unionInterface); RegisterDescriptor( new ResultParserMethodDescriptor( GetPathName(path), operation, fieldType, fieldSelection, path, unionInterface, resultParserTypes)); return(unionInterface); }