Esempio n. 1
0
 public FlagSetInputEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor,
                              InputValueEvaluator[] valueEvals)
     : base(inputDef, resultTypeRef, anchor)
 {
     ElemEvaluators = valueEvals;
     EnumTypeDef    = (EnumTypeDef)ResultTypeRef.TypeDef;
 }
Esempio n. 2
0
        private IList <InputValueDef> BuildArgDefs(IList <ParameterInfo> parameters, MethodBase method)
        {
            var argDefs = new List <InputValueDef>();

            foreach (var prm in parameters)
            {
                var attrs      = GetAllAttributes(prm, method);
                var prmTypeRef = GetTypeRef(prm.ParameterType, prm, $"Method {method.Name}, parameter {prm.Name}", method);
                if (prmTypeRef == null)
                {
                    continue;
                }
                if (prmTypeRef.IsList && !prmTypeRef.TypeDef.IsEnumFlagArray())
                {
                    VerifyListParameterType(prm.ParameterType, method, prm.Name);
                }
                var dftValue = prm.DefaultValue == DBNull.Value ? null : prm.DefaultValue;
                var argDef   = new InputValueDef()
                {
                    Name      = GetGraphQLName(prm), TypeRef = prmTypeRef, Attributes = attrs,
                    ParamType = prm.ParameterType, HasDefaultValue = prm.HasDefaultValue, DefaultValue = dftValue
                };
                argDef.Directives = BuildDirectivesFromAttributes(prm, DirectiveLocation.ArgumentDefinition, argDef);
                argDefs.Add(argDef);
            }
            return(argDefs);
        }
        private InputValueEvaluator GetInputListEvaluator(InputValueDef inputDef, ValueSource valueSource, TypeRef listTypeRef)
        {
            if (valueSource.IsConstNull())
            {
                if (listTypeRef.IsNotNull)
                {
                    throw new InvalidInputException("Input type '{valueTypeRef.Name}' is not-null type, but null was encountered.",
                                                    valueSource);
                }
            }
            if (!(valueSource is ListValueSource arrValue))
            {
                throw new InvalidInputException($"Input type '{listTypeRef.Name}' is not list or array, expected array.", valueSource);
            }
            var elemTypeRef = listTypeRef.GetListElementTypeRef();

            if (elemTypeRef == null)
            {
                throw new InvalidInputException($"Invalid input value for type {listTypeRef.Name}, expected list", valueSource);
            }
            var elemEvalList = arrValue.Values.Select(v => GetInputValueEvaluator(inputDef, v, elemTypeRef)).ToArray();

            // it can be regular array or enum flag set (which is special)
            if (elemTypeRef.TypeDef.IsEnumFlagArray())
            {
                return(new FlagSetInputEvaluator(inputDef, listTypeRef, valueSource, elemEvalList));
            }
            else
            {
                return(new InputListEvaluator(inputDef, listTypeRef, valueSource, elemEvalList));
            }
        }
Esempio n. 4
0
        private IList <InputValueDef> BuildArgDefs(IList <ParameterInfo> parameters, MethodBase method)
        {
            var argDefs = new List <InputValueDef>();

            foreach (var prm in parameters)
            {
                var attrs      = GetAllAttributesAndAdjustments(prm, method);
                var prmTypeRef = GetMemberGraphQLTypeRef(prm.ParameterType, prm, $"Method {method.Name}, parameter {prm.Name}", method);
                if (prmTypeRef == null)
                {
                    continue;
                }
                if (prmTypeRef.IsList && !prmTypeRef.TypeDef.IsEnumFlagArray())
                {
                    VerifyListParameterType(prm.ParameterType, method, prm.Name);
                }
                var dftValue = prm.DefaultValue == DBNull.Value ? null : prm.DefaultValue;
                // special case: if default value is null, it is nullable
                if (prm.HasDefaultValue && dftValue == null && prmTypeRef.Kind == TypeKind.NonNull)
                {
                    prmTypeRef = prmTypeRef.Inner; // nullable
                }
                var argDef = new InputValueDef()
                {
                    Name      = GetGraphQLName(prm), TypeRef = prmTypeRef, Attributes = attrs,
                    ParamType = prm.ParameterType, HasDefaultValue = prm.HasDefaultValue, DefaultValue = dftValue
                };
                argDef.Directives = BuildDirectivesFromAttributes(prm, DirectiveLocation.ArgumentDefinition);
                argDefs.Add(argDef);
            }
            return(argDefs);
        }
        private ConstInputValue CreateConstantInputValue(InputValueDef inputDef, RequestObjectBase anchor, TypeRef resultTypeRef, object value)
        {
            // We convert const value upfront to target typeRef
            var convValue = _requestContext.ValidateConvert(value, resultTypeRef, anchor);
            var constEval = new ConstInputValue(inputDef, resultTypeRef, anchor, convValue);

            return(constEval);
        }
        private InputValueEvaluator GetInputValueEvaluatorImpl(InputValueDef inputDef, ValueSource valueSource, TypeRef resultTypeRef)
        {
            if (valueSource is VariableValueSource vref)
            {
                return(GetVariableRefEvaluator(inputDef, resultTypeRef, vref));
            }
            if (resultTypeRef.IsList)
            {
                return(GetInputListEvaluator(inputDef, valueSource, resultTypeRef));
            }

            switch (resultTypeRef.TypeDef)
            {
            case ScalarTypeDef stdef:
                if (valueSource is TokenValueSource tknIv)
                {
                    var constValue = stdef.Scalar.ParseToken(_requestContext, tknIv.TokenData);
                    return(CreateConstantInputValue(inputDef, valueSource, resultTypeRef, constValue));
                }
                else
                {
                    throw new InvalidInputException("invalid input value, expected scalar", valueSource);
                }

            case EnumTypeDef etdef:
                if (etdef.IsFlagSet && valueSource is ListValueSource)
                {
                    return(GetInputListEvaluator(inputDef, valueSource, resultTypeRef));
                }
                if (valueSource is TokenValueSource tknValueSrc)
                {
                    if (tknValueSrc.TokenData.TermName != TermNames.Name)
                    {
                        throw new InvalidInputException($"Invalid value '{tknValueSrc.TokenData.Text}', expected Enum value.", valueSource);
                    }
                    var vname   = tknValueSrc.TokenData.Text;
                    var enumVal = etdef.EnumValues.FirstOrDefault(ev => ev.Name == vname);
                    if (enumVal == null)
                    {
                        throw new InvalidInputException($"Invalid value '{vname}' for enum '{etdef.ClrType.Name}'.", valueSource);
                    }
                    return(CreateConstantInputValue(inputDef, tknValueSrc, resultTypeRef, enumVal.ClrValue));
                }
                else
                {
                    throw new InvalidInputException($"Invalid input value, expected enum value.", valueSource);
                }

            case InputObjectTypeDef inpObjDef:
                return(GetInputObjectEvaluator(inputDef, valueSource, resultTypeRef));

            default:
                return(null); //never happens
            }
        }
Esempio n. 7
0
 public InputValueEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor)
 {
     InputDef      = inputDef;
     ResultTypeRef = resultTypeRef;
     Anchor        = anchor;
     // prepare directives
     if (inputDef.Directives != null)
     {
         Directives = inputDef.Directives.Where(d => d.Def.Handler is IInputValueDirectiveAction)
                      .Select(d => new RuntimeModelDirective(d)).ToList();
     }
 }
Esempio n. 8
0
 public InputListEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor,
                           InputValueEvaluator[] elemEvaluators) : base(inputDef, resultTypeRef, anchor)
 {
     ElemEvaluators = elemEvaluators;
     if (ResultTypeRef.Kind == TypeKind.NonNull)
     {
         ElemTypeRef = ResultTypeRef.Inner.Inner;
     }
     else
     {
         ElemTypeRef = ResultTypeRef.Inner;
     }
 }
Esempio n. 9
0
        }         //method

        private string FormatArg(InputValueDef argDef, object value)
        {
            string strV;

            if (value == null)
            {
                strV = "null";
            }
            else
            {
                strV = argDef.TypeRef.TypeDef.ToSchemaDocString(value);
            }
            return($"{argDef.Name}: {strV}");
        }
Esempio n. 10
0
        private IList <VariableDef> BuildOperationVariables(Node varDefsNode)
        {
            if (varDefsNode == null)
            {
                return(VariableDef.EmptyList);
            }

            var varList = new List <VariableDef>();

            foreach (var vn in varDefsNode.ChildNodes)
            {
                var name = vn.ChildNodes[0].GetText();
                // remove $ prefix; we define/track var name as a token without $; in Http/Json request variables are referenced without prefix;
                //     see https://graphql.org/learn/serving-over-http/#post-request
                name = name.Substring(1);
                var typeRef = BuildTypeReference(vn.ChildNodes[1]);
                if (typeRef == null)
                {
                    continue; // error already posted
                }
                var typeDef = typeRef.TypeDef;
                if (!_allowedVarTypeKinds.Contains(typeDef.Kind))
                {
                    AddError($"Invalid variable type ( {name}: {typeRef.Name}). Only scalar, enum or input types are allowed.", vn);
                    continue;
                }
                var inpDef = new InputValueDef()
                {
                    Name = name, TypeRef = typeRef
                };
                var varDef = new VariableDef()
                {
                    Name = name, InputDef = inpDef, SourceLocation = vn.GetLocation()
                };
                // check default value
                if (vn.ChildNodes.Count > 2)
                {
                    varDef.ParsedDefaultValue = BuildInputValue(vn.ChildNodes[2], varDef);
                }
                // directives
                var dirListNode = vn.FindChild(TermNames.DirListOpt);
                if (dirListNode != null)
                {
                    varDef.DirectiveRefs = BuildDirectives(dirListNode, DirectiveLocation.VariableDefinition, varDef);
                }
                varList.Add(varDef);
            }
            return(varList);
        }
Esempio n. 11
0
        private VariableRefEvaluator GetVariableRefEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, VariableValueSource varRef)
        {
            var varDecl = _currentOp.Variables.FirstOrDefault(vd => vd.Name == varRef.VariableName);

            if (varDecl == null)
            {
                throw new InvalidInputException($"Variable ${varRef.VariableName} not defined.", varRef);
            }
            // check type compatibility
            if (!resultTypeRef.IsConvertibleFrom(varDecl.InputDef.TypeRef))
            {
                throw new InvalidInputException(
                          $"Incompatible types: variable ${varRef.VariableName} cannot be converted to type '{resultTypeRef.Name}'", varRef);
            }
            return(new VariableRefEvaluator(inputDef, varDecl));
        }
Esempio n. 12
0
        internal InputValueEvaluator GetInputValueEvaluator(InputValueDef inputDef, ValueSource valueSource, TypeRef valueTypeRef)
        {
            if (valueSource.IsConstNull())
            {
                return(CreateConstantInputValue(inputDef, valueSource, valueTypeRef, null));
            }
            var eval = GetInputValueEvaluatorImpl(inputDef, valueSource, valueTypeRef);

            // replace with constant if it does not depend on vars
            if (eval.IsConst())
            {
                var value = eval.GetValue(_requestContext);
                eval = CreateConstantInputValue(inputDef, valueSource, valueTypeRef, value);
            }
            return(eval);
        }
Esempio n. 13
0
        private IList <VariableDef> BuildOperationVariables(Node varDefsNode)
        {
            if (varDefsNode == null)
            {
                return(VariableDef.EmptyList);
            }

            var varList = new List <VariableDef>();

            foreach (var vn in varDefsNode.ChildNodes)
            {
                var name    = vn.ChildNodes[0].ChildNodes[1].Token.Text;
                var typeRef = BuildTypeReference(vn.ChildNodes[1]);
                if (typeRef == null)
                {
                    continue; // error already posted
                }
                var typeDef = typeRef.TypeDef;
                if (!_allowedVarTypeKinds.Contains(typeDef.Kind))
                {
                    AddError($"Invalid variable type ( {name}: {typeRef.Name}). Only scalar, enum or input types are allowed.", vn);
                    continue;
                }
                var inpDef = new InputValueDef()
                {
                    Name = name, TypeRef = typeRef
                };
                var varDef = new VariableDef()
                {
                    Name = name, InputDef = inpDef, SourceLocation = vn.GetLocation()
                };
                // check default value
                if (vn.ChildNodes.Count > 2)
                {
                    varDef.ParsedDefaultValue = BuildInputValue(vn.ChildNodes[2], varDef);
                }
                // directives
                var dirListNode = vn.FindChild(TermNames.DirListOpt);
                if (dirListNode != null)
                {
                    varDef.DirectiveRefs = BuildDirectives(dirListNode, DirectiveLocation.VariableDefinition, varDef);
                }
                varList.Add(varDef);
            }
            return(varList);
        }
Esempio n. 14
0
 private void Append(InputValueDef valueDef, bool indent = false)
 {
     AppendDescr(valueDef.Description, true);
     if (indent)
     {
         _builder.Append(Indent);
     }
     _builder.Append(valueDef.Name);
     _builder.Append(": ");
     _builder.Append(valueDef.TypeRef.Name);
     if (valueDef.HasDefaultValue)
     {
         _builder.Append(" = ");
         var tdef = valueDef.TypeRef.TypeDef;
         _builder.Append(tdef.ToSchemaDocString(valueDef.DefaultValue));
     }
     AppendDirs(valueDef);
 }
Esempio n. 15
0
        private void BuildInputObjectFields(InputObjectTypeDef inpTypeDef)
        {
            var members = inpTypeDef.ClrType.GetFieldsProps();

            foreach (var member in members)
            {
                var attrs   = GetAllAttributes(member);
                var mtype   = member.GetMemberReturnType();
                var typeRef = GetTypeRef(mtype, member, $"Field {inpTypeDef.Name}.{member.Name}");
                if (typeRef == null)
                {
                    return; // error found, it is already logged
                }
                if (typeRef.IsList && !typeRef.TypeDef.IsEnumFlagArray())
                {
                    // list members must be IList<T> or T[] - this is important, lists are instantiated as arrays when deserializing
                    if (!mtype.IsArray && !mtype.IsInterface)
                    {
                        AddError($"Input type member {inpTypeDef.Name}.{member.Name}: list must be either array or IList<T>.");
                        continue;
                    }
                }
                switch (typeRef.TypeDef.Kind)
                {
                case TypeKind.Scalar:
                case TypeKind.Enum:
                case TypeKind.InputObject:
                    break;

                default:
                    AddError($"Input type member {inpTypeDef.Name}.{member.Name}: type {mtype} is not scalar or input type.");
                    continue;
                }
                var inpFldDef = new InputValueDef()
                {
                    Name = member.Name.FirstLower(), TypeRef = typeRef, Attributes = attrs,
                    InputObjectClrMember = member,
                    Description          = _docLoader.GetDocString(member, member.DeclaringType)
                };
                inpFldDef.Directives = BuildDirectivesFromAttributes(member, DirectiveLocation.InputFieldDefinition, inpFldDef);
                inpTypeDef.Fields.Add(inpFldDef);
            } //foreach
        }
        private InputObjectEvaluator GetInputObjectEvaluator(InputValueDef inputDef, ValueSource valueSource, TypeRef typeRef)
        {
            var inpObjTypeDef = (InputObjectTypeDef)typeRef.TypeDef;

            // valueSource is not null (its value), we already checked it before coming here
            if (!(valueSource is ObjectValueSource parsedInputObj))
            {
                throw new InvalidInputException($"Value is not InputObject, expected value of type '{typeRef.Name}'.", valueSource);
            }
            var fields = new List <InputFieldEvalInfo>();

            foreach (var fldDef in inpObjTypeDef.Fields)
            {
                InputValueEvaluator fldEval;
                if (parsedInputObj.Fields.TryGetValue(fldDef.Name, out var inpValue))
                {
                    fldEval = GetInputValueEvaluator(fldDef, inpValue, fldDef.TypeRef);
                }
                else if (fldDef.HasDefaultValue)
                {
                    fldEval = CreateConstantInputValue(fldDef, valueSource, typeRef, fldDef.DefaultValue);
                }
                else if (!fldDef.TypeRef.IsNotNull)
                {
                    fldEval = CreateConstantInputValue(fldDef, valueSource, typeRef, null);
                }
                else
                {
                    throw new InvalidInputException($"Missing value for field '{fldDef.Name}'.", valueSource);
                }
                fields.Add(new InputFieldEvalInfo()
                {
                    FieldDef = fldDef, ValueEvaluator = fldEval
                });
                // TODO: add check that there are no 'extra' members in parsed object
            }
            var result = new InputObjectEvaluator(inputDef, typeRef, valueSource, fields);

            return(result);
        }
Esempio n. 17
0
 public InputValueEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor)
 {
     InputDef      = inputDef;
     ResultTypeRef = resultTypeRef;
     Anchor        = anchor;
 }
Esempio n. 18
0
 public VariableRefEvaluator(InputValueDef inputDef, VariableDef varDecl) : base(inputDef, varDecl.InputDef.TypeRef, varDecl)
 {
     Variable = varDecl;
 }
Esempio n. 19
0
 public ConstInputValue(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor, object value)
     : base(inputDef, resultTypeRef, anchor)
 {
     Value = value;
 }
Esempio n. 20
0
 public InputObjectEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor,
                             IList <InputFieldEvalInfo> fields)  : base(inputDef, resultTypeRef, anchor)
 {
     Fields = fields;
 }