Beispiel #1
0
 internal ClassInfo(Type t)
 {
     members = new Hashtable();
     indexer = null;
 }
Beispiel #2
0
 internal ClassBase(Type tp)
 {
     indexer = null;
     type    = tp;
 }
Beispiel #3
0
        private static ClassInfo GetClassInfo(Type type)
        {
            var         ci      = new ClassInfo(type);
            var         methods = new Hashtable();
            ArrayList   list;
            MethodInfo  meth;
            ManagedType ob;
            string      name;
            object      item;
            Type        tp;
            int         i, n;

            // This is complicated because inheritance in Python is name
            // based. We can't just find DeclaredOnly members, because we
            // could have a base class A that defines two overloads of a
            // method and a class B that defines two more. The name-based
            // descriptor Python will find needs to know about inherited
            // overloads as well as those declared on the sub class.
            BindingFlags flags = BindingFlags.Static |
                                 BindingFlags.Instance |
                                 BindingFlags.Public |
                                 BindingFlags.NonPublic;

            MemberInfo[] info  = type.GetMembers(flags);
            var          local = new Hashtable();
            var          items = new ArrayList();
            MemberInfo   m;

            // Loop through once to find out which names are declared
            for (i = 0; i < info.Length; i++)
            {
                m = info[i];
                if (m.DeclaringType == type)
                {
                    local[m.Name] = 1;
                }
            }

            // Now again to filter w/o losing overloaded member info
            for (i = 0; i < info.Length; i++)
            {
                m = info[i];
                if (local[m.Name] != null)
                {
                    items.Add(m);
                }
            }

            if (type.IsInterface)
            {
                // Interface inheritance seems to be a different animal:
                // more contractual, less structural.  Thus, a Type that
                // represents an interface that inherits from another
                // interface does not return the inherited interface's
                // methods in GetMembers. For example ICollection inherits
                // from IEnumerable, but ICollection's GetMemebers does not
                // return GetEnumerator.
                //
                // Not sure if this is the correct way to fix this, but it
                // seems to work. Thanks to Bruce Dodson for the fix.

                Type[] inheritedInterfaces = type.GetInterfaces();

                for (i = 0; i < inheritedInterfaces.Length; ++i)
                {
                    Type         inheritedType = inheritedInterfaces[i];
                    MemberInfo[] imembers      = inheritedType.GetMembers(flags);
                    for (n = 0; n < imembers.Length; n++)
                    {
                        m = imembers[n];
                        if (local[m.Name] == null)
                        {
                            items.Add(m);
                        }
                    }
                }
            }

            for (i = 0; i < items.Count; i++)
            {
                var mi = (MemberInfo)items[i];

                switch (mi.MemberType)
                {
                case MemberTypes.Method:
                    meth = (MethodInfo)mi;
                    if (!(meth.IsPublic || meth.IsFamily ||
                          meth.IsFamilyOrAssembly))
                    {
                        continue;
                    }
                    name = meth.Name;
                    item = methods[name];
                    if (item == null)
                    {
                        item = methods[name] = new ArrayList();
                    }
                    list = (ArrayList)item;
                    list.Add(meth);
                    continue;

                case MemberTypes.Property:
                    var pi = (PropertyInfo)mi;

                    MethodInfo mm = null;
                    try
                    {
                        mm = pi.GetGetMethod(true);
                        if (mm == null)
                        {
                            mm = pi.GetSetMethod(true);
                        }
                    }
                    catch (SecurityException)
                    {
                        // GetGetMethod may try to get a method protected by
                        // StrongNameIdentityPermission - effectively private.
                        continue;
                    }

                    if (mm == null)
                    {
                        continue;
                    }

                    if (!(mm.IsPublic || mm.IsFamily || mm.IsFamilyOrAssembly))
                    {
                        continue;
                    }

                    // Check for indexer
                    ParameterInfo[] args = pi.GetIndexParameters();
                    if (args.GetLength(0) > 0)
                    {
                        Indexer idx = ci.indexer;
                        if (idx == null)
                        {
                            ci.indexer = new Indexer();
                            idx        = ci.indexer;
                        }
                        idx.AddProperty(pi);
                        continue;
                    }

                    ob = new PropertyObject(pi);
                    ci.members[pi.Name] = ob;
                    continue;

                case MemberTypes.Field:
                    var fi = (FieldInfo)mi;
                    if (!(fi.IsPublic || fi.IsFamily || fi.IsFamilyOrAssembly))
                    {
                        continue;
                    }
                    ob = new FieldObject(fi);
                    ci.members[mi.Name] = ob;
                    continue;

                case MemberTypes.Event:
                    var        ei = (EventInfo)mi;
                    MethodInfo me = ei.GetAddMethod(true);
                    if (!(me.IsPublic || me.IsFamily || me.IsFamilyOrAssembly))
                    {
                        continue;
                    }
                    ob = new EventObject(ei);
                    ci.members[ei.Name] = ob;
                    continue;

                case MemberTypes.NestedType:
                    tp = (Type)mi;
                    if (!(tp.IsNestedPublic || tp.IsNestedFamily ||
                          tp.IsNestedFamORAssem))
                    {
                        continue;
                    }
                    // Note the given instance might be uninitialized
                    ob = GetClass(tp);
                    ci.members[mi.Name] = ob;
                    continue;
                }
            }

            IDictionaryEnumerator iter = methods.GetEnumerator();

            while (iter.MoveNext())
            {
                name = (string)iter.Key;
                list = (ArrayList)iter.Value;

                var mlist = (MethodInfo[])list.ToArray(typeof(MethodInfo));

                ob = new MethodObject(type, name, mlist);
                ci.members[name] = ob;
            }

            return(ci);
        }