Exemple #1
0
        private DynamicMetaObject MakeSetMemberTarget(SetOrDeleteMemberInfo memInfo, DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
        {
            Type type = target.GetLimitType();
            DynamicMetaObject self = target;

            target = target.Restrict(target.GetLimitType());

            memInfo.Body.Restrictions = target.Restrictions;

            if (typeof(TypeTracker).IsAssignableFrom(type))
            {
                type = ((TypeTracker)target.Value).Type;
                self = null;

                memInfo.Body.Restrictions = memInfo.Body.Restrictions.Merge(
                    BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value)
                    );
            }

            MakeSetMemberRule(memInfo, type, self, value, errorSuggestion);

            return(memInfo.Body.GetMetaObject(target, value));
        }
Exemple #2
0
        public override DynamicMetaObject FallbackGetIndex(
            DynamicMetaObject target, DynamicMetaObject[] indexes,
            DynamicMetaObject errorSuggestion)
        {
            var deferArgs = Runtime.CheckDeferArgs(target, indexes);

            if (deferArgs != null)
            {
                return(Defer(deferArgs));
            }

            if (target.Value == null)
            {
                var expr          = Expression.Constant(null);
                var restrictions2 = BindingRestrictions.GetInstanceRestriction(target.Expression, null);
                return(new DynamicMetaObject(expr, restrictions2));
            }

            // Find our own binding.
            //
            // Conversions created in GetIndexExpression must be consistent with
            // restrictions made in GetTargetArgsRestrictions.
            var indexingExpr = Runtime.GetIndexingExpression(target, indexes);

            if (indexingExpr == null)
            {
                return(errorSuggestion ??
                       Runtime.CreateThrow(
                           target, indexes, BindingRestrictions.Empty,
                           typeof(InvalidOperationException),
                           "No get indexer found: " + target.LimitType.FullName + Runtime.CollectParameterInfo(target, indexes)));
            }

            var restrictions = Runtime.GetTargetArgsRestrictions(target, indexes, false);

            return(new DynamicMetaObject(Runtime.EnsureObjectResult(indexingExpr), restrictions));
        }
Exemple #3
0
            } // ctor

            public override DynamicMetaObject FallbackUnaryOperation(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
            {
                // defer the target
                if (!target.HasValue)
                {
                    return(Defer(target));
                }

                if (target.Value == null)
                {
                    return(errorSuggestion ??
                           new DynamicMetaObject(
                               ThrowExpression(Properties.Resources.rsNilOperatorError),
                               target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, null))
                               ));
                }
                else
                {
                    Expression expr;
                    try
                    {
                        expr = EnsureType(LuaEmit.UnaryOperationExpression(lua, Operation, target.Expression, target.LimitType, false), this.ReturnType);
                    }
                    catch (LuaEmitException e)
                    {
                        if (errorSuggestion != null)
                        {
                            return(errorSuggestion);
                        }
                        expr = ThrowExpression(e.Message, this.ReturnType);
                    }

                    var restrictions = target.Restrictions.Merge(BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType));
                    return(new DynamicMetaObject(expr, restrictions));
                }
            } // func FallbackUnaryOperation
        public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
        {
            List <JavaFieldInfo> overloads = GetFields(binder.Name);

            if (overloads == null)
            {
                return(binder.FallbackSetMember(this, value));
            }

            if (Disposed)
            {
                return(new DynamicMetaObject(ThrowObjectDisposedException(), BindingRestrictions.GetInstanceRestriction(Expression, Value)));
            }

            var field = overloads.FirstOrDefault(f => f.IsStatic == true);

            Action <IJavaPeerable, object> setValue = field.SetValue;
            var e = Expression.Block(
                Expression.Call(Expression.Constant(field), setValue.GetMethodInfo(),
                                GetSelf(), Expression.Convert(value.Expression, typeof(object))),
                Expression);

            return(new DynamicMetaObject(e, BindingRestrictions.GetInstanceRestriction(Expression, Value)));
        }
Exemple #5
0
                    public override DynamicMetaObject BindInvokeMember
                        (InvokeMemberBinder binder, DynamicMetaObject[] args)
                    {
                        Rumpelstiltskin targetObject = (Rumpelstiltskin)base.Value;
                        Expression      self         = Expression.Convert(base.Expression,
                                                                          typeof(Rumpelstiltskin));

                        Expression targetBehavior;

                        if (binder.Name == targetObject.name)
                        {
                            targetBehavior = Expression.Call(self, RightGuessMethod);
                        }
                        else
                        {
                            targetBehavior = Expression.Call(self, WrongGuessMethod,
                                                             Expression.Constant(binder.Name));
                        }

                        var restrictions = BindingRestrictions.GetInstanceRestriction
                                               (self, targetObject);

                        return(new DynamicMetaObject(targetBehavior, restrictions));
                    }
 DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
 => new MetaObject(parameter, BindingRestrictions.GetInstanceRestriction(parameter, this), this);
Exemple #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 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));
        }
Exemple #8
0
 public DynamicXmlMetaObject(Expression expression, XNode node)
     : base(expression, BindingRestrictions.GetInstanceRestriction(expression, node), node)
 {
 }
 public DynamicMetaObject metaObjectToThrowInvalidFunctionCallException(ESSymbol selector, DynamicMetaObject[] args, String messageText, Type expectedFunctionType, Type actualFunctionType)
 {
     return(ExpressionTreeGuru.expressionToThrowInvalidFunctionCallException(Expression, ValueClass, selector, messageText, (long)args.Length, expectedFunctionType, actualFunctionType).asDynamicMetaObject(BindingRestrictions.GetInstanceRestriction(Expression, Value), Value));
 }
        private DynamicMetaObject MakeGetMemberTarget(GetMemberInfo getMemInfo, DynamicMetaObject target)
        {
            Type targetType = target.GetLimitType();
            BindingRestrictions restrictions = target.Restrictions;
            DynamicMetaObject   self         = target;

            target = target.Restrict(target.GetLimitType());

            // Specially recognized types: TypeTracker, NamespaceTracker, and StrongBox.
            // TODO: TypeTracker and NamespaceTracker should technically be IDO's.
            MemberGroup members = MemberGroup.EmptyGroup;

            if (typeof(TypeTracker).IsAssignableFrom(targetType))
            {
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value)
                    );

                TypeGroup tg = target.Value as TypeGroup;
                if (tg == null || tg.TryGetNonGenericType(out Type _))
                {
                    members = GetMember(MemberRequestKind.Get, ((TypeTracker)target.Value).Type, getMemInfo.Name);
                    if (members.Count > 0)
                    {
                        // we have a member that's on the type associated w/ the tracker, return that...
                        targetType = ((TypeTracker)target.Value).Type;
                        self       = null;
                    }
                }
            }

            if (members.Count == 0)
            {
                // Get the members
                members = GetMember(MemberRequestKind.Get, targetType, getMemInfo.Name);
            }

            if (members.Count == 0)
            {
                if (typeof(TypeTracker).IsAssignableFrom(targetType))
                {
                    // Throws an exception if we don't have a non-generic type, and if we do report an error now.  This matches
                    // the rule version of the default binder but should probably be removed long term.
                    EnsureTrackerRepresentsNonGenericType((TypeTracker)target.Value);
                }
                else if (targetType.IsInterface)
                {
                    // all interfaces have object members
                    targetType = typeof(object);
                    members    = GetMember(MemberRequestKind.Get, targetType, getMemInfo.Name);
                }
            }

            DynamicMetaObject propSelf = self;

            // if lookup failed try the strong-box type if available.
            if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(targetType) && propSelf != null)
            {
                // properties/fields need the direct value, methods hold onto the strong box.
                propSelf = new DynamicMetaObject(
                    Expression.Field(AstUtils.Convert(propSelf.Expression, targetType), targetType.GetInheritedFields("Value").First()),
                    propSelf.Restrictions,
                    ((IStrongBox)propSelf.Value).Value
                    );

                targetType = targetType.GetGenericArguments()[0];

                members = GetMember(
                    MemberRequestKind.Get,
                    targetType,
                    getMemInfo.Name
                    );
            }

            MakeBodyHelper(getMemInfo, self, propSelf, targetType, members);

            getMemInfo.Body.Restrictions = restrictions;
            return(getMemInfo.Body.GetMetaObject(target));
        }
 /// <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));
 }
Exemple #12
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)));
        }
Exemple #13
0
        private static DynamicMetaObject ArrayOfDynamicsByContext(IEnumerable <XElement> subElems)
        {
            var xmlReaderArray = subElems.Select <XElement, object>(
                e =>
                e.HasElements || e.HasAttributes
                ? (dynamic) new DynamicXmlReaderDmoVersion(e)
                : (dynamic)e.Value
                ).ToArray();
            var target = Expression.Constant(xmlReaderArray);

            return(new DynamicMetaObject(target, BindingRestrictions.GetTypeRestriction(target, typeof(dynamic[])).Merge(BindingRestrictions.GetInstanceRestriction(target, xmlReaderArray)), xmlReaderArray));
        }
        public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
        {
            if (!_metadata.Schema.TryFindProperty(binder.Name, out var property) || property.Type.IsArray())
            {
                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.UnderlyingType())
            {
            case PropertyType.Int:
                argumentType = typeof(long);
                if (property.Type.IsNullable())
                {
                    setter = GetSetMethod <long?>(dummyHandle.SetNullableInt64);
                }
                else if (property.IsPrimaryKey)
                {
                    setter = GetSetMethod <long>(dummyHandle.SetInt64Unique);
                }
                else
                {
                    setter = GetSetMethod <long>(dummyHandle.SetInt64);
                }

                break;

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

                break;

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

                break;

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

                break;

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

                break;

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

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

                break;

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

            if (property.Type.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)));
        }
        public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
        {
            if (!_metadata.Schema.TryFindProperty(binder.Name, out var property))
            {
                return(base.BindGetMember(binder));
            }

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

            MethodInfo getter = null;

            if (property.Type.IsArray())
            {
                arguments.Insert(0, Expression.Field(GetLimitedSelf(), RealmObjectRealmField));
                arguments.Add(Expression.Constant(property.ObjectType, typeof(string)));
                switch (property.Type.UnderlyingType())
                {
                case PropertyType.Int:
                    if (property.Type.IsNullable())
                    {
                        getter = GetGetMethod(dummyHandle.GetList <long?>);
                    }
                    else
                    {
                        getter = GetGetMethod(dummyHandle.GetList <long>);
                    }

                    break;

                case PropertyType.Bool:
                    if (property.Type.IsNullable())
                    {
                        getter = GetGetMethod(dummyHandle.GetList <bool?>);
                    }
                    else
                    {
                        getter = GetGetMethod(dummyHandle.GetList <bool>);
                    }

                    break;

                case Schema.PropertyType.Float:
                    if (property.Type.IsNullable())
                    {
                        getter = GetGetMethod(dummyHandle.GetList <float?>);
                    }
                    else
                    {
                        getter = GetGetMethod(dummyHandle.GetList <float>);
                    }

                    break;

                case PropertyType.Double:
                    if (property.Type.IsNullable())
                    {
                        getter = GetGetMethod(dummyHandle.GetList <double?>);
                    }
                    else
                    {
                        getter = GetGetMethod(dummyHandle.GetList <double>);
                    }

                    break;

                case PropertyType.String:
                    getter = GetGetMethod(dummyHandle.GetList <string>);
                    break;

                case PropertyType.Data:
                    getter = GetGetMethod(dummyHandle.GetList <byte[]>);
                    break;

                case PropertyType.Date:
                    if (property.Type.IsNullable())
                    {
                        getter = GetGetMethod(dummyHandle.GetList <DateTimeOffset?>);
                    }
                    else
                    {
                        getter = GetGetMethod(dummyHandle.GetList <DateTimeOffset>);
                    }

                    break;

                case PropertyType.Object:
                    getter = GetGetMethod(dummyHandle.GetList <DynamicRealmObject>);
                    break;

                case PropertyType.LinkingObjects:
                    // ObjectHandle.GetBacklinks has only one argument.
                    arguments.Clear();
                    arguments.Add(Expression.Constant(_metadata.PropertyIndices[property.Name]));
                    getter = GetGetMethod(dummyHandle.GetBacklinks);
                    break;
                }
            }
            else
            {
                switch (property.Type.UnderlyingType())
                {
                case PropertyType.Int:
                    if (property.Type.IsNullable())
                    {
                        getter = GetGetMethod(dummyHandle.GetNullableInt64);
                    }
                    else
                    {
                        getter = GetGetMethod(dummyHandle.GetInt64);
                    }

                    break;

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

                    break;

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

                    break;

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

                    break;

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

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

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

                    break;

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

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

            if (property.Type.UnderlyingType() == 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)));
        }
Exemple #16
0
 public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
 {
     return(new DynamicMetaObject(Expression.Invoke(reader.f, Expression.Constant(binder.Name)), BindingRestrictions.GetInstanceRestriction(Expression.Constant(reader), reader)));
 }
Exemple #17
0
 public _dynamicReader(DynamicDataReader reader, Expression exp) : base(exp, BindingRestrictions.GetInstanceRestriction(Expression.Constant(reader), reader), reader)
 {
     this.reader = reader;
 }
Exemple #18
0
 void ISpecialParamHolder.Process(CallSiteContext info, Expression valueExpr)
 {
     info.AddRestriction(BindingRestrictions.GetInstanceRestriction(valueExpr, Value));
     info.TargetType = Value;
 }
Exemple #19
0
        public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            if (!target.HasValue)
            {
                return(base.Defer(target, args));
            }
            if (target.Value == AutomationNull.Value)
            {
                return(new DynamicMetaObject(Expression.Block(typeof(void), new Expression[] { Expression.Call(CachedReflectionInfo.PipelineOps_Nop, new Expression[0]) }), BindingRestrictions.GetInstanceRestriction(target.Expression, AutomationNull.Value)).WriteToDebugLog(this));
            }
            DynamicMetaObject obj2 = PSEnumerableBinder.IsEnumerable(target);

            if (obj2 == null)
            {
                DynamicMetaObject   obj3         = PSVariableAssignmentBinder.Get().Bind(target, new DynamicMetaObject[0]);
                BindingRestrictions restrictions = target.LimitType.IsValueType ? obj3.Restrictions : target.PSGetTypeRestriction();
                return(new DynamicMetaObject(Expression.Call(args[0].Expression, CachedReflectionInfo.Pipe_Add, new Expression[] { obj3.Expression.Cast(typeof(object)) }), restrictions).WriteToDebugLog(this));
            }
            bool b = !(PSObject.Base(target.Value) is IEnumerator);

            return(new DynamicMetaObject(Expression.Call(CachedReflectionInfo.EnumerableOps_WriteEnumerableToPipe, obj2.Expression, args[0].Expression, args[1].Expression, ExpressionCache.Constant(b)), obj2.Restrictions).WriteToDebugLog(this));
        }
Exemple #20
0
        public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            var restrictions = BindingRestrictions.Empty;

            PhpTypeInfo phptype;
            Expression  target_expr;

            //
            var ctx     = args[0];
            var fldName = ResolveName(args, ref restrictions);

            //
            if (target.LimitType == typeof(PhpTypeInfo))    // static field
            {
                target_expr = null;
                phptype     = (PhpTypeInfo)target.Value;

                //
                restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, phptype));
            }
            else
            {
                // instance field
                object target_value;
                BinderHelpers.TargetAsObject(target, out target_expr, out target_value, ref restrictions);

                if (target_value == null)
                {
                    var defaultexpr = ConvertExpression.BindDefault(_returnType);

                    if (!_access.Quiet())
                    {
                        // PhpException.VariableMisusedAsObject(target, _access.ReadRef)
                        var throwcall = Expression.Call(typeof(PhpException), "VariableMisusedAsObject", Array.Empty <Type>(),
                                                        ConvertExpression.BindToValue(target.Expression), Expression.Constant(_access.EnsureAlias()));
                        defaultexpr = Expression.Block(throwcall, defaultexpr);
                    }

                    return(new DynamicMetaObject(defaultexpr, restrictions));
                }

                var runtime_type = target_value.GetType();

                //
                if (target_expr.Type != runtime_type)
                {
                    restrictions = restrictions.Merge(BindingRestrictions.GetTypeRestriction(target_expr, runtime_type));
                    target_expr  = Expression.Convert(target_expr, runtime_type);
                }

                phptype = runtime_type.GetPhpTypeInfo();
            }

            Debug.Assert(IsClassConst == (target_expr == null));

            //
            var getter = IsClassConst
                ? BinderHelpers.BindClassConstant(phptype, _classContext, fldName, ctx.Expression)
                : BinderHelpers.BindField(phptype, _classContext, target_expr, fldName, ctx.Expression, _access, null);

            if (getter != null)
            {
                //
                return(new DynamicMetaObject(ConvertExpression.Bind(getter, _returnType, ctx.Expression), restrictions));
            }

            // field not found
            throw new NotImplementedException();
        }
Exemple #21
0
        public static void TargetAsObject(DynamicMetaObject target, out Expression target_expr, out object target_value, ref BindingRestrictions restrictions)
        {
            target_expr  = target.Expression;
            target_value = target.Value;

            if (target_value == null)
            {
                restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, Expression.Constant(null)));
                return;
            }

            for (;;)
            {
                if (target_expr.Type == typeof(PhpValue))
                {
                    // Template: target.Object // target.IsObject
                    var value = (PhpValue)target_value;
                    if (value.IsNull)
                    {
                        restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Property(target_expr, "IsNull")));

                        target_value = null;
                        target_expr  = Expression.Constant(null, Cache.Types.Object[0]);
                        break;
                    }
                    else if (value.IsObject)
                    {
                        restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Property(target_expr, "IsObject")));

                        target_value = value.Object;
                        target_expr  = Expression.Property(target_expr, "Object");
                        break;
                    }
                    else if (value.IsAlias)
                    {
                        restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Property(target_expr, "IsAlias")));

                        target_value = value.Alias;
                        target_expr  = Expression.Property(target_expr, "Alias");
                        continue;
                    }
                    else if (value.IsScalar)
                    {
                        restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Property(target_expr, "IsScalar")));

                        target_value = null;
                        target_expr  = Expression.Constant(null, Cache.Types.Object[0]);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else if (target_expr.Type == typeof(PhpAlias))
                {
                    // dereference
                    target_value = ((PhpAlias)target_value).Value;
                    target_expr  = Expression.PropertyOrField(target_expr, "Value");
                    continue;
                }

                //
                break;
            }
        }
Exemple #22
0
 public DynamicMetaObject GetMetaObject(Expression expression)
 {
     return(new SerializableDynamicMetaObject(expression,
                                              BindingRestrictions.GetInstanceRestriction(expression, this), this));
 }
Exemple #23
0
        public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue)
            {
                return(base.Defer(target, new DynamicMetaObject[0]).WriteToDebugLog(this));
            }
            if (target.Value == AutomationNull.Value)
            {
                return(new DynamicMetaObject(Expression.Call(Expression.Constant(EmptyArray), typeof(Array).GetMethod("GetEnumerator")), BindingRestrictions.GetInstanceRestriction(target.Expression, AutomationNull.Value)).WriteToDebugLog(this));
            }
            object obj2 = PSObject.Base(target.Value);

            if (((obj2 != null) && !(obj2 is string)) && !(obj2 is PSObject))
            {
                if (obj2.GetType().IsArray)
                {
                    return(new DynamicMetaObject(MaybeDebase(this, e => Expression.Call(Expression.Convert(e, typeof(Array)), typeof(Array).GetMethod("GetEnumerator")), target), GetRestrictions(target)).WriteToDebugLog(this));
                }
                if ((obj2 is IDictionary) || (obj2 is System.Xml.XmlNode))
                {
                    return((errorSuggestion ?? this.NullResult(target)).WriteToDebugLog(this));
                }
                if (obj2 is DataTable)
                {
                    return(new DynamicMetaObject(MaybeDebase(this, delegate(Expression e) {
                        ParameterExpression expression;
                        ParameterExpression expression2;
                        return Expression.Block(new ParameterExpression[] { expression = Expression.Parameter(typeof(DataTable), "table"), expression2 = Expression.Parameter(typeof(DataRowCollection), "rows") }, new Expression[] { Expression.Assign(expression, e.Cast(typeof(DataTable))), Expression.Condition(Expression.NotEqual(Expression.Assign(expression2, Expression.Property(expression, "Rows")), ExpressionCache.NullConstant), Expression.Call(expression2, typeof(DataRowCollection).GetMethod("GetEnumerator")), ExpressionCache.NullEnumerator) });
                    }, target), GetRestrictions(target)).WriteToDebugLog(this));
                }
                if (IsComObject(obj2))
                {
                    return(new DynamicMetaObject(MaybeDebase(this, e => Expression.Call(CachedReflectionInfo.EnumerableOps_GetCOMEnumerator, e), target), GetRestrictions(target)).WriteToDebugLog(this));
                }
                if (obj2 is IEnumerable)
                {
                    Type[] interfaces = obj2.GetType().GetInterfaces();
                    for (int j = 0; j < interfaces.Length; j++)
                    {
                        Func <Expression, Expression> generator = null;
                        Type i = interfaces[j];
                        if (i.IsGenericType && (i.GetGenericTypeDefinition() == typeof(IEnumerable <>)))
                        {
                            if (generator == null)
                            {
                                generator = e => Expression.Call(CachedReflectionInfo.EnumerableOps_GetGenericEnumerator.MakeGenericMethod(new Type[] { i.GetGenericArguments()[0] }), Expression.Convert(e, i));
                            }
                            return(new DynamicMetaObject(MaybeDebase(this, generator, target), GetRestrictions(target)).WriteToDebugLog(this));
                        }
                    }
                    return(new DynamicMetaObject(MaybeDebase(this, e => Expression.Call(CachedReflectionInfo.EnumerableOps_GetEnumerator, Expression.Convert(e, typeof(IEnumerable))), target), GetRestrictions(target)).WriteToDebugLog(this));
                }
                if (obj2 is IEnumerator)
                {
                    return(new DynamicMetaObject(MaybeDebase(this, e => e.Cast(typeof(IEnumerator)), target), GetRestrictions(target)).WriteToDebugLog(this));
                }
            }
            return((errorSuggestion ?? this.NullResult(target)).WriteToDebugLog(this));
        }
Exemple #24
0
            } // func FallbackInvoke

            public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
            {
                // defer target and all arguments
                if (!target.HasValue || args.Any(c => !c.HasValue))
                {
                    return(Defer(target, args));
                }

                if (target.Value == null)
                {
                    return(errorSuggestion ??
                           new DynamicMetaObject(
                               ThrowExpression(Properties.Resources.rsNilNotCallable, typeof(object)),
                               target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, null))
                               ));
                }
                else
                {
                    MethodInfo method =
                        LuaEmit.FindMethod(
                            LuaType.GetType(target.LimitType).GetInstanceMethods(BindingFlags.Public, Name),
                            args,
                            mo => mo.LimitType,
                            true);

                    if (method == null)
                    {
                        if (errorSuggestion != null)
                        {
                            return(errorSuggestion);
                        }
                        return(new DynamicMetaObject(ThrowExpression(String.Format(Properties.Resources.rsMemberNotResolved, target.LimitType.Name, Name), typeof(object)), GetMethodSignatureRestriction(target, args)));
                    }

                    try
                    {
                        Expression expr;
                        if (method.IsStatic)
                        {
                            expr = LuaEmit.BindParameter(lua,
                                                         a => Expression.Call(null, method, a),
                                                         method.GetParameters(),
                                                         (new DynamicMetaObject[] { target }).Concat(args).ToArray(),
                                                         mo => mo.Expression, mo => mo.LimitType, false);
                        }
                        else
                        {
                            expr = LuaEmit.BindParameter(lua,
                                                         a => Expression.Call(EnsureType(target.Expression, target.LimitType), method, a),
                                                         method.GetParameters(),
                                                         args,
                                                         mo => mo.Expression, mo => mo.LimitType, false);
                        }

                        return
                            (new DynamicMetaObject(
                                 EnsureType(expr, typeof(object), true),
                                 GetMethodSignatureRestriction(target, args)
                                 ));
                    }
                    catch (LuaEmitException e)
                    {
                        if (errorSuggestion != null)
                        {
                            return(errorSuggestion);
                        }
                        return(new DynamicMetaObject(ThrowExpression(e.Message, typeof(object)), GetMethodSignatureRestriction(target, args)));
                    }
                }
            } // func FallbackInvokeMember
Exemple #25
0
 private static BindingRestrictions GetInstanceRestriction(ArgumentValues ai)
 {
     return(BindingRestrictions.GetInstanceRestriction(ai.Self.Expression, ai.Self.Value));
 }
Exemple #26
0
        private static DynamicMetaObject StringForFirstAttribute(XElement asElem, Func <XAttribute, bool> attributeNameMatchPredicate)
        {
            var value  = asElem.Attributes().First(attributeNameMatchPredicate).Value;
            var target = Expression.Constant(value);

            return
                (new DynamicMetaObject(
                     target,
                     BindingRestrictions.GetTypeRestriction(target, typeof(string)).Merge(BindingRestrictions.GetInstanceRestriction(target, value)))
                );
        }
Exemple #27
0
            } // ctor

            public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
            {
                //defer the target and all arguments
                if (!target.HasValue || args.Any(c => !c.HasValue))
                {
                    return(Defer(target, args));
                }

                if (target.Value == null) // Invoke on null value
                {
                    return(errorSuggestion ??
                           new DynamicMetaObject(
                               ThrowExpression(Properties.Resources.rsNilNotCallable),
                               BindingRestrictions.GetInstanceRestriction(target.Expression, null)
                               ));
                }
                else
                {
                    BindingRestrictions restrictions = GetMethodSignatureRestriction(target, args);
                    Expression          expr;
                    Delegate            invokeTarget = target.Value as Delegate;

                    if (invokeTarget == null)
                    {
                        if (errorSuggestion != null)
                        {
                            return(errorSuggestion);
                        }
                        expr = ThrowExpression(LuaEmitException.GetMessageText(LuaEmitException.InvokeNoDelegate, target.LimitType.Name), typeof(object));
                    }
                    else
                    {
                        ParameterInfo[] methodParameters = invokeTarget.Method.GetParameters();
                        ParameterInfo[] parameters       = null;
                        MethodInfo      mi = target.LimitType.GetMethod("Invoke");
                        if (mi != null)
                        {
                            ParameterInfo[] typeParameters = mi.GetParameters();
                            if (typeParameters.Length != methodParameters.Length)
                            {
                                parameters = new ParameterInfo[typeParameters.Length];
                                // the hidden parameters are normally at the beginning
                                if (parameters.Length > 0)
                                {
                                    Array.Copy(methodParameters, methodParameters.Length - typeParameters.Length, parameters, 0, parameters.Length);
                                }
                            }
                            else
                            {
                                parameters = methodParameters;
                            }
                        }
                        else
                        {
                            parameters = methodParameters;
                        }

                        try
                        {
                            expr =
                                EnsureType(
                                    LuaEmit.BindParameter(lua,
                                                          _args => Expression.Invoke(EnsureType(target.Expression, target.LimitType), _args),
                                                          parameters,
                                                          args,
                                                          mo => mo.Expression, mo => mo.LimitType, false),
                                    typeof(object), true);
                        }
                        catch (LuaEmitException e)
                        {
                            if (errorSuggestion != null)
                            {
                                return(errorSuggestion);
                            }
                            expr = ThrowExpression(e.Message, ReturnType);
                        }
                    }

                    return(new DynamicMetaObject(expr, restrictions));
                }
            } // func FallbackInvoke
Exemple #28
0
        private static DynamicMetaObject DynamicXmlReaderForSingleElement(XElement elem)
        {
            var dynamicXmlReader = new DynamicXmlReaderDmoVersion(elem);
            var target           = Expression.Constant(dynamicXmlReader);

            return(new DynamicXmlMetaObject(target, BindingRestrictions.GetTypeRestriction(target, typeof(DynamicXmlReaderDmoVersion)).Merge(BindingRestrictions.GetInstanceRestriction(target, dynamicXmlReader)), elem));
        }
 public void InstanceRestrictionFromNull()
 {
     AssertExtensions.Throws <ArgumentNullException>(
         "expression", () => BindingRestrictions.GetInstanceRestriction(null, new object()));
 }
Exemple #30
0
        private static DynamicMetaObject StringForValue(XElement subElem)
        {
            var value  = subElem.Value;
            var target = Expression.Constant(value);

            return(new DynamicMetaObject(target, BindingRestrictions.GetTypeRestriction(target, typeof(string)).Merge(BindingRestrictions.GetInstanceRestriction(target, value)), value));
        }