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)); }
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)); }
} // 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))); }
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);
/// <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)); }
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)); }
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))); }
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))); }
public override DynamicMetaObject BindGetMember(GetMemberBinder binder) { return(new DynamicMetaObject(Expression.Invoke(reader.f, Expression.Constant(binder.Name)), BindingRestrictions.GetInstanceRestriction(Expression.Constant(reader), reader))); }
public _dynamicReader(DynamicDataReader reader, Expression exp) : base(exp, BindingRestrictions.GetInstanceRestriction(Expression.Constant(reader), reader), reader) { this.reader = reader; }
void ISpecialParamHolder.Process(CallSiteContext info, Expression valueExpr) { info.AddRestriction(BindingRestrictions.GetInstanceRestriction(valueExpr, Value)); info.TargetType = Value; }
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)); }
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(); }
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; } }
public DynamicMetaObject GetMetaObject(Expression expression) { return(new SerializableDynamicMetaObject(expression, BindingRestrictions.GetInstanceRestriction(expression, this), this)); }
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)); }
} // 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
private static BindingRestrictions GetInstanceRestriction(ArgumentValues ai) { return(BindingRestrictions.GetInstanceRestriction(ai.Self.Expression, ai.Self.Value)); }
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))) ); }
} // 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
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())); }
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)); }