Example #1
0
def getClassName(classNode):

    className = u''

    # check start node
    if classNode.type == "call":
        qxDefine = selectNode(classNode, "operand/variable")
        if qxDefine:
            qxDefineParts = qxDefine.children
    else:
        qxDefineParts = []
    if (qxDefineParts and len(qxDefineParts) > 2
            and qxDefineParts[0].get('name') == "qx"
            and qxDefineParts[2].get('name') == "define"):
        pass  # ok
    else:
        raise tree.NodeAccessException(
            "Expected qx define node (as from findQxDefine())", classNode)

    # get top-level class map
    nameNode = selectNode(classNode, "params/constant")

    if not nameNode or nameNode.type != "constant":
        raise tree.NodeAccessException("Expected a constant node!", nameNode)

    className = nameNode.get("value")

    return className
Example #2
0
def getClassMap(classNode):
    # return a map {'extend':..., 'include':..., 'members':...}, with nested keys present in the map,
    # and code given as a tree nodes
    classMap = {}

    # check start node
    if classNode.type == "call":
        qxDefine = selectNode(classNode, "operand/variable")
        if qxDefine:
            qxDefineParts = qxDefine.children
    else:
        qxDefineParts = []
    if (qxDefineParts and len(qxDefineParts) > 2
            and qxDefineParts[0].get('name') == "qx"
            and qxDefineParts[2].get('name') == "define"):
        pass  # ok
    else:
        raise tree.NodeAccessException(
            "Expected qx define node (as from findQxDefine())", classNode)

    # get top-level class map
    mapNode = selectNode(classNode, "params/map")

    if not mapNode or mapNode.type != "map":
        raise tree.NodeAccessException("Expected a map node!", mapNode)

    if mapNode.hasChildren():
        for child in mapNode.children:
            if child.type == "keyvalue":
                keyvalue = child.getChild("value").getFirstChild(True, True)
                if keyvalue.type == "map":
                    keyvalue = mapNodeToMap(keyvalue)
                classMap[child.get("key")] = keyvalue

    return classMap
Example #3
0
def assembleVariable(variableItem):
    """
    Return the full variable name from a variable node, and an isComplete flag if the name could
    be assembled completely.
    """
    if variableItem.type != "variable":
        raise tree.NodeAccessException("'variableItem' is no variable node",
                                       variableItem)

    assembled = ""
    for child in variableItem.children:
        if child.type == "commentsBefore":
            continue
        elif child.type == "accessor":
            for value in child.children:
                if value.type == "identifier":
                    if assembled:
                        assembled += "."
                    return assembled + value.get("name"), False
            return assembled, False
        elif child.type != "identifier":
            # this means there is some accessor like part in the variable
            # e.g. foo["hello"]
            return assembled, False

        if len(assembled) != 0:
            assembled += "."

        assembled += child.get("name")

    return assembled, True
Example #4
0
def variableOrArrayNodeToArray(node):
    """
    Normalizes a variable node or an array node containing variables
    to a python array of the variable names
    """

    arr = []
    if node.type == "array":
        if not node.children:
            raise tree.NodeAccessException("node has no children", node)
        for child in node.children:
            if child.isVar():
                arr.append(child.toJS(pp))
    elif node.isVar():
        arr.append(node.toJS(pp))
    else:
        raise tree.NodeAccessException("'node' is no variable or array node", node)
    return arr
Example #5
0
def assembleVariable(variableItem):
    """
    Return the full variable name from a variable node, and an isComplete flag if the name could
    be assembled completely.
    """
    if variableItem.type not in tree.NODE_VARIABLE_TYPES:
        raise tree.NodeAccessException("'variableItem' is no variable node", variableItem)

    else:
        varRoot = findVarRoot(variableItem)
        return varRoot.toJS(pp), True
Example #6
0
def mapNodeToMap(mapNode):
    """
    convert a "map" tree node into a python map.
    """
    if mapNode.type != "map":
        raise tree.NodeAccessException("Expected a map node!", mapNode)

    keys = {}
    if mapNode.hasChildren():
        for child in mapNode.children:
            if child.type == "keyvalue":
                keys[child.get("key")] = child.getChild("value")

    return keys
Example #7
0
def inlineIfStatement(ifNode, conditionValue):
    """
    Inline an if statement assuming that the condition of the if
    statement evaluates to "conditionValue" (True/False")
    """

    if ifNode.type != "loop" or ifNode.get("loopType") != "IF":
        raise tree.NodeAccessException("Expected a the LOOP node of an if statement!", mapNode)

    replacement = []
    newDefinitions = []
    reovedDefinitions = []

    if ifNode.getChild("elseStatement", False):
        if conditionValue:
            reovedDefinitions = getDefinitions(ifNode.getChild("elseStatement"))
            newDefinitions = getDefinitions(ifNode.getChild("statement"))
            replacement = ifNode.getChild("statement").children
        else:
            reovedDefinitions = getDefinitions(ifNode.getChild("statement"))
            newDefinitions = getDefinitions(ifNode.getChild("elseStatement"))
            replacement = ifNode.getChild("elseStatement").children
    else:
        if conditionValue:
            newDefinitions = getDefinitions(ifNode.getChild("statement"))
            replacement = ifNode.getChild("statement").children
        else:
            reovedDefinitions = getDefinitions(ifNode.getChild("statement"))

    newDefinitions = map(lambda x: x.get("identifier"), newDefinitions)
    definitions = []
    for definition in reovedDefinitions:
        if not definition.get("identifier") in newDefinitions:
            definitions.append(definition)

    if len(definitions) > 0:
        defList = tree.Node("definitionList")
        defList.set("line", ifNode.get("line"))
        for definition in definitions:
            if definition.hasChildren():
                del definition.children
            defList.addChild(definition)
        replacement.append(defList)

    if replacement != []:
        replaceChildWithNodes(ifNode.parent, ifNode, replacement)
    else:
        emptyBlock = tree.Node("block");
        emptyBlock.set("line", ifNode.get("line"))
        ifNode.parent.replaceChild(ifNode, emptyBlock)
Example #8
0
def getClassName(classNode):

    className = u''

    # check start node
    _checkQxDefineNode(classNode)

    # get top-level class map
    nameNode = selectNode(classNode, "arguments/constant")

    if not nameNode or nameNode.type != "constant":
        raise tree.NodeAccessException("Expected a constant node!", nameNode)

    className = nameNode.get("value")

    return className
Example #9
0
def variableOrArrayNodeToArray(node):
    """
    Normalizes a variable node or an array node containing variables
    to a python array of the variable names
    """

    arr = []
    if node.type == "array":
        for child in node.children:
            if child.type == "variable":
                arr.append((assembleVariable(child))[0])
    elif node.type == "variable":
        arr.append((assembleVariable(node))[0])
    else:
        raise tree.NodeAccessException("'node' is no variable or array node", node)
    return arr
Example #10
0
def _checkQxDefineNode(node):
    if node.type == "call":
        qxDefine = selectNode(node, "operand/dotaccessor")
        if qxDefine:
            qxDefineParts = qxDefine.toJS(pp).split('.')
        else:
            qxDefineParts = []
    else:
        qxDefineParts = []
    if (qxDefineParts and len(qxDefineParts) > 2 and qxDefineParts[0] == "qx"
            and qxDefineParts[2] == "define"):
        pass  # ok
    elif (qxDefineParts == ["q", "define"]):
        pass  # ok
    else:
        raise tree.NodeAccessException(
            "Expected qx define node (as from findQxDefine())", node)
Example #11
0
def getClassMap(classNode):
    # return a map {'extend':..., 'include':..., 'members':...}, with nested keys present in the map,
    # and code given as a tree nodes
    classMap = {}

    # check start node
    _checkQxDefineNode(classNode)

    # get top-level class map
    mapNode = selectNode(classNode, "arguments/map")

    if not mapNode or mapNode.type != "map":
        raise tree.NodeAccessException("Expected a map node!", mapNode)

    if mapNode.hasChildren():
        for child in mapNode.children:
            if child.type == "keyvalue":
                keyvalue = child.getChild("value").getFirstChild(True, True)
                if keyvalue.type == "map":
                    keyvalue = mapNodeToMap(keyvalue)
                classMap[child.get("key")] = keyvalue

    return classMap
Example #12
0
def inlineIfStatement(ifNode, conditionValue, inPlace=True):
    """
    Inline an if statement assuming that the condition of the if
    statement evaluates to "conditionValue" (True/False")
    """

    if ifNode.type != "loop" or ifNode.get("loopType") != "IF":
        raise tree.NodeAccessException(
            "Expected the LOOP node of an if statement!", ifNode)

    replacement = None
    replacement_is_empty = False
    newDefinitions = []
    removedDefinitions = []

    if len(ifNode.children) == 3:  # there is an 'else' part
        if conditionValue:
            removedDefinitions = getDefinitions(ifNode.children[2])
            newDefinitions = getDefinitions(ifNode.children[1])
            replacement = ifNode.children[1].children[
                0]  # <body>.children: single node, <block> or <statement>
        else:
            removedDefinitions = getDefinitions(ifNode.children[1])
            newDefinitions = getDefinitions(ifNode.children[2])
            replacement = ifNode.children[2].children[0]
    else:
        if conditionValue:
            newDefinitions = getDefinitions(ifNode.children[1])
            replacement = ifNode.children[1].children[0]
        else:
            removedDefinitions = getDefinitions(ifNode.children[1])
            # don't leave single-statement parent loops empty
            emptyBlock = treegenerator.symbol("block")()
            emptyBlock.set("line", ifNode.get("line"))
            stmts = treegenerator.symbol("statements")()
            stmts.set("line", ifNode.get("line"))
            emptyBlock.addChild(stmts)
            replacement = emptyBlock
            replacement_is_empty = True

    # Rescue var decls
    newDefinitions = [x.getDefinee().get("value") for x in newDefinitions]
    definitions = []
    for definition in removedDefinitions:
        if not definition.getDefinee().get("value") in newDefinitions:
            definitions.append(definition)

    if len(definitions) > 0:
        defList = treegenerator.symbol("var")()
        defList.set("line", ifNode.get("line"))
        defList.set("column", ifNode.get("column"))
        for definition in definitions:
            # remove initialisations
            if definition.children[0].type == "identifier":
                pass
            else:  # assignment
                idf = definition.getDefinee()
                definition.children[0] = idf
            defList.addChild(definition)

        # attach defList to replacement
        if replacement.type != 'block':  # treat single-statement branches
            block = treegenerator.symbol("block")()
            block.set("line", ifNode.get("line"))
            stmts = treegenerator.symbol("statements")()
            stmts.set("line", ifNode.get("line"))
            block.addChild(stmts)
            stmts.addChild(replacement)
            replacement = block
        replacement.getChild("statements").addChild(defList, 0)
        replacement_is_empty = False

    # move replacement
    if inPlace:
        if (replacement_is_empty and ifNode.parent.type in ["statements"]):
            ifNode.parent.removeChild(ifNode)
        else:
            ifNode.parent.replaceChild(ifNode, replacement)

    return replacement, replacement_is_empty
Example #13
0
def inlineIfStatement(ifNode, conditionValue):
    """
    Inline an if statement assuming that the condition of the if
    statement evaluates to "conditionValue" (True/False")
    """

    if ifNode.type != "loop" or ifNode.get("loopType") != "IF":
        raise tree.NodeAccessException(
            "Expected the LOOP node of an if statement!", mapNode)

    replacement = []
    newDefinitions = []
    removedDefinitions = []

    if ifNode.getChild("elseStatement", False):
        if conditionValue:
            removedDefinitions = getDefinitions(
                ifNode.getChild("elseStatement"))
            newDefinitions = getDefinitions(ifNode.getChild("statement"))
            replacement = ifNode.getChild("statement").children
        else:
            removedDefinitions = getDefinitions(ifNode.getChild("statement"))
            newDefinitions = getDefinitions(ifNode.getChild("elseStatement"))
            replacement = ifNode.getChild("elseStatement").children
    else:
        if conditionValue:
            newDefinitions = getDefinitions(ifNode.getChild("statement"))
            replacement = ifNode.getChild("statement").children
        else:
            removedDefinitions = getDefinitions(ifNode.getChild("statement"))

    newDefinitions = map(lambda x: x.get("identifier"), newDefinitions)
    definitions = []
    for definition in removedDefinitions:
        if not definition.get("identifier") in newDefinitions:
            definitions.append(definition)

    if len(definitions) > 0:
        defList = tree.Node("definitionList")
        defList.set("line", ifNode.get("line"))
        for definition in definitions:
            if definition.hasChildren():
                #del definition.children
                definition.children = []
            defList.addChild(definition)

        # move defList to higher node
        node = ifNode
        while node.type != "block":
            if node.hasParent():
                node = node.parent
            else:
                break
        node.addChild(defList, 0)

    # move replacement
    if replacement:
        replacement = replacement[:]  # retain copy for return value
        replaceChildWithNodes(ifNode.parent, ifNode, replacement)
    else:
        emptyBlock = tree.Node("block")
        emptyBlock.set("line", ifNode.get("line"))
        # TODO: experimental bug#4734: is this enough?
        if (ifNode.parent.type in ["block", "file"]):
            ifNode.parent.removeChild(ifNode)
        else:
            # don't leave single-statement parent loops empty
            ifNode.parent.replaceChild(ifNode, emptyBlock)
        replacement = [emptyBlock]

    return replacement
Example #14
0
def inlineIfStatement(ifNode, conditionValue):
    """
    Inline an if statement assuming that the condition of the if
    statement evaluates to "conditionValue" (True/False")
    """

    if ifNode.type != "loop" or ifNode.get("loopType") != "IF":
        raise tree.NodeAccessException("Expected the LOOP node of an if statement!", mapNode)

    replacement = []
    newDefinitions = []
    removedDefinitions = []

    if len(ifNode.children)==3:  # there is an 'else' part
        if conditionValue:
            removedDefinitions = getDefinitions(ifNode.children[2])
            newDefinitions = getDefinitions(ifNode.children[1])
            replacement = ifNode.children[1].children[0].children
        else:
            removedDefinitions = getDefinitions(ifNode.children[1])
            newDefinitions = getDefinitions(ifNode.children[2])
            replacement = ifNode.children[2].children[0].children
    else:
        if conditionValue:
            newDefinitions = getDefinitions(ifNode.children[1])
            replacement = ifNode.children[1].children[0].children
        else:
            removedDefinitions = getDefinitions(ifNode.children[1])

    newDefinitions = [x.getDefinee().get("value") for x in newDefinitions]
    definitions = []
    for definition in removedDefinitions:
        if not definition.getDefinee().get("value") in newDefinitions:
            definitions.append(definition)

    if len(definitions) > 0:
        defList = treegenerator.symbol("var")()
        defList.set("line", ifNode.get("line"))
        defList.set("column", ifNode.get("column"))
        for definition in definitions:
            # remove initialisations
            if definition.children[0].type == "identifier":
                pass
            else: # assignment
                idf = definition.getDefinee()
                definition.children[0] = idf
            defList.addChild(definition)

        # move defList to higher node
        node = ifNode
        while node.type not in ("statements",):
            if node.parent:
                node = node.parent
            else:
                break
        node.addChild(defList,0)

    # move replacement
    if replacement:
        replacement = replacement[:] # retain copy for return value
        replaceChildWithNodes(ifNode.parent, ifNode, replacement)
    else:
        emptyBlock = treegenerator.symbol("block")()
        emptyBlock.set("line", ifNode.get("line"))
        # TODO: experimental bug#4734: is this enough?
        if (ifNode.parent.type in ["block", "file"]):
            ifNode.parent.removeChild(ifNode)
        else:
            # don't leave single-statement parent loops empty
            ifNode.parent.replaceChild(ifNode, emptyBlock)
        replacement = [emptyBlock]

    return replacement