Exemplo n.º 1
0
        public void TypeRestrictionFalseForOtherType(object obj, Type type)
        {
            BindingRestrictions isType = BindingRestrictions.GetTypeRestriction(Expression.Constant(obj), type);

            Assert.False(Expression.Lambda <Func <bool> >(isType.ToExpression()).Compile()());
        }
Exemplo n.º 2
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));
                }
Exemplo n.º 3
0
 /// <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));
 }
Exemplo n.º 4
0
 public static BindingRestrictions ValueTypeRestriction(this DynamicMetaObject target)
 {
     return((target.HasValue && target.Value == null) ?
            BindingRestrictions.GetInstanceRestriction(target.Expression, null) :
            BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType));
 }
Exemplo n.º 5
0
        public override DynamicMetaObject FallbackBinaryOperation(
            DynamicMetaObject target, DynamicMetaObject arg,
            DynamicMetaObject errorSuggestion)
        {
            // Defer if any object has no value so that we evaulate their
            // Expressions and nest a CallSite for the InvokeMember.
            if (!target.HasValue || !arg.HasValue)
            {
                return(Defer(target, arg));
            }
            var restrictions = target.Restrictions.Merge(arg.Restrictions);

            if (target.Value == null)
            {
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetInstanceRestriction(target.Expression, null)
                    );
            }
            else
            {
                restrictions = restrictions.Merge(BindingRestrictions.GetTypeRestriction(
                                                      target.Expression, target.LimitType));
            }

            if (arg.Value == null)
            {
                restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(
                                                      arg.Expression, null));
            }
            else
            {
                restrictions = restrictions.Merge(BindingRestrictions.GetTypeRestriction(
                                                      arg.Expression, arg.LimitType));
            }

            if (this.Operation == ExpressionType.Add)
            {
                if (target.LimitType == typeof(string) && arg.LimitType == typeof(string))
                {
                    return(new DynamicMetaObject(
                               RuntimeHelpers.EnsureObjectResult(Expression.Call(
                                                                     typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }),
                                                                     Expression.Convert(target.Expression, target.LimitType),
                                                                     Expression.Convert(arg.Expression, arg.LimitType))),
                               restrictions
                               ));
                }
                if (target.LimitType == typeof(DateTime))
                {
                    return(new DynamicMetaObject(
                               RuntimeHelpers.EnsureObjectResult(Expression.Call(
                                                                     typeof(BuiltInFunctions).GetMethod("DateAdd"),
                                                                     Expression.Constant("d"),
                                                                     Expression.Convert(arg.Expression, typeof(object)),
                                                                     target.Expression)),
                               restrictions
                               ));
                }
                else if (arg.LimitType == typeof(DateTime))
                {
                    return(new DynamicMetaObject(
                               Expression.Call(
                                   typeof(BuiltInFunctions).GetMethod("DateAdd"),
                                   Expression.Constant("d"),
                                   Expression.Convert(target.Expression, typeof(object)),
                                   arg.Expression),
                               restrictions
                               ));
                }
                else if (!target.LimitType.IsPrimitive || !arg.LimitType.IsPrimitive)
                {
                    DynamicMetaObject[] args = new DynamicMetaObject[] { target, arg };
                    List <MethodInfo>   res  = RuntimeHelpers.GetExtensionMethods("op_Addition", target, args);
                    if (res.Count > 0)
                    {
                        MethodInfo mi = null;
                        if (res.Count > 1)
                        {
                            //If more than one results found, attempt overload resolution
                            mi = RuntimeHelpers.ResolveOverload(res, args);
                        }
                        else
                        {
                            mi = res[0];
                        }

                        // restrictions and conversion must be done consistently.
                        var callArgs = RuntimeHelpers.ConvertArguments(args, mi.GetParameters());

                        return(new DynamicMetaObject(
                                   RuntimeHelpers.EnsureObjectResult(
                                       Expression.Call(null, mi, callArgs)
                                       ),
                                   restrictions
                                   ));
                    }
                }
            }

            if (target.LimitType.IsPrimitive && arg.LimitType.IsPrimitive)
            {
                Type       targetType;
                Expression first;
                Expression second;
                if (target.LimitType == arg.LimitType || target.LimitType.IsAssignableFrom(arg.LimitType))
                {
                    targetType = target.LimitType;
                    first      = Expression.Convert(target.Expression, targetType);
                    //if variable is object type, need to convert twice (unbox + convert)
                    second = Expression.Convert(
                        Expression.Convert(arg.Expression, arg.LimitType),
                        targetType
                        );
                }
                else
                {
                    targetType = arg.LimitType;
                    first      = Expression.Convert(
                        Expression.Convert(target.Expression, target.LimitType),
                        targetType
                        );
                    second = Expression.Convert(arg.Expression, targetType);
                }

                return(new DynamicMetaObject(
                           RuntimeHelpers.EnsureObjectResult(
                               Expression.MakeBinary(
                                   this.Operation,
                                   first,
                                   second
                                   )
                               ),
                           restrictions
                           ));
            }
            else
            {
                DynamicMetaObject[] args = null;
                MethodInfo          mi   = null;

                mi = typeof(HelperFunctions).GetMethod("BinaryOp");
                Expression        op  = Expression.Constant(this.Operation);
                DynamicMetaObject mop = new DynamicMetaObject(Expression.Constant(this.Operation), BindingRestrictions.Empty, this.Operation);

                args = new DynamicMetaObject[] { mop, target, arg };
                // restrictions and conversion must be done consistently.
                var callArgs = RuntimeHelpers.ConvertArguments(args, mi.GetParameters());

                return(new DynamicMetaObject(
                           RuntimeHelpers.EnsureObjectResult(
                               Expression.Call(
                                   mi,
                                   callArgs
                                   )
                               ),
                           restrictions
                           ));
            }
        }
Exemplo n.º 6
0
        public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
        {
            Schema.Property property;
            if (!_metadata.Schema.TryFindProperty(binder.Name, out property))
            {
                return(base.BindSetMember(binder, value));
            }

            var arguments = new List <Expression>
            {
                Expression.Constant(_metadata.PropertyIndices[property.Name])
            };

            MethodInfo setter       = null;
            Type       argumentType = null;

            switch (property.Type)
            {
            case Schema.PropertyType.Int:
                argumentType = typeof(long);
                if (property.IsNullable)
                {
                    setter = GetSetMethod <long?>(dummyHandle.SetNullableInt64);
                }
                else if (property.IsPrimaryKey)
                {
                    setter = GetSetMethod <long>(dummyHandle.SetInt64Unique);
                }
                else
                {
                    setter = GetSetMethod <long>(dummyHandle.SetInt64);
                }

                break;

            case Schema.PropertyType.Bool:
                argumentType = typeof(bool);
                if (property.IsNullable)
                {
                    setter = GetSetMethod <bool?>(dummyHandle.SetNullableBoolean);
                }
                else
                {
                    setter = GetSetMethod <bool>(dummyHandle.SetBoolean);
                }

                break;

            case Schema.PropertyType.Float:
                argumentType = typeof(float);
                if (property.IsNullable)
                {
                    setter = GetSetMethod <float?>(dummyHandle.SetNullableSingle);
                }
                else
                {
                    setter = GetSetMethod <float>(dummyHandle.SetSingle);
                }

                break;

            case Schema.PropertyType.Double:
                argumentType = typeof(double);
                if (property.IsNullable)
                {
                    setter = GetSetMethod <double?>(dummyHandle.SetNullableDouble);
                }
                else
                {
                    setter = GetSetMethod <double>(dummyHandle.SetDouble);
                }

                break;

            case Schema.PropertyType.String:
                argumentType = typeof(string);
                if (property.IsPrimaryKey)
                {
                    setter = GetSetMethod <string>(dummyHandle.SetStringUnique);
                }
                else
                {
                    setter = GetSetMethod <string>(dummyHandle.SetString);
                }

                break;

            case Schema.PropertyType.Data:
                argumentType = typeof(byte[]);
                setter       = GetSetMethod <byte[]>(dummyHandle.SetByteArray);
                break;

            case Schema.PropertyType.Date:
                argumentType = typeof(DateTimeOffset);
                if (property.IsNullable)
                {
                    setter = GetSetMethod <DateTimeOffset?>(dummyHandle.SetNullableDateTimeOffset);
                }
                else
                {
                    setter = GetSetMethod <DateTimeOffset>(dummyHandle.SetDateTimeOffset);
                }

                break;

            case Schema.PropertyType.Object:
                argumentType = typeof(RealmObject);
                arguments.Insert(0, Expression.Field(GetLimitedSelf(), RealmObjectRealmField));
                setter = GetSetMethod <RealmObject>(dummyHandle.SetObject);
                break;
            }

            if (property.IsNullable && argumentType.GetTypeInfo().IsValueType)
            {
                argumentType = typeof(Nullable <>).MakeGenericType(argumentType);
            }

            var valueExpression = value.Expression;

            if (valueExpression.Type != argumentType)
            {
                valueExpression = Expression.Convert(valueExpression, argumentType);
            }

            arguments.Add(valueExpression);

            var expression = Expression.Block(Expression.Call(Expression.Field(GetLimitedSelf(), RealmObjectObjectHandleField), setter, arguments), Expression.Default(binder.ReturnType));

            var argumentShouldBeDynamicRealmObject = BindingRestrictions.GetTypeRestriction(Expression, typeof(DynamicRealmObject));
            var argumentShouldBeInTheSameRealm     = BindingRestrictions.GetInstanceRestriction(Expression.Field(GetLimitedSelf(), RealmObjectRealmField), _realm);

            return(new DynamicMetaObject(expression, argumentShouldBeDynamicRealmObject.Merge(argumentShouldBeInTheSameRealm)));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Access <paramref name="target"/> as object instance.
        /// </summary>
        /// <param name="target">Given target.</param>
        /// <param name="instance">Resolved instance with restrictions.</param>
        /// <returns>Whether <paramref name="target"/> contains an object instance.</returns>
        /// <remarks>Necessary restriction are already resolved within returned <paramref name="instance"/>.</remarks>
        public static bool TryTargetAsObject(DynamicMetaObject target, out DynamicMetaObject instance)
        {
            var expr         = target.Expression;
            var value        = target.Value;
            var restrictions = target.Restrictions;

            if (value == null)
            {
                instance = new DynamicMetaObject(
                    expr,
                    restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.ReferenceEqual(expr, Expression.Constant(null)))),
                    null);

                return(false);
            }

            // dereference PhpAlias first:
            if (expr.Type == typeof(PhpAlias))
            {
                // PhpAlias.Value
                expr  = Expression.Field(expr, Cache.PhpAlias.Value);
                value = ((PhpAlias)value).Value;

                //
                return(TryTargetAsObject(
                           new DynamicMetaObject(expr, restrictions, value),
                           out instance));
            }

            if (value is PhpAlias alias)
            {
                // PhpAlias is provided but typed as System.Object
                // create restriction and retry with properly typed {expr:PhpAlias}
                expr = Expression.Convert(expr, typeof(PhpAlias));

                return(TryTargetAsObject(
                           new DynamicMetaObject(expr, restrictions.Merge(BindingRestrictions.GetTypeRestriction(expr, typeof(PhpAlias))), alias),
                           out instance));
            }

            // unwrap PhpValue
            if (expr.Type == typeof(PhpValue))
            {
                // PhpValue.Object
                expr  = Expression.Property(expr, Cache.Properties.PhpValue_Object);
                value = ((PhpValue)value).Object;

                return(TryTargetAsObject(
                           new DynamicMetaObject(expr, restrictions, value),
                           out instance));
            }

            // well-known non-objects:
            Type nonObjectType = null;

            if (value is PhpResource)
            {
                nonObjectType = typeof(PhpResource);
            }
            if (value is PhpArray)
            {
                nonObjectType = typeof(PhpArray);
            }
            if (value is PhpString.Blob)
            {
                nonObjectType = typeof(PhpString.Blob);
            }

            if (nonObjectType != null)
            {
                instance = new DynamicMetaObject(
                    expr,
                    restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.TypeIs(expr, nonObjectType))),   // PhpValue.Object is T (including any derived class)
                    value);

                return(false);
            }

            //

            var lt = target.Expression.Type;

            if (!lt.IsValueType && !lt.IsSealed && !typeof(PhpArray).IsAssignableFrom(lt) && !typeof(PhpResource).IsAssignableFrom(lt))
            {
                // we need to set the type restriction
                restrictions = restrictions.Merge(BindingRestrictions.GetTypeRestriction(expr, value.GetType()));
            }

            //
            instance = new DynamicMetaObject(expr, restrictions, value);
            return(!(
                       value is string ||
                       value is bool ||
                       value is int ||
                       value is long ||
                       value is double ||
                       value is char ||
                       value is uint ||
                       value is ulong ||
                       value is PhpString));
        }
Exemplo n.º 8
0
            public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
            {
                var        ds        = (DynamicStruct)this.Value;
                var        dsP       = Parameter(typeof(DynamicStruct), "ds");
                var        structExp = Property(dsP, "Struct");
                var        node      = ds.SchemaNode.Node;
                Expression valueExp;

                switch (node.which)
                {
                case Node.Union.@struct:
                    foreach (var field in [email protected])
                    {
                        if (field.name.ToString() != binder.Name)
                        {
                            continue;
                        }

                        if (field.Is(out Field.groupGroup group))
                        {
                            var newSchemaNode = ds.SchemaNode.Container[group.typeId];
                            valueExp = New(
                                DynamicStructConstructor,
                                Constant(newSchemaNode),
                                structExp);
                        }
                        else if (field.Is(out Field.slotGroup slot))
                        {
                            var         dv = slot.defaultValue;
                            string      readMethod;
                            object      defaultValue;
                            System.Type type;
                            switch (slot.type.which)
                            {
                            case Type.Union.@void: throw new NotSupportedException();

                            case Type.Union.@bool: readMethod = "ReadBool"; defaultValue = dv.@bool; type = typeof(bool); break;

                            case Type.Union.int8: readMethod = "ReadInt8"; defaultValue = dv.int8; type = typeof(sbyte); break;

                            case Type.Union.int16: readMethod = "ReadInt16"; defaultValue = dv.int16; type = typeof(short); break;

                            case Type.Union.int32: readMethod = "ReadInt32"; defaultValue = dv.int32; type = typeof(int); break;

                            case Type.Union.int64: readMethod = "ReadInt64"; defaultValue = dv.int64; type = typeof(long); break;

                            case Type.Union.uint8: readMethod = "ReadUInt8"; defaultValue = dv.uint8; type = typeof(byte); break;

                            case Type.Union.uint16: readMethod = "ReadUInt16"; defaultValue = dv.uint16; type = typeof(ushort); break;

                            case Type.Union.uint32: readMethod = "ReadUInt32"; defaultValue = dv.uint32; type = typeof(uint); break;

                            case Type.Union.uint64: readMethod = "ReadUInt64"; defaultValue = dv.uint64; type = typeof(ulong); break;

                            case Type.Union.float32: readMethod = "ReadFloat32"; defaultValue = dv.float32; type = typeof(float); break;

                            case Type.Union.float64: readMethod = "ReadFloat64"; defaultValue = dv.float64; type = typeof(double); break;

                            case Type.Union.@enum:
                                readMethod   = "ReadUInt16";
                                defaultValue = dv.uint16;
                                type         = typeof(ushort); // TODO: should be an enum type; dynamically generate one?
                                break;

                            case Type.Union.text:
                            case Type.Union.data:
                            case Type.Union.list:
                            case Type.Union.@struct:
                            case Type.Union.@interface:
                            case Type.Union.anyPointer:
                                readMethod   = "DereferencePointer";
                                defaultValue = null;
                                type         = null;

                                break;

                            default:
                                throw new NotSupportedException();
                            }

                            if (readMethod.StartsWith("Read"))
                            {
                                valueExp = Call(
                                    structExp,
                                    typeof(Struct).GetTypeInfo().GetDeclaredMethod(readMethod),
                                    Constant((int)slot.offset),
                                    Constant(defaultValue));
                            }
                            else if (slot.type.Is(out Type.structGroup @struct))
                            {
                                var newSchemaNode = ds.SchemaNode.Container[@struct.typeId];
                                valueExp = New(
                                    DynamicStructConstructor,
                                    Constant(newSchemaNode),
                                    Call(
                                        structExp,
                                        typeof(Struct).GetTypeInfo().GetDeclaredMethod("DereferencePointer").MakeGenericMethod(typeof(Struct)),
                                        Constant((int)slot.offset)));
                            }
                            else
                            {
                                throw new NotImplementedException();
                            }
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }

                        var target = Block(
                            new[] { dsP },
                            Assign(dsP, Convert(this.Expression, typeof(DynamicStruct))),
                            Condition(
                                // if 'this' refers to a new with the same schema...
                                Equal(Property(dsP, "SchemaNode"), Constant(ds.SchemaNode)),
                                // then: perform the get-member
                                Convert(
                                    valueExp,
                                    binder.ReturnType),
                                // else: try to look up the member under the other schema
                                binder.GetUpdateExpression(binder.ReturnType)));

                        return(new DynamicMetaObject(
                                   target,
                                   BindingRestrictions.GetTypeRestriction(this.Expression, typeof(DynamicStruct))));
                    }

                    return(binder.FallbackGetMember(this));

                case Node.Union.@enum:
                    break;

                case Node.Union.@interface:
                    break;

                case Node.Union.@const:
                    break;

                case Node.Union.file:
                case Node.Union.annotation:
                default:
                    throw new NotSupportedException();
                }

                throw new NotImplementedException();
            }
Exemplo n.º 9
0
        public override DynamicMetaObject BindConvert(ConvertBinder binder)
        {
            Expression convertExpression;

            if (binder.Type.IsAssignableFrom(LimitType))
            {
                convertExpression = Expression.Convert(Expression, binder.Type);
            }
            else if (binder.Type == typeof(InternalHandle) && Value is IHandleBased)
            {
                Func <object, InternalHandle> toInertnalHandleConversionDelegate = _GetInternalHandleFromObject;
                convertExpression = Expression.Convert(Expression, typeof(InternalHandle), toInertnalHandleConversionDelegate.Method);
            }
            else if (binder.Type == typeof(Handle) && Value is IHandleBased)
            {
                Func <object, Handle> toInertnalHandleConversionDelegate = _GetHandleFromObject;
                convertExpression = Expression.Convert(Expression, typeof(Handle), toInertnalHandleConversionDelegate.Method);
            }
            else if (typeof(V8NativeObject).IsAssignableFrom(binder.Type) && Value is IHandleBased)
            {
                Func <object, V8NativeObject> getUnderlyingObject = _GetUnderlyingObject;

                convertExpression = Expression.Convert(Expression.Convert(Expression, typeof(V8NativeObject), getUnderlyingObject.Method), binder.Type);
            }
            else
            {
                MethodInfo conversionMethodInfo;

                if (Value is IHandleBased) // (if this is a handle, read the 'Value' property, which returns all values as objects.
                {
                    var valueMemberInfo = typeof(InternalHandle).GetProperty(nameof(InternalHandle.Value));
                    Func <object, InternalHandle> toInertnalHandleConversionDelegate = _GetInternalHandleFromObject;
                    var valueMemberExpr = Expression.MakeMemberAccess(Expression.Convert(Expression, typeof(InternalHandle), toInertnalHandleConversionDelegate.Method), valueMemberInfo);
                    convertExpression = Expression.Convert(valueMemberExpr, binder.Type);
                }
                else
                {
                    if (binder.Type == typeof(InternalHandle))
                    {
                        conversionMethodInfo = ((Func <object, InternalHandle>)_GetInternalHandleFromObject).Method;
                    }
                    else if (binder.Type == typeof(Handle))
                    {
                        conversionMethodInfo = ((Func <object, Handle>)_GetHandleFromObject).Method;
                    }
                    else
                    {
                        conversionMethodInfo = null;
                    }

                    if (conversionMethodInfo != null)
                    {
                        convertExpression = Expression.Convert(Expression, binder.Type, conversionMethodInfo);
                    }
                    else
                    {
                        convertExpression = Expression.Convert(Expression, binder.Type);
                    }
                }
            }

            BindingRestrictions restrictions = Restrictions.Merge(BindingRestrictions.GetTypeRestriction(convertExpression, binder.Type));

            return(new DynamicMetaObject(convertExpression, Restrictions));
        }
Exemplo n.º 10
0
 private BindingRestrictions GetRestrictions()
 {
     return(BindingRestrictions.GetTypeRestriction(Expression, Value.GetType()));
 }
Exemplo n.º 11
0
 static BindingRestrictions CreateRestrictionsOnTarget(DynamicMetaObject arg)
 {
     return(arg.HasValue && arg.Value == null?
            BindingRestrictions.GetInstanceRestriction(arg.Expression, null) :
                BindingRestrictions.GetTypeRestriction(arg.Expression, arg.LimitType));
 }
Exemplo n.º 12
0
        /// <summary>
        /// This method binds rules for PhpMethod
        /// </summary>
        private void InvokePhpMethod(DynamicMetaObject /*!*/ target, DynamicMetaObject[] /*!!*/ args, /*object targetObj,*/ PhpRoutine /*!*/ routine, out BindingRestrictions restrictions, out Expression invokeMethodExpr)
        {
            Debug.Assert(target != null && target.Value != null);
            Debug.Assert(!(target.Value is IClrValue), "PhpRoutine should not be declared on CLR value type!");

            /*if (target.Value is PhpObject)
             * {
             *  // Restriction: typeof(target) == |target.TypeDesc.RealType|
             *  var targetPhpObj = (PhpObject)target.Value;
             *  Debug.Assert(targetPhpObj.TypeDesc.RealType == target.LimitType);
             *  Debug.Assert(target.Value.GetType() == target.LimitType);
             *  restrictions = BindingRestrictions.GetTypeRestriction(target.Expression, targetPhpObj.TypeDesc.RealType);
             * }
             * else*/
            Debug.Assert(typeof(ClrObject).IsSealed);   // just to ensure following condition is correct
            if (target.Value.GetType() == typeof(ClrObject))
            {
                target       = new ClrDynamicMetaObject(target); // unwrap the real object, get restrictions
                restrictions = target.Restrictions;
            }
            else
            {
                Debug.Assert(target.Value.GetType() == target.LimitType);   // just for sure
                Debug.Assert(!(target.Value is PhpObject) || ((PhpObject)target.Value).TypeDesc.RealType == target.LimitType);

                restrictions = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType);
            }

            BindingRestrictions argumentsRestrictions;

            Expression[] arguments;

            if (routine.Name != PHP.Core.Reflection.DObject.SpecialMethodNames.Call)
            {
                args = GetArgumentsRange(args, 0, RealMethodArgumentCount);// This can't be done when _call method is invoked

                //Check if method has ArgAware attribute
                if ((routine.Properties & RoutineProperties.IsArgsAware) != 0 ||
                    routine.IsStatic)// this is because of hack in PHP.Library.XML library static methods that can be also called like instance methods
                {
                    DynamicMetaObject scriptContext = args[0];

                    //Select arguments without scriptContext
                    DynamicMetaObject[] realArgs = GetArgumentsRange(args, 1, RealMethodArgumentCount - 1);

                    InvokeArgLess(target, scriptContext, routine.RoutineDesc, realArgs, out argumentsRestrictions, out invokeMethodExpr);
                    restrictions = restrictions.Merge(argumentsRestrictions);
                    return;
                }

                arguments    = routine.PrepareArguments(args, _genericParamsCount, _paramsCount, out argumentsRestrictions);
                restrictions = restrictions.Merge(argumentsRestrictions);
            }
            else
            {
                arguments = BinderHelper.PackToExpressions(args);
            }

            //((PhpObject)target))
            var realObjEx = Expression.Convert(target.Expression, routine.ArgFullInfo.DeclaringType);//targetObj.TypeDesc.RealType);

            //ArgFull( ((PhpObject)target), ScriptContext, args, ... )
            invokeMethodExpr = Expression.Call(BinderHelper.WrapInstanceMethodCall(routine.ArgFullInfo),
                                               BinderHelper.CombineArguments(realObjEx, arguments));

            invokeMethodExpr = ReturnArgumentHelpers.ReturnValueConversion(routine.ArgFullInfo, invokeMethodExpr);

            invokeMethodExpr = HandleResult(invokeMethodExpr, routine.ArgFullInfo.ReturnType, false);
        }
Exemplo n.º 13
0
        protected override DynamicMetaObject /*!*/ FallbackInvokeMember(DynamicMetaObject target /*!*/, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            Expression invokeMethodExpr;

            DObject obj = target.Value as DObject;// target.Value can be something else which isn't DObject ?

            WrappedClrDynamicMetaObject wrappedTarget = null;

            bool invokeCallMethod = false;

            // Restrictions
            BindingRestrictions restrictions;
            BindingRestrictions classContextRestrictions = BindingRestrictions.Empty;
            BindingRestrictions defaultRestrictions      = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType);

            DTypeDesc classContext = this._classContext;

            if (!ClassContextIsKnown)//ClassContext wasn't supplied during creation of binder => put it into restriction
            {
                Debug.Assert(args.Length > RealMethodArgumentCount, "Not enough arguments!");

                DynamicMetaObject dmoRuntimeClassContext = GetRuntimeClassContext(args);
                Debug.Assert(dmoRuntimeClassContext.Value == null || Types.DTypeDesc[0].IsAssignableFrom(dmoRuntimeClassContext.LimitType), "Wrong class context type!");

                classContext = (DTypeDesc)dmoRuntimeClassContext.Value;
                Debug.Assert(classContext == null || !classContext.IsUnknown, "Class context should be known at run time!");

                classContextRestrictions = BindingRestrictions.GetInstanceRestriction(dmoRuntimeClassContext.Expression, classContext);
                defaultRestrictions      = defaultRestrictions.Merge(classContextRestrictions);
            }

            if (obj == null)
            {
                if (target.Value != null && Configuration.Application.Compiler.ClrSemantics)
                {
                    // TODO: some normalizing conversions (PhpString, PhpBytes -> string):
                    target = new WrappedClrDynamicMetaObject(target);
                    obj    = target.Value as DObject;

                    wrappedTarget = target as WrappedClrDynamicMetaObject;

                    Debug.Assert(obj != null);
                }
                else
                {
                    //defaultRestrictions = defaultRestrictions.Merge(BindingRestrictions.GetTypeRestriction
                    if (target.Value == null)
                    {
                        defaultRestrictions = BindingRestrictions.GetInstanceRestriction(target.Expression, null);
                    }

                    return(DoAndReturnDefault(
                               BinderHelper.ThrowError("method_called_on_non_object", ActualMethodName),
                               defaultRestrictions));
                }
            }



            // obtain the appropriate method table
            DTypeDesc type_desc = obj.TypeDesc;

            // perform method lookup
            DRoutineDesc    method;
            GetMemberResult result = type_desc.GetMethod(new Name(ActualMethodName), classContext, out method);

            //PhpStack stack = context.Stack;

            if (result == GetMemberResult.NotFound)
            {
                if ((result = type_desc.GetMethod(DObject.SpecialMethodNames.Call, classContext, out method)) == GetMemberResult.NotFound)
                {
                    return(DoAndReturnDefault(
                               Expression.Call(Methods.PhpException.UndefinedMethodCalled, Expression.Constant(obj.TypeName), Expression.Constant(ActualMethodName)),
                               defaultRestrictions
                               ));    // TODO: alter restrictions
                }
                else
                {
                    invokeCallMethod = true;
                }
            }

            // throw an error if the method was found but the caller is not allowed to call it due to its visibility
            if (result == GetMemberResult.BadVisibility)
            {
                return(DoAndReturnDefault(
                           BinderHelper.ThrowVisibilityError(method, classContext),
                           defaultRestrictions));
            }

            if (invokeCallMethod)
            {
                InvokeCallMethod(target, args, obj, method, out restrictions, out invokeMethodExpr);

                return(new DynamicMetaObject(invokeMethodExpr, restrictions.Merge(classContextRestrictions)));
            }
            else
            {
                // we are invoking the method

                // PhpRoutine (function or method)
                if (method.Member is PhpRoutine)
                {
                    InvokePhpMethod(target, args, method.PhpRoutine, out restrictions, out invokeMethodExpr);
                    return(new DynamicMetaObject(invokeMethodExpr, restrictions.Merge(classContextRestrictions)));
                }
                // ClrMethod
                else if (method.Member is ClrMethod)
                {
                    var targetwrapper = (target.LimitType == typeof(ClrObject)) ?
                                        (DynamicMetaObject) new ClrDynamicMetaObject(target) :     // ((ClrObject)target).RealType restriction
                                        (DynamicMetaObject) new ClrValueDynamicMetaObject(target); // simple type restriction, IClrValue<T> or any .NET class inheriting PhpObject

                    InvokeClrMethod(targetwrapper, args, method, out restrictions, out invokeMethodExpr);

                    if (wrappedTarget != null)
                    {
                        return(new DynamicMetaObject(Expression.Block(wrappedTarget.WrapIt(),
                                                                      invokeMethodExpr), wrappedTarget.Restrictions.Merge(classContextRestrictions)));
                    }

                    return(new DynamicMetaObject(invokeMethodExpr, restrictions.Merge(classContextRestrictions)));
                }
            }

            throw new NotImplementedException();
        }
Exemplo n.º 14
0
 private BindingRestrictions GetRestrictions()
 {
     return(BindingRestrictions.GetTypeRestriction(Expression, typeof(T)));
 }
Exemplo n.º 15
0
 private BindingRestrictions ComTypeLibInfoRestrictions(params DynamicMetaObject[] args)
 {
     return(BindingRestrictions.Combine(args).Merge(BindingRestrictions.GetTypeRestriction(Expression, typeof(ComTypeLibInfo))));
 }
        public override DynamicMetaObject FallbackSetMember(
            DynamicMetaObject targetMO, DynamicMetaObject value,
            DynamicMetaObject errorSuggestion)
        {
#if !NETSTANDARD
            // First try COM binding.
            DynamicMetaObject result;
            if (ComBinder.TryBindSetMember(this, targetMO, value, out result))
            {
                return(result);
            }
#endif
            // 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.
            var flags = BindingFlags.IgnoreCase | BindingFlags.Static |
                        BindingFlags.Instance | BindingFlags.Public;
            var members = targetMO.LimitType.GetMember(this.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),
                               "Sympl only supports setting Properties and " +
                               "fields at this time."));
                }
                return(new DynamicMetaObject(
                           // Assign returns the stored value, so we're good for Sympl.
                           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)));
            }
            else
            {
                return(errorSuggestion ??
                       RuntimeHelpers.CreateThrow(
                           targetMO, null,
                           BindingRestrictions.GetTypeRestriction(targetMO.Expression,
                                                                  targetMO.LimitType),
                           typeof(MissingMemberException),
                           "IDynObj member name conflict."));
            }
        }
Exemplo n.º 17
0
        public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
        {
            var invoke = Expression.Call(GetDynamicMemberMethodInfo, this.Expression, Expression.Constant(binder.Name));

            return(new DynamicMetaObject(invoke, BindingRestrictions.GetTypeRestriction(this.Expression, this.LimitType)));
        }
Exemplo n.º 18
0
        private DynamicMetaObject /*!*/ FallbackInvokeMember(DynamicMetaObject target /*!*/, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            // determine run time values and additional restrictions:
            DTypeDesc           classContext = this._classContext;
            string              fieldName    = this._fieldName;
            BindingRestrictions restrictions = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType); //target.Restrictions;

            int currentArg = 0;

            if (!ClassContextIsKnown)
            {
                Debug.Assert(args.Length > currentArg, "Not enough arguments!");
                Debug.Assert(args[currentArg].Value == null || Types.DTypeDesc[0].IsAssignableFrom(args[currentArg].LimitType), "Wrong class context type!");
                classContext = (DTypeDesc)args[currentArg].Value;
                Debug.Assert(classContext == null || !classContext.IsUnknown, "Class context should be known at run time!");

                restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(args[currentArg].Expression, classContext));

                currentArg++;
            }
            if (IsIndirect)
            {
                Debug.Assert(args.Length > currentArg, "Not enough arguments!");
                Debug.Assert(Types.String[0].IsAssignableFrom(args[currentArg].LimitType), "Wrong field name type!");
                fieldName = (string)args[currentArg].Value;

                restrictions = restrictions.Merge(
                    BindingRestrictions.GetExpressionRestriction(
                        Expression.Equal(
                            args[currentArg].Expression,
                            Expression.Constant(fieldName, Types.String[0]))));

                currentArg++;
            }

            //
            ////Debug.Assert(!(var is PhpReference) && name != null);
            Debug.Assert(target.HasValue && target.LimitType != Types.PhpReference[0], "Target should not be PhpReference!");

            ////if (ReferenceEquals(obj, ScriptContext.SetterChainSingletonObject))
            ////{
            ////    ScriptContext.CurrentContext.AbortSetterChain(false);
            ////    return new PhpReference();
            ////}
            if (WantReference && ReferenceEquals(target.Value, ScriptContext.SetterChainSingletonObject))
            {
                // GetObjectPropertyRef:
                Func <PhpReference> abortSetterChain = () =>
                {
                    ScriptContext.CurrentContext.AbortSetterChain(false);
                    return(new PhpReference());
                };

                return(new DynamicMetaObject(
                           Expression.Call(abortSetterChain.Method),
                           BindingRestrictions.GetInstanceRestriction(target.Expression, ScriptContext.SetterChainSingletonObject)
                           ));
            }

            DObject obj;

            ////// a property of a DObject:
            if ((obj = target.Value as DObject) != null)
            {
                if (obj is ClrObject /*|| obj is IClrValue // IClrValue -> ClrValue<T> -> already in restriction */)
                {
                    // ((DObject)target).RealType == <obj>.RealType
                    restrictions = restrictions.Merge(
                        BindingRestrictions.GetInstanceRestriction(
                            Expression.Property(Expression.Convert(target.Expression, Types.DObject[0]), Properties.DObject_RealType),
                            obj.RealType));
                }

                ////    return GetObjectProperty(obj, name, caller, quiet);
                DPropertyDesc   property;
                GetMemberResult result = obj.TypeDesc.GetInstanceProperty(new VariableName(fieldName), classContext, out property);

                switch (result)
                {
                case GetMemberResult.OK:
                    ////object value = property.Get(this);
                    ////PhpReference reference = value as PhpReference;

                    if (property.Member is PhpField || property.Member is PhpVisibleProperty)
                    {
                        var          realType     = property.DeclaringType.RealType;
                        FieldInfo    realField    = (property.Member is PhpField) ? property.PhpField.RealField : null;
                        PropertyInfo realProperty = (property.Member is PhpVisibleProperty) ? ((PhpVisibleProperty)property.Member).RealProperty : null;

                        Debug.Assert(realField != null ^ realProperty != null);

                        MemberExpression getter = null;

                        if (realField != null)
                        {
                            getter = Expression.Field(Expression.Convert(target.Expression, realType), realField);
                        }
                        else if (realProperty != null)
                        {
                            getter = Expression.Property(Expression.Convert(target.Expression, realType), realProperty);
                        }


                        if (Types.PhpReference[0].IsAssignableFrom(getter.Type))
                        {
                            var reference  = Expression.Variable(Types.PhpReference[0]);
                            var assignment = Expression.Assign(reference, getter);

                            if (WantReference)
                            {
                                ////value = property.Get(this);
                                ////reference = value as PhpReference;

                                var returnLabel = Expression.Label(this._returnType);

                                ////if (reference != null && reference.IsSet)
                                ////{
                                ////    reference.IsAliased = true;
                                ////    return reference;
                                ////}

                                var isset = Expression.IfThen(
                                    Expression.Property(assignment, Properties.PhpReference_IsSet),
                                    Expression.Block(
                                        Expression.Assign(Expression.Property(reference, Properties.PhpReference_IsAliased), Expression.Constant(true)),
                                        Expression.Return(returnLabel, reference)));

                                ////// the CT property has been unset -> try to invoke __get
                                ////PhpReference get_ref = InvokeGetterRef(name, caller, out getter_exists);
                                ////if (getter_exists) return (get_ref == null ? new PhpReference() : get_ref);

                                ////if (reference == null)
                                ////{
                                ////    reference = new PhpReference(value);
                                ////    property.Set(this, reference);
                                ////}
                                ////else
                                ////{
                                ////    reference.IsAliased = true;
                                ////    reference.IsSet = true;
                                ////}
                                Func <DObject, string, DTypeDesc, PhpReference, PhpReference> notsetOperation = (self, name, caller, refrnc) =>
                                {
                                    bool getter_exists;
                                    // the CT property has been unset -> try to invoke __get
                                    PhpReference get_ref = self.InvokeGetterRef(name, caller, out getter_exists);
                                    if (getter_exists)
                                    {
                                        return(get_ref ?? new PhpReference());
                                    }

                                    Debug.Assert(refrnc != null);

                                    refrnc.IsAliased = true;
                                    refrnc.IsSet     = true;

                                    return(refrnc);
                                };

                                ////return reference;

                                return(new DynamicMetaObject(
                                           Expression.Block(this._returnType,
                                                            new[] { reference },
                                                            new Expression[] {
                                    isset,
                                    Expression.Label(returnLabel,
                                                     Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]), reference))
                                }),
                                           restrictions));
                            }
                            else
                            {
                                ////if (reference != null && !reference.IsSet)
                                ////{
                                ////    // the property is CT but has been unset
                                ////    if (issetSemantics)
                                ////    {
                                ////        bool handled;
                                ////        return PropertyIssetHandler(name, caller, out handled);
                                ////    }
                                ////    else return GetRuntimeField(name, caller);
                                ////}
                                ////else return value;


                                Func <DObject, string, DTypeDesc, object> notsetOperation;
                                if (_issetSemantics)
                                {
                                    notsetOperation = (self, name, caller) =>
                                    {
                                        return(PhpVariable.Dereference(self.GetRuntimeField(name, caller)));
                                    }
                                }
                                ;
                                else
                                {
                                    notsetOperation = (self, name, caller) =>
                                    {
                                        bool handled;
                                        return(PhpVariable.Dereference(self.PropertyIssetHandler(name, caller, out handled)));
                                    }
                                };
                                var value =
                                    Expression.Block(this._returnType,
                                                     new[] { reference },
                                                     Expression.Condition(
                                                         Expression.Property(assignment, Properties.PhpReference_IsSet),
                                                         Expression.Field(reference, Fields.PhpReference_Value),
                                                         Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))
                                                         ));

                                return(new DynamicMetaObject(value, restrictions));
                            }
                        }
                        else
                        {
                            if (WantReference)
                            {
                                return(new DynamicMetaObject(
                                           Expression.New(Constructors.PhpReference_Object, Expression.Convert(getter, Types.Object[0])),
                                           restrictions));
                            }
                            else
                            {
                                return(new DynamicMetaObject(
                                           Expression.Call(Methods.PhpVariable.Dereference, Expression.Convert(getter, Types.Object[0])),
                                           restrictions));
                            }
                        }
                    }
                    else if (property.Member is ClrProperty)
                    {
                        var realType     = property.DeclaringType.RealType;
                        var realProperty = property.ClrProperty.RealProperty;

                        // (target.{RealObject|realValue}).<realProperty>
                        Expression value = Expression.Convert(
                            BinderHelper.ClrObjectWrapDynamic(
                                Expression.Property(
                                    BinderHelper.ClrRealObject(target, realType),
                                    realProperty)),
                            Types.Object[0]);

                        if (WantReference)
                        {
                            value = BinderHelper.MakePhpReference(value);
                        }

                        return(new DynamicMetaObject(value, restrictions));
                    }
                    else if (property.Member is ClrField)
                    {
                        var realType  = property.DeclaringType.RealType;
                        var realField = property.ClrField.FieldInfo;

                        // (target.{RealObject|realValue}).<realField>
                        Expression value = Expression.Convert(
                            BinderHelper.ClrObjectWrapDynamic(
                                Expression.Field(
                                    BinderHelper.ClrRealObject(target, realType),
                                    realField)),
                            Types.Object[0]);

                        if (WantReference)
                        {
                            value = BinderHelper.MakePhpReference(value);
                        }

                        return(new DynamicMetaObject(value, restrictions));
                    }
                    else if (property.Member is ClrEvent)
                    {
                        var clrEvent = (ClrEvent)property.Member;
                        var realType = property.DeclaringType.RealType;

                        // emit stub that Wraps event as [ ClrEventObject<handlerType>.Wrap(<SC>, <event name>, <addMethod>, <removeMethod>) ]
                        var stub = new System.Reflection.Emit.DynamicMethod(
                            string.Format("event<{0}>", fieldName),
                            Types.DObject[0], new[] { realType }, realType);
                        var il = new ILEmitter(stub);
                        clrEvent.EmitGetEventObject(
                            il,
                            new Place(null, Properties.ScriptContext_CurrentContext),
                            new IndexedPlace(PlaceHolder.Argument, 0),
                            false);
                        il.Emit(System.Reflection.Emit.OpCodes.Ret);

                        Expression value = Expression.Call(stub, BinderHelper.ClrRealObject(target, realType));
                        if (WantReference)
                        {
                            value = BinderHelper.MakePhpReference(value);
                        }
                        return(new DynamicMetaObject(value, restrictions));
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                case GetMemberResult.NotFound:
                    if (WantReference)
                    {
                        Func <DObject, string, DTypeDesc, PhpReference> op = (self, name, caller) =>
                        {
                            PhpReference reference;
                            bool         getter_exists;

                            // search in RT fields
                            if (self.RuntimeFields != null && self.RuntimeFields.ContainsKey(name))
                            {
                                var namekey = new IntStringKey(name);
                                return(self.RuntimeFields.table._ensure_item_ref(ref namekey, self.RuntimeFields));
                            }

                            // property is not present -> try to invoke __get
                            reference = self.InvokeGetterRef(name, caller, out getter_exists);
                            if (getter_exists)
                            {
                                return((reference == null) ? new PhpReference() : reference);
                            }

                            // (no notice/warning/error thrown by PHP)

                            // add the field
                            reference = new PhpReference();
                            if (self.RuntimeFields == null)
                            {
                                self.RuntimeFields = new PhpArray();
                            }
                            self.RuntimeFields[name] = reference;

                            return(reference);
                        };

                        return(new DynamicMetaObject(
                                   Expression.Call(null, op.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0])),
                                   restrictions));
                    }
                    else
                    {
                        ////if (issetSemantics)
                        ////{
                        ////    OrderedHashtable<string>.Element element;
                        ////    if (RuntimeFields != null && (element = RuntimeFields.GetElement(name)) != null)
                        ////    {
                        ////        return element.Value;
                        ////    }
                        ////    else
                        ////    {
                        ////        bool handled;
                        ////        return PropertyIssetHandler(name, caller, out handled);
                        ////    }
                        ////}
                        ////else return GetRuntimeField(name, caller);

                        if (_issetSemantics)
                        {
                            Func <DObject, string, DTypeDesc, object> notsetOperation = (self, name, caller) =>
                            {
                                if (self.RuntimeFields != null)
                                {
                                    object value;
                                    if (self.RuntimeFields.TryGetValue(name, out value))
                                    {
                                        return(value);
                                    }
                                }

                                bool handled;
                                return(self.PropertyIssetHandler(name, caller, out handled));
                            };

                            return(new DynamicMetaObject(
                                       Expression.Call(Methods.PhpVariable.Dereference,
                                                       Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))),
                                       restrictions));
                        }
                        else
                        {
                            return(new DynamicMetaObject(
                                       Expression.Call(
                                           Methods.PhpVariable.Dereference,
                                           Expression.Call(
                                               Expression.Convert(target.Expression, Types.DObject[0]),
                                               Methods.DObject_GetRuntimeField, Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))),
                                       restrictions));
                        };
                    }

                case GetMemberResult.BadVisibility:
                {
                    ////PhpException.PropertyNotAccessible(
                    ////    property.DeclaringType.MakeFullName(),
                    ////    name.ToString(),
                    ////    (caller == null ? String.Empty : caller.MakeFullName()),
                    ////    property.IsProtected);

                    string stringResourceKey = property.IsProtected ? "protected_property_accessed" : "private_property_accessed";

                    return(new DynamicMetaObject(
                               Expression.Block(this._returnType,
                                                Expression.Call(null, Methods.PhpException.Throw,
                                                                Expression.Constant(PhpError.Error, Types.PhpError_String[0]),
                                                                Expression.Constant(CoreResources.GetString(stringResourceKey, property.DeclaringType.MakeFullName(), fieldName, (classContext == null ? String.Empty : classContext.MakeFullName())))),
                                                WantReference ? (Expression)Expression.New(Constructors.PhpReference_Void) : Expression.Constant(null)
                                                ),
                               restrictions));
                }
                }
            }

            ////// warnings:
            ////if (!quiet) // not in isset() operator only
            ////{
            if (!_issetSemantics)
            {
                ////    if (PhpVariable.IsEmpty(var))
                ////        // empty:
                ////        PhpException.Throw(PhpError.Notice, CoreResources.GetString("empty_used_as_object"));
                ////    else
                ////        // PhpArray, string, scalar type:
                ////        PhpException.VariableMisusedAsObject(var, false);

                Action <object> error = (var) =>
                {
                    if (PhpVariable.IsEmpty(var))
                    {
                        // empty:
                        PhpException.Throw(PhpError.Notice, CoreResources.GetString("empty_used_as_object"));
                    }
                    else
                    {
                        // PhpArray, string, scalar type:
                        PhpException.VariableMisusedAsObject(var, false);
                    }
                };

                return(new DynamicMetaObject(
                           Expression.Block(this._returnType,
                                            Expression.Call(error.Method, target.Expression),
                                            WantReference ? (Expression)Expression.New(Constructors.PhpReference_Void) : Expression.Constant(null)),
                           (target.HasValue && target.Value == null) ?
                           BindingRestrictions.GetInstanceRestriction(target.Expression, null) :
                           BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType)));
            }
            ////}

            ////// property does not exist
            ////return null;
            return(new DynamicMetaObject(
                       Expression.Constant(null),
                       (target.HasValue && target.Value == null) ?
                       BindingRestrictions.GetInstanceRestriction(target.Expression, null) :
                       BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType)));
        }
Exemplo n.º 19
0
        public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
        {
            Schema.Property property;
            if (!_metadata.Schema.TryFindProperty(binder.Name, out property))
            {
                return(base.BindGetMember(binder));
            }

            var arguments = new List <Expression>
            {
                Expression.Constant(_metadata.PropertyIndices[property.Name])
            };

            MethodInfo getter = null;

            switch (property.Type)
            {
            case Schema.PropertyType.Int:
                if (property.IsNullable)
                {
                    getter = GetGetMethod(dummyHandle.GetNullableInt64);
                }
                else
                {
                    getter = GetGetMethod(dummyHandle.GetInt64);
                }

                break;

            case Schema.PropertyType.Bool:
                if (property.IsNullable)
                {
                    getter = GetGetMethod(dummyHandle.GetNullableBoolean);
                }
                else
                {
                    getter = GetGetMethod(dummyHandle.GetBoolean);
                }

                break;

            case Schema.PropertyType.Float:
                if (property.IsNullable)
                {
                    getter = GetGetMethod(dummyHandle.GetNullableSingle);
                }
                else
                {
                    getter = GetGetMethod(dummyHandle.GetSingle);
                }

                break;

            case Schema.PropertyType.Double:
                if (property.IsNullable)
                {
                    getter = GetGetMethod(dummyHandle.GetNullableDouble);
                }
                else
                {
                    getter = GetGetMethod(dummyHandle.GetDouble);
                }

                break;

            case Schema.PropertyType.String:
                getter = GetGetMethod(dummyHandle.GetString);
                break;

            case Schema.PropertyType.Data:
                getter = GetGetMethod(dummyHandle.GetByteArray);
                break;

            case Schema.PropertyType.Date:
                if (property.IsNullable)
                {
                    getter = GetGetMethod(dummyHandle.GetNullableDateTimeOffset);
                }
                else
                {
                    getter = GetGetMethod(dummyHandle.GetDateTimeOffset);
                }

                break;

            case Schema.PropertyType.Object:
                arguments.Insert(0, Expression.Field(GetLimitedSelf(), RealmObjectRealmField));
                arguments.Add(Expression.Constant(property.ObjectType));
                getter = GetGetMethod(dummyHandle.GetObject <DynamicRealmObject>);
                break;

            case Schema.PropertyType.Array:
                arguments.Insert(0, Expression.Field(GetLimitedSelf(), RealmObjectRealmField));
                arguments.Add(Expression.Constant(property.ObjectType));
                getter = GetGetMethod(dummyHandle.GetList <DynamicRealmObject>);
                break;

            case Schema.PropertyType.LinkingObjects:
                getter = GetGetMethod(dummyHandle.GetBacklinks);
                break;
            }

            var        self       = GetLimitedSelf();
            var        instance   = Expression.Field(self, RealmObjectObjectHandleField);
            Expression expression = Expression.Call(instance, getter, arguments);

            if (property.Type == Schema.PropertyType.LinkingObjects)
            {
                expression = Expression.Call(self, RealmObjectGetBacklinksForHandleMethod, Expression.Constant(binder.Name), expression);
            }

            if (binder.ReturnType != expression.Type)
            {
                expression = Expression.Convert(expression, binder.ReturnType);
            }

            var argumentShouldBeDynamicRealmObject = BindingRestrictions.GetTypeRestriction(Expression, typeof(DynamicRealmObject));
            var argumentShouldBeInTheSameRealm     = BindingRestrictions.GetInstanceRestriction(Expression.Field(self, RealmObjectRealmField), _realm);

            return(new DynamicMetaObject(expression, argumentShouldBeDynamicRealmObject.Merge(argumentShouldBeInTheSameRealm)));
        }
Exemplo n.º 20
0
        public override DynamicMetaObject FallbackInvokeMember(
            DynamicMetaObject targetMO, DynamicMetaObject[] args,
            DynamicMetaObject errorSuggestion)
        {
#if !NETSTANDARD
            // First try COM binding.
            DynamicMetaObject result;
            if (ComBinder.TryBindInvokeMember(this, targetMO, args, out result))
            {
                return(result);
            }
#endif
            // Defer if any object has no value so that we evaulate their
            // Expressions and nest a CallSite for the InvokeMember.
            if (!targetMO.HasValue || args.Any((a) => !a.HasValue))
            {
                var deferArgs = new DynamicMetaObject[args.Length + 1];
                for (int i = 0; i < args.Length; i++)
                {
                    deferArgs[i + 1] = args[i];
                }
                deferArgs[0] = targetMO;
                return(Defer(deferArgs));
            }
            // Find our own binding.
            // Could consider allowing invoking static members from an instance.
            var flags = BindingFlags.IgnoreCase | BindingFlags.Instance |
                        BindingFlags.Public;
            var members = targetMO.LimitType.GetMember(this.Name, flags);

            var restrictions = RuntimeHelpers.GetTargetArgsRestrictions(
                targetMO, args, false);

            // Assigned a Null
            if (targetMO.HasValue && targetMO.Value == null)
            {
                return(RuntimeHelpers.CreateThrow(targetMO,
                                                  args,
                                                  restrictions,
                                                  typeof(NullReferenceException),
                                                  "Object reference not set to an instance of an object."));
            }

            if ((members.Length == 1) && (members[0] is PropertyInfo ||
                                          members[0] is FieldInfo))
            {
                // NEED TO TEST, should check for delegate value too
                var mem    = members[0];
                var target = new DynamicMetaObject(
                    RuntimeHelpers.EnsureObjectResult(
                        Expression.MakeMemberAccess(
                            Expression.Convert(targetMO.Expression,
                                               members[0].DeclaringType),
                            members[0])),
                    // 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));

                //If no arguments, to allow scenario like Request.QueryString()
                if (args == null || args.Length == 0)
                {
                    return(target);
                }

                return(new DynamicMetaObject(
                           RuntimeHelpers.GetIndexingExpression(target, args),
                           restrictions
                           ));
                // Don't test for eventinfos since we do nothing with them now.
            }
            else
            {
                bool isExtension = false;

                // Get MethodInfos with right arg counts.
                var mi_mems = members.
                              Select(m => m as MethodInfo).
                              Where(m => m is MethodInfo &&
                                    ((MethodInfo)m).GetParameters().Length ==
                                    args.Length);
                // Get MethodInfos with param types that work for args.  This works
                // except for value args that need to pass to reftype params.
                // We could detect that to be smarter and then explicitly StrongBox
                // the args.
                List <MethodInfo> res = new List <MethodInfo>();
                foreach (var mem in mi_mems)
                {
                    if (RuntimeHelpers.ParametersMatchArguments(
                            mem.GetParameters(), args))
                    {
                        res.Add(mem);
                    }
                }

                List <DynamicMetaObject> argList = new List <DynamicMetaObject>(args);

                //Try extension methods if no methods found
                if (res.Count == 0)
                {
                    isExtension = true;
                    argList.Insert(0, targetMO);

                    res = RuntimeHelpers.GetExtensionMethods(this.Name, targetMO, argList.ToArray());
                }

                // False below means generate a type restriction on the MO.
                // We are looking at the members targetMO's Type.
                if (res.Count == 0)
                {
                    return(errorSuggestion ??
                           RuntimeHelpers.CreateThrow(
                               targetMO, args, restrictions,
                               typeof(MissingMemberException),
                               string.Format("Can't bind member invoke {0}.{1}({2})", targetMO.RuntimeType.Name, this.Name, args.ToString())));
                }

                //If more than one results found, attempt overload resolution
                MethodInfo mi = null;
                if (res.Count > 1)
                {
                    mi = RuntimeHelpers.ResolveOverload(res, argList.ToArray());
                }
                else
                {
                    mi = res[0];
                }

                // restrictions and conversion must be done consistently.
                var callArgs = RuntimeHelpers.ConvertArguments(
                    argList.ToArray(), mi.GetParameters());

                if (isExtension)
                {
                    return(new DynamicMetaObject(
                               RuntimeHelpers.EnsureObjectResult(
                                   Expression.Call(
                                       null,
                                       mi, callArgs)),
                               restrictions));
                }
                else
                {
                    return(new DynamicMetaObject(
                               RuntimeHelpers.EnsureObjectResult(
                                   Expression.Call(
                                       Expression.Convert(targetMO.Expression,
                                                          targetMO.LimitType),
                                       mi, callArgs)),
                               restrictions));
                }
                // Could hve tried just letting Expr.Call factory do the work,
                // but if there is more than one applicable method using just
                // assignablefrom, Expr.Call throws.  It does not pick a "most
                // applicable" method or any method.
            }
        }
Exemplo n.º 21
0
        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:
                var limitType = self.GetLimitType();
                if ((limitType == typeof(Bytes) || limitType == typeof(PythonBuffer) || limitType == typeof(ByteArray)) &&
                    !_context.PythonOptions.Python30)
                {
                    res = new DynamicMetaObject(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("MakeString"),
                            AstUtils.Convert(self.Expression, typeof(IList <byte>))
                            ),
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, limitType)
                        );
                }
                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("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()) && IsIndexless(self))
                    {
                        res = ConvertToIEnumerable(this, self.Restrict(self.GetLimitType()));
                    }
                }
                else if (type == typeof(IEnumerator))
                {
                    if (!typeof(IEnumerator).IsAssignableFrom(self.GetLimitType()) &&
                        !typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) &&
                        IsIndexless(self))
                    {
                        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("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)));
        }
Exemplo n.º 22
0
 public override DynamicMetaObject FallbackDeleteIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
 {
     if (indexes[0].LimitType == typeof(string))
     {
         return(new DynamicMetaObject(
                    Expression.Dynamic(new TjsDeleteMemberBinder(_context, (string)indexes[0].Value, false), ReturnType, target.Expression),
                    BindingRestrictions.Combine(ArrayUtils.Insert(target, indexes)).Merge(
                        BindingRestrictions.GetInstanceRestriction(indexes[0].Expression, indexes[0].Value)
                        ).Merge(
                        BindingRestrictions.GetTypeRestriction(indexes[0].Expression, indexes[0].LimitType)
                        )
                    ));
     }
     return(errorSuggestion ?? new DynamicMetaObject(
                Expression.Throw(Expression.Constant(new MissingMemberException(indexes[0].Value.ToString())), typeof(object)),
                BindingRestrictions.Combine(ArrayUtils.Insert(target, indexes)).Merge(BindingRestrictions.GetTypeRestriction(indexes[0].Expression, indexes[0].LimitType))
                ));
 }
        private BindingRestrictions GetBindingRestrictions()
        {
            var restrictions = BindingRestrictions.GetTypeRestriction(this.Expression, this.LimitType);

            return(restrictions.Merge(BindingRestrictions.GetInstanceRestriction(this.Expression, this.Host)));
        }
Exemplo n.º 24
0
 public DynamicMetaObject GetMetaObject(Expression parameter)
 {
     return(new Meta(parameter, BindingRestrictions.GetTypeRestriction(parameter, typeof(Function)), this));
 }
Exemplo n.º 25
0
 public override BindingRestrictions GetRestrictions()
 {
     return(BindingRestrictions.GetTypeRestriction(ArgumentExpression, typeof(NativeArgument)));
 }
Exemplo n.º 26
0
 private BindingRestrictions GetRestrictions()
 {
     return(BindingRestrictions.GetTypeRestriction(Expression, typeof(AttributesAdapter)));
 }
Exemplo n.º 27
0
 public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
 {
     System.Linq.Expressions.Expression s     = System.Linq.Expressions.Expression.Convert(this.Expression, typeof(ModelItemImpl));
     System.Linq.Expressions.Expression value = System.Linq.Expressions.Expression.Call(s, getPropertyValueMethodInfo, System.Linq.Expressions.Expression.Constant(binder.Name));
     return(new DynamicMetaObject(value, BindingRestrictions.GetTypeRestriction(this.Expression, this.LimitType)));
 }
Exemplo n.º 28
0
        /// <summary>
        /// Access <paramref name="target"/> as object instance.
        /// </summary>
        /// <param name="target">Given target.</param>
        /// <param name="instance">Resolved instance with restrictions.</param>
        /// <returns>Whether <paramref name="target"/> contains an object instance.</returns>
        /// <remarks>Necessary restriction are already resolved within returned <paramref name="instance"/>.</remarks>
        public static bool TryTargetAsObject(DynamicMetaObject target, out DynamicMetaObject instance)
        {
            var value = target.Value;

            if (value == null)
            {
                instance = new DynamicMetaObject(
                    target.Expression,
                    target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, Expression.Constant(null))),
                    null);

                return(false);
            }

            var expr = target.Expression;

            // dereference PhpAlias first:
            if (target.LimitType == typeof(PhpAlias))
            {
                expr   = Expression.Field(expr, "Value");
                value  = ((PhpAlias)value).Value;
                target = new DynamicMetaObject(expr, target.Restrictions, value);
                // continue
            }

            // unwrap PhpValue
            if (target.LimitType == typeof(PhpValue))
            {
                var phpvalue = (PhpValue)value;
                if (phpvalue.IsAlias)
                {
                    // target of PhpValue.Alias when PhpValue.IsAlias
                    return(TryTargetAsObject(
                               new DynamicMetaObject(
                                   Expression.Property(expr, "Alias"),
                                   target.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Property(expr, "IsAlias"))),
                                   phpvalue.Alias),
                               out instance));
                }

                if (phpvalue.IsObject)
                {
                    expr = Expression.Property(expr, "Object");

                    // PhpValue.Object when PhpValue.IsObject
                    instance = new DynamicMetaObject(
                        expr,                                                                                               // PhpValue.Object
                        target.Restrictions.Merge(BindingRestrictions.GetTypeRestriction(expr, phpvalue.Object.GetType())), // PhpValue.Object.GetType() == TYPE
                        phpvalue.Object);

                    // PhpResource is an exception, not acting like an object in PHP
                    if (phpvalue.Object is PhpResource)
                    {
                        // "PhpValue.Object is PhpResource"
                        // ignore the "PhpValue.IsObject" restriction (not needed)
                        instance = new DynamicMetaObject(
                            expr,                                                                                                                  // PhpValue.Object
                            target.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.TypeIs(expr, typeof(PhpResource)))), // PhpValue.Object is PhpResource
                            instance.Value);
                        return(false);
                    }

                    //
                    return(true);
                }

                // anything else is not an object, PhpValue.TypeCode == value.TypeCode
                instance = new DynamicMetaObject(
                    expr,
                    target.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Equal(Expression.Property(expr, "TypeCode"), Expression.Constant(phpvalue.TypeCode)))),
                    value);
                return(false);
            }

            //

            var restrictions = target.Restrictions;
            var lt           = target.Expression.Type.GetTypeInfo();

            if (!lt.IsValueType && !lt.IsSealed && !typeof(PhpArray).IsAssignableFrom(lt.AsType()) && !typeof(PhpResource).IsAssignableFrom(lt.AsType()))
            {
                // we need to set the type restriction
                restrictions = restrictions.Merge(BindingRestrictions.GetTypeRestriction(expr, value.GetType()));
            }

            //
            instance = new DynamicMetaObject(expr, restrictions, value);
            return(!(   // TODO: ReflectionUtils.IsClassType
                       value is PhpResource ||
                       value is PhpArray ||
                       value is bool ||
                       value is int ||
                       value is long ||
                       value is double ||
                       value is string ||
                       value is PhpString));
        }
Exemplo n.º 29
0
        public override DynamicMetaObject FallbackSetMember(
            DynamicMetaObject target, DynamicMetaObject value,
            DynamicMetaObject errorSuggestion)
        {
            // Used by (set-attr obj name value)

            if (!target.HasValue)
            {
                return(Defer(target));
            }

            var name = Name.LispToPascalCaseName();

            if (target.Value == null)
            {
                var id = target.LimitType.Name + "." + name;
                return(Runtime.CheckTargetNullReference(target, "Cannot set property on null reference:" + id + "(null)"));
            }

            var flags   = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
            var members = target.LimitType.GetMember(name, flags);

            if (members.Length == 1 && members[0] is PropertyInfo)
            {
                var prop = (PropertyInfo)members[0];
                var val  = Runtime.ConvertArgument(value, prop.PropertyType);
                var expr = Expression.Assign(Expression.MakeMemberAccess(Expression.Convert(target.Expression, prop.DeclaringType), prop), val);
                return(new DynamicMetaObject(Runtime.EnsureObjectResult(expr),
                                             BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType)));
            }
            else if (members.Length == 1 && members[0] is FieldInfo)
            {
                var field = (FieldInfo)members[0];
                var val   = Runtime.ConvertArgument(value, field.FieldType);
                var expr  = Expression.Assign(Expression.MakeMemberAccess(Expression.Convert(target.Expression, field.DeclaringType), field), val);
                return(new DynamicMetaObject(Runtime.EnsureObjectResult(expr),
                                             BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType)));
            }
            else if (members.Length == 1 && members[0] is EventInfo)
            {
                //public static void AddEventHandler( System.Reflection.EventInfo eventinfo, object target, object func )

                var evt  = (EventInfo)members[0];
                var expr = Expression.Call(Runtime.AddEventHandlerMethod,
                                           Expression.Constant(evt, typeof(EventInfo)),
                                           Expression.Convert(target.Expression, evt.DeclaringType),
                                           Expression.Convert(value.Expression, typeof(IApply)));
                return(new DynamicMetaObject(Runtime.EnsureObjectResult(expr),
                                             BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType)));
            }
            else
            {
                return(errorSuggestion ??
                       Runtime.CreateThrow(
                           target, null,
                           BindingRestrictions.GetTypeRestriction(target.Expression,
                                                                  target.LimitType),
                           typeof(MissingMemberException),
                           "Property or field not found: " + target.LimitType.Name + "." + name + Runtime.CollectParameterInfo(target)));
            }
        }
Exemplo n.º 30
0
        public void TypeRestrictionTrueForMatchType(object obj)
        {
            BindingRestrictions isType = BindingRestrictions.GetTypeRestriction(Expression.Constant(obj), obj.GetType());

            Assert.True(Expression.Lambda <Func <bool> >(isType.ToExpression()).Compile()());
        }