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)); }
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; Type nonGen; if (tg == null || tg.TryGetNonGenericType(out nonGen)) { 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( Ast.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)); }