Inheritance: MemberTracker
Ejemplo n.º 1
0
        /// <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));
        }
Ejemplo n.º 2
0
        /// <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));
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        /// <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));
        }
Ejemplo n.º 5
0
        /// <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]);
        }
Ejemplo n.º 6
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]);
        }
Ejemplo n.º 7
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;
        }
Ejemplo n.º 8
0
 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();
 }
Ejemplo n.º 9
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(
                    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);
        }
Ejemplo n.º 10
0
	public static object GetItem (BoundMemberTracker self, params object[] keys)
	{
		throw new NotImplementedException ();
	}