Exemplo n.º 1
0
            public override MetaObject BindGetMember(GetMemberBinder binder)
            {
                ContractUtils.RequiresNotNull(binder, "binder");

                ExpandoClass klass = Value.Class;

                int    index      = klass.GetValueIndex(binder.Name, binder.IgnoreCase);
                string methodName = binder.IgnoreCase ? "ExpandoGetValueIgnoreCase" : "ExpandoGetValue";

                Expression target;

                if (index == -1)
                {
                    // the key does not exist, report a MissingMemberException
                    target = Expression.Convert(
                        Expression.Throw(
                            Expression.New(
                                typeof(MissingMemberException).GetConstructor(new Type[] { typeof(string) }),
                                Expression.Constant(binder.Name)
                                )
                            ),
                        typeof(object)
                        );
                }
                else
                {
                    target = Expression.Call(
                        typeof(RuntimeOps).GetMethod(methodName),
                        GetLimitedSelf(),
                        Expression.Constant(klass),
                        Expression.Constant(index)
                        );
                }

                // add the dynamic test for the target
                return(new MetaObject(
                           AddDynamicTestAndDefer(
                               binder,
                               new MetaObject[] { this },
                               klass,
                               null,
                               target
                               ),
                           GetRestrictions()
                           ));
            }
Exemplo n.º 2
0
            /// <summary>
            /// Gets the class and the index associated with the given name.  Does not update the expando object.  Instead
            /// this returns both the original and desired new class.  A rule is created which includes the test for the
            /// original class, the promotion to the new class, and the set/delete based on the class post-promotion.
            /// </summary>
            private ExpandoClass GetClassEnsureIndex(string name, bool ignoreCase, out ExpandoClass klass, out int index)
            {
                ExpandoClass originalClass = Value.Class;

                index = originalClass.GetValueIndex(name, ignoreCase);
                if (index == -1)
                {
                    // go ahead and find a new class now...
                    ExpandoClass newClass = originalClass.FindNewClass(name, ignoreCase);

                    klass = newClass;
                    index = newClass.GetValueIndex(name, ignoreCase);

                    Debug.Assert(index != -1);
                    return(originalClass);
                }
                else
                {
                    klass = originalClass;
                    return(null);
                }
            }