Exemple #1
0
def regularize(node):
    """? This function ensures that the tree is complete and regular.  For example it breaks descriptions into brief and desc tags.
  """
    if microdom.isInstanceOf(node, microdom.MicroDom):
        if node.tag_ in [TagCtor, TagMethod, TagFunction]:
            # Add the "decl" tag
            t = microdom.MicroDom({"tag_": TagDecl}, None,
                                  node.name + node.args)
            node.addChild(t)

            # Supplement the args tags
            args = node.args
            args = args.replace("(", "").replace(
                ")", "")  # remove leading and trailing paren
            arglst = args.split(',')
            for arg in arglst:
                if arg != "void":
                    (typequal, atype, aname) = reargdecl.match(arg).groups()

                    argdefs = node.filterByAttr({AttrName: aname})
                    if not argdefs:
                        t = microdom.MicroDom(
                            {
                                "tag_": TagParam,
                                AttrType: typequal + atype,
                                AttrName: aname
                            }, None, None)
                        node.addChild(t)
                    for t in argdefs:
                        t.addAttr(AttrType, typequal + atype)

        for c in node.children_:
            regularize(c)

    return node
Exemple #2
0
 def createChild(self, parent, childName):
   name = childName
   childTag = parent.getElementsByTagName(name)
   if childTag:
     childTag = childTag[0]
   else:
     childTag = microdom.MicroDom({"tag_":name},[],[])
     parent.addChild(childTag)
   return childTag
Exemple #3
0
def fixupFileDocstring(xml):
    # This is a docstring that should be associated with the whole file
    tmp = filter(lambda x: isInstanceOf(x, microdom.MicroDom), xml.children_)
    if tmp:  # If there is ANY documentation at all:
        t = tmp[0]
        if int(t.linenum) == 1:
            #pdb.set_trace()
            if t.tag_ == "_":
                (briefText, sp, desc) = t.data_.partition("\n")
                t.data_ = desc.strip()
                #        if type(t.children_[0]) in StringTypes:  # Clean it up in the children list as well
                #          (briefText,sp,desc) = tmp[0].partition("\n")
                #          t.children_[0] = desc.strip()

                xml.addChild(
                    microdom.MicroDom({"tag_": TagBrief}, [briefText.strip()]))
                t.reTag(TagDesc)
            for c in t.children_:  # Pull all the tags that shouldn't be in the Desc out of it
                if isInstanceOf(c, microdom.MicroDom) and c.tag_ in NoDescTags:
                    c.reParent(xml)
Exemple #4
0
def regularize(node, zzdepth=0):
    """?? This function ensures that the tree is complete and regular.  For example it breaks descriptions into brief and desc tags.
  """

    if 0:  # Print the nodes
        try:
            t = node.pfxsfx()
            print "**" + ("  " * zzdepth) + t[0]
        except AttributeError:
            print "**" + str("  " * zzdepth) + str(node)

    # Regularize the children
    try:
        children = node.children_
    except AttributeError:
        children = []

    for c in children:
        regularize(c, zzdepth + 1)

    # Combine common children (in this case sections with the same name)
    lkup = {}
    for c in children:
        if microdom.isInstanceOf(
                c, microdom.MicroDom
        ) and c.tag_ in CombinedTags:  # It is a candidate to be merged
            if lkup.has_key(
                    c.tag_ +
                    c.name):  # Yes there is another tag, so it must be merged
                orig = lkup[c.tag_ + c.name]
                orig.merge(c)
            else:
                lkup[c.tag_ + c.name] = c

    if microdom.isInstanceOf(node, microdom.MicroDom):

        # Add an empty "type" attribute if it does not have one
        if node.tag_ in TypedTags:
            if not node.attributes_.has_key(AttrType):
                node.attributes_[AttrType] = ""

        if node.tag_ in ConstructTags:
            #print str(node)

            # Regularize the "brief" and "desc" children

            if not node.child_.has_key(TagDesc):
                # Split the children into who should go under the desc and who should go back under me
                chLst = node.removeChildren()
                (descChildren, myChildren) = split(
                    lambda x:
                    (not microdom.isInstanceOf(x, microdom.MicroDom)) or
                    (not x.tag_ in NoDescTags), chLst)
                #descChildren = filter(lambda x: (not microdom.isInstanceOf(x,microdom.MicroDom)) or (not x.tag_ in NoDescTags)  ,node.children_)
                #myChildren   = filter(lambda x: not((not microdom.isInstanceOf(x,microdom.MicroDom)) or (not x.tag_ in NoDescTags))  ,node.children_)

                # Reset me with new children (but all else the same)
                #node.reset(node.attributes_,myChildren,None,node.parent_)
                for c in myChildren:
                    node.addChild(c)
                # Add the Desc tag
                node.addChild(
                    microdom.MicroDom({"tag_": TagDesc}, descChildren, None,
                                      node))
                #node.addChild(microdom.MicroDom({"tag_":TagDesc},[],None,node))

            if not node.child_.has_key(TagBrief):
                candidate = node.data_.split("\n")[0].split(". ")[
                    0]  # Get the first sentence in the first line
                if candidate:  # If there is something then use it as the brief
                    brief = candidate + "..."
                else:  # Or use the 1st sentence of the description
                    brief = node.child_[TagDesc].data_.split(". ")[0] + "..."
                t = microdom.MicroDom({"tag_": TagBrief}, [brief], None)
                node.addChild(t)

            # If there is no "decl" then use the name
            # TODO: we could search for TagParam children to build the declaration
            # But really dp.py should generate the decl
            if node.tag_ in [TagFunction, TagMethod]:
                if not node.child_.has_key(TagDecl):
                    t = microdom.MicroDom({"tag_": TagDecl}, [node.name], None)
                    node.addChild(t)

    return node
Exemple #5
0
    def recurse(nlst, context=None, forceParentNode=None):

        for node in nlst:
            xmlnode = findRelevantTag(xml, node.lineno)
            #print xmlnode
            if xmlnode is None: xmlnode = xml

            # Imports
            if isInstanceOf(node, ast.ImportFrom):
                fdxml = xmlnode.findParent(TagFile)[0]
                fdxml.addChild(
                    microdom.MicroDom(
                        {
                            "tag_": "requires",
                            "module": node.module,
                            "linenum": node.lineno
                        }, [], None))

            if isInstanceOf(node, ast.Import):
                fdxml = xmlnode.findParent(TagFile)[0]
                for mod in node.names:
                    fdxml.addChild(
                        microdom.MicroDom(
                            {
                                "tag_": "requires",
                                "module": mod.name,
                                "linenum": node.lineno
                            }, [], None))

            # Assignment / Variable declaration
            elif isInstanceOf(node, ast.Assign):
                if context == TagCtor:
                    varnames = []
                    for tgt in node.targets:
                        try:
                            varnames.append(tgt.attr)
                        except AttributeError:
                            log.warning("Skipping ctor assignment %s" %
                                        str(tgt))
                            pass

                else:
                    varnames = [getLvalue(tgt) for tgt in node.targets]

                if len(varnames) == 1:
                    varnames = varnames[0]

                # I'm trying to grab the value of an assignment to put into the documentation, i.e. MY_CONST = 50
                val = None
                try:
                    val = node.value.n  # for numbers
                except:
                    pass
                try:
                    val = node.value.s  # for strings
                except:
                    pass
                try:
                    val = node.value.id  # for names (modules)
                except:
                    pass

                if val == None:
                    # But if the assignment is complex, then it does not make any sense to grab it
                    # But maybe you can make sense of these and figure out some cool documentation to add?
                    if isInstanceOf(node.value, ast.Subscript): pass
                    elif isInstanceOf(node.value, ast.Dict): pass
                    elif isInstanceOf(node.value, ast.List): pass
                    elif isInstanceOf(node.value, ast.Call): pass
                    elif isInstanceOf(node.value, ast.Attribute): pass
                    elif isInstanceOf(node.value, ast.BinOp): pass
                    elif isInstanceOf(node.value, ast.IfExp): pass
                    elif isInstanceOf(node.value, ast.Tuple): pass
                    elif isInstanceOf(node.value, ast.Lambda): pass
                    elif isInstanceOf(node.value, ast.ListComp): pass
                    elif isInstanceOf(node.value, ast.Compare): pass
                    else:
                        pdb.set_trace()

                xmlAttrInsert(xmlnode, {
                    AttrTag: TagVariable,
                    AttrName: varnames,
                    AttrValue: val
                })

            # Function handling
            elif isInstanceOf(node, ast.FunctionDef):
                fdxml = xmlnode.findParent(TagFunction)
                if not fdxml: fdxml = xmlnode
                else: fdxml = fdxml[0]

                if node.name == fdxml.attributes_.get(
                        "name", node.name
                ):  # If it HAS a name, its has to be == or I've got the wrong comment

                    # The comments form an XML tree, and the language structure forms a tree as well.
                    # If the language structure's tree should override the XML tree, then forceParentNode
                    # will be true and so this comment will be extracted from its current location and pushed under the forceParentNode
                    # This happens when a class defines its member functions, for example and the user uses ?? instead of correctly matching
                    # xml class scope with the true class scope.
                    if forceParentNode and forceParentNode != fdxml:
                        fdxml.extract()
                        forceParentNode.addChild(fdxml)

                    xmlAttrInsert(fdxml, {
                        AttrTag: TagFunction,
                        AttrName: node.name
                    })
                # If its a constructor, hunt thru for member variables
                if node.name == "__init__": recurse(node.body, TagCtor)

            # Class handling
            elif isInstanceOf(node, ast.ClassDef):
                fdxml = xmlnode.findParent(TagClass)
                if not fdxml: fdxml = xmlnode
                else: fdxml = fdxml[0]

                fp = None

                # TODO: This class has no documentation, create it based on configuration option
                if fdxml.tag_ != TagClass and fdxml.tag_ != "_":
                    pass
                else:
                    xmlAttrInsert(fdxml, {
                        AttrTag: TagClass,
                        AttrName: node.name
                    })
                    recurse(node.body, TagClass, fdxml)

            elif isInstanceOf(node, ast.Expr) or isInstanceOf(node, ast.If):
                pass
                #- pdb.set_trace()
            else:
                log.warning("unrecognised node %s" % str(node))
Exemple #6
0
  def updateMicrodom(self):
    """Write the dynamically changing information back to the loaded microdom tree.
       The reason I don't create an entirely new tree is to preserve any application extensions that might have been put into the file.
    """
    # First, update the model to make sure that it is internally consistent
    for (name,i) in self.instances.items():
      for parent in filter(lambda ent: isinstance(ent, Entity), i.childOf):  # If the object has parent pointers, update them.  This is pretty specific to SAFplus data types...
        fieldName = parent.et.name[0].lower() + parent.et.name[1:]  # uncapitalize the first letter to make it use SAFplus bumpycase
        if i.data.has_key(fieldName):
          i.data[fieldName] = parent.data["name"]

    # Locate or create the needed sections in the XML file

    #   find or create the entity area in the microdom
    entities = self.data.getElementsByTagName("entities")
    if not entities:
      entities = microdom.MicroDom({"tag_":"entities"},[],[])
      self.data.addChild(entities)
    else: 
      assert(len(entities)==1)
      entities = entities[0]
    
    # Find or create the GUI area in the microdom.  The GUI area is structured like:
    # ide
    #   ide_entity_info
    #   ide_instance_info
    ide = self.data.getElementsByTagName("ide")
    if not ide:
      ide = microdom.MicroDom({"tag_":"ide"},[],[])
      self.data.addChild(ide)
    else: 
      assert(len(ide)==1)
      ide = ide[0]
          
    ideEntities = ide.getElementsByTagName("ide_entity_info")
    if not ideEntities:
      ideEntities = microdom.MicroDom({"tag_":"ide_entity_info"},[],[])
      ide.addChild(ideEntities)
    else: 
      assert(len(ideEntities)==1)
      ideEntities = ideEntities[0]

    ideInsts = ide.getElementsByTagName("ide_instance_info")
    if not ideInsts:
      ideInsts = microdom.MicroDom({"tag_":"ide_instance_info"},[],[])
      ide.addChild(ideInsts)
    else: 
      assert(len(ideInsts)==1)
      ideInsts = ideInsts[0]
    

    # Write out the entities


    #   iterate through all entities writing them to the microdom, or changing the existing microdom
    for (name,e) in self.entities.items():
      # Find the existing DOM nodes for the entity information, creating the node if it is missing
      entity = entities.findOneByChild("name",name)
      if not entity:
        entity = microdom.MicroDom({"tag_":e.et.name},[],[])
        entities.addChild(entity)
      ideEntity = ideEntities.getElementsByTagName(name)
      if ideEntity: ideEntity = ideEntity[0]
      else:
        ideEntity = microdom.MicroDom({"tag_":name},[],[])
        ideEntities.addChild(ideEntity)

      # Remove all "None", replacing with the default or ""
      temp = {}
      for (key,val) in e.data.items():
        if val is None:
          val = e.et.data[key].get("default",None)
          if val is None:
            val = ""
        if val == "None": val = ""
        temp[key] = val

      # Write all the data fields into the model's microdom
      entity.update(temp)
      # write the IDE specific information to the IDE area of the model xml
      ideEntity["position"] = str(e.pos)
      ideEntity["size"] = str(e.size) 
      # Now write all the arrows
      contains = {} # Create a dictionary to hold all linkages by type
      for arrow in e.containmentArrows:
        # Add the contained object to the dictionary keyed off of the object's entitytype
        tmp = contains.get(arrow.contained.et.name,[])
        tmp.append(arrow.contained.data["name"])
        contains[arrow.contained.et.name] = tmp
        # TODO: write the containment arrow IDE specific information to the IDE area of the model xml
        self.writeContainmentArrow(ideEntity, arrow)
      # Now erase the missing linkages from the microdom
      for (key, val) in self.entityTypes.items():   # Look through all the children for a key that corresponds to the name of an entityType (+ s), eg: "ServiceGroups"
          if not contains.has_key(key): # Element is an entity type but no linkages
            if entity.child_.has_key(key + 's'): entity.delChild(key + 's')
      # Ok now write the linkages to the microdom
      for (key, val) in contains.items():
        k = key + "s"
        if entity.child_.has_key(k): entity.delChild(k)
        entity.addChild(microdom.MicroDom({"tag_":k},[",".join(val)],""))  # TODO: do we really need to pluralize?  Also validate comma separation is ok

      # Building instance lock fields
      etType = ide.getElementsByTagName(e.et.name)
      if not etType:
        etType = microdom.MicroDom({"tag_":e.et.name},[],[])
        ide.addChild(etType)
      else: 
        assert(len(etType)==1)
        etType = etType[0]
      et = etType.getElementsByTagName(name)
      if not et:
        et = microdom.MicroDom({"tag_":name},[],[])
        etType.addChild(et)
      else: 
        assert(len(et)==1)
        et = et[0]

      et.update(e.instanceLocked)


    # Find or create the instance area in the microdom
    instances = self.data.getElementsByTagName("instances")
    if not instances:
      instances = microdom.MicroDom({"tag_":"instances"},[],[])
      self.data.addChild(instances)
    else: 
      assert(len(instances)==1)
      instances = instances[0]

    # iterate through all instances writing them to the microdom, or changing the existing microdom
    for (name,e) in self.instances.items():
      instance = instances.findOneByChild("name",name)
      if not instance:
        instance = microdom.MicroDom({"tag_":e.et.name},[],[])
        instances.addChild(instance)

      # Remove all "None", replacing with the default or ""
      temp = {}      
      for (key,val) in e.data.items():
        if val is None:
          val = e.et.data[key].get("default",None)
          if val is None:
            val = ""
        if val == "None": val = ""
        temp[key] = val

      # Add module and xpath attributes
      instance.addAttribute("xpath",e.entity.et.data["xpath"] + ("[@name=\"%s\"]" % e.data["name"]))
      instance.addAttribute("module",e.entity.et.data["module"])

      # Write all the data fields into the model's microdom
      instance.update(temp)  
      # Now write all the arrows
      contains = {} # Create a dictionary to hold all linkages by type
      for arrow in e.containmentArrows:
        # Add the contained object to the dictionary keyed off of the object's entitytype
        # leaf-list entity type with camelCase(s)
        key = arrow.contained.et.name[0].lower() + arrow.contained.et.name[1:] + 's'
        tmp = contains.get(key,[])
        tmp.append(arrow.contained.data["name"])
        contains[key] = tmp

      # Now erase the missing linkages from the microdom
      for (key, val) in self.entityTypes.items():   # Look through all the children for a key that corresponds to the name of an entityType (+ s), eg: "serviceUnits"
          key = key[0].lower() + key[1:] + 's'
          if not contains.has_key(key): # Element is an entity type but no linkages
            if instance.child_.has_key(key): instance.delChild(key)

      # Ok now write the linkages to the microdom
      for (key, vals) in contains.items():
        if instance.child_.has_key(key): instance.delChild(key)
        for val in vals:
          instance.addChild(microdom.MicroDom({"tag_":key},[val],""))  # TODO: do we really need to pluralize?  Also validate comma separation is ok

      # Extra parent entity name
      entityParentVal = e.entity.data["name"]
      entityParentKey = "%sType"%e.et.name
      if instance.child_.has_key(entityParentKey): instance.delChild(entityParentKey)
      instance.addChild(microdom.MicroDom({"tag_":entityParentKey},[entityParentVal],""))