public MetaObject DeleteMember(string name, MetaObject target, Expression codeContext) { ContractUtils.RequiresNotNull(name, "name"); ContractUtils.RequiresNotNull(target, "target"); return MakeDeleteMemberTarget( new SetOrDeleteMemberInfo( name, codeContext ), target.Restrict(target.LimitType) ); }
private MetaObject MakeSetMemberTarget(SetOrDeleteMemberInfo memInfo, MetaObject target, MetaObject value) { Type type = target.LimitType.IsCOMObject ? target.Expression.Type : target.LimitType; Expression self = target.Expression; target = target.Restrict(target.LimitType); memInfo.Body.Restrictions = target.Restrictions; if (typeof(TypeTracker).IsAssignableFrom(type)) { type = ((TypeTracker)target.Value).Type; self = null; memInfo.Body.Restrictions = memInfo.Body.Restrictions.Merge( Restrictions.GetInstanceRestriction(target.Expression, target.Value) ); } MakeSetMemberRule(memInfo, type, self, value); return memInfo.Body.GetMetaObject(target, value); }
private MetaObject MakeGetMemberTarget(GetMemberInfo getMemInfo, MetaObject target) { Type type = target.LimitType.IsCOMObject ? target.Expression.Type : target.LimitType; Restrictions restrictions = target.Restrictions; Expression self = target.Expression; target = target.Restrict(target.LimitType); // needed for GetMember call until DynamicAction goes away OldDynamicAction act = OldGetMemberAction.Make( this, getMemInfo.Name ); // Specially recognized types: TypeTracker, NamespaceTracker, and StrongBox. // TODO: TypeTracker and NamespaceTracker should technically be IDO's. MemberGroup members = MemberGroup.EmptyGroup; if (typeof(TypeTracker).IsAssignableFrom(type)) { restrictions = restrictions.Merge( Restrictions.GetInstanceRestriction(target.Expression, target.Value) ); TypeGroup tg = target.Value as TypeGroup; Type nonGen; if (tg == null || tg.TryGetNonGenericType(out nonGen)) { members = GetMember(act, ((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... type = ((TypeTracker)target.Value).Type; self = null; } } } if (members.Count == 0) { // Get the members members = GetMember(act, type, getMemInfo.Name); } if (members.Count == 0) { if (typeof(TypeTracker).IsAssignableFrom(type)) { // ensure 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 Type x = ((TypeTracker)target.Value).Type; } else if (type.IsInterface) { // all interfaces have object members type = typeof(object); members = GetMember(act, type, getMemInfo.Name); } } Expression propSelf = self; // if lookup failed try the strong-box type if available. if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(type)) { // properties/fields need the direct value, methods hold onto the strong box. propSelf = Ast.Field(AstUtils.Convert(self, type), type.GetField("Value")); type = type.GetGenericArguments()[0]; members = GetMember( act, type, getMemInfo.Name ); } MakeBodyHelper(getMemInfo, self, propSelf, type, members); getMemInfo.Body.Restrictions = restrictions; return getMemInfo.Body.GetMetaObject(target); }