def BuildInterfaceInfo(iid):
    assert not have_shutdown, "Can't build interface info after a shutdown"
    ret = interface_cache.get(iid, None)
    if ret is None:
        # Build the data for the cache.
        method_code_blocks = []
        getters = {}
        setters = {}
        method_infos = {}

        interface = xpt.Interface(iid)
        for m in interface.methods:
            flags = m.flags
            if flags & FLAGS_TO_IGNORE == 0:
                if flags & XPT_MD_SETTER:
                    param_flags = map(
                        lambda x: (x.param_flags, ) + xpt.MakeReprForInvoke(x),
                        m.params)
                    setters[m.name] = m.method_index, param_flags
                elif flags & XPT_MD_GETTER:
                    param_flags = map(
                        lambda x: (x.param_flags, ) + xpt.MakeReprForInvoke(x),
                        m.params)
                    getters[m.name] = m.method_index, param_flags
                else:
                    method_infos[m.name] = m

        # Build the constants.
        constants = {}
        for c in interface.constants:
            constants[c.name] = c.value
        ret = method_infos, getters, setters, constants
        interface_cache[iid] = ret
    return ret
    def do_describe_interface(self, name=None, language=None, **kwargs):
        assert not isinstance(threading.current_thread(),
                              threading._MainThread), \
            "Should not be describing interfaces on the main thread"
        if not name:
            name = "nsISupports"
        methods = {}
        attributes = {}
        constants = {}
        try:
            iface = xpt.Interface(name)
        except:
            pass
        else:
            attributes = {}
            methods = {}
            for thing in iface.methods:
                if thing.IsNotXPCOM():
                    continue
                args, returntype = self._process_method_argument(
                    thing, language)
                if thing.IsGetter() or thing.IsSetter():
                    if thing.name in attributes and not returntype:
                        continue  # don't override getters with setters
                    attributes[thing.name] = {
                        "tag": "variable",
                        "name": thing.name,
                        "citdl": returntype
                    }
                else:
                    # XPCOM things that are not getters or setters... it's a
                    # method
                    result = {
                        "tag": "scope",
                        "name": thing.name,
                        "ilk": "function"
                    }
                    signature = "%s(%s)" % (thing.name, ", ".join(args))
                    if returntype is not None:
                        result["returns"] = returntype
                        signature += " => %s" % (returntype, )
                    result["signature"] = signature
                    methods[thing.name] = result
            const_citdl = self._LANG_TYPE_FROM_XPT_TAG\
                              .get(language, {})\
                              .get(xpt.T_U32, "Number")
            for constant in iface.constants:
                constants[constant.name] = {
                    "tag": "variable",
                    "name": constant.name,
                    "citdl": const_citdl,
                    "attributes": "constant"
                }

        name_getter = operator.itemgetter("name")
        results = methods.values() + attributes.values() + constants.values()
        self.send(results=sorted(results, key=name_getter))
    def iid_to_cix(iid):
        elem = Element("scope", name=iid, ilk="class")
        try:
            interface = xpt.Interface(iid)
        except:
            print "No interface with iid: %r" % (iid, )
        else:
            # Filter out non-xpcom methods
            methods = [m for m in interface.methods if not m.IsNotXPCOM()]
            getters = [m for m in methods if m.IsGetter()]
            getters += [m for m in methods if m.IsSetter()]
            methods = [
                m for m in methods if not m.IsGetter() and not m.IsSetter()
            ]

            for m in getters:
                args, returntype = process_xpcom_arguments(m)
                variable_elem = elem.names.get(m.name)
                # Don't override an existing element.
                if variable_elem is None:
                    variable_elem = SubElement(elem,
                                               "variable",
                                               name=m.name,
                                               citdl=returntype)
                # Else, this must be a setter, which does not have a type.
            for m in methods:
                #print m.name
                func_elem = SubElement(elem,
                                       "scope",
                                       name=m.name,
                                       ilk="function")
                args, returntype = process_xpcom_arguments(m)
                signature = "%s(%s)" % (m.name, ", ".join(args))
                if returntype is not None:
                    func_elem.attrib["returns"] = returntype
                    signature += " => %s" % (returntype, )
                func_elem.attrib["signature"] = signature
            for c in interface.constants:
                # XXX: assuming all constants are integers, I am yet to see a
                #      case where this is not true...
                variable_elem = SubElement(elem,
                                           "variable",
                                           name=c.name,
                                           citdl="Number",
                                           attributes="constant")
        return elem
# The contents of this file are subject to the Mozilla Public License Version