internal ComInvokeBinder( CallInfo callInfo, DynamicMetaObject[] args, bool[] isByRef, BindingRestrictions restrictions, Expression method, Expression dispatch, ComMethodDesc methodDesc ) { Debug.Assert(callInfo != null, "arguments"); Debug.Assert(args != null, "args"); Debug.Assert(isByRef != null, "isByRef"); Debug.Assert(method != null, "method"); Debug.Assert(dispatch != null, "dispatch"); Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(ComMethodDesc), method.Type), "method"); Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(IDispatch), dispatch.Type), "dispatch"); _method = method; _dispatch = dispatch; _methodDesc = methodDesc; _callInfo = callInfo; _args = args; _isByRef = isByRef; _restrictions = restrictions; // Set Instance to some value so that CallBinderHelper has the right number of parameters to work with _instance = dispatch; }
/// <summary> /// Initializes a new instance of the <see cref="DynamicMetaObject"/> class. /// </summary> /// <param name="expression">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param> /// <param name="restrictions">The set of binding restrictions under which the binding is valid.</param> public DynamicMetaObject(Expression expression, BindingRestrictions restrictions) { ContractUtils.RequiresNotNull(expression, "expression"); ContractUtils.RequiresNotNull(restrictions, "restrictions"); _expression = expression; _restrictions = restrictions; }
/// <summary> /// Merges the set of binding restrictions with the current binding restrictions. /// </summary> /// <param name="restrictions">The set of restrictions with which to merge the current binding restrictions.</param> /// <returns>The new set of binding restrictions.</returns> public BindingRestrictions Merge(BindingRestrictions restrictions) { ContractUtils.RequiresNotNull(restrictions, "restrictions"); if (this == Empty) { return restrictions; } if (restrictions == Empty) { return this; } return new MergedRestriction(this, restrictions); }
private static DynamicMetaObject NoThisParam(DynamicMetaObjectBinder binder, BindingRestrictions restrictions) { return new DynamicMetaObject( binder.Throw( Expression.Call( typeof(PythonOps).GetMethod("ValueError"), Expression.Constant("native com method call without 'this' parameter"), Expression.NewArrayInit(typeof(object)) ), typeof(object) ), restrictions ); }
DynamicMetaObject BindSetMember(object key, Expression value, DynamicMetaObjectBinder binder, BindingRestrictions additional, Func <DynamicMetaObject> fallback) { IForceMemberCreatable creatable = binder as IForceMemberCreatable; var v = Expression.Variable(typeof(object)); var accessible = binder as IDirectAccessible; var exp = Expression.Block(new[] { v }, Expression.Assign(v, Expression.Convert(value, v.Type)), Expression.Condition( Expression.Call( LimitedInstance, (MethodInfo)Utils.GetMember(() => Value.TrySetValue(null, false, false, null)), Expression.Constant(key, typeof(object)), Expression.Constant(accessible != null && accessible.DirectAccess), Expression.Constant(creatable == null || creatable.ForceCreate), v ), v, Expression.Convert(fallback().Expression, typeof(object)) ) ); return(Restrict(exp, binder, additional)); }
public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value) { return(BindSetMember(indexes[0].Value, value.Expression, binder, BindingRestrictions.GetInstanceRestriction(indexes[0].Expression, indexes[0].Value), () => base.BindSetIndex(binder, indexes, value))); }
public BindingRestrictionsProxy(BindingRestrictions node) { _node = node; }
public DynamicMetaNode( Expression parameter, BindingRestrictions rest, object value ) : base( parameter, rest, value ) { }
private static DynamicMetaObject IncorrectArgCount(BindingRestrictions restrictions, int expected, int got) { return new DynamicMetaObject( Expression.Throw( Expression.Call( typeof(PythonOps).GetMethod("TypeError"), Expression.Constant(String.Format("this function takes {0} arguments ({1} given)", expected, got)), Expression.NewArrayInit(typeof(object)) ), typeof(object) ), restrictions ); }
internal ComFallbackMetaObject(Expression expression, BindingRestrictions restrictions, object arg) : base(expression, restrictions, arg) { }
private DynamicMetaObject MakeArrayIndexRule(OverloadResolverFactory factory, IndexType oper, DynamicMetaObject[] args) { if (CanConvertFrom(GetArgType(args, 1), typeof(int), false, NarrowingLevel.All)) { BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args)); if (oper == IndexType.Get) { return(new DynamicMetaObject( Ast.ArrayAccess( args[0].Expression, ConvertIfNeeded(factory, args[1].Expression, typeof(int)) ), restrictions )); } else { return(new DynamicMetaObject( Ast.Assign( Ast.ArrayAccess( args[0].Expression, ConvertIfNeeded(factory, args[1].Expression, typeof(int)) ), ConvertIfNeeded(factory, args[2].Expression, args[0].GetLimitType().GetElementType()) ), restrictions.Merge(args[1].Restrictions) )); } } return(null); }
private DynamicMetaObject TryMakeBindingTarget(OverloadResolverFactory resolverFactory, MethodInfo[] targets, DynamicMetaObject[] args, BindingRestrictions restrictions) { var resolver = resolverFactory.CreateOverloadResolver(args, new CallSignature(args.Length), CallTypes.None); BindingTarget target = resolver.ResolveOverload(targets[0].Name, targets, NarrowingLevel.None, NarrowingLevel.All); if (target.Success) { return(new DynamicMetaObject( target.MakeExpression(), restrictions.Merge(target.RestrictedArguments.GetAllRestrictions()) )); } return(null); }
private static DynamicMetaObject TryPrimitiveCompare(OperatorInfo info, DynamicMetaObject[] args) { if (TypeUtils.GetNonNullableType(args[0].GetLimitType()) == TypeUtils.GetNonNullableType(args[1].GetLimitType()) && TypeUtils.IsNumeric(args[0].GetLimitType())) { Expression arg0 = args[0].Expression; Expression arg1 = args[1].Expression; // TODO: Nullable<PrimitveType> Support Expression expr; switch (info.Operator) { case ExpressionType.Equal: expr = Ast.Equal(arg0, arg1); break; case ExpressionType.NotEqual: expr = Ast.NotEqual(arg0, arg1); break; case ExpressionType.GreaterThan: expr = Ast.GreaterThan(arg0, arg1); break; case ExpressionType.LessThan: expr = Ast.LessThan(arg0, arg1); break; case ExpressionType.GreaterThanOrEqual: expr = Ast.GreaterThanOrEqual(arg0, arg1); break; case ExpressionType.LessThanOrEqual: expr = Ast.LessThanOrEqual(arg0, arg1); break; default: throw new InvalidOperationException(); } return(new DynamicMetaObject( expr, BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg0, args[0].GetLimitType()).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg1, args[0].GetLimitType())).Merge(BindingRestrictions.Combine(args)) )); } return(null); }
private static DynamicMetaObject TryMakeDefaultUnaryRule(OperatorInfo info, DynamicMetaObject[] args) { if (args.Length == 1) { BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args)); switch (info.Operator) { case ExpressionType.IsTrue: if (args[0].GetLimitType() == typeof(bool)) { return(args[0]); } break; case ExpressionType.Negate: if (TypeUtils.IsArithmetic(args[0].GetLimitType())) { return(new DynamicMetaObject( Ast.Negate(args[0].Expression), restrictions )); } break; case ExpressionType.Not: if (TypeUtils.IsIntegerOrBool(args[0].GetLimitType())) { return(new DynamicMetaObject( Ast.Not(args[0].Expression), restrictions )); } break; } } return(null); }
/// <summary> /// Produces a rule for comparing a value to null - supports comparing object references and nullable types. /// </summary> private static DynamicMetaObject TryNullComparisonRule(DynamicMetaObject[] args) { Type otherType = args[1].GetLimitType(); BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args)); if (args[0].GetLimitType() == typeof(DynamicNull)) { if (!otherType.IsValueType) { return(new DynamicMetaObject( Ast.Equal(args[0].Expression, AstUtils.Constant(null)), restrictions )); } else if (otherType.GetGenericTypeDefinition() == typeof(Nullable <>)) { return(new DynamicMetaObject( Ast.Property(args[0].Expression, otherType.GetProperty("HasValue")), restrictions )); } } else if (otherType == typeof(DynamicNull)) { if (!args[0].GetLimitType().IsValueType) { return(new DynamicMetaObject( Ast.Equal(args[0].Expression, AstUtils.Constant(null)), restrictions )); } else if (args[0].GetLimitType().GetGenericTypeDefinition() == typeof(Nullable <>)) { return(new DynamicMetaObject( Ast.Property(args[0].Expression, otherType.GetProperty("HasValue")), restrictions )); } } return(null); }
private DynamicMetaObject TryToCharConversion(DynamicMetaObject /*!*/ self) { DynamicMetaObject res; // we have an implicit conversion to char if the // string length == 1, but we can only represent // this is implicit via a rule. string strVal = self.Value as string; Expression strExpr = self.Expression; if (strVal == null) { Extensible <string> extstr = self.Value as Extensible <string>; if (extstr != null) { strVal = extstr.Value; strExpr = Ast.Property( AstUtils.Convert( strExpr, typeof(Extensible <string>) ), typeof(Extensible <string>).GetProperty("Value") ); } } // we can only produce a conversion if we have a string value... if (strVal != null) { self = self.Restrict(self.GetRuntimeType()); Expression getLen = Ast.Property( AstUtils.Convert( strExpr, typeof(string) ), typeof(string).GetProperty("Length") ); if (strVal.Length == 1) { res = new DynamicMetaObject( Ast.Call( AstUtils.Convert(strExpr, typeof(string)), typeof(string).GetMethod("get_Chars"), AstUtils.Constant(0) ), self.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Ast.Equal(getLen, AstUtils.Constant(1)))) ); } else { res = new DynamicMetaObject( this.Throw( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.TypeError)), AstUtils.Constant("expected string of length 1 when converting to char, got '{0}'"), Ast.NewArrayInit(typeof(object), self.Expression) ), ReturnType ), self.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Ast.NotEqual(getLen, AstUtils.Constant(1)))) ); } } else { // let the base class produce the rule res = null; } return(res); }
internal DynamicMetaObject FallbackConvert(Type returnType, DynamicMetaObject self, DynamicMetaObject errorSuggestion) { Type type = Type; DynamicMetaObject res = null; switch (type.GetTypeCode()) { case TypeCode.Boolean: res = MakeToBoolConversion(self); break; case TypeCode.Char: res = TryToCharConversion(self); break; case TypeCode.String: break; case TypeCode.Object: // !!! Deferral? if (type.IsArray && self.Value is PythonTuple && type.GetArrayRank() == 1) { res = MakeToArrayConversion(self, type); } else if (type.IsGenericType && !type.IsAssignableFrom(CompilerHelpers.GetType(self.Value))) { Type genTo = type.GetGenericTypeDefinition(); // Interface conversion helpers... if (genTo == typeof(IList <>)) { if (self.LimitType == typeof(string)) { res = new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeByteArray)), AstUtils.Convert(self.Expression, typeof(string)) ), BindingRestrictions.GetTypeRestriction( self.Expression, typeof(string) ) ); } else { res = TryToGenericInterfaceConversion(self, type, typeof(IList <object>), typeof(ListGenericWrapper <>)); } } else if (genTo == typeof(IDictionary <,>)) { res = TryToGenericInterfaceConversion(self, type, typeof(IDictionary <object, object>), typeof(DictionaryGenericWrapper <,>)); } else if (genTo == typeof(IEnumerable <>)) { res = TryToGenericInterfaceConversion(self, type, typeof(IEnumerable), typeof(IEnumerableOfTWrapper <>)); } } else if (type == typeof(IEnumerable)) { if (!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType())) { res = ConvertToIEnumerable(this, self.Restrict(self.GetLimitType())); } } else if (type == typeof(IEnumerator)) { if (!typeof(IEnumerator).IsAssignableFrom(self.GetLimitType()) && !typeof(IEnumerable).IsAssignableFrom(self.GetLimitType())) { res = ConvertToIEnumerator(this, self.Restrict(self.GetLimitType())); } } break; } if (type.IsEnum() && Enum.GetUnderlyingType(type) == self.GetLimitType()) { // numeric type to enum, this is ok if the value is zero object value = Activator.CreateInstance(type); return(new DynamicMetaObject( Ast.Condition( Ast.Equal( AstUtils.Convert(self.Expression, Enum.GetUnderlyingType(type)), AstUtils.Constant(Activator.CreateInstance(self.GetLimitType())) ), AstUtils.Constant(value), Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.TypeErrorForBadEnumConversion)).MakeGenericMethod(type), AstUtils.Convert(self.Expression, typeof(object)) ) ), self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, self.GetLimitType())), value )); } return(res ?? EnsureReturnType(returnType, Context.Binder.ConvertTo(Type, ResultKind, self, _context.SharedOverloadResolverFactory, errorSuggestion))); }
public override DynamicMetaObject FallbackSetMember( DynamicMetaObject targetMO, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { // Defer if any object has no value so that we evaulate their // Expressions and nest a CallSite for the InvokeMember. if (!targetMO.HasValue) { return(Defer(targetMO)); } // Find our own binding. const BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public; var members = targetMO.LimitType.GetMember(Name, flags); if (members.Length == 1) { MemberInfo mem = members[0]; Expression val; // Should check for member domain type being Type and value being // TypeModel, similar to ConvertArguments, and building an // expression like GetRuntimeTypeMoFromModel. if (mem.MemberType == MemberTypes.Property) { val = Expression.Convert(value.Expression, ((PropertyInfo)mem).PropertyType); } else if (mem.MemberType == MemberTypes.Field) { val = Expression.Convert(value.Expression, ((FieldInfo)mem).FieldType); } else { return(errorSuggestion ?? RuntimeHelpers.CreateThrow( targetMO, null, BindingRestrictions.GetTypeRestriction( targetMO.Expression, targetMO.LimitType), typeof(InvalidOperationException), "Crispy only supports setting Properties and " + "fields at this time.")); } return(new DynamicMetaObject( // Assign returns the stored value, so we're good for Crispy. RuntimeHelpers.EnsureObjectResult( Expression.Assign( Expression.MakeMemberAccess( Expression.Convert(targetMO.Expression, members[0].DeclaringType), members[0]), val)), // Don't need restriction test for name since this // rule is only used where binder is used, which is // only used in sites with this binder.Name. BindingRestrictions.GetTypeRestriction(targetMO.Expression, targetMO.LimitType))); } return(errorSuggestion ?? RuntimeHelpers.CreateThrow( targetMO, null, BindingRestrictions.GetTypeRestriction(targetMO.Expression, targetMO.LimitType), typeof(MissingMemberException), "IDynObj member name conflict.")); }
public DynamicMetaObject GetMetaObject(Expression parameter) { return(new Meta(parameter, BindingRestrictions.GetTypeRestriction(parameter, typeof(Function)), this)); }
private DynamicMetaObject /*!*/ GetInstance(Expression /*!*/ instance, Type /*!*/ testType) { Assert.NotNull(instance, testType); object instanceValue = Value.BindingSelf; BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(instance, testType); // cast the instance to the correct type if (CompilerHelpers.IsStrongBox(instanceValue)) { instance = ReadStrongBoxValue(instance); instanceValue = ((IStrongBox)instanceValue).Value; } else if (!testType.IsEnum()) { // We need to deal w/ wierd types like MarshalByRefObject. // We could have an MBRO whos DeclaringType is completely different. // Therefore we special case it here and cast to the declaring type Type selfType = CompilerHelpers.GetType(Value.BindingSelf); selfType = CompilerHelpers.GetVisibleType(selfType); if (selfType == typeof(object) && Value.DeclaringType.IsInterface()) { selfType = Value.DeclaringType; Type genericTypeDefinition = null; // the behavior is different on Mono, it sets FullName for the DeclaringType if (Value.DeclaringType.IsGenericType() && (ClrModule.IsMono || Value.DeclaringType.FullName == null) && Value.DeclaringType.ContainsGenericParameters() && !Value.DeclaringType.IsGenericTypeDefinition()) { // from MSDN: If the current type contains generic type parameters that have not been replaced by // specific types (that is, the ContainsGenericParameters property returns true), but the type // is not a generic type definition (that is, the IsGenericTypeDefinition property returns false), // this property returns Nothing. For example, consider the classes Base and Derived in the following code. // if this type is completely generic (no type arguments specified) then we'll go ahead and get the // generic type definition for the this parameter - that'll let us successfully type infer on it later. var genericArgs = Value.DeclaringType.GetGenericArguments(); bool hasOnlyGenerics = genericArgs.Length > 0; foreach (var genericParam in genericArgs) { if (!genericParam.IsGenericParameter) { hasOnlyGenerics = false; break; } } if (hasOnlyGenerics) { genericTypeDefinition = Value.DeclaringType.GetGenericTypeDefinition(); } } else if (Value.DeclaringType.IsGenericTypeDefinition()) { genericTypeDefinition = Value.DeclaringType; } if (genericTypeDefinition != null) { // we're a generic interface method on a non-public type. // We need to see if we can match any types implemented on // the concrete selfType. var interfaces = CompilerHelpers.GetType(Value.BindingSelf).GetInterfaces(); foreach (var iface in interfaces) { if (iface.IsGenericType() && iface.GetGenericTypeDefinition() == genericTypeDefinition) { selfType = iface; break; } } } } if (Value.DeclaringType.IsInterface() && selfType.IsValueType()) { // explicit interface implementation dispatch on a value type, don't // unbox the value type before the dispatch. instance = AstUtils.Convert(instance, Value.DeclaringType); } else if (selfType.IsValueType()) { // We might be calling a a mutating method (like // Rectangle.Intersect). If so, we want it to mutate // the boxed value directly instance = Ast.Unbox(instance, selfType); } else { #if FEATURE_REMOTING Type convType = selfType == typeof(MarshalByRefObject) ? CompilerHelpers.GetVisibleType(Value.DeclaringType) : selfType; instance = AstUtils.Convert(instance, convType); #else instance = AstUtils.Convert(instance, selfType); #endif } } else { // we don't want to cast the enum to its real type, it will unbox it // and turn it into its underlying type. We presumably want to call // a method on the Enum class though - so we cast to Enum instead. instance = AstUtils.Convert(instance, typeof(Enum)); } return(new DynamicMetaObject( instance, restrictions, instanceValue )); }
public Meta(Expression expression, BindingRestrictions restrictions, Function value) : base(expression, restrictions, value) { }
private readonly DynamicMetaObject _baseMetaObject; // if we're a subtype of MetaObject this is the base class MO public MetaUserObject(Expression/*!*/ expression, BindingRestrictions/*!*/ restrictions, DynamicMetaObject baseMetaObject, IPythonObject value) : base(expression, restrictions, value) { _baseMetaObject = baseMetaObject; }
public override BindingRestrictions GetRestrictions() { return(BindingRestrictions.GetTypeRestriction(ArgumentExpression, typeof(NativeArgument))); }
internal void Append(BindingRestrictions restrictions) { if (_unique.Contains(restrictions)) { return; } _unique.Add(restrictions); Push(restrictions.GetExpression(), 0); }
public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args) { CodeContext context = PythonContext.GetPythonContext(binder).SharedContext; ArgumentMarshaller[] signature = GetArgumentMarshallers(args); BindingRestrictions restrictions = BindingRestrictions.GetTypeRestriction( Expression, Value.GetType() ).Merge( BindingRestrictions.GetExpressionRestriction( Expression.Call( typeof(ModuleOps).GetMethod("CheckFunctionId"), Expression.Convert(Expression, typeof(_CFuncPtr)), Expression.Constant(Value.Id) ) ) ); foreach (var arg in signature) { restrictions = restrictions.Merge(arg.GetRestrictions()); } int argCount = args.Length; if (Value._comInterfaceIndex != -1) { argCount--; } // need to verify we have the correct # of args if (Value._argtypes != null) { if (argCount < Value._argtypes.Count || (Value.CallingConvention != CallingConvention.Cdecl && argCount > Value._argtypes.Count)) { return(IncorrectArgCount(binder, restrictions, Value._argtypes.Count, argCount)); } } else { CFuncPtrType funcType = ((CFuncPtrType)Value.NativeType); if (funcType._argtypes != null && (argCount < funcType._argtypes.Length || (Value.CallingConvention != CallingConvention.Cdecl && argCount > funcType._argtypes.Length))) { return(IncorrectArgCount(binder, restrictions, funcType._argtypes.Length, argCount)); } } if (Value._comInterfaceIndex != -1 && args.Length == 0) { return(NoThisParam(binder, restrictions)); } Expression call = MakeCall(signature, GetNativeReturnType(), Value.Getrestype() == null, GetFunctionAddress(args)); List <Expression> block = new List <Expression>(); Expression res; if (call.Type != typeof(void)) { ParameterExpression tmp = Expression.Parameter(call.Type, "ret"); block.Add(Expression.Assign(tmp, call)); AddKeepAlives(signature, block); block.Add(tmp); res = Expression.Block(new[] { tmp }, block); } else { block.Add(call); AddKeepAlives(signature, block); res = Expression.Block(block); } res = AddReturnChecks(context, args, res); return(new DynamicMetaObject(Utils.Convert(res, typeof(object)), restrictions)); }
public MetaPythonFunction(Expression/*!*/ expression, BindingRestrictions/*!*/ restrictions, PythonFunction/*!*/ value) : base(expression, BindingRestrictions.Empty, value) { Assert.NotNull(value); }
private static DynamicMetaObject IncorrectArgCount(DynamicMetaObjectBinder binder, BindingRestrictions restrictions, int expected, int got) { return(new DynamicMetaObject( binder.Throw( Expression.Call( typeof(PythonOps).GetMethod("TypeError"), Expression.Constant(String.Format("this function takes {0} arguments ({1} given)", expected, got)), Expression.NewArrayInit(typeof(object)) ), typeof(object) ), restrictions )); }
DynamicMetaObject BindGetMember(object key, DynamicMetaObjectBinder binder, BindingRestrictions additional, Func <DynamicMetaObject> fallback) { var v = Expression.Variable(typeof(object)); var accessible = binder as IDirectAccessible; var exp = Expression.Block(new[] { v }, Expression.Condition( Expression.Call( LimitedInstance, (MethodInfo)Utils.GetMember <object>(x => Value.TryGetValue(null, false, out x)), Expression.Constant(key, typeof(object)), Expression.Constant(accessible != null && accessible.DirectAccess), v ), v, Expression.Convert(fallback().Expression, typeof(object)) ) ); return(Restrict(exp, binder, additional)); }
/// <summary> /// Initializes a new instance of the <see cref="DynamicMetaObject"/> class. /// </summary> /// <param name="expression">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param> /// <param name="restrictions">The set of binding restrictions under which the binding is valid.</param> /// <param name="value">The runtime value represented by the <see cref="DynamicMetaObject"/>.</param> public DynamicMetaObject(Expression expression, BindingRestrictions restrictions, object value) : this(expression, restrictions) { _value = value; _hasValue = true; }
public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes) { return(BindDeleteMember(indexes[0].Value, binder, BindingRestrictions.GetInstanceRestriction(indexes[0].Expression, indexes[0].Value), () => base.BindDeleteIndex(binder, indexes))); }
public MetaBuiltinMethodDescriptor(Expression/*!*/ expression, BindingRestrictions/*!*/ restrictions, BuiltinMethodDescriptor/*!*/ value) : base(expression, BindingRestrictions.Empty, value) { Assert.NotNull(value); }
/// <summary> /// Translates our CallSignature into a DLR Argument list and gives the simple MetaObject's which are extracted /// from the tuple or dictionary parameters being splatted. /// </summary> private void TranslateArguments(DynamicMetaObject target, DynamicMetaObject/*!*/[]/*!*/ args, out List<ArgumentInfo/*!*/>/*!*/ newArgs, out List<Expression/*!*/>/*!*/ metaArgs, out Expression test, out BindingRestrictions restrictions) { Argument[] argInfo = _signature.GetArgumentInfos(); newArgs = new List<ArgumentInfo>(); metaArgs = new List<Expression>(); metaArgs.Add(target.Expression); Expression splatArgTest = null; Expression splatKwArgTest = null; restrictions = BindingRestrictions.Empty; for (int i = 0; i < argInfo.Length; i++) { Argument ai = argInfo[i]; switch (ai.Kind) { case ArgumentType.Dictionary: IAttributesCollection iac = (IAttributesCollection)args[i].Value; List<string> argNames = new List<string>(); foreach (KeyValuePair<object, object> kvp in iac) { string key = (string)kvp.Key; newArgs.Add(Expression.NamedArg(key)); argNames.Add(key); metaArgs.Add( Expression.Call( AstUtils.Convert(args[i].Expression, typeof(IAttributesCollection)), typeof(IAttributesCollection).GetMethod("get_Item"), AstUtils.Constant(SymbolTable.StringToId(key)) ) ); } restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[i].Expression, args[i].GetLimitType())); splatKwArgTest = Expression.Call( typeof(PythonOps).GetMethod("CheckDictionaryMembers"), AstUtils.Convert(args[i].Expression, typeof(IAttributesCollection)), Expression.Constant(argNames.ToArray()) ); break; case ArgumentType.List: IList<object> splattedArgs = (IList<object>)args[i].Value; splatArgTest = Expression.Equal( Expression.Property(AstUtils.Convert(args[i].Expression, args[i].GetLimitType()), typeof(ICollection<object>).GetProperty("Count")), Expression.Constant(splattedArgs.Count) ); for (int splattedArg = 0; splattedArg < splattedArgs.Count; splattedArg++) { newArgs.Add(Expression.PositionalArg(splattedArg + i)); metaArgs.Add( Expression.Call( AstUtils.Convert(args[i].Expression, typeof(IList<object>)), typeof(IList<object>).GetMethod("get_Item"), Expression.Constant(splattedArg) ) ); } restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[i].Expression, args[i].GetLimitType())); break; case ArgumentType.Named: newArgs.Add(Expression.NamedArg(SymbolTable.IdToString(ai.Name))); metaArgs.Add(args[i].Expression); break; case ArgumentType.Simple: newArgs.Add(Expression.PositionalArg(i)); metaArgs.Add(args[i].Expression); break; default: throw new InvalidOperationException(); } } test = splatArgTest; if (splatKwArgTest != null) { if (test != null) { test = Expression.AndAlso(test, splatKwArgTest); } else { test = splatKwArgTest; } } }
private DynamicMetaObject MakeDeferred(BindingRestrictions rs, params DynamicMetaObject[] args) { var exprs = DynamicMetaObject.GetExpressions(args); Type delegateType = DelegateHelpers.MakeDeferredSiteDelegate(args, ReturnType); // Because we know the arguments match the delegate type (we just created the argument types) // we go directly to DynamicExpression.Make to avoid a bunch of unnecessary argument validation return new DynamicMetaObject( DynamicExpression.Make(ReturnType, delegateType, this, new TrueReadOnlyCollection<Expression>(exprs)), rs ); }
private static DynamicMetaObject NoThisParam(DynamicMetaObjectBinder binder, BindingRestrictions restrictions) { return(new DynamicMetaObject( binder.Throw( Expression.Call( typeof(PythonOps).GetMethod("ValueError"), Expression.Constant("native com method call without 'this' parameter"), Expression.NewArrayInit(typeof(object)) ), typeof(object) ), restrictions )); }
public MetaBuiltinFunction(Expression /*!*/ expression, BindingRestrictions /*!*/ restrictions, BuiltinFunction /*!*/ value) : base(expression, BindingRestrictions.Empty, value) { Assert.NotNull(value); }
public MetaTotemFunction(Expression expression, BindingRestrictions restrictions, TotemFunction value) : base(expression, restrictions, value) { Assert.Equals(restrictions, BindingRestrictions.Empty); Assert.NotNull(value); }
public MetaPythonObject(Expression /*!*/ expression, BindingRestrictions /*!*/ restrictions, object value) : base(expression, restrictions, value) { }
private static BindingRestrictions AddRemoteObjectRestrictions(BindingRestrictions restrictions, object[] args, ReadOnlyCollection<ParameterExpression> parameters) { #if !SILVERLIGHT for (int i = 0; i < parameters.Count; i++) { var expr = parameters[i]; var value = args[i] as MarshalByRefObject; // special case for MBR objects. // when MBR objects are remoted they can have different conversion behavior // so bindings created for local and remote objects should not be mixed. if (value != null && !IsComObject(value)) { BindingRestrictions remotedRestriction; if (RemotingServices.IsObjectOutOfAppDomain(value)) { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ); } else { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Not( Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ) ); } restrictions = restrictions.Merge(remotedRestriction); } } #endif return restrictions; }
public MetaPythonType(Expression /*!*/ expression, BindingRestrictions /*!*/ restrictions, PythonType /*!*/ value) : base(expression, BindingRestrictions.Empty, value) { Assert.NotNull(value); }
internal DynamicMetaObject Invoke() { _keywordArgNames = _callInfo.ArgumentNames.ToArray(); _totalExplicitArgs = _args.Length; Type[] marshalArgTypes = new Type[_args.Length]; // We already tested the instance, so no need to test it again for (int i = 0; i < _args.Length; i++) { DynamicMetaObject curMo = _args[i]; _restrictions = _restrictions.Merge(ComBinderHelpers.GetTypeRestrictionForDynamicMetaObject(curMo)); marshalArgTypes[i] = MarshalType(curMo, _isByRef[i]); } _varEnumSelector = new VarEnumSelector(marshalArgTypes); return new DynamicMetaObject( CreateScope(MakeIDispatchInvokeTarget()), BindingRestrictions.Combine(_args).Merge(_restrictions) ); }
/// <summary> /// Creating a Python type involves calling __new__ and __init__. We resolve them /// and generate calls to either the builtin funcions directly or embed sites which /// call the slots at runtime. /// </summary> private DynamicMetaObject /*!*/ MakePythonTypeCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { ValidationInfo valInfo = MakeVersionCheck(); DynamicMetaObject self = new RestrictedMetaObject( AstUtils.Convert(Expression, LimitType), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(Expression, LimitType), Value ); CallSignature sig = BindingHelpers.GetCallSignature(call); ArgumentValues ai = new ArgumentValues(sig, self, args); NewAdapter newAdapter; InitAdapter initAdapter; if (TooManyArgsForDefaultNew(call, args)) { return(MakeIncorrectArgumentsForCallError(call, ai, valInfo)); } else if (Value.UnderlyingSystemType.IsGenericTypeDefinition()) { return(MakeGenericTypeDefinitionError(call, ai, valInfo)); } else if (Value.HasAbstractMethods(PythonContext.GetPythonContext(call).SharedContext)) { return(MakeAbstractInstantiationError(call, ai, valInfo)); } DynamicMetaObject translated = BuiltinFunction.TranslateArguments(call, codeContext, self, args, false, Value.Name); if (translated != null) { return(translated); } GetAdapters(ai, call, codeContext, out newAdapter, out initAdapter); PythonContext state = PythonContext.GetPythonContext(call); // get the expression for calling __new__ DynamicMetaObject createExpr = newAdapter.GetExpression(state.Binder); if (createExpr.Expression.Type == typeof(void)) { return(BindingHelpers.AddDynamicTestAndDefer( call, createExpr, args, valInfo )); } Expression res; BindingRestrictions additionalRestrictions = BindingRestrictions.Empty; if (!Value.IsSystemType && (!(newAdapter is DefaultNewAdapter) || HasFinalizer(call))) { // we need to dynamically check the return value to see if it's a subtype of // the type that we are calling. If it is then we need to call __init__/__del__ // for the actual returned type. res = DynamicExpression.Dynamic( Value.GetLateBoundInitBinder(sig), typeof(object), ArrayUtils.Insert( codeContext, Expression.Convert(createExpr.Expression, typeof(object)), DynamicUtils.GetExpressions(args) ) ); additionalRestrictions = createExpr.Restrictions; } else { // just call the __init__ method, built-in types currently have // no wacky return values which don't return the derived type. // then get the statement for calling __init__ ParameterExpression allocatedInst = Ast.Variable(createExpr.GetLimitType(), "newInst"); Expression tmpRead = allocatedInst; DynamicMetaObject initCall = initAdapter.MakeInitCall( state.Binder, new RestrictedMetaObject( AstUtils.Convert(allocatedInst, Value.UnderlyingSystemType), createExpr.Restrictions ) ); List <Expression> body = new List <Expression>(); Debug.Assert(!HasFinalizer(call)); // add the call to init if we need to if (initCall.Expression != tmpRead) { // init can fail but if __new__ returns a different type // no exception is raised. DynamicMetaObject initStmt = initCall; if (body.Count == 0) { body.Add( Ast.Assign(allocatedInst, createExpr.Expression) ); } if (!Value.UnderlyingSystemType.IsAssignableFrom(createExpr.Expression.Type)) { // return type of object, we need to check the return type before calling __init__. body.Add( AstUtils.IfThen( Ast.TypeIs(allocatedInst, Value.UnderlyingSystemType), initStmt.Expression ) ); } else { // just call the __init__ method, no type check necessary (TODO: need null check?) body.Add(initStmt.Expression); } } // and build the target from everything we have if (body.Count == 0) { res = createExpr.Expression; } else { body.Add(allocatedInst); res = Ast.Block(body); } res = Ast.Block(new ParameterExpression[] { allocatedInst }, res); additionalRestrictions = initCall.Restrictions; } return(BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject( res, self.Restrictions.Merge(additionalRestrictions) ), ArrayUtils.Insert(this, args), valInfo )); }
public CallAdapter(ArgumentValues/*!*/ ai, PythonContext/*!*/ state, Expression/*!*/ codeContext) { _argInfo = ai; _state = state; _restrictions = BindingRestrictions.Empty; _context = codeContext; }
private static BindingRestrictions GetInstanceRestriction(ArgumentValues ai) { return(BindingRestrictions.GetInstanceRestriction(ai.Self.Expression, ai.Self.Value)); }
internal static DynamicMetaObject/*!*/ TypeErrorGenericMethod(Type/*!*/ type, string/*!*/ name, BindingRestrictions/*!*/ restrictions) { return new DynamicMetaObject( Ast.Throw( Ast.Call( typeof(PythonOps).GetMethod("TypeErrorForGenericMethod"), AstUtils.Constant(type), AstUtils.Constant(name) ), typeof(object) ), restrictions ); }
/// <summary> /// Helper for generating the call to a builtin function. This is used for calls from built-in method /// descriptors and built-in functions w/ and w/o a bound instance. /// /// This provides all sorts of common checks on top of the call while the caller provides a delegate /// to do the actual call. The common checks include: /// check for generic-only methods /// reversed operator support /// transforming arguments so the default binder can understand them (currently user defined mapping types to PythonDictionary) /// returning NotImplemented from binary operators /// Warning when calling certain built-in functions /// /// </summary> /// <param name="call">The call binder we're doing the call for</param> /// <param name="codeContext">An expression which points to the code context</param> /// <param name="function">the meta object for the built in function</param> /// <param name="hasSelf">true if we're calling with an instance</param> /// <param name="args">The arguments being passed to the function</param> /// <param name="functionRestriction">A restriction for the built-in function, method desc, etc...</param> /// <param name="bind">A delegate to perform the actual call to the method.</param> internal DynamicMetaObject /*!*/ MakeBuiltinFunctionCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/ function, DynamicMetaObject /*!*/[] args, bool hasSelf, BindingRestrictions /*!*/ functionRestriction, Func <DynamicMetaObject /*!*/[] /*!*/, BindingResult /*!*/> bind) { DynamicMetaObject res = null; // if we have a user defined operator for **args then transform it into a PythonDictionary DynamicMetaObject translated = TranslateArguments(call, codeContext, new DynamicMetaObject(function.Expression, functionRestriction, function.Value), args, hasSelf, Name); if (translated != null) { return(translated); } // swap the arguments if we have a reversed operator if (IsReversedOperator) { ArrayUtils.SwapLastTwo(args); } // do the appropriate calling logic BindingResult result = bind(args); // validate the result BindingTarget target = result.Target; res = result.MetaObject; if (target.Overload != null && target.Overload.IsProtected) { // report an error when calling a protected member res = new DynamicMetaObject( BindingHelpers.TypeErrorForProtectedMember( target.Overload.DeclaringType, target.Overload.Name ), res.Restrictions ); } else if (IsBinaryOperator && args.Length == 2 && IsThrowException(res.Expression)) { // Binary Operators return NotImplemented on failure. res = new DynamicMetaObject( Ast.Property(null, typeof(PythonOps), "NotImplemented"), res.Restrictions ); } else if (target.Overload != null) { // Add profiling information for this builtin function, if applicable IPythonSite pythonSite = (call as IPythonSite); if (pythonSite != null) { var pc = pythonSite.Context; var po = pc.Options as PythonOptions; if (po != null && po.EnableProfiler) { Profiler profiler = Profiler.GetProfiler(pc); res = new DynamicMetaObject( profiler.AddProfiling(res.Expression, target.Overload.ReflectionInfo), res.Restrictions ); } } } // add any warnings that are applicable for calling this function WarningInfo info; if (target.Overload != null && BindingWarnings.ShouldWarn(PythonContext.GetPythonContext(call), target.Overload, out info)) { res = info.AddWarning(codeContext, res); } // finally add the restrictions for the built-in function and return the result. res = new DynamicMetaObject( res.Expression, functionRestriction.Merge(res.Restrictions) ); // The function can return something typed to boolean or int. // If that happens, we need to apply Python's boxing rules. if (res.Expression.Type.IsValueType()) { res = BindingHelpers.AddPythonBoxing(res); } else if (res.Expression.Type == typeof(void)) { res = new DynamicMetaObject( Expression.Block( res.Expression, Expression.Constant(null) ), res.Restrictions ); } return(res); }
public MetaMethod(Expression/*!*/ expression, BindingRestrictions/*!*/ restrictions, Method/*!*/ value) : base(expression, BindingRestrictions.Empty, value) { Assert.NotNull(value); }
internal static DynamicMetaObject TranslateArguments(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject function, DynamicMetaObject /*!*/[] args, bool hasSelf, string name) { if (hasSelf) { args = ArrayUtils.RemoveFirst(args); } CallSignature sig = BindingHelpers.GetCallSignature(call); if (sig.HasDictionaryArgument()) { int index = sig.IndexOf(ArgumentType.Dictionary); DynamicMetaObject dict = args[index]; if (!(dict.Value is IDictionary) && dict.Value != null) { // The DefaultBinder only handles types that implement IDictionary. Here we have an // arbitrary user-defined mapping type. We'll convert it into a PythonDictionary // and then have an embedded dynamic site pass that dictionary through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonDictionary)), codeContext, args[index].Expression, AstUtils.Constant(name) ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()), PythonOps.UserMappingToPythonDictionary(PythonContext.GetPythonContext(call).SharedContext, dict.Value, name) ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType())) )); } } if (sig.HasListArgument()) { int index = sig.IndexOf(ArgumentType.List); DynamicMetaObject str = args[index]; // TODO: ANything w/ __iter__ that's not an IList<object> if (!(str.Value is IList <object>) && str.Value is IEnumerable) { // The DefaultBinder only handles types that implement IList<object>. Here we have a // string. We'll convert it into a tuple // and then have an embedded dynamic site pass that tuple through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeTupleFromSequence)), Expression.Convert(args[index].Expression, typeof(object)) ), BindingRestrictions.Empty ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), function.Restrictions.Merge( BindingRestrictions.Combine(args).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(str.Expression, str.GetLimitType())) ) )); } } return(null); }
internal ComUnwrappedMetaObject(Expression expression, BindingRestrictions restrictions, object value) : base(expression, restrictions, value) { }
/// <summary> /// Returns a Restrictions object which includes our current restrictions merged /// with a restriction limiting our type /// </summary> private BindingRestrictions GetRestrictions() { return((Value == null && HasValue) ? BindingRestrictions.GetInstanceRestriction(Expression, null) : BindingRestrictions.GetTypeRestriction(Expression, LimitType)); }
internal MergedRestriction(BindingRestrictions left, BindingRestrictions right) { Left = left; Right = right; }
public void FinishCondition(DynamicMetaObject body) { _restrictions = _restrictions.Merge(body.Restrictions); FinishCondition(body.Expression); }
public MetaOldInstance(Expression/*!*/ expression, BindingRestrictions/*!*/ restrictions, OldInstance/*!*/ value) : base(expression, BindingRestrictions.Empty, value) { Assert.NotNull(value); }
/// <summary> /// Helper for generating the call to a builtin function. This is used for calls from built-in method /// descriptors and built-in functions w/ and w/o a bound instance. /// /// This provides all sorts of common checks on top of the call while the caller provides a delegate /// to do the actual call. The common checks include: /// check for generic-only methods /// reversed operator support /// transforming arguments so the default binder can understand them (currently user defined mapping types to PythonDictionary) /// returning NotImplemented from binary operators /// Warning when calling certain built-in functions /// /// </summary> /// <param name="call">The call binder we're doing the call for</param> /// <param name="codeContext">An expression which points to the code context</param> /// <param name="args">The arguments being passed to the function</param> /// <param name="functionRestriction">A restriction for the built-in function, method desc, etc...</param> /// <param name="bind">A delegate to perform the actual call to the method.</param> internal DynamicMetaObject/*!*/ MakeBuiltinFunctionCall(DynamicMetaObjectBinder/*!*/ call, Expression/*!*/ codeContext, DynamicMetaObject/*!*/ function, DynamicMetaObject/*!*/[] args, bool hasSelf, bool enforceProtected, BindingRestrictions/*!*/ functionRestriction, Func<DynamicMetaObject/*!*/[]/*!*/, BindingResult/*!*/> bind) { DynamicMetaObject res = null; // produce an error if all overloads are generic if (IsOnlyGeneric) { return BindingHelpers.TypeErrorGenericMethod(DeclaringType, Name, functionRestriction); } // swap the arguments if we have a reversed operator if (IsReversedOperator) { ArrayUtils.SwapLastTwo(args); } // if we have a user defined operator for **args then transform it into a PythonDictionary CallSignature sig = BindingHelpers.GetCallSignature(call); if (sig.HasDictionaryArgument()) { int index = sig.IndexOf(ArgumentType.Dictionary); if (hasSelf) { index++; } DynamicMetaObject dict = args[index]; if (!(dict.Value is IDictionary)) { // The DefaultBinder only handles types that implement IDictionary. Here we have an // arbitrary user-defined mapping type. We'll convert it into a PythonDictionary // and then have an embedded dynamic site pass that dictionary through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod("UserMappingToPythonDictionary"), codeContext, args[index].Expression, Ast.Constant(Name) ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()), PythonOps.UserMappingToPythonDictionary(BinderState.GetBinderState(call).Context, dict.Value, Name) ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return new DynamicMetaObject( Ast.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType())) ); } } // do the appropriate calling logic BindingResult result = bind(args); // validate the result BindingTarget target = result.Target; res = result.MetaObject; // BUG: enforceProtected should alwyas be enforced, but we have some tests that depend upon it not being enforced. if (enforceProtected && target.Method != null && (target.Method.IsFamily || target.Method.IsFamilyOrAssembly)) { // report an error when calling a protected member res = new DynamicMetaObject( BindingHelpers.TypeErrorForProtectedMember( target.Method.DeclaringType, target.Method.Name ), res.Restrictions ); } else if (IsBinaryOperator && args.Length == 2 && res.Expression.NodeType == ExpressionType.Throw) { // Binary Operators return NotImplemented on failure. res = new DynamicMetaObject( Ast.Property(null, typeof(PythonOps), "NotImplemented"), res.Restrictions ); } // add any warnings that are applicable for calling this function WarningInfo info; if (target.Method != null && BindingWarnings.ShouldWarn(BinderState.GetBinderState(call).Binder, target.Method, out info)) { res = info.AddWarning(codeContext, res); } // finally add the restrictions for the built-in function and return the result. res = new DynamicMetaObject( res.Expression, functionRestriction.Merge(res.Restrictions) ); // The function can return something typed to boolean or int. // If that happens, we need to apply Python's boxing rules. if (res.Expression.Type == typeof(bool) || res.Expression.Type == typeof(int)) { res = new DynamicMetaObject( AstUtils.Convert(res.Expression, typeof(object)), res.Restrictions ); } return res; }