Example #1
0
        /// <summary> if a member-injector is defined-on or registered-for this type call it </summary>
        private void MakeOperatorGetMemberBody(GetMemberInfo getMemInfo, Expression instance, Type type, string name)
        {
            MethodInfo getMem = GetMethod(type, name);

            if (getMem != null && getMem.IsSpecialName)
            {
                ParameterExpression tmp = Ast.Variable(typeof(object), "getVal");
                getMemInfo.Body.AddVariable(tmp);

                getMemInfo.Body.AddCondition(
                    Ast.NotEqual(
                        Ast.Assign(
                            tmp,
                            MakeCallExpression(
                                getMemInfo.CodeContext,
                                getMem,
                                AstUtils.Convert(instance, type),
                                Ast.Constant(getMemInfo.Name)
                                )
                            ),
                        Ast.Field(null, typeof(OperationFailed).GetField("Value"))
                        ),
                    tmp
                    );
            }
        }
Example #2
0
        void MakeOperatorGetMemberBody(GetMemberInfo info, DynamicMetaObject instance, Type type, string name)
        {
            var getMem = GetMethod(type, name);

            if (getMem != null)
            {
                var tmp = Expression.Variable(typeof(object), "getVal");
                info.Body.AddVariable(tmp);
                info.Body.AddCondition(
                    Expression.NotEqual(
                        Expression.Assign(
                            tmp,
                            MakeCallExpression(
                                info.ResolutionFactory,
                                getMem,
                                new DynamicMetaObject(Expression.Convert(instance.Expression, type), instance.Restrictions, instance.Value),
                                new DynamicMetaObject(Expression.Constant(info.Name), BindingRestrictions.Empty, info.Name)
                                ).Expression
                            ),
                        MakeOperationFailed()
                        ),
                    tmp
                    );
            }
        }
Example #3
0
        private void MakeGenericBody(GetMemberInfo getMemInfo, Type instanceType, MemberGroup members, DynamicMetaObject instance)
        {
            MemberTracker bestMember = members[0];

            if (members.Count > 1)
            {
                // if we were given multiple members pick the member closest to the type...
                Type bestMemberDeclaringType = members[0].DeclaringType;

                for (int i = 1; i < members.Count; i++)
                {
                    MemberTracker mt = members[i];
                    if (!IsTrackerApplicableForType(instanceType, mt))
                    {
                        continue;
                    }

                    if (members[i].DeclaringType.IsSubclassOf(bestMemberDeclaringType) ||
                        !IsTrackerApplicableForType(instanceType, bestMember))
                    {
                        bestMember = members[i];
                        bestMemberDeclaringType = members[i].DeclaringType;
                    }
                }
            }

            MakeGenericBodyWorker(getMemInfo, instanceType, bestMember, instance);
        }
Example #4
0
        /// <summary> if a member-injector is defined-on or registered-for this type call it </summary>
        private void MakeOperatorGetMemberBody(GetMemberInfo getMemInfo, DynamicMetaObject instance, Type instanceType, string name)
        {
            MethodInfo getMem = GetMethod(instanceType, name);

            if (getMem != null)
            {
                ParameterExpression tmp = Expression.Variable(typeof(object), "getVal");
                getMemInfo.Body.AddVariable(tmp);

                getMemInfo.Body.AddCondition(
                    Expression.NotEqual(
                        Expression.Assign(
                            tmp,
                            MakeCallExpression(
                                getMemInfo.ResolutionFactory,
                                getMem,
                                new DynamicMetaObject(
                                    Expression.Convert(instance.Expression, instanceType),
                                    instance.Restrictions,
                                    instance.Value
                                    ),
                                new DynamicMetaObject(
                                    Expression.Constant(getMemInfo.Name),
                                    BindingRestrictions.Empty,
                                    getMemInfo.Name
                                    )
                                ).Expression
                            ),
                        Expression.Field(null, typeof(OperationFailed).GetDeclaredField("Value"))
                        ),
                    tmp
                    );
            }
        }
Example #5
0
        private void MakeGenericBodyWorker(GetMemberInfo getMemInfo, Type instanceType, MemberTracker tracker, DynamicMetaObject instance)
        {
            if (instance != null)
            {
                tracker = tracker.BindToInstance(instance);
            }

            DynamicMetaObject val = tracker.GetValue(getMemInfo.ResolutionFactory, this, instanceType);

            if (val != null)
            {
                getMemInfo.Body.FinishCondition(val);
            }
            else
            {
                ErrorInfo ei = tracker.GetError(this, instanceType);
                if (ei.Kind != ErrorInfoKind.Success && getMemInfo.IsNoThrow)
                {
                    getMemInfo.Body.FinishError(MakeOperationFailed());
                }
                else
                {
                    getMemInfo.Body.FinishError(MakeError(ei, typeof(object)));
                }
            }
        }
Example #6
0
 void MakeGenericBodyWorker(GetMemberInfo info, Type type, MemberTracker tracker, DynamicMetaObject instance)
 {
     if (instance != null)
     {
         tracker = tracker.BindToInstance(instance);
     }
     info.Body.FinishCondition(ReturnMemberTracker(type, tracker).Expression);
 }
Example #7
0
        void MakeBodyHelper(GetMemberInfo info, DynamicMetaObject self, DynamicMetaObject expandedSelf, Type type, MemberGroup members)
        {
            Expression error;
            var        memberType = GetMemberType(members, out error);

            if (error == null)
            {
                switch (memberType)
                {
                case TrackerTypes.TypeGroup:
                case TrackerTypes.Type:
                    info.Body.FinishCondition(members.Cast <TypeTracker>().Aggregate((x, y) => TypeGroup.Merge(x, y)).GetValue(info.ResolutionFactory, this, type).Expression);
                    break;

                case TrackerTypes.Method:
                    // MethodGroup になる
                    MakeGenericBodyWorker(info, type, ReflectionCache.GetMethodGroup(info.Name, members), self);
                    break;

                case TrackerTypes.Event:
                case TrackerTypes.Field:
                case TrackerTypes.Property:
                case TrackerTypes.Constructor:
                case TrackerTypes.Custom:
                    // もし複数のメンバーが与えられたら、その型に一番近いメンバを探す
                    MakeGenericBodyWorker(info, type, members.Aggregate((w, x) => !IsTrackerApplicableForType(type, x) && (x.DeclaringType.IsSubclassOf(w.DeclaringType) || !IsTrackerApplicableForType(type, w)) ? x : w), expandedSelf);
                    break;

                case TrackerTypes.All:
                    // どのメンバも見つからなかった
                    if (self != null)
                    {
                        MakeOperatorGetMemberBody(info, expandedSelf, type, "GetBoundMember");
                    }
                    if (info.ErrorSuggestion != null)
                    {
                        info.Body.FinishCondition(info.ErrorSuggestion);
                    }
                    else if (info.IsNoThrow)
                    {
                        info.Body.FinishCondition(MakeOperationFailed());
                    }
                    else
                    {
                        info.Body.FinishCondition(MakeError(MakeMissingMemberError(type, self, info.Name), typeof(object)).Expression);
                    }
                    break;

                default:
                    throw new InvalidOperationException(memberType.ToString());
                }
            }
            else
            {
                info.Body.FinishCondition(info.ErrorSuggestion ?? error);
            }
        }
Example #8
0
        private void MakeTypeBody(GetMemberInfo getMemInfo, Type instanceType, MemberGroup members)
        {
            TypeTracker typeTracker = (TypeTracker)members[0];

            for (int i = 1; i < members.Count; i++)
            {
                typeTracker = TypeGroup.UpdateTypeEntity(typeTracker, (TypeTracker)members[i]);
            }

            getMemInfo.Body.FinishCondition(typeTracker.GetValue(getMemInfo.ResolutionFactory, this, instanceType));
        }
Example #9
0
        private void MakeGenericBodyWorker(GetMemberInfo getMemInfo, Type type, MemberTracker tracker, Expression instance)
        {
            if (instance != null)
            {
                tracker = tracker.BindToInstance(instance);
            }

            Expression val = tracker.GetValue(getMemInfo.CodeContext, this, type);

            getMemInfo.Body.FinishCondition(
                val != null ?
                val :
                MakeError(tracker.GetError(this))
                );
        }
Example #10
0
 private void MakeMissingMemberRuleForGet(GetMemberInfo getMemInfo, Type type)
 {
     if (getMemInfo.IsNoThrow)
     {
         getMemInfo.Body.FinishCondition(
             Ast.Field(null, typeof(OperationFailed).GetField("Value"))
             );
     }
     else
     {
         getMemInfo.Body.FinishCondition(
             MakeError(MakeMissingMemberError(type, getMemInfo.Name))
             );
     }
 }
Example #11
0
        DynamicMetaObject MakeGetMemberTarget(GetMemberInfo info, DynamicMetaObject target)
        {
            var type         = target.GetLimitType();
            var restrictions = target.Restrictions;
            var self         = target;

            target = target.Restrict(target.GetLimitType());
            var members = MemberGroup.EmptyGroup;

            // メンバ取得対象が TypeTracker である場合
            if (typeof(TypeTracker).IsAssignableFrom(type))
            {
                restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value));
                var tg = target.Value as TypeGroup;
                if (tg == null || tg.TypesByArity.ContainsKey(0))
                {
                    var targetedType = ((TypeTracker)target.Value).Type;
                    members = GetMember(MemberRequestKind.Get, targetedType, info.Name);
                    if (members.Count > 0)
                    {
                        type = targetedType;
                        self = null;
                    }
                }
            }
            // 通常のメンバ一覧を検索
            if (members.Count == 0)
            {
                members = GetMember(MemberRequestKind.Get, type, info.Name);
            }
            // インターフェイスの場合、object メンバを検索
            if (members.Count == 0 && type.IsInterface)
            {
                members = GetMember(MemberRequestKind.Get, type = typeof(object), info.Name);
            }
            // プロパティ・フィールド用に StrongBox を展開し、そこから検索
            var expandedSelf = self;

            if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(type) && expandedSelf != null)
            {
                expandedSelf = new DynamicMetaObject(Expression.Field(AstUtils.Convert(expandedSelf.Expression, type), type.GetField("Value")), expandedSelf.Restrictions, ((IStrongBox)expandedSelf.Value).Value);
                type         = type.GetGenericArguments()[0];
                members      = GetMember(MemberRequestKind.Get, type, info.Name);
            }
            MakeBodyHelper(info, self, expandedSelf, type, members);
            return(info.Body.GetMetaObject(restrictions));
        }
Example #12
0
 private void MakeMissingMemberRuleForGet(GetMemberInfo getMemInfo, DynamicMetaObject self, Type type)
 {
     if (getMemInfo.ErrorSuggestion != null)
     {
         getMemInfo.Body.FinishError(getMemInfo.ErrorSuggestion.Expression);
     }
     else if (getMemInfo.IsNoThrow)
     {
         getMemInfo.Body.FinishError(MakeOperationFailed());
     }
     else
     {
         getMemInfo.Body.FinishError(
             MakeError(MakeMissingMemberError(type, self, getMemInfo.Name), typeof(object))
             );
     }
 }
Example #13
0
        private void MakeBodyHelper(GetMemberInfo getMemInfo, DynamicMetaObject self, DynamicMetaObject propSelf, Type targetType, MemberGroup members)
        {
            if (self != null)
            {
                MakeOperatorGetMemberBody(getMemInfo, propSelf, targetType, "GetCustomMember");
            }

            TrackerTypes memberType = GetMemberType(members, out Expression error);

            if (error == null)
            {
                MakeSuccessfulMemberAccess(getMemInfo, self, propSelf, targetType, members, memberType);
            }
            else
            {
                getMemInfo.Body.FinishError(getMemInfo.ErrorSuggestion?.Expression ?? error);
            }
        }
Example #14
0
        private void MakeBodyHelper(GetMemberInfo getMemInfo, Expression self, Expression propSelf, Type type, MemberGroup members)
        {
            if (self != null)
            {
                MakeOperatorGetMemberBody(getMemInfo, propSelf, type, "GetCustomMember");
            }

            Expression   error;
            TrackerTypes memberType = GetMemberType(members, out error);

            if (error == null)
            {
                MakeSuccessfulMemberAccess(getMemInfo, self, propSelf, type, members, memberType);
            }
            else
            {
                getMemInfo.Body.FinishCondition(error);
            }
        }
Example #15
0
        private void MakeSuccessfulMemberAccess(GetMemberInfo getMemInfo, DynamicMetaObject self, DynamicMetaObject propSelf, Type selfType, MemberGroup members, TrackerTypes memberType)
        {
            switch (memberType)
            {
            case TrackerTypes.TypeGroup:
            case TrackerTypes.Type:
                MakeTypeBody(getMemInfo, selfType, members);
                break;

            case TrackerTypes.Method:
                // turn into a MethodGroup
                MakeGenericBodyWorker(getMemInfo, selfType, ReflectionCache.GetMethodGroup(getMemInfo.Name, members), self);
                break;

            case TrackerTypes.Event:
            case TrackerTypes.Field:
            case TrackerTypes.Property:
            case TrackerTypes.Constructor:
            case TrackerTypes.Custom:
                MakeGenericBody(getMemInfo, selfType, members, propSelf);
                break;

            case TrackerTypes.All:
                // no members were found
                if (self != null)
                {
                    MakeOperatorGetMemberBody(getMemInfo, propSelf, selfType, "GetBoundMember");
                }

                MakeMissingMemberRuleForGet(getMemInfo, self, selfType);
                break;

            default:
                throw new InvalidOperationException(memberType.ToString());
            }
        }
        /// <summary> if a member-injector is defined-on or registered-for this type call it </summary>
        private void MakeOperatorGetMemberBody(GetMemberInfo getMemInfo, DynamicMetaObject instance, Type type, string name) {
            MethodInfo getMem = GetMethod(type, name);
            if (getMem != null) {
                ParameterExpression tmp = Ast.Variable(typeof(object), "getVal");
                getMemInfo.Body.AddVariable(tmp);

                getMemInfo.Body.AddCondition(
                    Ast.NotEqual(
                        Ast.Assign(
                            tmp,
                            MakeCallExpression(
                                getMemInfo.ResolutionFactory,
                                getMem,
                                new DynamicMetaObject(
                                    Expression.Convert(instance.Expression, type),
                                    instance.Restrictions,
                                    instance.Value
                                ),
                                new DynamicMetaObject(
                                    Expression.Constant(getMemInfo.Name),
                                    BindingRestrictions.Empty,
                                    getMemInfo.Name
                                )
                            ).Expression
                        ),
                        Ast.Field(null, typeof(OperationFailed).GetField("Value"))
                    ),
                    tmp
                );
            }
        }
Example #17
0
        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;
                if (tg == null || tg.TryGetNonGenericType(out Type _))
                {
                    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(
                    Expression.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));
        }
        private void MakeGenericBodyWorker(GetMemberInfo getMemInfo, Type type, MemberTracker tracker, Expression instance) {
            if (instance != null) {
                tracker = tracker.BindToInstance(instance);
            }

            Expression val = tracker.GetValue(getMemInfo.CodeContext, this, type);

            getMemInfo.Body.FinishCondition(
                val != null ?
                    val :
                    MakeError(tracker.GetError(this))
            );
        }
 private void MakeMissingMemberRuleForGet(GetMemberInfo getMemInfo, Type type) {
     if (getMemInfo.IsNoThrow) {
         getMemInfo.Body.FinishCondition(
             Ast.Field(null, typeof(OperationFailed).GetField("Value"))
         );
     } else {
         getMemInfo.Body.FinishCondition(
             MakeError(MakeMissingMemberError(type, getMemInfo.Name))
         );
     }
 }
        private void MakeGenericBody(GetMemberInfo getMemInfo, Type type, MemberGroup members, Expression instance) {
            MemberTracker bestMember = members[0];
            if (members.Count > 1) {
                // if we were given multiple members pick the member closest to the type...                
                Type bestMemberDeclaringType = members[0].DeclaringType;

                for (int i = 1; i < members.Count; i++) {
                    MemberTracker mt = members[i];
                    if (!IsTrackerApplicableForType(type, mt)) {
                        continue;
                    }

                    if (members[i].DeclaringType.IsSubclassOf(bestMemberDeclaringType) ||
                        !IsTrackerApplicableForType(type, bestMember)) {
                        bestMember = members[i];
                        bestMemberDeclaringType = members[i].DeclaringType;
                    }
                }
            }

            MakeGenericBodyWorker(getMemInfo, type, bestMember, instance);
        }
 private void MakeMissingMemberRuleForGet(GetMemberInfo getMemInfo, Type type) {
     if (getMemInfo.ErrorSuggestion != null) {
         getMemInfo.Body.FinishCondition(getMemInfo.ErrorSuggestion.Expression);
     } else if (getMemInfo.IsNoThrow) {
         getMemInfo.Body.FinishCondition(MakeOperationFailed());
     } else {
         getMemInfo.Body.FinishCondition(
             MakeError(MakeMissingMemberError(type, getMemInfo.Name), typeof(object))
         );
     }
 }
Example #22
0
        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));
        }
        /// <summary> if a member-injector is defined-on or registered-for this type call it </summary>
        private void MakeOperatorGetMemberBody(GetMemberInfo getMemInfo, Expression instance, Type type, string name) {
            MethodInfo getMem = GetMethod(type, name);
            if (getMem != null && getMem.IsSpecialName) {
                ParameterExpression tmp = Ast.Variable(typeof(object), "getVal");
                getMemInfo.Body.AddVariable(tmp);

                getMemInfo.Body.AddCondition(
                    Ast.NotEqual(
                        Ast.Assign(
                            tmp,
                            MakeCallExpression(
                                getMemInfo.CodeContext,
                                getMem,
                                AstUtils.Convert(instance, type),
                                AstUtils.Constant(getMemInfo.Name)
                            )
                        ),
                        Ast.Field(null, typeof(OperationFailed).GetField("Value"))
                    ),
                    tmp
                );
            }
        }
Example #24
0
        private DynamicMetaObject MakeGetMemberTarget(GetMemberInfo getMemInfo, DynamicMetaObject target) {
            Type type = 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(type)) {
                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...
                        type = ((TypeTracker)target.Value).Type;
                        self = null;
                    }
                }
            }

            if (members.Count == 0) {
                // Get the members
                members = GetMember(MemberRequestKind.Get, type, getMemInfo.Name);
            }

            if (members.Count == 0) {
                if (type.IsInterface) {
                    // all interfaces have object members
                    type = typeof(object);
                    members = GetMember(MemberRequestKind.Get, type, getMemInfo.Name);
                }
            }

            DynamicMetaObject propSelf = self == null ? null : self;
            // if lookup failed try the strong-box type if available.
            if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(type) && propSelf != null) {
                // properties/fields need the direct value, methods hold onto the strong box.
                propSelf = new DynamicMetaObject(
                    Ast.Field(AstUtils.Convert(propSelf.Expression, type), type.GetField("Value")),
                    propSelf.Restrictions,
                    ((IStrongBox)propSelf.Value).Value
                );

                type = type.GetGenericArguments()[0];

                members = GetMember(
                    MemberRequestKind.Get,
                    type,
                    getMemInfo.Name
                );
            }

            MakeBodyHelper(getMemInfo, self, propSelf, type, members);

            getMemInfo.Body.Restrictions = restrictions;
            return getMemInfo.Body.GetMetaObject(target);
        }
        private void MakeBodyHelper(GetMemberInfo getMemInfo, Expression self, Expression propSelf, Type type, MemberGroup members) {
            if (self != null) {
                MakeOperatorGetMemberBody(getMemInfo, propSelf, type, "GetCustomMember");
            }

            Expression error;
            TrackerTypes memberType = GetMemberType(members, out error);

            if (error == null) {
                MakeSuccessfulMemberAccess(getMemInfo, self, propSelf, type, members, memberType);
            } else {
                getMemInfo.Body.FinishCondition(getMemInfo.ErrorSuggestion != null ? getMemInfo.ErrorSuggestion.Expression : error);
            }
        }
        private void MakeGenericBodyWorker(GetMemberInfo getMemInfo, Type type, MemberTracker tracker, DynamicMetaObject instance) {
            if (instance != null) {
                tracker = tracker.BindToInstance(instance);
            }

            DynamicMetaObject val = tracker.GetValue(getMemInfo.ResolutionFactory, this, type);

            if (val != null) {
                getMemInfo.Body.FinishCondition(val);
            } else {
                ErrorInfo ei = tracker.GetError(this);
                if (ei.Kind != ErrorInfoKind.Success && getMemInfo.IsNoThrow) {
                    getMemInfo.Body.FinishError(MakeOperationFailed());
                } else {
                    getMemInfo.Body.FinishError(MakeError(tracker.GetError(this), typeof(object)));
                }
            }
        }
        private DynamicMetaObject MakeGetMemberTarget(GetMemberInfo getMemInfo, DynamicMetaObject target) {
            Type type = target.GetLimitType();
            BindingRestrictions restrictions = target.Restrictions;
            Expression self = target.Expression;
            target = target.Restrict(target.GetLimitType());

            // 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(
                    BindingRestrictions.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 void MakeTypeBody(GetMemberInfo getMemInfo, Type type, MemberGroup members) {
            TypeTracker typeTracker = (TypeTracker)members[0];
            for (int i = 1; i < members.Count; i++) {
                typeTracker = TypeGroup.UpdateTypeEntity(typeTracker, (TypeTracker)members[i]);
            }

            getMemInfo.Body.FinishCondition(typeTracker.GetValue(getMemInfo.CodeContext, this, type));
        }
        private void MakeSuccessfulMemberAccess(GetMemberInfo getMemInfo, Expression self, Expression propSelf, Type type, MemberGroup members, TrackerTypes memberType) {
            switch (memberType) {
                case TrackerTypes.TypeGroup:
                case TrackerTypes.Type:
                    MakeTypeBody(getMemInfo, type, members);
                    break;
                case TrackerTypes.Method:
                    // turn into a MethodGroup                    
                    MakeGenericBodyWorker(getMemInfo, type, ReflectionCache.GetMethodGroup(getMemInfo.Name, members), self);
                    break;
                case TrackerTypes.Event:
                case TrackerTypes.Field:
                case TrackerTypes.Property:
                case TrackerTypes.Constructor:
                case TrackerTypes.Custom:
                    MakeGenericBody(getMemInfo, type, members, propSelf);
                    break;
                case TrackerTypes.All:
                    // no members were found
                    if (self != null) {
                        MakeOperatorGetMemberBody(getMemInfo, propSelf, type, "GetBoundMember");
                    }

                    MakeMissingMemberRuleForGet(getMemInfo, type);
                    break;
                default:
                    throw new InvalidOperationException(memberType.ToString());
            }
        }
        private void MakeGenericBodyWorker(GetMemberInfo getMemInfo, Type type, MemberTracker tracker, Expression instance) {
            if (instance != null) {
                tracker = tracker.BindToInstance(instance);
            }

            Expression val = tracker.GetValue(getMemInfo.CodeContext, this, type);

            if (val != null) {
                getMemInfo.Body.FinishCondition(val);
            } else {
                ErrorInfo ei = tracker.GetError(this);
                if (ei.Kind != ErrorInfoKind.Success && getMemInfo.IsNoThrow) {
                    getMemInfo.Body.FinishCondition(MakeOperationFailed());
                } else {
                    getMemInfo.Body.FinishCondition(MakeError(tracker.GetError(this), typeof(object)));
                }
            }
        }
 private void MakeMissingMemberRuleForGet(GetMemberInfo getMemInfo, Type type) {
     if (getMemInfo.IsNoThrow) {
         getMemInfo.Body.FinishCondition(MakeOperationFailed());
     } else {
         getMemInfo.Body.FinishCondition(
             MakeError(MakeMissingMemberError(type, getMemInfo.Name))
         );
     }
 }