/Packages/SublimeCodeIntel/libs/codeintel2/gencix_utils.py
Python | 364 lines | 316 code | 4 blank | 44 comment | 1 complexity | 91f3a532d5c6548c17c3a47be1f2cc3a MD5 | raw file
- #!/usr/bin/env python
- # ***** BEGIN LICENSE BLOCK *****
- # Version: MPL 1.1/GPL 2.0/LGPL 2.1
- #
- # The contents of this file are subject to the Mozilla Public License
- # Version 1.1 (the "License"); you may not use this file except in
- # compliance with the License. You may obtain a copy of the License at
- # http://www.mozilla.org/MPL/
- #
- # Software distributed under the License is distributed on an "AS IS"
- # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- # License for the specific language governing rights and limitations
- # under the License.
- #
- # The Original Code is Komodo code.
- #
- # The Initial Developer of the Original Code is ActiveState Software Inc.
- # Portions created by ActiveState Software Inc are Copyright (C) 2000-2007
- # ActiveState Software Inc. All Rights Reserved.
- #
- # Contributor(s):
- # ActiveState Software Inc
- #
- # Alternatively, the contents of this file may be used under the terms of
- # either the GNU General Public License Version 2 or later (the "GPL"), or
- # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- # in which case the provisions of the GPL or the LGPL are applicable instead
- # of those above. If you wish to allow use of your version of this file only
- # under the terms of either the GPL or the LGPL, and not to allow others to
- # use your version of this file under the terms of the MPL, indicate your
- # decision by deleting the provisions above and replace them with the notice
- # and other provisions required by the GPL or the LGPL. If you do not delete
- # the provisions above, a recipient may use your version of this file under
- # the terms of any one of the MPL, the GPL or the LGPL.
- #
- # ***** END LICENSE BLOCK *****
- """Shared CIX tools for Code Intelligence
- CIX helpers for codeintel creation. Code Intelligence XML format. See:
- http://specs.tl.activestate.com/kd/kd-0100.html#xml-based-import-export-syntax-cix
- """
- import os
- import sys
- import re
- import shutil
- from cStringIO import StringIO
- import warnings
- from ciElementTree import Element, ElementTree, SubElement
- from codeintel2.util import parseDocSummary
- # Dictionary of known js types and what they map to
- known_javascript_types = {
- "object": "Object",
- "obj": "Object",
- "function": "Function",
- "array": "Array",
- "string": "String",
- "text": "String",
- "int": "Number",
- "integer": "Number",
- "number": "Number",
- "numeric": "Number",
- "decimal": "Number",
- "short": "Number",
- "unsigned short": "Number",
- "long": "Number",
- "unsigned long":"Number",
- "float": "Number",
- "bool": "Boolean",
- "boolean": "Boolean",
- "true": "Boolean",
- "false": "Boolean",
- "date": "Date",
- "regexp": "RegExp",
- # Dom elements
- "element": "Element",
- "node": "Node",
- "domnode": "DOMNode",
- "domstring": "DOMString",
- "widget": "Widget",
- "domwidget": "DOMWidget",
- "htmlelement": "HTMLElement",
- "xmldocument": "XMLDocument",
- "htmldocument": "HTMLDocument",
- # Special
- "xmlhttprequest": "XMLHttpRequest",
- "void": "",
- # Mozilla special
- "UTF8String": "String",
- "AString": "String",
- }
- def standardizeJSType(vartype):
- """Return a standardized name for the given type if it is a known type.
- Example1: given vartype of "int", returns "Number"
- Example2: given vartype of "YAHOO.tool", returns "YAHOO.tool"
- """
- if vartype:
- typename = known_javascript_types.get(vartype.lower(), None)
- if typename is None:
- #print "Unknown type: %s" % (vartype)
- return vartype
- return typename
- spacere = re.compile(r'\s+')
- def condenseSpaces(s):
- """Remove any line enedings and condense multiple spaces"""
- s = s.replace("\n", " ")
- s = spacere.sub(' ', s)
- return s.strip()
- def remove_directory(dirpath):
- """ Recursively remove the directory path given """
- if os.path.exists(dirpath):
- shutil.rmtree(dirpath, ignore_errors=True)
- def getText(elem):
- """Return the internal text for the given ElementTree node"""
- l = []
- for element in elem.getiterator():
- if element.text:
- l.append(element.text)
- if element.tail:
- l.append(element.tail)
- return " ".join(l)
- def getAllTextFromSubElements(elem, subelementname):
- descnodes = elem.findall(subelementname)
- if len(descnodes) == 1:
- return getText(descnodes[0])
- return None
- _invalid_char_re = re.compile(u'[^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD]')
- def strip_invalid_xml_chars(s):
- """Return the string with any invalid XML characters removed.
- The valid characters are listed here:
- http://www.w3.org/TR/REC-xml/#charsets
- #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
- """
- return _invalid_char_re.sub("", s)
- def setCixDoc(cixelement, doctext, parse=False):
- if parse:
- doclines = parseDocSummary(doctext.splitlines(0))
- doctext = "\n".join(doclines)
- elif sys.platform.startswith("win"):
- doctext = doctext.replace("\r\n", "\n")
- #TODO: By default clip doc content down to a smaller set -- just
- # enough for a good calltip. By then also want an option to
- # *not* clip, for use in documentation generation.
- #if len(doctext) > 1000:
- # warnings.warn("doctext for cixelement: %r has length: %d" % (
- # cixelement.get("name"), len(doctext)))
- cixelement.attrib["doc"] = strip_invalid_xml_chars(doctext)
- def setCixDocFromNodeChildren(cixelement, node, childnodename):
- doctext = getAllTextFromSubElements(node, childnodename)
- if doctext:
- setCixDoc(cixelement, condenseSpaces(doctext), parse=True)
- 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 addCixReturns(cixelement, returntype=None):
- if returntype and returntype != "void":
- cixelement.attrib["returns"] = returntype
- def addCixType(cixobject, vartype):
- if vartype:
- cixobject.attrib["citdl"] = vartype
- def addCixAttribute(cixobject, attribute):
- attrs = cixobject.get("attributes")
- if attrs:
- sp = attrs.split()
- if attribute not in sp:
- attrs = "%s %s" % (attrs, attribute)
- else:
- attrs = attribute
- cixobject.attrib["attributes"] = attrs
- def addClassRef(cixclass, name):
- refs = cixclass.get("classrefs", None)
- if refs:
- if name not in refs.split(" "):
- cixclass.attrib["classrefs"] = "%s %s" % (refs, name)
- else:
- cixclass.attrib["classrefs"] = "%s" % (name)
- def addInterfaceRef(cixinterface, name):
- refs = cixinterface.get("interfacerefs", None)
- if refs:
- if name not in refs.split(" "):
- cixinterface.attrib["interfacerefs"] = "%s %s" % (refs, name)
- else:
- cixinterface.attrib["interfacerefs"] = "%s" % (name)
- def setCixSignature(cixelement, signature):
- cixelement.attrib["signature"] = signature
- 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 createCixInterface(cixmodule, name):
- return SubElement(cixmodule, "scope", ilk="interface", name=name)
- def createCixClass(cixmodule, name):
- return SubElement(cixmodule, "scope", ilk="class", name=name)
- def createCixNamespace(cixmodule, name):
- return SubElement(cixmodule, "scope", ilk="namespace", 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 createOrFindCixModule(cixfile, name, lang, src=None):
-