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
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
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
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
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
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
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)
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
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
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)
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
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
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
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