/// <summary> /// Returns a ClassBase object representing a type that appears in /// this module's namespace or a ModuleObject representing a child /// namespace (or null if the name is not found). This method does /// not increment the Python refcount of the returned object. /// </summary> public ManagedType GetAttribute(string name, bool guess) { ManagedType cached = null; cache.TryGetValue(name, out cached); if (cached != null) { return(cached); } ModuleObject m; ClassBase c; Type type; //if (AssemblyManager.IsValidNamespace(name)) //{ // IntPtr py_mod_name = Runtime.PyString_FromString(name); // IntPtr modules = Runtime.PyImport_GetModuleDict(); // IntPtr module = Runtime.PyDict_GetItem(modules, py_mod_name); // if (module != IntPtr.Zero) // return (ManagedType)this; // return null; //} string qname = _namespace == string.Empty ? name : _namespace + "." + name; // If the fully-qualified name of the requested attribute is // a namespace exported by a currently loaded assembly, return // a new ModuleObject representing that namespace. if (AssemblyManager.IsValidNamespace(qname)) { m = new ModuleObject(qname); StoreAttribute(name, m); return(m); } // Look for a type in the current namespace. Note that this // includes types, delegates, enums, interfaces and structs. // Only public namespace members are exposed to Python. type = AssemblyManager.LookupType(qname); if (type != null) { if (!type.IsPublic) { return(null); } c = ClassManager.GetClass(type); StoreAttribute(name, c); return(c); } // This is a little repetitive, but it ensures that the right // thing happens with implicit assembly loading at a reasonable // cost. Ask the AssemblyManager to do implicit loading for each // of the steps in the qualified name, then try it again. bool ignore = name.StartsWith("__"); if (AssemblyManager.LoadImplicit(qname, !ignore)) { if (AssemblyManager.IsValidNamespace(qname)) { m = new ModuleObject(qname); StoreAttribute(name, m); return(m); } type = AssemblyManager.LookupType(qname); if (type != null) { if (!type.IsPublic) { return(null); } c = ClassManager.GetClass(type); StoreAttribute(name, c); return(c); } } // We didn't find the name, so we may need to see if there is a // generic type with this base name. If so, we'll go ahead and // return it. Note that we store the mapping of the unmangled // name to generic type - it is technically possible that some // future assembly load could contribute a non-generic type to // the current namespace with the given basename, but unlikely // enough to complicate the implementation for now. if (guess) { string gname = GenericUtil.GenericNameForBaseName(_namespace, name); if (gname != null) { ManagedType o = GetAttribute(gname, false); if (o != null) { StoreAttribute(name, o); return(o); } } } return(null); }
//=================================================================== // Scans an assembly for exported namespaces, adding them to the // mapping of valid namespaces. Note that for a given namespace // a.b.c.d, each of a, a.b, a.b.c and a.b.c.d are considered to // be valid namespaces (to better match Python import semantics). //=================================================================== static void ScanAssembly(Assembly assembly) { // A couple of things we want to do here: first, we want to // gather a list of all of the namespaces contributed to by // the assembly. Type[] types = assembly.GetTypes(); for (int i = 0; i < types.Length; i++) { Type t = types[i]; string ns = t.Namespace; if ((ns != null) && (!namespaces.ContainsKey(ns))) { string[] names = ns.Split('.'); string s = ""; for (int n = 0; n < names.Length; n++) { s = (n == 0) ? names[0] : s + "." + names[n]; if (!namespaces.ContainsKey(s)) { namespaces.Add(s, new Dictionary <Assembly, string>() ); } } } if (ns != null && !namespaces[ns].ContainsKey(assembly)) { namespaces[ns].Add(assembly, String.Empty); } if (t.IsGenericTypeDefinition) { GenericUtil.Register(t); // Dictionary<string, string> map = null; // generics.TryGetValue(t.Namespace, out map); // if (map == null) { // map = new Dictionary<string, string>(); // generics[t.Namespace] = map; // } // string bname = t.Name; // string mapped = null; // int tick = bname.IndexOf("`"); // if (tick > -1) { // bname = bname.Substring(0, tick); // } // map.TryGetValue(bname, out mapped); // if (mapped == null) { // map[bname] = t.Name; // } } // if (t.IsGenericTypeDefinition) { // List<string> snames = null; // special.TryGetValue(t.Namespace, out snames); // if (snames == null) { // snames = new List<string>(8); // special[t.Namespace] = snames; // } // snames.Add(t.Name); // } } }