Пример #1
0
        static PropertyDescriptor[] GetPropertiesImpl(object self, Attribute[] attributes)
        {
            bool ok = true;

            foreach (var attr in attributes)
            {
                if (attr.GetType() != typeof(BrowsableAttribute))
                {
                    ok = false;
                    break;
                }
            }
            if (!ok)
            {
                return(new PropertyDescriptor[0]);
            }

            RubyClass   immediateClass = GetImmediateClass(self);
            RubyContext context        = immediateClass.Context;

            const int readable = 0x01;
            const int writable = 0x02;

            var properties = new Dictionary <string, int>();

            using (context.ClassHierarchyLocker()) {
                immediateClass.ForEachMember(true, RubyMethodAttributes.DefaultVisibility, delegate(string /*!*/ name, RubyModule /*!*/ module, RubyMemberInfo /*!*/ member) {
                    ExpressionType operatorType;

                    int flag = 0;
                    if (member is RubyAttributeReaderInfo)
                    {
                        flag = readable;
                    }
                    else if (member is RubyAttributeWriterInfo)
                    {
                        flag = writable;
                    }
                    else if (name == "initialize" || RubyUtils.TryMapOperator(name, out operatorType) != 0)
                    {
                        // Special case; never a property
                    }
                    else
                    {
                        int arity = member.GetArity();
                        if (arity == 0)
                        {
                            flag = readable;
                        }
                        else if (arity == 1 && name.LastCharacter() == '=')
                        {
                            flag = writable;
                        }
                    }
                    if (flag != 0)
                    {
                        if (flag == writable)
                        {
                            name = name.Substring(0, name.Length - 1);
                        }
                        int oldFlag;
                        properties.TryGetValue(name, out oldFlag);
                        properties[name] = oldFlag | flag;
                    }
                });
            }

            var result = new List <PropertyDescriptor>(properties.Count);

            foreach (var pair in properties)
            {
                if (pair.Value == (readable | writable))
                {
                    result.Add(new RubyPropertyDescriptor(context, pair.Key, self, immediateClass.GetUnderlyingSystemType()));
                }
            }
            return(result.ToArray());
        }