/// <summary> /// Provides an opportunity for languages to replace all MemberInfo's with their own type. /// /// Alternatlely a language can expose MemberInfo's directly. /// </summary> /// <param name="memberTracker">The member which is being returned to the user.</param> /// <param name="type">Tthe type which the memberTrack was accessed from</param> /// <returns></returns> public virtual Expression ReturnMemberTracker(Type type, MemberTracker memberTracker) { if (memberTracker.MemberType == TrackerTypes.Bound) { BoundMemberTracker bmt = (BoundMemberTracker)memberTracker; return(Expression.New( typeof(BoundMemberTracker).GetConstructor(new Type[] { typeof(MemberTracker), typeof(object) }), Expression.Constant(bmt.BoundTo), bmt.Instance)); } return(Expression.Constant(memberTracker)); }
/// <summary> /// Provides an opportunity for languages to replace all MemberInfo's with their own type. /// /// Alternatlely a language can expose MemberInfo's directly. /// </summary> /// <param name="memberTracker">The member which is being returned to the user.</param> /// <param name="type">Tthe type which the memberTrack was accessed from</param> /// <returns></returns> protected internal virtual Expression ReturnMemberTracker(Type type, MemberTracker memberTracker) { if (memberTracker.MemberType == TrackerTypes.Bound) { BoundMemberTracker bmt = (BoundMemberTracker)memberTracker; return(Ast.Ast.New( typeof(BoundMemberTracker).GetConstructor(new Type[] { typeof(MemberTracker), typeof(object) }), Ast.Ast.RuntimeConstant(bmt.BoundTo), bmt.Instance)); } return(Ast.Ast.RuntimeConstant(memberTracker)); }
private MethodBase[] GetBoundMemberTargets(BoundMemberTracker bmt) { Debug.Assert(bmt.Instance == null); // should be null for trackers that leak to user code MethodBase[] targets; _instance = Ast.Convert( Ast.Property( Ast.Convert(Rule.Parameters[0], typeof(BoundMemberTracker)), typeof(BoundMemberTracker).GetProperty("ObjectInstance") ), bmt.BoundTo.DeclaringType ); _test = Ast.AndAlso( _test, Ast.Equal( Ast.Property( Ast.Convert(Rule.Parameters[0], typeof(BoundMemberTracker)), typeof(BoundMemberTracker).GetProperty("BoundTo") ), Ast.Constant(bmt.BoundTo) ) ); _test = Ast.AndAlso( _test, Rule.MakeTypeTest( CompilerHelpers.GetType(bmt.ObjectInstance), Ast.Property( Ast.Convert(Rule.Parameters[0], typeof(BoundMemberTracker)), typeof(BoundMemberTracker).GetProperty("ObjectInstance") ) ) ); switch (bmt.BoundTo.MemberType) { case TrackerTypes.MethodGroup: targets = ((MethodGroup)bmt.BoundTo).GetMethodBases(); break; case TrackerTypes.Method: targets = new MethodBase[] { ((MethodTracker)bmt.BoundTo).Method }; break; default: throw new InvalidOperationException(); // nothing else binds yet } return(targets); }
/// <summary> /// Provides an opportunity for languages to replace all MemberTracker's with their own type. /// /// Alternatlely a language can expose MemberTracker's directly. /// </summary> /// <param name="memberTracker">The member which is being returned to the user.</param> /// <param name="type">Tthe type which the memberTrack was accessed from</param> /// <returns></returns> public virtual DynamicMetaObject ReturnMemberTracker(Type type, MemberTracker memberTracker) { if (memberTracker.MemberType == TrackerTypes.Bound) { BoundMemberTracker bmt = (BoundMemberTracker)memberTracker; return(new DynamicMetaObject( Expression.New( typeof(BoundMemberTracker).GetConstructor(new[] { typeof(MemberTracker), typeof(object) }), AstUtils.Constant(bmt.BoundTo), bmt.Instance.Expression ), BindingRestrictions.Empty )); } return(new DynamicMetaObject(AstUtils.Constant(memberTracker), BindingRestrictions.Empty, memberTracker)); }
/// <summary> /// Gets alternate members which are specially recognized by the DLR for specific types when /// all other member lookup fails. /// </summary> private static MethodInfo[] GetFallbackMembers(Type t, OperatorInfo info, MetaObject[] args, out Restrictions restrictions) { // if we have an event we need to make a strongly-typed event handler // TODO: Events, we need to look in the args and pull out the real values if (t == typeof(EventTracker)) { EventTracker et = ((EventTracker)args[0].Value); if (info.Operator == Operators.InPlaceAdd) { restrictions = GetFallbackRestrictions(t, et, args[0]); return(new MethodInfo[] { typeof(BinderOps).GetMethod("EventTrackerInPlaceAdd").MakeGenericMethod(et.Event.EventHandlerType) }); } else if (info.Operator == Operators.InPlaceSubtract) { restrictions = GetFallbackRestrictions(t, et, args[0]); return(new MethodInfo[] { typeof(BinderOps).GetMethod("EventTrackerInPlaceRemove").MakeGenericMethod(et.Event.EventHandlerType) }); } } else if (t == typeof(BoundMemberTracker)) { BoundMemberTracker bmt = ((BoundMemberTracker)args[0].Value); if (bmt.BoundTo.MemberType == TrackerTypes.Event) { EventTracker et = ((EventTracker)bmt.BoundTo); if (info.Operator == Operators.InPlaceAdd) { restrictions = GetFallbackRestrictions(t, et, args[0]); return(new MethodInfo[] { typeof(BinderOps).GetMethod("BoundEventTrackerInPlaceAdd").MakeGenericMethod(et.Event.EventHandlerType) }); } else if (info.Operator == Operators.InPlaceSubtract) { restrictions = GetFallbackRestrictions(t, et, args[0]); return(new MethodInfo[] { typeof(BinderOps).GetMethod("BoundEventTrackerInPlaceRemove").MakeGenericMethod(et.Event.EventHandlerType) }); } } } restrictions = Restrictions.Empty; return(new MethodInfo[0]); }
/// <summary> /// Gets alternate members which are specially recognized by the DLR for specific types when /// all other member lookup fails. /// </summary> private MethodInfo[] GetFallbackMembers(Type t, OperatorInfo info) { // if we have an event we need to make a strongly-typed event handler if (t == typeof(EventTracker)) { EventTracker et = ((EventTracker)_args[0]); if (info.Operator == Operators.InPlaceAdd) { AddFallbackMemberTest(t, et); return(new MethodInfo[] { typeof(BinderOps).GetMethod("EventTrackerInPlaceAdd").MakeGenericMethod(et.Event.EventHandlerType) }); } else if (info.Operator == Operators.InPlaceSubtract) { AddFallbackMemberTest(t, et); return(new MethodInfo[] { typeof(BinderOps).GetMethod("EventTrackerInPlaceRemove").MakeGenericMethod(et.Event.EventHandlerType) }); } } else if (t == typeof(BoundMemberTracker)) { BoundMemberTracker bmt = ((BoundMemberTracker)_args[0]); if (bmt.BoundTo.MemberType == TrackerTypes.Event) { EventTracker et = ((EventTracker)bmt.BoundTo); if (info.Operator == Operators.InPlaceAdd) { AddFallbackMemberTest(t, et); return(new MethodInfo[] { typeof(BinderOps).GetMethod("BoundEventTrackerInPlaceAdd").MakeGenericMethod(et.Event.EventHandlerType) }); } else if (info.Operator == Operators.InPlaceSubtract) { AddFallbackMemberTest(t, et); return(new MethodInfo[] { typeof(BinderOps).GetMethod("BoundEventTrackerInPlaceRemove").MakeGenericMethod(et.Event.EventHandlerType) }); } } } return(new MethodInfo[0]); }
/// <summary> /// Binds to the BoundMemberTracker and uses the instance in the tracker and restricts /// based upon the object instance type. /// </summary> private TargetInfo TryGetBoundMemberTargets(DynamicMetaObject self, DynamicMetaObject[] args, BoundMemberTracker bmt) { if (bmt != null) { Debug.Assert(bmt.Instance == null); // should be null for trackers that leak to user code MethodBase[] targets; // instance is pulled from the BoundMemberTracker and restricted to the correct // type. DynamicMetaObject instance = new DynamicMetaObject( Ast.Convert( Ast.Property( Ast.Convert(self.Expression, typeof(BoundMemberTracker)), typeof(BoundMemberTracker).GetProperty("ObjectInstance") ), bmt.BoundTo.DeclaringType ), self.Restrictions ).Restrict(CompilerHelpers.GetType(bmt.ObjectInstance)); // we also add a restriction to make sure we're going to the same BoundMemberTracker BindingRestrictions restrictions = BindingRestrictions.GetExpressionRestriction( Ast.Equal( Ast.Property( Ast.Convert(self.Expression, typeof(BoundMemberTracker)), typeof(BoundMemberTracker).GetProperty("BoundTo") ), Ast.Constant(bmt.BoundTo) ) ); switch (bmt.BoundTo.MemberType) { case TrackerTypes.MethodGroup: targets = ((MethodGroup)bmt.BoundTo).GetMethodBases(); break; case TrackerTypes.Method: targets = new MethodBase[] { ((MethodTracker)bmt.BoundTo).Method }; break; default: throw new InvalidOperationException(); // nothing else binds yet } return new TargetInfo(instance, args, restrictions, targets); } return null; }
private static Expression ReturnBoundTracker(BoundMemberTracker boundMemberTracker, bool privateBinding) { MemberTracker boundTo = boundMemberTracker.BoundTo; switch (boundTo.MemberType) { case TrackerTypes.Property: PropertyTracker pt = (PropertyTracker)boundTo; Debug.Assert(pt.GetIndexParameters().Length > 0); return Ast.New( typeof(ReflectedIndexer).GetConstructor(new Type[] { typeof(ReflectedIndexer), typeof(object) }), Ast.Constant(new ReflectedIndexer(((ReflectedPropertyTracker)pt).Property, NameType.Property, privateBinding)), boundMemberTracker.Instance ); case TrackerTypes.Event: return Ast.Call( typeof(PythonOps).GetMethod("MakeBoundEvent"), Ast.Constant(PythonTypeOps.GetReflectedEvent((EventTracker)boundMemberTracker.BoundTo)), boundMemberTracker.Instance, Ast.Constant(boundMemberTracker.DeclaringType) ); case TrackerTypes.MethodGroup: return Ast.Call( typeof(PythonOps).GetMethod("MakeBoundBuiltinFunction"), Ast.Constant(GetBuiltinFunction((MethodGroup)boundTo)), AstUtils.Convert( boundMemberTracker.Instance, typeof(object) ) ); } throw new NotImplementedException(); }
/// <summary> /// Binds to the BoundMemberTracker and uses the instance in the tracker and restricts /// based upon the object instance type. /// </summary> private TargetInfo TryGetBoundMemberTargets(DynamicMetaObject self, DynamicMetaObject[] args, BoundMemberTracker bmt) { if (bmt != null) { Debug.Assert(bmt.Instance == null); // should be null for trackers that leak to user code MethodBase[] targets; // instance is pulled from the BoundMemberTracker and restricted to the correct // type. DynamicMetaObject instance = new DynamicMetaObject( AstUtils.Convert( Ast.Property( Ast.Convert(self.Expression, typeof(BoundMemberTracker)), typeof(BoundMemberTracker).GetDeclaredProperty("ObjectInstance") ), bmt.BoundTo.DeclaringType ), self.Restrictions ).Restrict(CompilerHelpers.GetType(bmt.ObjectInstance)); // we also add a restriction to make sure we're going to the same BoundMemberTracker BindingRestrictions restrictions = BindingRestrictions.GetExpressionRestriction( Ast.Equal( Ast.Property( Ast.Convert(self.Expression, typeof(BoundMemberTracker)), typeof(BoundMemberTracker).GetDeclaredProperty("BoundTo") ), AstUtils.Constant(bmt.BoundTo) ) ); switch (bmt.BoundTo.MemberType) { case TrackerTypes.MethodGroup: targets = ((MethodGroup)bmt.BoundTo).GetMethodBases(); break; case TrackerTypes.Method: targets = new MethodBase[] { ((MethodTracker)bmt.BoundTo).Method }; break; default: throw new InvalidOperationException(); // nothing else binds yet } return(new TargetInfo(instance, args, restrictions, targets)); } return(null); }
public static object GetItem (BoundMemberTracker self, params object[] keys) { throw new NotImplementedException (); }