예제 #1
0
        private void MapSelectionSubSet(SelectionSubset selSubset, TypeDefBase typeDef)
        {
            switch (typeDef)
            {
            case ScalarTypeDef _:
            case EnumTypeDef _:
                // that should never happen
                AddError($"Scalar or Enum may not have a selection subset", selSubset);
                break;

            case ObjectTypeDef objTypeDef:
                MapObjectSelectionSubset(selSubset, objTypeDef);
                break;

            case InterfaceTypeDef intTypeDef:
                foreach (var objType in intTypeDef.PossibleTypes)
                {
                    MapObjectSelectionSubset(selSubset, objType);
                }
                break;

            case UnionTypeDef unionTypeDef:
                foreach (var objType in unionTypeDef.PossibleTypes)
                {
                    MapObjectSelectionSubset(selSubset, objType, isForUnion: true);
                }
                break;
            }
        }
        private void RegisterTypeDef(TypeDefBase typeDef)
        {
            _model.Types.Add(typeDef);
            // do not register further (by name or CLR type) the special objects
            if (typeDef is ObjectTypeDef otd && otd.TypeRole != ObjectTypeRole.Data)
            {
                return;
            }
            // data types - we register them by name and CLR type; they always have module and CLR type
            var modName = typeDef.Module.Name;

            if (typeDef.IsDefaultForClrType)
            {
                if (_model.TypesByClrType.ContainsKey(typeDef.ClrType))
                {
                    AddError($"Duplicate registration of type {typeDef.Name} as default for CLR type {typeDef.ClrType}, module {modName}.");
                    return;
                }
                _model.TypesByClrType.Add(typeDef.ClrType, typeDef);
            }
            if (_model.TypesByName.ContainsKey(typeDef.Name))
            {
                AddError($"GraphQL type {typeDef.Name} already registered; module: {modName}.");
                return;
            }
            _model.TypesByName.Add(typeDef.Name, typeDef);
        }
예제 #3
0
 public static bool IsOneOf(this TypeDefBase typeDef, params TypeKind[] kinds)
 {
     for (int i = 0; i < kinds.Length; i++)
     {
         if (typeDef.Kind == kinds[i])
         {
             return(true);
         }
     }
     return(false);
 }
예제 #4
0
 public FieldContext(RequestContext requestContext, OperationFieldExecuter fieldExecuter, MappedSelectionField mappedField,
                     IList <OutputObjectScope> allParentScopes = null)
 {
     _requestContext = requestContext;
     _executer       = fieldExecuter;
     MappedField     = mappedField;
     FieldDef        = MappedField.Resolver.Field;
     TypeDef         = FieldDef.TypeRef.TypeDef;
     AllParentScopes = allParentScopes ?? OutputObjectScope.EmptyList;
     if (MappedField.Field.SelectionSubset != null)
     {
         AllResultScopes = new List <OutputObjectScope>();
     }
 }
예제 #5
0
        private void RegisterTypeDef(TypeDefBase typeDef)
        {
            _model.Types.Add(typeDef);
            // data types - we register them by name and CLR type; they always have module and CLR type
            var modName = typeDef.Module?.Name ?? "(no module)";

            if (typeDef.ClrType != null && typeDef.IsDefaultForClrType)
            {
                if (_model.TypesByClrType.ContainsKey(typeDef.ClrType))
                {
                    AddError($"Duplicate registration of type {typeDef.Name} as default for CLR type {typeDef.ClrType}, module {modName}.");
                    return;
                }
                _model.TypesByClrType.Add(typeDef.ClrType, typeDef);
            }
            if (_model.TypesByName.ContainsKey(typeDef.Name))
            {
                AddError($"GraphQL type {typeDef.Name} already registered; module: {modName}.");
                return;
            }
            _model.TypesByName.Add(typeDef.Name, typeDef);
        }
예제 #6
0
        private void CreateTypeObject(TypeDefBase typeDef)
        {
            var type_ = new __Type()
            {
                Name = typeDef.Name, Kind = typeDef.Kind, Description = typeDef.Description, DisplayName = typeDef.Name,
            };

            typeDef.Intro_ = type_;
            _schema.Types.Add(type_);

            // Initialize lists - we do this for all types upfront to allow Build methods to access other type's lists
            //  without worrying if it is created or not. For ex, BuildObjectType finds interfaces and adds itself
            //  to PossibleTypes list of each interface it implements
            switch (type_.Kind)
            {
            case TypeKind.Object:
                type_.Fields     = new List <__Field>();
                type_.Interfaces = new List <__Type>();
                break;

            case TypeKind.Interface:
                type_.Fields        = new List <__Field>();
                type_.PossibleTypes = new List <__Type>();
                break;

            case TypeKind.InputObject:
                type_.InputFields = new List <__InputValue>();
                break;

            case TypeKind.Enum:
                type_.EnumValues = new List <__EnumValue>();
                break;

            case TypeKind.Union:
                type_.PossibleTypes = new List <__Type>();
                break;
            }
        }
예제 #7
0
        private void MapSelectionFieldSubsetIfPresent(SelectionField selField, TypeDefBase fieldType)
        {
            var selSubset = selField.SelectionSubset;

            switch (fieldType)
            {
            case ScalarTypeDef _:
            case EnumTypeDef _:
                if (selSubset != null)
                {
                    AddError($"Field '{selField.Key}' of type '{fieldType.Name}' may not have a selection subset.", selSubset);
                }
                break;

            default: // ObjectType, Union or Interface
                if (selSubset == null)
                {
                    AddError($"Field '{selField.Key}' of type '{fieldType.Name}' must have a selection subset.", selField);
                    return;
                }
                MapSelectionSubSet(selSubset, fieldType);
                break;
            }
        }
예제 #8
0
        public static ObjectTypeMapping FindMapping(this TypeDefBase typeDef, Type fromType)
        {
            ObjectTypeMapping mapping = null;

            switch (typeDef)
            {
            case ObjectTypeDef otd:
                mapping = otd.FindObjectTypeMapping(fromType);
                break;

            case InterfaceTypeDef itd:
                mapping = FindObjectTypeMapping(itd.PossibleTypes, fromType);
                break;

            case UnionTypeDef utd:
                mapping = FindObjectTypeMapping(utd.PossibleTypes, fromType);
                break;

            default:
                // should never happen
                throw new Exception($"FATAL: Invalid target type kind {typeDef.Kind}, type {typeDef.Name}");
            }
            return(mapping);
        }
예제 #9
0
        } //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);
        }