def createCixRoot(version="2.0", name=None, description=None): cixroot = Element("codeintel", version=version) if name is not None: cixroot.attrib["name"] = name if description is not None: cixroot.attrib["description"] = description return cixroot
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 elementFromTag(tree, tag, parent=None): tagName = tag[1] if not tagName: tagName = "" ns = None if tag[0]: if tag[0] in tree.prefixmap: ns = tree.prefixmap[tag[0]] else: nsattr = "xmlns:%s"%tag[0] if nsattr in tag[2]: ns = tag[2][nsattr] del tag[2][nsattr] tree.prefixmap[tag[0]] = ns elif "xmlns" in tag[2]: ns = tag[2]["xmlns"] del tag[2]["xmlns"] elif parent is not None: ns = parent.ns localName = tag if ns: tagName = "{%s}%s" % (ns, tagName) elem = Element(tagName, tag[2]) try: elem.start = tree.err_info elem.end = None except: # will happen when parsing with cElementTree pass #print elem.localName if parent is not None: parent.append(elem) tree.nodemap[elem] = parent tree.nodes.append(elem) if elem.ns is not None: if elem.ns not in tree.tags: tree.tags[elem.ns] = {} tree.tags[elem.ns][elem.localName]=elem return elem
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 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)
traceback.print_exc() 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]
handlerclass = get_tree_handler(tree, tree.current, default_completion.get(lang)) values = handlerclass.values(attr, tree) if not values: return None values.sort() return values # configure catalogs to use basedir = os.path.dirname(os.path.dirname(os.getcwd())) catalogs = os.path.join(basedir, "test", "stuff", "xml") getService().setCatalogs([os.path.join(catalogs, "testcat.xml")]) from ciElementTree import Element tree = koXMLTreeService.XMLDocument() tree.root = tree.current = Element('') handlerclass = get_tree_handler(tree, tree.current) assert handlerclass != None, "no handler class for empty tree" xml = """<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html" indent="yes"/> <html> < """ tags = getValidTagNames(xml, lang="XSLT") assert tags == ['body', 'head'], \ "invalid output tags for stylesheet" xml = "<" assert getValidTagNames(xml) == None, "invalid children for html"
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 check_insert_rails_env(path, blob_scope): role_parts = rails_role_from_path(path) if role_parts is None: return add_models = False if len(role_parts) > 1 and role_parts[0] == "app": if role_parts[1] == "views": # This stuff only works if the evaluator will load class names as well # as namespace names. blob_scope.insert(0, Element("import", symbol="ActionView::Base")) elif len(role_parts) > 2: if role_parts[1] in ("controllers", "models"): if role_parts[1] == "controllers": if role_parts[2] != "application.rb": blob_scope.insert( 0, Element("import", module="./application", symbol='*')) # For loading models apath = abspath(path) add_models = True models_dir = join(dirname(dirname(apath)), "models") rel_part = "../" # For loading migrations modelName = "*" else: # add requires for each migration file # Here's how it works: # If the file is app/models/my_thing.rb, # For each file foo in ../../db/migrate/*.rb, # Try to load module=foo, # symbol=inflector.camelcase(drop_ext(basename(filename))) modelName = ruby_parser.get_inflector().camelize( splitext(basename(path))[0]) # Load the migration modules apath = abspath(path) migration_dir = join(dirname(dirname(dirname(apath))), "db", "migrate") migration_files = _modelDirInfo.get_files(migration_dir) idx = 0 for migration_file in migration_files: idx += 1 base_part = "../../db/migrate/" + \ splitext(basename(migration_file))[0] blob_class = blob_scope.find("scope") assert blob_class.get('ilk') == 'class' blob_class.insert( idx, Element("import", module=base_part, symbol=modelName)) elif (len(role_parts) > 2 and ((role_parts[0] == "db" and role_parts[1] == "migrate" and role_parts[2][0].isdigit()) or role_parts[0] == "test")): apath = abspath(path) add_models = True models_dir = join(dirname(dirname(dirname(apath))), "app", "models") rel_part = "../../app/" if role_parts[0] == "test" and role_parts[1] == 'functional': # Each file functional/foo_controller_test.rb will contain a line reading # require 'foo' # but codeintel won't know where to look for this foo, so we'll tell it explicitly # Use 'index' to throw an exception because # RubyCommonBufferMixin.check_for_rails_app_path specified this # pattern. end_part = role_parts[2].index("_test.rb") controller_file = rel_part + \ "controllers/" + role_parts[2][0:end_part] blob_scope.insert( 0, Element("import", module=controller_file, symbol='*')) modelName = '*' # XXX - tests can't see migration dirs yet. # migration_dir = join(dirname(dirname(dirname(apath))), "db", # "migrate") if add_models: model_files = _modelDirInfo.get_files(models_dir) idx = 0 for model_file in model_files: idx += 1 base_part = rel_part + "models/" + \ splitext(basename(model_file))[0] blob_scope.insert(idx, Element("import", module=base_part, symbol='*'))