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
def createCixVariable(cixobject, name, vartype=None, attributes=None): if attributes: v = SubElement(cixobject, "variable", name=name, attributes=attributes) else: v = SubElement(cixobject, "variable", name=name) if vartype: addCixType(v, vartype) return v
def createCixFunction(cixmodule, name, attributes=None): if attributes: return SubElement(cixmodule, "scope", ilk="function", name=name, attributes=attributes) else: return SubElement(cixmodule, "scope", ilk="function", name=name)
def createCixModule(cixfile, name, lang, src=None): if src is None: return SubElement(cixfile, "scope", ilk="blob", name=name, lang=lang) else: return SubElement(cixfile, "scope", ilk="blob", name=name, lang=lang, src=src)
def createCixModule(cixfile, name, lang, src=None): if src is None: return SubElement(cixfile, "scope", ilk="blob", name=name, lang=lang) else: if sys.platform.startswith("win"): # When searching for scannable files, the language import handlers # use lower-case directory and file names. name = name.lower() src = src.lower() return SubElement(cixfile, "scope", ilk="blob", name=name, lang=lang, src=src)
def _convertFunctionToHtml(html, elem): elem_name = elem.get("name") elem_type = elem.get('ilk') or elem.tag div = SubElement(html, "div", {"class": "function"}) span = SubElement(div, "span", {"class": elem_type}) codeElements = elem.get('attributes', "").split(" ") isCtor = False if "__ctor__" in codeElements: isCtor = True codeElements.remove("__ctor__") #else: # codeElements.push("void") if not isCtor: #span.text = "%s %s %s" % (elem_type, " ".join(codeElements), # elem.get('signature') or elem_name + "()") span.text = "%s %s" % (" ".join(codeElements), elem.get('signature') or elem_name + "()") _convertDocToHtml(div, elem) else: span.text = "%s" % (elem.get('signature') or elem_name + "()") function_arguments = [ x for x in elem if x.get("ilk") == "argument" and (x.get("citdl") or x.get("doc")) ] if function_arguments: arg_div = SubElement(div, "div", {"class": "function_arguments"}) arg_div.text = "Arguments" for arg_elem in function_arguments: #sys.stderr.write("function arg: %r\n" % (arg_elem)) _convertArgumentToHtml(arg_div, arg_elem) returns = elem.get('returns') if returns: ret_div = SubElement(div, "div", {"class": "function_returns"}) ret_p = SubElement(ret_div, "p") ret_p.text = "Returns - " span = SubElement(ret_p, "span", {"class": "function_returns"}) span.text = returns
def _convertArgumentToHtml(html, elem): elem_name = elem.get("name") elem_type = elem.get('ilk') or elem.tag para = SubElement(html, "p") span = SubElement(para, "span", {"class": elem_type}) span.text = elem_name citdl = elem.get("citdl") if citdl: citdl_span = SubElement(para, "span", {"class": "citdl"}) citdl_span.text = " - %s" % (citdl, ) _convertDocToHtml(html, elem, "doc_for_argument")
def produce_elementTree_cix(parse_tree, filename, target_lang, gen_lang="Python"): cix_root = Element("codeintel", version="2.0") fileAttrs = {"lang": target_lang, "path": filename, } file_cix_node = SubElement(cix_root, "file", **fileAttrs) module_cix_node = SubElement(file_cix_node, "scope", ilk='blob', lang=gen_lang, name=splitext(basename(filename))[0]) produce_elementTree_contents_cix(parse_tree, module_cix_node) return cix_root
def _convertClassToHtml(html, elem): html = SubElement(html, "div", {"class": "class"}) span = SubElement(html, "span", {"class": "class"}) span.text = "class %s" % (elem.get("name")) _convertDocToHtml(html, elem) variables = sorted([x for x in elem if x.tag == "variable"], _elemCompare) functions = sorted([x for x in elem if x.get( "ilk") == "function"], _elemCompare) constructors = [x for x in functions if "__ctor__" in x.get( "attributes", "").split(" ")] if constructors: h3 = SubElement(html, "h3", {"class": "class"}) h3.text = "Constructor" div = SubElement(html, "div", {"class": "class_variables"}) for ctor_elem in constructors: functions.remove(ctor_elem) _convertFunctionToHtml(div, ctor_elem) SubElement(div, "hr", {"class": "constructor_separator"}) if variables: h3 = SubElement(html, "h3", {"class": "class"}) h3.text = "Class variables" div = SubElement(html, "div", {"class": "class_variables"}) for var_elem in variables: _convertVariableToHtml(div, var_elem) SubElement(div, "hr", {"class": "variable_separator"}) if functions: h3 = SubElement(html, "h3", {"class": "class"}) h3.text = "Class functions" div = SubElement(html, "div", {"class": "class_functions"}) for var_elem in functions: _convertFunctionToHtml(div, var_elem) SubElement(div, "hr", {"class": "function_separator"})
def process_class_using_instance(rootElt, obj, name, callables): doc = getsdoc(obj) or None classElt = SubElement(rootElt, "scope", ilk="class", name=name) if doc: classElt.set('doc', doc) callables[name] = classElt classElt.set('attributes', '__hidden__') for key, value in sorted(inspect.getmembers(obj)): if not visiblename(key): continue if inspect.isbuiltin(value): process_routine(classElt, value, key, callables) elif (_gIsPy3 and hasattr(value, 'class')) or ( not _gIsPy3 and isinstance(value, types.InstanceType)): klass = value.__class__ if klass.__module__ == name: t = klass.__name__ else: t = "%s.%s" % (klass.__module__, klass.__name__) varElt = SubElement(classElt, "variable", name=key, citdl=t) elif isdata(value): varElt = SubElement(classElt, "variable", name=key, citdl=type(value).__name__)
def get_arguments_cix(parse_tree_node, cix_node): for c in parse_tree_node.args: attrs = get_common_attrs(c) attrs['name'] = c.get_full_name() if not c.arg_attrs is None: attrs['attributes'] = c.arg_attrs SubElement(cix_node, 'variable', ilk='argument', **attrs)
def addCixArgument(cixelement, argname, argtype=None, doc=None): cixarg = SubElement(cixelement, "variable", ilk="argument", name=argname) if argtype: addCixType(cixarg, argtype) if doc: setCixDoc(cixarg, doc) return cixarg
def get_imports_cix(parse_tree_node, cix_node): for imp in getattr(parse_tree_node, "imports", []): SubElement(cix_node, "import", module=imp.name, line=str(imp.line_num), symbol="*")
def createCixFile(cix, path, lang="JavaScript", mtime="1102379523"): return SubElement( cix, "file", lang=lang, # mtime=mtime, path=path)
def _convertVariableToHtml(html, elem): """Convert cix elements into html documentation elements Generally this will operate on blobs and variables with citdl="Object". """ elem_name = elem.get("name") elem_type = elem.get('ilk') or elem.tag div = SubElement(html, "div", {"class": "variable"}) para = SubElement(div, "p") span = SubElement(para, "span", {"class": elem_type}) span.text = elem_name citdl = elem.get("citdl") if citdl: citdl_span = SubElement(para, "span", {"class": "variable_cidtl"}) citdl_span.text = " - %s" % (citdl, ) _convertDocToHtml(div, elem)
def _add_xpcom_blob(built_in_blob): global _g_xpcom_components_elem global _g_xpcom_interfaces_elem if _xpcom_: if _g_xpcom_components_elem is None: # create the blob to hold xpcom data #print "Building xpcom cix wrapper for the first time" _g_xpcom_components_elem = SubElement(built_in_blob, "variable", citdl="Object", name="Components") xpcComponents = iid_to_cix("nsIXPCComponents") elem_classes = None for elem in xpcComponents: if elem.get("name") == "classes": #print "Found the classes elem: %r" % (elem, ) elem.attrib["citdl"] = "Object" elem_classes = elem elif elem.get("name") == "interfaces": #print "Found the interfaces elem: %r" % (elem, ) elem.attrib["citdl"] = "Object" _g_xpcom_interfaces_elem = elem _g_xpcom_components_elem.append(elem) # Add Components.interfaces data for interface in components.interfaces.keys(): elem = SubElement(_g_xpcom_interfaces_elem, "scope", ilk="class", name=interface) # Add Components.classes data for klass in components.classes.keys(): elem = SubElement(elem_classes, "variable", name=klass) # Add some common aliases for alias_name in ("CI", "Ci", ): SubElement(built_in_blob, "variable", citdl="Components.interfaces", name=alias_name) for alias_name in ("CC", "Cc", ): SubElement(built_in_blob, "variable", citdl="Components.classes", name=alias_name) for alias_name in ("CU", "Cu", ): SubElement(built_in_blob, "variable", citdl="Components.utils", name=alias_name) # This check is necessary as sometimes a blob will be cached and # will already contain the Components elem. elif built_in_blob.names.get("Components") is None: built_in_blob.append(_g_xpcom_components_elem)
def _convertScopeToHtml(html, scope, namespace, namespace_elements): name = scope.get('name') if namespace: namespace += ".%s" % (name) else: namespace = name # sys.stderr.write("namespace: %s\n" % (namespace, )) a_href = SubElement(html, "a", name=namespace) # This is to fix a bug where firefox displays all elements with the same # css style as set in "a", like underline etc... a_href.text = " " div = SubElement(html, "div", {"name": namespace, "class": "namespace"}) namespace_elements.append((namespace, div)) h2 = SubElement(div, "h2", {"name": namespace, "class": "namespace"}) h2.text = namespace _convertDocToHtml(div, scope, "doc_for_namespace") variables = set([x for x in scope if x.tag == "variable"]) functions = set([x for x in scope if x.get("ilk") == "function"]) classes = set([x for x in scope if x.get("ilk") == "class"]) subscopes = set([x for x in variables if x.get("citdl") == "Object"]) variables.difference_update(subscopes) if variables: h3 = SubElement(div, "h3") h3.text = "Variables" for elem in sorted(variables, _elemCompare): _convertVariableToHtml(div, elem) SubElement(div, "hr", {"class": "variable_separator"}) if functions: h3 = SubElement(div, "h3") h3.text = "Functions" for elem in sorted(functions, _elemCompare): _convertFunctionToHtml(div, elem) SubElement(div, "hr", {"class": "function_separator"}) if classes: h3 = SubElement(div, "h3") h3.text = "Classes" for elem in sorted(classes, _elemCompare): _convertClassToHtml(div, elem) SubElement(div, "hr", {"class": "class_separator"}) for elem in sorted(subscopes, _elemCompare): _convertScopeToHtml(div, elem, namespace, namespace_elements)
def method_etree_cix(parse_tree_node, cix_node): attrs = get_common_attrs(parse_tree_node) method_cix_node = SubElement(cix_node, 'scope', ilk='function', **attrs) get_docstring_cix(parse_tree_node, method_cix_node) get_signature_cix(parse_tree_node, method_cix_node) # XXX: Get classrefs, doc, symbols(?) get_arguments_cix(parse_tree_node, method_cix_node) get_imports_cix(parse_tree_node, method_cix_node) get_includes_cix(parse_tree_node, method_cix_node) get_vars_cix(parse_tree_node, method_cix_node) visit_children_get_cix(parse_tree_node, method_cix_node)
def process_class_using_instance(rootElt, obj, name, callables): doc = getsdoc(obj) or None classElt = SubElement(rootElt, "scope", ilk="class", name=name) if doc: classElt.set('doc', doc) callables[name] = classElt classElt.set('attributes', '__hidden__') for key, value in sorted(inspect.getmembers(obj)): if not visiblename(key): continue if inspect.isbuiltin(value): process_routine(classElt, value, key, callables) elif (_gIsPy3 and hasattr(value, 'class')) or (not _gIsPy3 and isinstance(value, types.InstanceType)): klass = value.__class__ if klass.__module__ == name: t = klass.__name__ else: t = "%s.%s" % (klass.__module__, klass.__name__) varElt = SubElement(classElt, "variable", name=key, citdl=t) elif isdata(value): varElt = SubElement(classElt, "variable", name=key, citdl=type(value).__name__)
def process_routine(rootElt, obj, name, callables): if inspect.isfunction(obj): if _gIsPy3: argspec = inspect.getfullargspec(obj) else: argspec = inspect.getargspec(obj) sig = name + inspect.formatargspec(*argspec) else: sig = '' doc = getdoc(obj) or None call_sig_lines, description_lines = parsePyFuncDoc(doc, [sig]) if description_lines: doc = '\n'.join(parseDocSummary(description_lines)) if call_sig_lines: signature = '\n'.join(call_sig_lines) else: signature = sig if name == '__init__': if doc == obj.__init__.__doc__: doc = None if signature == obj.__init__.__doc__: signature = None funcElt = SubElement(rootElt, "scope", ilk="function", name=name) if doc: funcElt.set('doc', doc) if signature: funcElt.set('signature', signature) callables[name] = funcElt
def get_arguments_cix(parse_tree_node, cix_node): for c in parse_tree_node.args: attrs = get_common_attrs(c) attrs['name'] = c.get_full_name() if not c.arg_attrs is None: attrs['attributes'] = c.arg_attrs try: lineno = parse_tree_node.line_num if lineno is not None: attrs['line'] = str(lineno) except AttributeError: pass SubElement(cix_node, 'variable', ilk='argument', **attrs)
def common_module_class_cix(parse_tree_node, cix_node, class_ref_fn=None, **additional_attrs): attrs = get_common_attrs(parse_tree_node) attrs.update(additional_attrs) if 'ilk' not in attrs: attrs['ilk'] = 'class' class_cix_node = SubElement(cix_node, 'scope', **attrs) get_docstring_cix(parse_tree_node, class_cix_node) get_signature_cix(parse_tree_node, class_cix_node) get_imports_cix(parse_tree_node, class_cix_node) get_includes_cix(parse_tree_node, class_cix_node) get_vars_cix(parse_tree_node, class_cix_node) if class_ref_fn: class_ref_fn(parse_tree_node, class_cix_node) visit_children_get_cix(parse_tree_node, class_cix_node)
def process_class(rootElt, obj, name, callables, __hidden__=False): doc = getsdoc(obj) or None classElt = SubElement(rootElt, "scope", ilk="class", name=name) if doc: classElt.set('doc', doc) callables[name] = classElt if __hidden__: classElt.set('attributes', '__hidden__') classrefs = [base.__name__ for base in obj.__bases__] if classrefs: classElt.set('classrefs', ' '.join(classrefs)) # Functions are method descriptors in Python inspect module parlance. def attrfilter(attr): # Only add methods and attributes of the class to the CIX. # - "os._Environ" seems to be a particular problem case in that # some methods defined on it are inspect.ismethod() but not # inspect.ismethoddescriptor(). Not so for other examples in # modules that stdcix.py processes, and adding .ismethod() to this # filter adds unwanted methods on C-defined module exception # classes. if not (inspect.isdatadescriptor(attr) or inspect.ismethoddescriptor(attr) or inspect.ismethod(attr) or inspect.isfunction(attr)): return False # Skip inherited attributes in the CIX. try: attrname = attr.__name__ for base in obj.__bases__: if hasattr(base, attrname) and getattr(base, attrname) is \ getattr(obj, attrname): return False except AttributeError: # staticmethod and classmethod objects don't have a __name__ pass # print "Couldn't process: %r, assuming ok" % str(attr) return True # attrs = inspect.getmembers(object, attrfilter) # should I be using # getmembers or class attr's? attrs = [(name, getattr( obj, name)) for name in obj.__dict__ if name not in ('__abstractmethods__')] attrs = [(name, attr) for (name, attr) in attrs if attrfilter(attr)] for (key, value) in attrs: if inspect.isfunction(value) or inspect.ismethod(value) or inspect.ismethoddescriptor(value): process_routine(classElt, value, key, callables)
def process_module_list(module_list, fname, catalog_name=None, catalog_description=None): root = Element("codeintel", version="2.0") if catalog_name: root.set("name", catalog_name) if catalog_description: root.set("description", catalog_description) cixfile = SubElement(root, "file", lang=lang, mtime=str(0), path=os.path.basename(fname)) print("Generating CIX Info: ") for mod in module_list: print(mod) sys.stdout.flush() try: # Introspect the module. gencix.docmodule(mod, cixfile, False) # Cile it as well, then merge the cile and introspect data. This # gives us additional information, including return type info, # docs strings, line numbers... mod_path = module_paths.get(mod) if mod_path and os.path.splitext(mod_path)[1] == ".py": # Need Python 2.6 to perform the cile. tree = get_pythoncile_cix_tree_for_path(mod_path) merge_module_scopes( mod, root, tree, use_init_fallback=(mod_path.endswith("__init__.py")), log=False) except Exception: import traceback print("\nEXCEPTION:", sys.exc_info()[1], "when processing", mod) traceback.print_exc() gencix.writeCixFileForElement(fname, root) print("done writing generic bits: %r." % fname)
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
def _convertClassToHtml(html, elem): html = SubElement(html, "div", {"class": "class"}) span = SubElement(html, "span", {"class": "class"}) span.text = "class %s" % (elem.get("name")) _convertDocToHtml(html, elem) variables = sorted([x for x in elem if x.tag == "variable"], _elemCompare) functions = sorted([x for x in elem if x.get("ilk") == "function"], _elemCompare) constructors = [ x for x in functions if "__ctor__" in x.get("attributes", "").split(" ") ] if constructors: h3 = SubElement(html, "h3", {"class": "class"}) h3.text = "Constructor" div = SubElement(html, "div", {"class": "class_variables"}) for ctor_elem in constructors: functions.remove(ctor_elem) _convertFunctionToHtml(div, ctor_elem) SubElement(div, "hr", {"class": "constructor_separator"}) if variables: h3 = SubElement(html, "h3", {"class": "class"}) h3.text = "Class variables" div = SubElement(html, "div", {"class": "class_variables"}) for var_elem in variables: _convertVariableToHtml(div, var_elem) SubElement(div, "hr", {"class": "variable_separator"}) if functions: h3 = SubElement(html, "h3", {"class": "class"}) h3.text = "Class functions" div = SubElement(html, "div", {"class": "class_functions"}) for var_elem in functions: _convertFunctionToHtml(div, var_elem) SubElement(div, "hr", {"class": "function_separator"})
def createCixInterface(cixmodule, name): return SubElement(cixmodule, "scope", ilk="interface", name=name)
def docmodule(modname, root, force=False, usefile=False, dir=None): name = modname modulename = modname if modname == '*': if _gIsPy3: modname = 'builtins' else: modname = '__builtin__' if dir: modinfo = imp.find_module(modname, [dir]) try: obj = imp.load_module(modname, *modinfo) except ImportError: ex = sys.exc_info()[1] cixfile = SubElement(root, "file", lang="Python", mtime=str(int(time.time())), path=os.path.basename(modinfo[1]), error=str(ex)) return else: # no dir is given, try to load from python path try: obj, modulename = pydoc.resolve(modname) except Exception: print(sys.exc_info()[1]) return result = '' try: all = obj.__all__ except AttributeError: all = None try: filename = inspect.getabsfile(obj) except TypeError: filename = '(built-in)' if usefile: cixfile = SubElement(root, "file", lang="Python", mtime=str(int(time.time())), path=os.path.basename(filename)) else: cixfile = root module = obj doc = getsdoc(obj) or None moduleElt = SubElement(cixfile, "scope", ilk="blob", name=name, lang="Python") if doc: moduleElt.set('doc', doc) skips = module_skips.get(name, []) callables = {} for key, value in sorted(inspect.getmembers(obj)): if key in skips: continue if inspect.ismodule(value): process_module(moduleElt, value, key, callables, modname) continue if not visiblename(key): # forget about __all__ continue if (inspect.isfunction(value) or inspect.ismethod(value) or inspect.ismethoddescriptor(value) or inspect.isroutine(value) or inspect.isbuiltin(value)): process_routine(moduleElt, value, key, callables) elif inspect.isclass(value) or (not _gIsPy3 and isinstance(value, types.TypeType)): process_class(moduleElt, value, key, callables) elif (_gIsPy3 and hasattr(value, 'class')) or (not _gIsPy3 and isinstance(value, types.InstanceType)): klass = value.__class__ if klass.__module__ == name: t = klass.__name__ else: t = "%s.%s" % (klass.__module__, klass.__name__) varElt = SubElement(moduleElt, "variable", name=key, citdl=t) # make sure we also process the type of instances process_class(moduleElt, klass, klass.__name__, callables) elif isdata(value): varElt = SubElement(moduleElt, "variable", name=key, citdl=type(value).__name__) else: log.warn("unexpected element in module '%s': '%s' is %r", modulename, name, type(value)) helpername = os.path.join("helpers", modname + '_helper.py') namespace = {} if os.path.exists(helpername): sys.stderr.write("Found helper module: %r\n" % helpername) if _gIsPy3: exec(compile(open(helpername).read(), os.path.basename(helpername), 'exec'), namespace, namespace) else: execfile(helpername, namespace, namespace) # look in helpername for analyze_retval_exprs, which is a list of (callable_string, *args) # and which corresponds to callables which when called w/ the specified args, will return # variables which should be used to specify the <return> subelement of the callable. analyze_retval_exprs = namespace.get('analyze_retval_exprs', []) signatures = namespace.get('signatures', {}) for retval_expr in analyze_retval_exprs: name, args = retval_expr if name in callables: callableElt = callables[name] if name in signatures: sig = signatures[name] callableElt.set('signature', sig) # XXX??? playarea = module.__dict__ var = eval(name, playarea)(*args) # find out what type that is callableElt.set("returns", type(var).__name__) else: print("Don't know about: %r" % expr) hidden_classes_exprs = namespace.get('hidden_classes_exprs', []) for expr in hidden_classes_exprs: playarea = module.__dict__ var = eval(expr, playarea) name = type(var).__name__ process_class_using_instance(moduleElt, var, name, callables) function_overrides = namespace.get('function_overrides') if function_overrides is not None: for name in function_overrides: namesplit = name.split(".") callableElt = callables[namesplit[0]] for subname in namesplit[1:]: for childElt in callableElt: if childElt.get("name") == subname: callableElt = childElt break else: callableElt = None break if callableElt is None: print(" couldn't find elem with name: %r" % (name, )) continue overrides = function_overrides[name] for setting, value in overrides.items(): print(" overriding %s.%s %s attribute from %r to %r" % (modname, name, setting, callableElt.get(setting), value)) callableElt.set(setting, value)
def _html_ci_elem(opts, elem, lang=None): # Taken from codeintel2.tree, modified to ensure it keeps all # existing text and tail data. Since this is used on generated # xml content, there is no need to worry about existing newlines # and whitespace, as there will be none existing at this point. def pretty_tree_from_tree(tree, indent_width=2): """Add appropriate .tail and .text values to the given tree so that it will have a pretty serialization. Presumption: This is a CIX 2.0 tree. """ INDENT = ' ' * indent_width def _prettify(elem, indent_level=0): if elem: # i.e. elem has child elements elem.text = '\n' + INDENT * (indent_level + 1) + (elem.text or "") for child in elem: _prettify(child, indent_level + 1) elem[-1].tail = (elem[-1].tail or "") + '\n' + INDENT * indent_level elem.tail = (elem.tail or "") + '\n' + INDENT * indent_level else: # elem.text = None elem.tail = (elem.tail or "") + '\n' + INDENT * indent_level _prettify(tree) return tree def remove_private_elements(elem): """Remove all the private cix elements.""" parent_map = dict((c, p) for p in elem.getiterator() for c in p) for node in list(elem.getiterator()): attributes = node.get("attributes", "").split(" ") if "private" in attributes or "__hidden__" in attributes: # Remove it parentnode = parent_map.get(node) if parentnode is not None: parentnode.remove(node) # Set the css reference file if not opts.css_reference_files: opts.css_reference_files = ["aspn.css", "api.css"] html = Element("html") head = SubElement(html, "head") for css_filename in opts.css_reference_files: SubElement(head, "link", rel="stylesheet", type="text/css", href=css_filename) body = SubElement(html, "body") body_div = SubElement(body, "div", {"id": "body"}) namespace_elements = [] # Remove any private cix elements, as they are not externally visible. remove_private_elements(elem) if elem.tag == "file": for child in elem: for subchild in child: _convertScopeToHtml(body_div, subchild, "", namespace_elements) else: _convertScopeToHtml(body_div, elem, "", namespace_elements) # Now, we can print out the html in a few formats: # Single file - the default and only implemented format at present # File for each namespace and an index - Not done. # Try to build an index, placed in same html file # nav_div = SubElement(body, "div", {"id": "nav"}) # ul = SubElement(nav_div, "ul") # for ns, elem in namespace_elements: # li = SubElement(ul, "li") # a_href = SubElement(li, "a", href="#%s" % (ns)) # a_href.text = ns footer_div = SubElement(body, "div", {"id": "footer"}) pretty_tree_from_tree(html) tree = ElementTree(html) xhtml_header = '<?xml version="1.0"?>\n' \ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' \ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n' stream = sys.stdout if opts.output: stream = file(opts.output, "wb") stream.write(xhtml_header) tree.write(stream) if opts.toc_file: file_href = opts.output or "komodo-js-api.html" toc_node = Element("node", name="Komodo JavaScript API Reference", link=file_href) for ns, elem in namespace_elements: sub_node = SubElement(toc_node, "node", name=ns, link="%s#%s" % ( file_href, ns, )) pretty_tree_from_tree(toc_node) toc_file = open(opts.toc_file, "w") tree = ElementTree(toc_node) tree.write(toc_file)
def createCixClass(cixmodule, name): return SubElement(cixmodule, "scope", ilk="class", name=name)
def _convertDocToHtml(html, elem, cls="doc"): doc = elem.get('doc') if doc: p = SubElement(html, "p", {"class": cls}) p.text = doc
def createCixNamespace(cixmodule, name): return SubElement(cixmodule, "scope", ilk="namespace", name=name)
def _convertFunctionToHtml(html, elem): elem_name = elem.get("name") elem_type = elem.get('ilk') or elem.tag div = SubElement(html, "div", {"class": "function"}) span = SubElement(div, "span", {"class": elem_type}) codeElements = elem.get('attributes', "").split(" ") isCtor = False if "__ctor__" in codeElements: isCtor = True codeElements.remove("__ctor__") # else: # codeElements.push("void") if not isCtor: # span.text = "%s %s %s" % (elem_type, " ".join(codeElements), # elem.get('signature') or elem_name + "()") span.text = "%s %s" % (" ".join(codeElements), elem.get('signature') or elem_name + "()") _convertDocToHtml(div, elem) else: span.text = "%s" % (elem.get('signature') or elem_name + "()") function_arguments = [ x for x in elem if x.get("ilk") == "argument" and (x.get("citdl") or x.get("doc")) ] if function_arguments: arg_div = SubElement(div, "div", {"class": "function_arguments"}) arg_div.text = "Arguments" for arg_elem in function_arguments: # sys.stderr.write("function arg: %r\n" % (arg_elem)) _convertArgumentToHtml(arg_div, arg_elem) returns = elem.get('returns') if returns: ret_div = SubElement(div, "div", {"class": "function_returns"}) ret_p = SubElement(ret_div, "p") ret_p.text = "Returns - " span = SubElement(ret_p, "span", {"class": "function_returns"}) span.text = returns
gencix.writeCixFileForElement(fname, root) print("done writing generic bits: %r." % fname) fname = '../../../lib/codeintel2/stdlibs/%s-%d.%d.cix' % (lang.lower(), major, minor) pywin32fname = '../../../lib/codeintel2/catalogs/pywin32.cix' # Remember the original cix, we'll merge with it after the current scan. try: orig_root = parse(fname).getroot() except (IOError, SyntaxError): # When the CIX file does not yet exist (new scan), create an empty root. orig_root = Element("codeintel", version="2.0") SubElement(orig_root, "file", lang=lang, mtime=str(0), path=os.path.basename(fname)) process_module_list(module_names, fname) if sys.platform.startswith('win'): # Generate the windows specific bits into separate CIX files. process_module_list(pywin32_module_names, pywin32fname, catalog_name="PyWin32", catalog_description="Python Extensions for Windows") # Read in the just generated CIX. main_root = parse(fname).getroot() file_elem = main_root[0] def fixup_cgi_module(cgi_elem): # Remove the environment strings that get set in these function signatures.
def get_var_cix(cix_node, var_type, **attrs): var_cix_node = SubElement(cix_node, 'variable', **attrs) if var_type: var_cix_node.set('citdl', var_type)