private bool MakeGetMemberRule(OldGetMemberAction action, CodeContext context, RuleBuilder rule) { object value; if (TryGetValue(action.Name, out value)) { Debug.Assert(value is MemberTracker); MemberTracker memValue = (MemberTracker)value; rule.MakeTest(typeof(NamespaceTracker)); rule.AddTest( Expression.Equal( Expression.Property( Expression.Convert(rule.Parameters[0], typeof(NamespaceTracker)), typeof(NamespaceTracker).GetProperty("Id") ), Expression.Constant(Id) ) ); Expression target = context.LanguageContext.Binder.ReturnMemberTracker(memValue.DeclaringType, memValue); rule.Target = rule.MakeReturn(context.LanguageContext.Binder, target); return(true); } return(false); }
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)); }